Correction de la non prise en charge des blacklists appartements

This commit is contained in:
Pierre-Elliott Bécue 2015-11-26 17:34:35 +01:00
parent 8b86e04dba
commit 14167847db
5 changed files with 66 additions and 82 deletions

View file

@ -34,13 +34,13 @@ class firewall(utils.firewall_tools) :
self.use_ipset = [self.blacklist_hard, self.test_mac_ip, self.blacklists] self.use_ipset = [self.blacklist_hard, self.test_mac_ip, self.blacklists]
self.ipset['mac_ip']={ self.ipset['mac_ip']={
'adh' : Ipset("MAC-IP-ADH","macipmap","--from 138.231.136.0 --to 138.231.151.255"), 'adh' : Ipset("MAC-IP-ADH", "bitmap:ip,mac", "range 138.231.136.0-138.231.151.255"),
'adm' : Ipset("MAC-IP-ADM","macipmap","--from 10.231.136.0 --to 10.231.136.255"), 'adm' : Ipset("MAC-IP-ADM", "bitmap:ip,mac", "range 10.231.136.0-10.231.136.255"),
'app' : Ipset("MAC-IP-APP","macipmap","--from 10.2.9.0 --to 10.2.9.255"), 'app' : Ipset("MAC-IP-APP", "bitmap:ip,mac", "range 10.2.9.0-10.2.9.255"),
} }
self.ipset['blacklist']={ self.ipset['blacklist']={
'hard' : Ipset("BLACKLIST-HARD","ipmap","--from 138.231.136.0 --to 138.231.151.255"), 'hard' : Ipset("BLACKLIST-HARD", "hash:ip"),
} }
@ -110,7 +110,7 @@ class firewall(utils.firewall_tools) :
if fill_ipset: if fill_ipset:
# On récupère la liste de toutes les ips blacklistés hard # On récupère la liste de toutes les ips blacklistés hard
bl_hard_ips = self.blacklisted_ips(config.blacklist_sanctions, config.NETs['all']) bl_hard_ips = self.blacklisted_ips(config.blacklist_sanctions)
anim('\tRestoration de l\'ipset %s' % self.ipset['blacklist']['hard']) anim('\tRestoration de l\'ipset %s' % self.ipset['blacklist']['hard'])
self.ipset['blacklist']['hard'].restore(bl_hard_ips) self.ipset['blacklist']['hard'].restore(bl_hard_ips)
print OK print OK

View file

