Mise en forme.

darcs-hash:20060617085415-68412-a672588b6e8a27ab15d31294e2fef28a939a3027.gz
This commit is contained in:
glondu 2006-06-17 10:54:15 +02:00
parent 3ad3ea3809
commit d25251392f

View file

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