#!/usr/bin/env python # -*- coding: iso-8859-1 -*- # The author of this code is Manuel Sabban # # Copyright (c) 2004 Manuel Sabban. # # Permission to use, copy, and modify this software with or without fee # is hereby granted, provided that this entire notice is included in # all source code copies of any software which is or includes a copy or # modification of this software. # # THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR # IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY # REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE # MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR # PURPOSE. """ classe Firewall de Komaz """ import sys,os import iptools,config,fileinput from ldap_crans import * from config_firewall import * from affich_tools import * def test(pouet): print pouet os.system(pouet) class ErrorArgument(Exception): """ User defined exception Erreur sur les arguments d'appel du firewall """ pass class ErrorIp(Exception): """ User defined exception Erreur dans les fonctions Ips """ def __init__(self, ip): self.ip=ip class ErrorMoreThanOneIp(ErrorIp): """ User defined exception Au moins deux utilisateurs ont la même ip """ pass class ErrorIptables(Exception): pass """ User defined exception Les erreurs d'iptables """ class ErrorNoSuchIp(ErrorIp): """ User defined exception Personne n'a cette ip """ pass class firewall: def start(self): """ Construit le firewall Pas d'arguments """ self.komaz self.serveurs() self.filtrage_mac() self.create_forward() self.blacklist() self.create_adherents() def stop(self): """ Arrête le firewall Pas d'arguments """ print "Arrêt du firewall" os.system("iptables -F") os.system("iptables -t nat -F") os.system("iptables -X") def create_defaults(self): """ Crée la chaîne par laquelle tous les adhérents passent par défault Pas d'argument """ for proto in ["tcp","udp"]: for i in range(len(config.port_default["%s_input" % proto])): os.system("iptables -A DEFAULT_INPUT -p %s --dport "%proto+\ config.port_default["%s_input" % proto][i]+\ " -j ACCEPT") for i in range(len(config.port_default["%s_output" % proto])): os.system("iptables -A DEFAULT_OUTPUT -p %s --sport "%proto+\ config.port_default["%s_output" % proto][i]+\ " -j ACCEPT") def del_entree(self,ip): """ Détruit une entrée dans le firewall Note: Il faut *os.systemer lourdement* cette fonction. """ try: os.system("iptables -L -n > /tmp/firewall") except: print "Impossible de créer le fichier d'états /tmp/firewall" exit() chaines=[] count=0 for line in fileinput.input('/tmp/firewall'): count=count+1 if "Chain" in line: tmp=line.split(' ') chaine=tmp[1] count=0 if ip in line: os.system("iptables -L") test("iptables -D %s %i"%(chaine,count)) count=count-1 os.system("rm -f /tmp/firewall") def paire_macip(self,ip,mac): """ Crée le filtrage pour une paire mac-ip """ os.system("iptables -t nat -A PREROUTING -s %s -m mac --mac-source %s -j ACCEPT"\ %(ip,mac)) def filtrage_mac(self): """ Crée tout le routage sur la chaîne PREROUTING """ db=crans_ldap() search=db.search('host!=*.wifi.crans.org')['machine'] barre=anim("Filtrage mac-ip des machines fixes.",len(search)) for i in range(0,len(search)): self.paire_macip(search[i].ip(),search[i].mac()) barre.cycle() barre.reinit() print OK search=db.search('host=*.wifi.crans.org')['machine'] barre=anim("Filtrage mac-ip des machines wifi.",len(search)) for i in range(0,len(search)): self.paire_macip(search[i].ip(),'00:0c:f1:fa:f1:4b') barre.cycle() barre.reinit() print OK os.system("iptables -t nat -A PREROUTING -i %s -s \\!"%int_crans+\ " 138.231.136.0/21 -j ACCEPT") os.system("iptables -t nat -A PREROUTING -i %s -s \\!"%int_crans+\ " 138.231.148.0/22 -j ACCEPT") for i in reseaux_non_routables: os.system("iptables -t nat -A PREROUTING -i %s -s %s"%(int_crans,i)+\ " -m limit --limit %s --limit-burst %s"%(loglimit,logburst)+\ " -j LOG --log-level %s --log-prefix %s"%\ (loglevel,logprefix_macip)) os.system("iptables -t nat -A PREROUTING -i %s -s %s -j DROP"%\ (int_crans,i)) os.system("iptables -t nat -A PREROUTING -i %s -d %s"%(int_crans,i)+\ " -m limit --limit %s --limit-burst %s"%(loglimit,logburst)+\ " -j LOG --log-level %s --log-prefix %s"%\ (loglevel,logprefix_macip)) os.system("iptables -t nat -A PREROUTING -i %s -d %s -j DROP"%\ (int_crans,i)) os.system("iptables -t nat -A PREROUTING -i %s -p tcp "%int_crans+\ " -m limit --limit %s --limit-burst %s"%(loglimit,logburst)+\ " -j LOG --log-level %s --log-prefix %s"%\ (loglevel,logprefix_macip)) os.system("iptables -t nat -A PREROUTING -i %s -p tcp"%int_crans+\ " -j DROP") os.system("iptables -t nat -A PREROUTING -i %s -p udp"%int_crans+\ " -m limit --limit %s --limit-burst %s"%(loglimit,logburst)+\ " -j LOG --log-level %s --log-prefix %s"%\ (loglevel,logprefix_macip)) os.system("iptables -t nat -A PREROUTING -i %s -p udp"%int_crans+\ " -j DROP") def komaz(self): """ Crée les règles spécifiques à la machine komaz """ ports=komaz_ports['portTCPin'] for i in ports.split(' '): os.system("iptables -A INPUT -d 138.231.136.4 -p tcp --dport %s"%i+\ " -j ACCEPT") ports=komaz_ports['portTCPout'] for i in ports.split(' '): os.system("iptables -A OUTPUT -s 138.231.136.4 -p tcp --dport %s"%i+\ " -j ACCEPT") ports=komaz_ports['portUDPin'] for i in ports.split(' '): os.system("iptables -A INPUT -d 138.231.136.4 -p udp --dport %s"%i+\ " -j ACCEPT") ports=komaz_ports['portUDPout'] for i in ports.split(' '): os.system("iptables -A OUTPUT -s 138.231.136.4 -p udp --dport %s"%i+\ " -j ACCEPT") def serveurs(self): def fonction_utile(valeur): return valeur """ Définit les chaînes relatives au serveur Note: Ça marche pas si port{TCP,UDP}{in,out} est '' Fred corrigera """ for serveur in serveurs_list: ports=serveurs_ports[serveur]['portTCPin'] for i in ports.split(' '): os.system("iptables -A FORWARD -d %s"%\ eval(fonction_utile(serveur))['ip']+\ " -p tcp --dport %s -j ACCEPT"%i) ports=serveurs_ports[serveur]['portTCPout'] for i in ports.split(' '): os.system("iptables -A FORWARD -s %s"%\ eval(fonction_utile(serveur))['ip']+\ " -p tcp --dport %s -j ACCEPT"%i) ports=serveurs_ports[serveur]['portUDPin'] for i in ports.split(' '): os.system("iptables -A FORWARD -d %s"%\ eval(fonction_utile(serveur))['ip']+\ " -p udp --dport %s -j ACCEPT"%i) ports=serveurs_ports[serveur]['portUDPout'] for i in ports.split(' '): os.system("iptables -A FORWARD -s %s"%\ eval(fonction_utile(serveur))['ip']+\ " -p udp --dport %s -j ACCEPT"%i) for serveur in serveurs_list: self.paire_macip(eval(fonction_utile(serveur))['ip'],\ eval(fonction_utile(serveur))['mac']) def blacklist(self): """ Bloque les adhérents blacklistés """ os.system("iptables -N DEFAULT_INPUT") os.system("iptables -N DEFAULT_OUTPUT") db=crans_ldap() blacklist=[] search=db.search('blacklist=*&paiement=%s'%ann_scol) for entite in search['adherent']+\ search['club']+search['machine']: if 'upload' in entite.blacklist_actif(): if search.__class__==machine: blacklist+=[entite] else: blacklist+=entite.machines() for instance_machine in blacklist: os.system("iptables -A BLACKLIST_INPUT -d %s"%\ instance_machine.ip().encode("iso-8859-15")+\ "-m limit --limit %s --limit-burst %s"%(loglimit,logburst)+\ " -j LOG --log-level %s --log-prefix_macip %s"%\ (loglevel,logprefix_blacklist)) os.system("iptables -A BLACKLIST_INPUT -d %s -j REJECT"%\ instance_machine.ip()) os.system("iptables -A BLACKLIST_OUTPUT -s %s"%\ instance_machine.ip().encode("iso-8859-15")+\ "-m limit --limit %s --limit-burst %s"%(loglimit,logburst)+\ " -j LOG --log-level %s --log-prefix_macip %s"%\ (loglevel,logprefix_blacklist)) os.system("iptables -A BLACKLIST_OUTPUT -s %s -j REJECT"%\ instance_machine.ip()) os.system("iptables -A BLACKLIST_INPUT -j DEFAULT_INPUT") os.system("iptables -A BLACKLIST_OUTPUT -j DEFAULT_OUTPUT") def create_forward(self): """ Différencie ce qui arrive et ce qui part dans la chaîne FORWARD """ os.system("iptables -N BLACKLIST_INPUT") os.system("iptables -N BLACKLIST_OUTPUT") os.system("iptables -A FORWARD -s 138.231.136.0/21 -j BLACKLIST_OUTPUT") os.system("iptables -A FORWARD -s 138.231.136.0/22 -j BLACKLIST_OUTPUT") os.system("iptables -A FORWARD -d 138.231.148.0/21 -j BLACKLIST_INPUT") os.system("iptables -A FORWARD -d 138.231.148.0/22 -j BLACKLIST_INPUT") def create_adherents(self): """ Crée toutes les règles relatives aux adhérents ayant des règles spéciales """ os.system("iptables -N ADHERENTS_OUTPUT") os.system("iptables -N ADHERENTS_INPUT") os.system("iptables -A ADHERENTS_INPUT -m state --state "+\ "RELATED -j ACCEPT") os.system("iptables -A ADHERENTS_OUTPUT -m state --state "+\ "RELATED -j ACCEPT") os.system("iptables -A ADHERENTS_INPUT -m state --state "+\ "ESTABLISHED -m limit --limit-burst "+\ "%s -j ACCEPT"%limite_connexion) os.system("iptables -A ADHERENTS_OUTPUT -m state --state "+\ "ESTABLISHED -m limit --limit-burst "+\ "%s -j ACCEPT"%limite_connexion) os.system("iptables -A DEFAULT_INPUT -j ADHERENTS_INPUT") os.system("iptables -A DEFAULT_OUTPUT -j ADHERENTS_OUTPUT") db=crans_ldap() search=db.search('host=*.crans.org & portTCPin=*')['machine'] for champ in search: ports=champ.portTCPin() for j in ports.split(' '): os.system("iptables -A ADHERENTS_INPUT -d %s"%champ.ip()+\ " -p tcp --dport %s -j ACCEPT"%j) search=db.search('host=*.crans.org & portTCPout=*')['machine'] for champ in search: ports=champ.portTCPout() for j in ports.split(' '): os.system("iptables -A ADHERENTS_OUTPUT -d %s"%champ.ip()+\ " -p tcp --dport %s -j ACCEPT"%j) search=db.search('host=*.crans.org & portUDPin=*')['machine'] for champ in search: ports=champ.portUDPin() for j in ports.split(' '): os.system("iptables -A ADHERENTS_INPUT -d %s"%champ.ip()+\ " -p udp --dport %s -j ACCEPT"%j) search=db.search('host=*.crans.org & portUDPin=*')['machine'] for champ in search: ports=champ.portUDPout() for j in ports.split(' '): os.system("iptables -A ADHERENTS_OUTPUT -d %s"%champ.ip()+\ " -p udp --dport %s -j ACCEPT"%j) os.system("iptables -A ADHERENTS_INPUT"+\ " -m limit --limit %s --limit-burst %s"%(loglimit,logburst)+\ " -j LOG --log-level %s --log-prefix %s"%\ (loglevel,logprefix_adherents)) os.system("iptables -A ADHERENTS_INPUT -j REJECT") os.system("iptables -A ADHERENTS_OUTPUT"+\ " -m limit --limit %s --limit-burst %s"%(loglimit,logburst)+\ " -j LOG --log-level %s --log-prefix %s"%\ (loglevel,logprefix_adherents)) os.system("iptables -A ADHERENTS_OUTPUT -j REJECT") def adherent(self,ip): """ Gère complètement l'ajout d'un adhérent dans le firewall os.systemer la blacklist """ db=crans_ldap() search=db.search('ip='+ip)['machine'] if len(search)==0: raise ErrorNoSuchIp(ip) elif len(search)!=1: raise ErrorMoreThanOneIp(ip) i=0 wifi=False while (i