@ -33,13 +33,13 @@ class firewall(base.firewall_routeur):
self.use_tc.extend([self.limitation_debit]) self.use_tc.extend([self.limitation_debit])
self.ipset['reseaux_non_routable'] = { self.ipset['reseaux_non_routable'] = {
'deny' : base.Ipset("RESEAUX-NON-ROUTABLE-DENY","nethash"), 'deny' : base.Ipset("RESEAUX-NON-ROUTABLE-DENY", "hash:net"),
'allow' : base.Ipset("RESEAUX-NON-ROUTABLE-ALLOW","nethash"), 'allow' : base.Ipset("RESEAUX-NON-ROUTABLE-ALLOW", "hash:net"),
} }
self.ipset['blacklist'].update({ self.ipset['blacklist'].update({
'soft' : base.Ipset("BLACKLIST-SOFT","ipmap","--from 138.231.136.0 --to 138.231.151.255"), 'soft' : base.Ipset("BLACKLIST-SOFT", "hash:ip"),
'upload' : base.Ipset("BLACKLIST-UPLOAD","ipmap","--from 138.231.136.0 --to 138.231.151.255"), 'upload' : base.Ipset("BLACKLIST-UPLOAD", "hash:ip"),
}) })
# Portail captif/blacklist soft: ipset des gens ayant cliqué pour continuer à naviguer # Portail captif/blacklist soft: ipset des gens ayant cliqué pour continuer à naviguer
@ -344,7 +344,7 @@ class firewall(base.firewall_routeur):
if fill_ipset: if fill_ipset:
# On récupère la liste de toutes les ips blacklistés soft # On récupère la liste de toutes les ips blacklistés soft
bl_soft_ips = self.blacklisted_ips(base.config.blacklist_sanctions_soft, base.config.NETs['all']) bl_soft_ips = self.blacklisted_ips(base.config.blacklist_sanctions_soft)
anim('\tRestoration de l\'ipset %s' % self.ipset['blacklist']['soft']) anim('\tRestoration de l\'ipset %s' % self.ipset['blacklist']['soft'])
self.ipset['blacklist']['soft'].restore(bl_soft_ips) self.ipset['blacklist']['soft'].restore(bl_soft_ips)
print OK print OK
@ -375,7 +375,7 @@ class firewall(base.firewall_routeur):
if fill_ipset: if fill_ipset:
# On récupère la liste de toutes les ips blacklistés hard # On récupère la liste de toutes les ips blacklistés hard
bl_hard_ips = self.blacklisted_ips(base.config.blacklist_sanctions, base.config.NETs['all']) bl_hard_ips = self.blacklisted_ips(base.config.blacklist_sanctions)
anim('\tRestoration de l\'ipset %s' % self.ipset['blacklist']['hard']) anim('\tRestoration de l\'ipset %s' % self.ipset['blacklist']['hard'])
self.ipset['blacklist']['hard'].restore(bl_hard_ips) self.ipset['blacklist']['hard'].restore(bl_hard_ips)
print OK print OK
@ -422,7 +422,7 @@ class firewall(base.firewall_routeur):
if fill_ipset: if fill_ipset:
# On récupère la liste de toutes les ips blacklistés pour upload # On récupère la liste de toutes les ips blacklistés pour upload
bl_upload_ips = self.blacklisted_ips(base.config.blacklist_bridage_upload, base.config.NETs['all']) bl_upload_ips = self.blacklisted_ips(base.config.blacklist_bridage_upload)
anim('\tRestoration de l\'ipset %s' % self.ipset['blacklist']['upload']) anim('\tRestoration de l\'ipset %s' % self.ipset['blacklist']['upload'])
self.ipset['blacklist']['upload'].restore(bl_upload_ips) self.ipset['blacklist']['upload'].restore(bl_upload_ips)
print OK print OK

View file

