diff --git a/gestion/config.py b/gestion/config.py index 306d173d..f177b868 100644 --- a/gestion/config.py +++ b/gestion/config.py @@ -383,6 +383,22 @@ domains = { 'machineFixe': 'crans.org', 'machineWifi': 'wifi.crans.org', 'borneWifi': 'wifi.crans.org' } +# VLans +vlans = { + # VLan d'administration + 'adm' : 2, + # VLan pour le wifi + 'wifi' : 3, + # VLan pour le wifi de l'ens + 'hotspot' : 4, + # VLan des gens qui paient + 'adherent' : 1, + # VLan des inconnus + 'accueil' : 7, + # VLan des radins + 'radin' : 6 + } + ####################### ## Mail de bienvenue ## ####################### diff --git a/gestion/gen_confs/switchs.py b/gestion/gen_confs/switchs.py index 3ef0407c..13903409 100755 --- a/gestion/gen_confs/switchs.py +++ b/gestion/gen_confs/switchs.py @@ -23,6 +23,7 @@ from annuaires import chbre_prises, uplink_prises, reverse, bat_manuels, all_swi from random import shuffle from gen_confs import * from time import localtime +import config from annuaires import bat_switchs @@ -57,31 +58,36 @@ logging 10.231.136.7 %(INTERFACES_CONF)s ;-------------------------------------------------------- IP du switch ip default-gateway 10.231.136.4 -vlan 1 +vlan %(vlan_adherent)s name "DEFAULT_VLAN" - %(prises_default)s + untagged %(prises_default)s no ip address ip igmp no ip igmp querier exit -vlan 2 +vlan %(vlan_adm)s name "Adm" - %(prises_adm)s + %(prises_adm)s ip address %(ip)s 255.255.255.0 exit -vlan 3 +vlan %(vlan_wifi)s name "Wifi" %(prises_wifi)s no ip address exit -vlan 4 +vlan %(vlan_hotspot)s name "Hotspot" %(prises_hotspot)s no ip address exit -vlan 6 +vlan %(vlan_radin)s name "Radin" - %(prises_radin) + tagged %(prises_default)s + no ip address + exit +vlan %(vlan_accueil)s + name "Accueil" + tagged %(prises_default)s no ip address exit ;------------------------------------------------------- Accès d'administration @@ -116,7 +122,7 @@ no cdp run no stack """ - interface_template = """interface %(prise)i%(etat)s + interface_template = """interface %(prise)i enable name "%(nom)s" flow-control%(speed)s no lacp @@ -283,8 +289,10 @@ exit vlans = { 'wifi_tagged' : [] , 'wifi_untagged' : [] , 'hotspot_tagged' : [], 'hotspot_untagged' : [], 'adm_tagged' : [] , 'adm_untagged' : [] , - 'default_tagged' : [] , 'default_untagged' : [], - 'radin_tagged' : [], 'radin_untagged' : [] } + + # VLans pour le reste: le vlan des adhérents, des + # inconnus et de ceux qui ne paie pas + 'default' : [] } # Génération de la conf de chaque prise for prise in range(1,nb_prises+1): @@ -299,11 +307,10 @@ exit ### Prise d'uplink prise_params['nom'] = uplink_prises[bat][int(annu_prise)] params['uplinks'].append(prise) - vlans['default_untagged'].append(prise) + vlans['default'].append(prise) vlans['adm_tagged'].append(prise) vlans['wifi_tagged'].append(prise) vlans['hotspot_tagged'].append(prise) - vlans['radin_tagged'].append(prise) params['INTERFACES_CONF'] += self.interface_template % prise_params continue @@ -329,7 +336,7 @@ exit if len(chbres) > 1 : prise_params['nom'] += 's' for chbre in chbres : prise_params['nom'] += '_%s%s' % (bat.upper(), chbre) - vlans['default_untagged'].append(prise) + vlans['default'].append(prise) else : prise_params['nom'] = "Wifi" vlans['hotspot_tagged'].append(prise) @@ -344,58 +351,36 @@ exit else : # Tous les vlans prise_params['nom'] = "Prise_crans" - vlans['default_untagged'].append(prise) + vlans['default'].append(prise) vlans['adm_tagged'].append(prise) vlans['wifi_tagged'].append(prise) vlans['hotspot_tagged'].append(prise) - vlans['radin_tagged'].append(prise) params['INTERFACES_CONF'] += self.interface_template % prise_params continue - - # A quelle chambre correspond la prise ? - if prise_chbres.has_key(annu_prise) : - chbres = prise_chbres[annu_prise] - elif prise_chbres.has_key(annu_prise+'-') : - # Prise en 10 - prise_params['speed'] = '\n speed-duplex auto-10' - chbres = prise_chbres[annu_prise+'-'] - else : - # Prise non référencée dans l'annuaire - prise_params['nom'] = "Pas_dans_l'annuaire" - prise_params['etat']='\n disable' - params['INTERFACES_CONF'] += self.interface_template % prise_params - continue - + + # Quelle(s) chambre(s) est/sont sur la prise. A cause du + # cas PDJ il peux y avoir des prises avec plusieurs + # chambres. + chbres = prise_chbres.get(annu_prise, []) + + # "unauth-vid" est le vlan sur lequel sont envoyé les + # inconnus, qui est le vlan d'accueil params['INTERFACES_CONF'] += """aaa port-access mac-based %(prise)s aaa port-access mac-based %(prise)s addr-limit %(nbmac)s aaa port-access mac-based %(prise)s logoff-period 3600 +aaa port-access mac-based %(prise)s unauth-vid 7 """ % { 'nbmac': 1+2*len(chbres), 'prise': prise } - ## Configuration de la prise adhérent - # Nom - prise_params['nom'] = 'Chambre' - if len(chbres) > 1 : prise_params['nom'] += 's' - for chbre in chbres : - prise_params['nom'] += '_%s%s' % (bat.upper(), chbre) - - # Besoin d'activer la prise ? - prise_params['etat']='\n disable' - for chbre in chbres : - res = self.db.search('chbre=%s%s' % (bat.upper(), chbre) ) - quelqu_un_a_paye = False - for res in res['adherent'] + res['club'] : - if res.adherentPayant() : - quelqu_un_a_paye = True - if 'bloq' not in res.blacklist_actif() : - prise_params['etat']='' - break - if quelqu_un_a_paye : - # Si quelqu'un a payé on lui met le vlan default - vlans['default_untagged'].append(prise) - else : - # Sinon tout le monde reste sur le vlan radin - vlans['radin_untagged'].append(prise) + # On donne à la prise un nom qui dépend des chambres + # connectés dessus + if chbres : + prise_params['nom'] = 'Chambre' + if len(chbres) > 1 : prise_params['nom'] += 's' + for chbre in chbres : + prise_params['nom'] += '_%s%s' % (bat.upper(), chbre) + else : + prise_params['nom'] = 'Inconnu' params['INTERFACES_CONF'] += self.interface_template % prise_params @@ -442,15 +427,18 @@ aaa port-access mac-based %(prise)s logoff-period 3600 for key, prises in vlans.items() : vlans[key]=mk_list(prises) - # Config des vlan - for v in ('default', 'adm', 'wifi', 'hotspot', 'radin') : + # Config des vlans spéciaux (adm et wifi) + for v in ('adm', 'wifi', 'hotspot') : params['prises_%s' % v] = '' for t in ('tagged' , 'untagged') : if vlans['%s_%s' % (v,t)] : params['prises_%s' % v] += '\n %s %s' % (t, vlans['%s_%s' % (v,t)]) # Saut de ligne parasite params['prises_%s' % v] = params['prises_%s' % v][4:] - + + for name, number in config.vlans: + params["vlan_%s" % name] = number + # Ecriture fd = self._open_conf(self.CONF_REP + switch + '.conf') fd.write(self.config % params) diff --git a/gestion/ldap_crans.py b/gestion/ldap_crans.py index f71e2c8e..7fb905bc 100755 --- a/gestion/ldap_crans.py +++ b/gestion/ldap_crans.py @@ -1661,11 +1661,6 @@ class BaseProprietaire(BaseClasseCrans): ret = '' if self._init_data: nouveau = 0 - # Reconfiguration switch si changement de chambre et si machine fixe - if 'chbre' in self.modifs: - if self.machines_fixes(): - self.services_to_restart('switch', [self._data['chbre'][0]]) - self.services_to_restart('switch', [self._init_data.get('chbre', '')[0]]) else: nouveau = 1 @@ -1701,7 +1696,6 @@ class BaseProprietaire(BaseClasseCrans): self.services_to_restart('conf_wifi_ng') self.services_to_restart('ragnarok-dhcp') else: - self.services_to_restart('switch', [self.chbre()]) self.services_to_restart('rouge-dhcp') # Vérification si changement de bât, ce qui obligerai un changement d'IP @@ -2893,10 +2887,6 @@ class Machine(BaseClasseCrans): if self.proprietaire().__class__ == AssociationCrans and not (isadm() or user_tests.getuser() == 'www-data'): raise EnvironmentError(u'Il faut être administrateur pour effectuer cette opération.') - if not self._init_data: - # Nouvelle machine => configuration prise - self.services_to_restart('switch', [self.proprietaire().chbre()]) - ret = '' # Besoin de redémarrer les firewalls ? diff --git a/radius_auth.py b/radius_auth.py index 5758c956..cd68f4e2 100755 --- a/radius_auth.py +++ b/radius_auth.py @@ -7,7 +7,7 @@ from syslog import * sys.path.append('/usr/scripts/gestion') from ldap_crans import crans_ldap, AssociationCrans -from config import ann_scol, dat +from config import ann_scol, dat, vlans def chap_ok(password, challenge, clear_pass) : """ Test l'authentification chap fournie @@ -28,27 +28,38 @@ def chap_ok(password, challenge, clear_pass) : return False def do_auth(mac): + """Effectue l'authentification. Renvoie (success, msg, + vlan). success est 0 si l'authentification est réussie, msg est + pour les logs et vlan est le vlan non taggé à utiliser pour la + prise.""" + global ann_scol if not chap_ok(os.getenv('CHAP_PASSWORD'), os.getenv('CHAP_CHALLENGE'), mac): - return (-1, "Échec test CHAP") + return (-1, "Échec test CHAP", "") # Mac dans la base LDAP m = crans_ldap(readonly=True).search('mac=%s' % mac)['machine'] - if len(m) != 1: - return (-1, "Pb recherche mac (nb résultat %d!=1)" % len(m)) + if len(m) == 0: + return (0, "Mac inconnue", "accueil") + elif len(m) > 1: + return (-1, "Pb recherche mac (nb résultat %d!=1)" % len(m), "") # N'appartient pas au Crans et n'a pas de prise attribuée # donc sur uplink ou switch non filtré # But : éviter le spoof d'une mac d'une machine clef proprio = m[0].proprietaire() if proprio.__class__ == AssociationCrans and m[0].prise() == u'N/A': - return (-1, "Machine du crans") + return (-1, "Machine du crans", "") # blockliste bloq if 'bloq' in m[0].blacklist_actif(): - return (-1, "Bloquage total des services pour cette machine") + return (-1, "Bloquage total des services pour cette machine", "") + # L'adherent ne paie pas, on le met sur le vlan radin + if not proprio.adherentPayant(): + return (0, "Ne paie pas", "radin") + # Paiment ok ? paid = max(proprio.paiement() + [0]) if dat[1] in (8, 9): @@ -58,17 +69,17 @@ def do_auth(mac): # On laisse 3 jours ou les gens ont une page sur squid ann_scol -= 1 if ann_scol > paid: - return (-1, "Échec test LDAP") + return (0, "N'a pas payé", "accueil") # C'est bon - return (0, "Accès OK") + return (0, "Accès adhérent OK", "adherent") if __name__ == '__main__' : # Test chap (comme cela on est sur que c'est bien un switch qui demande) mac = os.getenv('USER_NAME', '').replace('"', '') # On vérifie si la mac est autorisée - (r, msg) = do_auth(mac) + (r, msg, vlan) = do_auth(mac) # On logue la prise sur laquelle a lieu la tentative openlog("radius_auth.py") @@ -76,6 +87,12 @@ if __name__ == '__main__' : prise = (len(switch) == 6 and (switch[3] + switch[5]) or (switch + "-")) prise += "%02d" % int(os.getenv("NAS_PORT", 0)) syslog("%s -> %s [%s]" % (prise, mac, msg)) - - print msg + + if vlan: + # Cela indique au switch comment configurer le vlan par défaut + # pour cette prise + print ", ".join(["Tunnel-Type = VLAN", + "Tunnel-Medium-Type = IEEE-802", + "Tunnel-Private-Group-Id = \"%d\"" % vlans[vlan]]) + sys.exit(r)