diff --git a/gestion/gen_confs/firewall.py b/gestion/gen_confs/firewall.py index d372818f..8d2fd54c 100755 --- a/gestion/gen_confs/firewall.py +++ b/gestion/gen_confs/firewall.py @@ -71,16 +71,16 @@ def iptables(cmd): def tc(cmd): """ Interface de tc """ - syslog.syslog(syslog.LOG_INFO,cmd) - status,output=getstatusoutput("/sbin/tc "+cmd) + syslog.syslog(syslog.LOG_INFO, cmd) + status, output = getstatusoutput("/sbin/tc " + cmd) if status: - raise TcError(cmd,status,output) + raise TcError(cmd, status, output) return output def redirect_chain(table, chain_in, chain_out, ip) : - try : + try: iptables("-t %s -N %s" % (table, chain_out)) - except IptablesError : + except IptablesError: iptables("-t %s -F %s" % (table, chain_out)) # On redirige les paquets de la chaîne in dans la chaîne out iptables("-t %s -A %s -o ens -s %s -j %s" % (table, chain_in, ip, chain_out)) @@ -490,45 +490,50 @@ class firewall_komaz(firewall_crans) : self.anim.reinit() print OK - def mangle_table(self) : + def mangle_table(self): self.anim = anim('\tStructure de la table mangle') + # On vide complètement la table iptables("-t mangle -F") iptables("-t mangle -X") + # Proxy transparent iptables("-t mangle -A PREROUTING -s %s -j RETURN" % self.zone_serveur) - iptables("-t mangle -A PREROUTING -p tcp --destination-port 80 " + - "-s %s -d ! %s -j MARK " % (NETs['fil'][0], NETs['wifi'][0]) + - "--set-mark %s" % conf_fw.mark['proxy']) - iptables("-t mangle -A PREROUTING -m mark --mark %s -j ACCEPT" % conf_fw.mark['proxy']) + iptables("-t mangle -A PREROUTING -p tcp --destination-port 80 " + "-s %s -d ! %s -j MARK --set-mark %s" % + (NETs['fil'][0], NETs['wifi'][0], conf_fw.mark['proxy'])) + iptables("-t mangle -A PREROUTING -m mark --mark %s -j ACCEPT" % + conf_fw.mark['proxy']) # On ne va pas plus loin si il ne s'agit pas de bittorrent - iptables("-t mangle -A POSTROUTING -m mark ! --mark %s -j ACCEPT" % conf_fw.mark['bittorrent']) + iptables("-t mangle -A POSTROUTING -m mark ! --mark %s -j ACCEPT" % + conf_fw.mark['bittorrent']) # On marque les paquets bittorrent uniquement iptables("-t mangle -A PREROUTING -p tcp -j CONNMARK --restore-mark") - iptables("-t mangle -A PREROUTING -p tcp -m mark ! --mark 0x0 " + - "-j ACCEPT") - iptables("-t mangle -A PREROUTING -p tcp -m ipp2p --bit -j MARK " + - "--set-mark %s" % conf_fw.mark['bittorrent']) - iptables("-t mangle -A PREROUTING -p tcp -m mark " + - "--mark %s -j CONNMARK --save-mark" % conf_fw.mark['bittorrent']) + iptables("-t mangle -A PREROUTING -p tcp -m mark ! --mark 0x0 -j ACCEPT") + iptables("-t mangle -A PREROUTING -p tcp -m ipp2p --bit " + "-j MARK --set-mark %s" % conf_fw.mark['bittorrent']) + iptables("-t mangle -A PREROUTING -p tcp -m mark --mark %s " + "-j CONNMARK --save-mark" % conf_fw.mark['bittorrent']) warn = '' - # Par défaut on envoit les paquets dans la classe 9998 - for net in NETs['all'] : - iptables("-t mangle -A POSTROUTING -o crans -d %s " % net + - "-j CLASSIFY --set-class 1:9998") - iptables("-t mangle -A POSTROUTING -o ens -s %s " % net + - "-j CLASSIFY --set-class 1:9998") + + # Par défaut, on envoit les paquets dans la classe 9998 + for net in NETs['all']: + iptables("-t mangle -A POSTROUTING -o crans -d %s " + "-j CLASSIFY --set-class 1:9998" % net) + iptables("-t mangle -A POSTROUTING -o ens -s %s " + "-j CLASSIFY --set-class 1:9998" % net) + # On crée les chaînes de sous-réseaux - for net in NETs['all'] : - for mask in conf_fw.mask : - for subnet in NetSubnets(net, mask) : + for net in NETs['all']: + for mask in conf_fw.mask: + for subnet in NetSubnets(net, mask): index = conf_fw.mask.index(mask) - if index == 0 : + if index == 0: prev_chain = "POSTROUTING" - else : + else: ip = subnet.split('/')[0] prev_subnet = IpSubnet(ip, conf_fw.mask[index-1]) prev_chain = "SUBNET-%s" % prev_subnet @@ -536,39 +541,46 @@ class firewall_komaz(firewall_crans) : redirect_chain('mangle', prev_chain, next_chain, subnet) print OK + adherents = db.search('paiement=ok')['adherent'] + self.anim = anim('\tGénération des classes de filtrage p2p', len(adherents)) + # Création des classes et qdisc - for interface in [self.eth_ext, self.eth_int] : + for interface in [self.eth_ext, self.eth_int]: # On vide les classes et qdisc - try : + try: tc("qdisc del dev %s root" % interface) except TcError, c: warn += str(c) + '\n' # On construit les classes et qdisc de base # La partie principale qui définit le comportement par défaut tc("qdisc add dev %s root handle 1: htb r2q 1" % interface) - tc("class add dev %s parent 1: classid 1:1 htb rate %s ceil %s" % (interface, p2p.debit_max, p2p.debit_max)) - tc("class add dev %s parent 1:1 classid 1:9998 htb rate %s ceil %s" % (interface, p2p.debit_adh, p2p.debit_adh)) + tc("class add dev %s parent 1: classid 1:1 htb rate %s ceil %s" % + (interface, p2p.debit_max, p2p.debit_max)) + tc("class add dev %s parent 1:1 classid 1:9998 htb rate %s ceil %s" % + (interface, p2p.debit_adh, p2p.debit_adh)) tc("qdisc add dev %s parent 1:9998 handle 9999: sfq perturb 10" % interface) - adherents = db.search('paiement=ok')['adherent'] - self.anim = anim('\tGénération des classes de filtrage p2p', len(adherents)) # On construit ensuite les classes et qdisc pour chaque adhérent - for adherent in adherents : + for adherent in adherents: self.anim.cycle() - class_id = int(adherent.id())+1 # On ne peut pas reprendre le numéro 1 - qdisc_id = class_id+5000 # Il nous faut un n° inférieur à 9998 unique - for interface in [self.eth_ext, self.eth_int] : - tc("class add dev %s parent 1:1 classid 1:%d htb rate %s ceil %s" % (interface, class_id, p2p.debit_adh, p2p.debit_max)) - tc("qdisc add dev %s parent 1:%d handle %d: sfq perturb 10" % (interface, class_id, qdisc_id)) + # On ne peut pas reprendre le numéro 1 + class_id = int(adherent.id()) + 1 + # Il nous faut un n° inférieur à 9998 unique + qdisc_id = class_id + 5000 + for interface in [self.eth_ext, self.eth_int]: + tc("class add dev %s parent 1:1 classid 1:%d htb rate %s ceil %s" % + (interface, class_id, p2p.debit_adh, p2p.debit_max)) + tc("qdisc add dev %s parent 1:%d handle %d: sfq perturb 10" % + (interface, class_id, qdisc_id)) # Classification des adhérents dans leur classe respective - for machine in adherent.machines() : + for machine in adherent.machines(): ip = machine.ip() - subnet = IpSubnet(machine.ip(), conf_fw.mask[len(conf_fw.mask)-1]) - iptables("-t mangle -A SUBNET-%s -o crans -d %s " % (subnet, ip) + - "-j CLASSIFY --set-class 1:%s" % class_id) - iptables("-t mangle -A SUBNET-%s -o ens -s %s " % (subnet, ip) + - "-j CLASSIFY --set-class 1:%s" % class_id) + subnet = IpSubnet(machine.ip(), conf_fw.mask[-1]) + iptables("-t mangle -A SUBNET-%(subnet)s -o crans -d %(ip)s " + "-j CLASSIFY --set-class 1:%(class_id)s" % locals()) + iptables("-t mangle -A SUBNET-%(subnet)s -o ens -s %(ip)s " + "-j CLASSIFY --set-class 1:%(class_id)s" % locals()) self.anim.reinit() print OK @@ -619,13 +631,13 @@ class firewall_komaz(firewall_crans) : iptables("-I FORWARD -m mark --mark %s -j ACCEPT" % conf_fw.mark['proxy']) print OK - def classes_p2p_maj(self, ip_list) : + def classes_p2p_maj(self, ip_list): """ Mise à jour de la classification pour les ip fournies On ne crée que les règles iptables pour classer les paquets, les classes correspondantes ne sont à créer que toutes à la fois """ ## Que faut-il faire ? self.anim = anim('\tAnalyse du travail à effectuer') - if ip_list == [''] : + if ip_list == ['']: print OK + ' (rien à faire)' return @@ -633,56 +645,68 @@ class firewall_komaz(firewall_crans) : ## Traitement # MAJ des règles de classification de l'IP - def procedure() : + def procedure(): self.anim = anim('\tMise à jour des classes p2p') warn = '' - try : - for ip in ip_list : - recherche = db.search('ip=%s&paiement=ok'% ip) + mark = conf_fw.mark['bittorrent'] + debit_adh = p2p.debit_adh + debit_max = p2p.debit_max + eth_ext = self.eth_ext + eth_int = self.eth_int + try: + for ip in ip_list: + recherche = db.search('ip=%s&paiement=ok' % ip) # Si l'ip n'appartient pas à un adhérent, - # on cherche pas plus loin - if not recherche['adherent'] : + # on ne cherche pas plus loin + if not recherche['adherent']: continue machines = recherche['machine'] - if not machines : + if not machines: # Il faut supprimer cette entrée iptables_option = '-D' tc_option = 'del' - subnet = IpSubnet(ip, conf_fw.mask[len(conf_fw.mask)-1]) + subnet = IpSubnet(ip, conf_fw.mask[-1]) regles = iptables("-t mangle -L SUBNET-%s -n | tee `tempfile -s _firewall`date -u +%y%m%d%H%M%S`` | grep %s" % (subnet, ip)).split('\n') # On sélectionne la première qui doit contenir ce que l'on veut regle = regles[0].split() - mark = regle[7] - class_id = int(mark.split(':')[1]) - elif len(machines) == 1 : + class_id = int(regle[7].split(':')[1]) + elif len(machines) == 1: # Il faut ajouter cette entrée iptables_option = '-A' tc_option = 'add' machine = machines[0] adherent = machine.proprietaire() ip = machine.ip() - subnet = IpSubnet(ip, conf_fw.mask[len(conf_fw.mask)-1]) - class_id = int(adherent.id())+1 # On ne peut pas reprendre le numéro 1 - else : + subnet = IpSubnet(ip, conf_fw.mask[-1]) + # On ne peut pas reprendre le numéro 1 + class_id = int(adherent.id()) + 1 + else: warn += "Plusieurs machines avec l'IP %s\n" % ip - qdisc_id = class_id+5000 # Il nous faut un n° inférieur à 9998 unique - for interface in [self.eth_ext, self.eth_int] : - if tc_option : - tc("class %s dev %s parent 1:1 classid 1:%d htb rate %s ceil %s" % (tc_option, interface, class_id, p2p.debit_adh, p2p.debit_max)) - tc("qdisc %s dev %s parent 1:%d handle %d: sfq perturb 10" % (tc_option, interface, class_id, qdisc_id)) - iptables("-t mangle %s SUBNET-%s -o crans -d %s -m mark " % (iptables_option, subnet, ip) + - "--mark %s -j CLASSIFY --set-class 1:%s" % (conf_fw.mark['bittorrent'], class_id)) - iptables("-t mangle %s SUBNET-%s -o ens -s %s -m mark " % (iptables_option, subnet, ip) + - "--mark %s -j CLASSIFY --set-class 1:%s" % (conf_fw.mark['bittorrent'], class_id)) + # Il nous faut un n° inférieur à 9998 unique + qdisc_id = class_id + 5000 + for interface in [eth_ext, eth_int]: + if tc_option: + tc("class %(tc_option)s dev %(interface)s " + "parent 1:1 classid 1:%(class_id)d htb " + "rate %(debit_adh)s ceil %(debit_max)s" % locals()) + tc("qdisc %(tc_option)s dev %(interface)s " + "parent 1:%(class_id)d handle %(qdisc_id)d: " + "sfq perturb 10" % locals()) + iptables("-t mangle %(iptables_option)s SUBNET-%(subnet)s " + "-o %(eth_int)s -d %(ip)s -m mark --mark %(mark)s " + "-j CLASSIFY --set-class 1:%(class_id)s" % locals()) + iptables("-t mangle %(iptables_option)s SUBNET-%(subnet)s " + "-o %(eth_ext)s -s %(ip)s -m mark --mark %(mark)s " + "-j CLASSIFY --set-class 1:%(class_id)s" % locals()) except IptablesError, c: warn += str(c) + '\n' - except KeyError : + except KeyError: print OK - if warn : + if warn: print WARNING sys.stdout.write(warn) - else : + else: print OK self.exception_catcher(procedure)