@ -55,7 +55,7 @@ class firewall_tools(object) :
"""Classe de base du pare-feu implémentant l'association mac-ip (pour les machines filaires) et les blacklists hard""" """Classe de base du pare-feu implémentant l'association mac-ip (pour les machines filaires) et les blacklists hard"""
def machines(self): def machines(self):
"""Renvois la liste de toutes les machines""" """Renvoit la liste de toutes les machines"""
if self._machines: if self._machines:
return self._machines return self._machines
# On utilise allMachinesAdherents car on a besoin que # On utilise allMachinesAdherents car on a besoin que
@ -63,48 +63,37 @@ class firewall_tools(object) :
# les blacklistes d'un proprio lorsque l'on regarde les blacklistes # les blacklistes d'un proprio lorsque l'on regarde les blacklistes
# d'une machine # d'une machine
anim('\tChargement des machines') anim('\tChargement des machines')
self._machines, self._adherents = self.conn.allMachinesAdherents() # On prend toutes les machines y compris celles de ceux qui n'ont pas payé
self._adherents = [ adh for adh in self._adherents if adh.paiement_ok() ] # elles seront ajoutées dans mac_ip mais blacklistées du fait du non paiement ensuite
self._machines = self.conn.allMachines()
print OK print OK
return self._machines return self._machines
def adherents(self):
"""
Renvois la liste de tous les adhérents à jour de paiement
(car on suppose que la blackliste paiement est hard)
"""
if self._adherents:
return self._adherents
self._machines, self._adherents = self.conn.allMachinesAdherents()
self._adherents = [ adh for adh in self._adherents if adh.paiement_ok() ]
return self._adherents
def blacklisted_machines(self): def blacklisted_machines(self):
"""Renvois la liste de toutes les machines ayant une blackliste actives""" """Renvoit la liste de toutes les machines ayant une blackliste actives"""
if self._blacklisted_machines: if self._blacklisted_machines:
return self._blacklisted_machines return self._blacklisted_machines
self._blacklisted_machines = [ machine for machine in self.machines() if machine.blacklist_actif() ] self._blacklisted_machines = [ machine for machine in self.machines() if machine.blacklist_actif() ]
return self._blacklisted_machines return self._blacklisted_machines
def blacklisted_ips(self, blacklist_sanctions=None, nets=None): def blacklisted_ips(self, blacklist_sanctions=None):
"""Renvois l'ensemble des ips des machines ayant une blacklist dans blacklist_sanctions et étant dans nets si spécifié""" """Renvoit l'ensemble des ips des machines ayant une blacklist dans blacklist_sanctions et étant dans nets si spécifié"""
bl_ips = set() bl_ips = set()
for machine in self.blacklisted_machines(): for machine in self.blacklisted_machines():
if blacklist_sanctions is None or set(bl['type'] for bl in machine.blacklist_actif()).intersection(blacklist_sanctions): if blacklist_sanctions is None or set(bl['type'] for bl in machine.blacklist_actif()).intersection(blacklist_sanctions):
for ip in machine['ipHostNumber']: for ip in machine['ipHostNumber']:
if nets is None: bl_ips.add(str(ip))
bl_ips.add(str(ip))
else:
for net in nets:
if ip.value in netaddr.IPNetwork(net):
bl_ips.add(str(ip))
return bl_ips return bl_ips
def blacklisted_adherents(self, excepts=[]): def blacklisted_adherents(self, excepts=[]):
"""Renvois la liste de tous les adhérents ayant une blackliste active en ignorant les blacklist de excepts""" """Renvoit la liste de tous les adhérents ayant une blackliste active en ignorant les blacklist de excepts"""
if not self._adherents:
self._adherents = self.conn.allAdherents()
if self._blacklisted_adherents and self._blacklisted_adherents_type == set(excepts): if self._blacklisted_adherents and self._blacklisted_adherents_type == set(excepts):
return self._blacklisted_adherents return self._blacklisted_adherents
self._blacklisted_adherents = filter(lambda adh: adh.blacklist_actif(excepts), self.adherents()) self._blacklisted_adherents = filter(lambda adh: adh.blacklist_actif(excepts), self._adherents)
self._blacklisted_adherents_type = set(excepts) self._blacklisted_adherents_type = set(excepts)
return self._blacklisted_adherents return self._blacklisted_adherents

View file

@ -102,7 +102,7 @@ class firewall(base.firewall):
self.add(table, chain, '-d 127.0.0.1/8 -j RETURN') self.add(table, chain, '-d 127.0.0.1/8 -j RETURN')
for net in base.config.NETs['all']: for net in base.config.NETs['all']:
self.add(table, chain, '-d %s -j RETURN' % net) self.add(table, chain, '-d %s -j RETURN' % net)
for adh in self.blacklisted_adherents(): for adh in self.blacklisted_adherents(excepts=['paiement']):
if 'uidNumber' in adh: if 'uidNumber' in adh:
self.add(table, chain, '-m owner --uid-owner %s -j REJECT' % adh['uidNumber'][0]) self.add(table, chain, '-m owner --uid-owner %s -j REJECT' % adh['uidNumber'][0])
print OK print OK

View file

@ -30,24 +30,23 @@ if not os.path.exists(IPSET_PATH):
class IpsetError(Exception): class IpsetError(Exception):
# Gestion des erreurs d'ipset # Gestion des erreurs d'ipset
def __init__(self,cmd,err_code,output): def __init__(self, cmd, err_code, output):
self.cmd=cmd self.cmd = cmd
self.err_code=err_code self.err_code = err_code
self.output=output self.output = output
def __str__(self): def __str__(self):
return "%s\n status : %s\n %s" % (self.cmd,self.err_code,self.output) return "%s\n status : %s\n %s" % (self.cmd, self.err_code, self.output)
class Ipset(object): class Ipset(object):
ipset=IPSET_PATH ipset = IPSET_PATH
def __str__(self): def __str__(self):
return self.set return self.set
def __init__(self,set,type,typeopt=''): def __init__(self, set, type, typeopt=''):
self.set=set self.set = set
self.type=type self.type = type
self.typeopt=typeopt self.typeopt = typeopt
self.squeeze = os.uname()[2] < '3'
try: try:
self.create() self.create()
except IpsetError as error: except IpsetError as error:
@ -57,62 +56,58 @@ class Ipset(object):
raise raise
pass pass
def call(self,cmd,arg=''): def call(self, cmd, arg=''):
"""Appel système à ipset""" """Appel système à ipset"""
cmd_line="%s %s %s %s" % (self.ipset,cmd,self.set,arg) cmd_line = "%s %s %s %s" % (self.ipset, cmd, self.set, arg)
status,output=commands.getstatusoutput(cmd_line) status, output = commands.getstatusoutput(cmd_line)
if status: if status:
raise IpsetError(cmd_line,status,output) raise IpsetError(cmd_line, status, output)
return output return output
def create(self,opt=''): def create(self, opt=''):
self.call("-N","%s %s" % (self.type, self.typeopt)) self.call("create", "%s %s" % (self.type, self.typeopt))
def add(self,arg): def add(self, arg):
self.call("-A",arg) self.call("add", arg)
def list(self): def list(self):
output=self.call("-L").splitlines() output = self.call("list").splitlines()
list=[] list = []
for line in output[6:]: for line in output[6:]:
if line=='Bindings:': if line == 'Bindings:':
break break
list.append(line) list.append(line)
return list return list
def delete(self,ip): def delete(self, ip):
"""Delete an IP""" """Delete an IP"""
self.call("-D",ip) self.call("del", ip)
def restore(self,rules): def restore(self, rules):
""" restore le set courrant""" """ restore le set courrant"""
rules_str=self.restore_format(rules) rules_str = self.restore_format(rules)
if self.squeeze: str = "%s\nCOMMIT\n" % rules_str
create_str="-N %s %s %s" % (self.set,self.type,self.typeopt) path = '/tmp/ipset_%s' % self.set
str="%s\n%s\nCOMMIT\n" % (create_str,rules_str) f = open(path, 'w+')
else:
str="%s\nCOMMIT\n" % rules_str
path='/tmp/ipset_%s' % self.set
f=open(path, 'w+')
f.write(str) f.write(str)
f.close() f.close()
try: try:
self.flush() self.flush()
if self.squeeze: except IpsetError as error:
self.destroy() sys.stderr.write("%s\n" % error)
except IpsetError as error: sys.stderr.write("%s\n" % error)
cmd="cat %s | %s -R" % (path,self.ipset) cmd = "cat %s | %s -R" % (path, self.ipset)
status,output=commands.getstatusoutput(cmd) status, output = commands.getstatusoutput(cmd)
if status: if status:
raise IpsetError(cmd,status,output) raise IpsetError(cmd, status, output)
return output return output
def flush(self): def flush(self):
self.call("-F") self.call("flush")
def destroy(self): def destroy(self):
self.call("-X") self.call("destroy")
def restore_format(self,rules): def restore_format(self, rules):
return '\n'.join(["-A %s %s" % (self.set,data) for data in rules]) return '\n'.join(["add %s %s" % (self.set, data) for data in rules])