Taille: 8261
Commentaire:
|
Taille: 17408
Commentaire:
|
Texte supprimé. | Texte ajouté. |
Ligne 1: | Ligne 1: |
## page was renamed from CransTechnique/Services/Re2oServices/FireWall ## page was renamed from CransTechnique/Services/FireWall |
|
Ligne 2: | Ligne 4: |
= Le parefeu = Il existe actuellement 2 parefeu en production. Le plus récent, gen_conf/firewall.py, remplace les anciens firewall v6 et v4 sur zamok, les radius et le routeur v6. L'ancien parefeu v4, gen_conf/firewall4/firewall.py reste en production sur odlyd et sable, temporairement. |
= Le pare-feu = Le pare-feu (en anglais firewall) se place entre la machine qui a accès à Internet et Internet lui-même. Il protège l'une de l'autre et inversement en limitant les types de connexions qui ont le droit d'entrer et de sortir. <<TableOfContents>> :s règles sont générées par un script, qui termine en remplaçant le set de règles courant par celui qu'il a généré. Cette opération est atomique (on utilise {{{iptables-restore}}}, donc il n'y a pas de phase pendant laquelle tout est ouvert (ou fermé) le temps que la régénération se termine. La table est généré à partir des infos de re2o, cf [[CransTechnique/Services/Re2oServices|re2o-services]] |
Ligne 12: | Ligne 13: |
Ligne 14: | Ligne 14: |
Il se lance avec /usr/scripts/gestion/gen_conf/firewall.py restart. Il se coupe avec l'instruction stop. Celle-ci coupure injectera un set de règles vide, avec policy accept. |
Il se lance avec {{{/var/local/re2o-services/firewall/main.py restart}}} (potentiellement avec l'option --force) et se coupe avec l'instruction {{{stop}}}. Celle dernière injectera un set de règles vide, avec policy ACCEPT. |
Ligne 18: | Ligne 17: |
Ligne 20: | Ligne 18: |
Le script est une class iptables qui a différentes sous-fonctions selon ce qu'on veut générer. Le début contient les fonctions de bases, d'intialisation des chaines iptables etc. |
Le script est une classe {{{iptables}}} qui a différentes sous-fonctions selon ce qu'on veut générer. Le début contient les fonctions de base, d'intialisation des chaînes iptables, etc. |
Ligne 31: | Ligne 28: |
self.conn = shortcuts.lc_ldap_readonly() etc... |
self.subnet_ports = api_client.list("firewall/subnet-ports/") self.interface_ports = api_client.list("firewall/interface-ports/") self.normal_users = api_client.list("users/normaluser/") self.verbose = False self.action = None self.export = False self.role = getattr(firewall_config, 'role', None) self.interfaces_settings = getattr(firewall_config, 'interfaces_type', None) self.nat_settings = getattr(firewall_config, 'nat', None) self.portail_settings = getattr(firewall_config, 'portail', None) |
Ligne 64: | Ligne 70: |
Ainsi; au moment de l'injection des règles qui est faite au démarrage du parefeu, (iptables-restore) : | Ainsi, au moment de l'injection des règles qui est faite au démarrage du parefeu, (iptables-restore) : |
Ligne 84: | Ligne 90: |
Ligne 96: | Ligne 101: |
Ainsi l'appel à init_filter(subtable) va initialiser la sous table ESTABLISHED-CONN dans la chaine filter. Mais vu que cette chaine n'existe pas (rappellez-vous, c'est filter4 ou filter6), il va l'ajouter dans les 2. Idem pour jump_all_trafic, qui va attraper tout le trafic sur toutes les interfaces, en v4 ou en v6, dans le forward ou dans l'input, et l'envoyer vers la sous-table ESTABLISHED-CONN. | Ainsi l'appel à {{{init_filter(subtable)}}} va initialiser la sous table ESTABLISHED-CONN dans la chaîne filter. Mais, étant donné que cette chaine n'existe pas (rappellez-vous, c'est filter4 ou filter6), il va l'ajouter dans les 2. Idem pour {{{jump_all_trafic}}}, qui va attraper tout le trafic sur toutes les interfaces, en v4 ou en v6, dans le forward ou dans l'input, et l'envoyer vers la sous-table ESTABLISHED-CONN. |
Ligne 100: | Ligne 105: |
=== Selections des chaines à ajouter ==== |
==== Génération du firewall en v4 , v6 ou les 2 ? ==== |
Ligne 104: | Ligne 108: |
Regardons comment est appellé restore-iptables : | Regardons comment est appelé {{{restore-iptables}}} : |
Ligne 122: | Ligne 126: |
Ca parait clair, on regarde donc self.roles pour savoir si c'est un v4, un v6 ou les 2, et on restore. Mais comment faire la différence par exemple entre le parefeu v6 de zamok et le parefeuv6 de la VM ipv6 du routage ? |
Ca parait clair, on regarde donc self.roles pour savoir si c'est un v4, un v6 ou les 2, et on restore. Mais comment faire la différence par exemple entre le parefeu v6 de zamok et le parefeu v6 de la VM ipv6 du routage ? ==== Sélection des rôles ==== Les rôles sont spécifiés dans {{{firewall_config.py}}} installé par Bcfg2 ({{{/var/local/bcfg2/Python/var/local/re2o-services/firewall/firewall_config.py}}} Exemple : {{{ ─( 15:34:36 )─< /var/local/re2o-services/firewall >───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(git)─[firewall/crans]─[ 0 ]─ jacomme@gulp $ cat firewall_config.py #! role = ['routeur4'] ### Specify each interface role interfaces_type = { 'routable' : ['eno1.1', 'ens1f0.21', 'ens1f0.22', 'ens1f0.23', 'ens1f0.24'], 'sortie' : ['ens1f0.26', 'ens1f0.1132'], 'admin' : ['eno1.2', 'eno1.3'] } ### Specify nat settings: name, interfaces with range, and global range for nat ### WARNING : "interface_ip_to_nat' MUST contain /24 ranges, and ip_sources MUST ### contain /16 range nat = [ { 'name' : 'Wifi', 'interfaces_ip_to_nat' : { 'ens1f0.26' : '185.230.76.0/24', 'eno1.1' : '138.231.144.0/24', 'ens1f0.1132' : '138.231.144.0/24', }, 'ip_sources' : '10.53.0.0/16' }, { 'name' : 'Filaire', 'interfaces_ip_to_nat' : { 'ens1f0.26' : '185.230.77.0/24', 'eno1.1' : '138.231.145.0/24', 'ens1f0.1132' : '138.231.145.0/24', }, 'ip_sources' : '10.54.0.0/16' } ] }}} On spécifie donc ici les roles, ne pas mettre 4 ou 6 générera un parefeu v4 et v6. On spécifie également les interfaces non routables, routables, et si il y a lieu l'interface de sortie vers le monde extérieur. Ne pas mettre de roles générera un parefeu minimal, cf plus bas. ==== Application des rôles ==== |
Ligne 149: | Ligne 206: |
Exemple pour le role routeur6 (role donc du routeur ipv6), on appelle base_filter (une factorisation de plusieurs règles, vous le trouverez dessous) et différentes fonctions necessaires, tel que le filtrage port en v6, la limitation des connexions ssh , etc. | ==== Sélections des chaînes à ajouter ==== Exemple pour le rôle routeur6 (role donc du routeur ipv6), on appelle {{{base_filter}}} (une factorisation de plusieurs règles, vous le trouverez dessous) et différentes fonctions necessaires, tel que le filtrage ports en v6, la limitation des connexions ssh, etc. |
Ligne 153: | Ligne 211: |
"""Methode appellée spécifiquement pour le parefeu v6""" | """Methode appelée spécifiquement pour le parefeu v6""" |
Ligne 174: | Ligne 232: |
Base filter est appellée par pas mal de roles, (zamok, routeur etc) c'était donc plus joli de tout factoriser. | Base filter est appelée par pas mal de roles, (zamok, routeur etc) c'était donc plus joli de tout factoriser. |
Ligne 192: | Ligne 250: |
Voilà, à priori là on a tout pour générer notre fichier iptables. Evidemment, se référer aux docstring pour voir ce que chaque fonction fait. == Pour les divers pare feu du crans == |
Voilà,''a priori'', là on a tout pour générer notre fichier iptables. Evidemment, se référer aux docstrings pour voir ce que chaque fonction fait. === Fonction des différents serveurs === ==== Synchronisation en re2o-services ==== Certaines instances du parefeu (odlyd, gulp, ipv6 et zamok) ont besoin d'être regen, par ex à l'ajout d'un adhérent, ou d'ouvertures d'un port, en conséquence ils sont gérés dans la page machines/services; et regen par le cron re2o-services quand il est nécessaires. Les autres instances (radius, routeur) sont purement statiques; et seulement générées au boot (donc cron @reboot --force dans leur etc/cron.d) ==== Routage principal (Odlyd, gulp et ipv6-zayo) ==== Gulp et odlyd ont la même instance de parefeu. Leur rôle est routeur4, ce qui signifie que seule la partie v4 donc iptables est générée et appliquée. En plus des fonctions de base (filtrage icmp/ssh/etc); ce parefeu contient en gros la protection en forward de toute la zone crans. Il s'appuie uniquement sur les interfaces pour être souple. Il possède des chaines filter, nat et mangle. {{{ def routeur4(self, table): """Methode appellée spécifiquement pour le parefeu v4""" if table == "filter": self.base_filter() if self.verbose: print("Filter : filtrage ports 4") self.filtrage_ports(ip_type='4') if self.verbose: print("Filter : limit ssh connexion forward") self.limit_ssh_connexion_forward() if self.verbose: print("Filter : limit connexion src ip") self.limit_connexion_srcip() elif table == "mangle": if self.verbose: print("Mangle : Mise en place des logs") self.log() if self.verbose: print("Mangle : Réglage correct du MSS") self.mss() elif table == "nat": for nat_to_do in self.nat_settings: if self.verbose: print("Nat : priv" + nat_to_do['name']) self.nat_prive_ip(nat_to_do) }}} ===== Filter ===== Enfin il contient la fonction filtrage port, qui récupère auprès de re2o-server, les politiques par default de chaque range et les politiques particulières. Ce serait fastidieux de print tout le code ici... disons que la chaine filtrage-port est automatiquement appellée pour tout paquet entrant et sortant de la zone crans (FORWARD). D'abord est appliquée la règle par default, puis les règles particulières, et si rien ne match, le paquet est rejeté. ===== Nat ===== Ce qui est remarquable ici est la chaine de nat, comme son nom l'indique qui va nater de manière statique et par plage de ports (25 ip privées sur 2000 ports chacun d'une ip publique). On a donc 25*255 ip privées potentiellement natées. {{{ nat_prive_ip_plage = nat_type['ip_sources'] for nat_ip_range in range(1, 26): range_name = 'nat' + nat_prive_ip_plage.split('.')[1] + '_' + str("%02d" % nat_ip_range ) self.init_nat(range_name, decision="-") self.add_in_subtable("nat", subtable, '-s ' + '.'.join(nat_prive_ip_plage.split('.')[:2]) + '.' + str(nat_ip_range) + '.0/24 -j ' + range_name) for nat_ip_range in range(1, 26): range_name = 'nat' + nat_prive_ip_plage.split('.')[1] + '_' + str("%02d" % nat_ip_range) for nat_ip_subrange in range(16): subrange_name = range_name + '_' + str(hex(nat_ip_subrange)[2:]) self.init_nat(subrange_name, decision="-") }}} etc ===== Mangle ===== Dans cette chaine, on log tout ce qui rentre et sort de la zone + mise en place du mss pour éviter les prb de drop dû au MTU. == Cahier des charges == === Fonctions de base commmunes === ==== Filter ==== * Acceptation de toute connexion déjà établie * Acceptation du ping v4 et v6 en input et forward * ping ⊊ ICMP. Réfléchir à si on veut tout l'ICMP (ne pas oublier que les "ça a pas marché", c'est aussi de l'ICMP, mais pas du ping). -- [[Wiki20-100]] <<DateTime(2018-05-17T13:46:48+0200)>> * Blocage des connexions entrantes vers les réseaux admin (adm, admbornes etc) sur l'interface correspondante * Oui. Mais je pense qu'il manque la fin de la phrase. -- [[Wiki20-100]] <<DateTime(2018-05-17T13:46:48+0200)>> * DROP du traffic illégitime venant de l'extérieur (broadcast et multicast qu'on n'est pas censés recevoir, IP non routables, etc.) * Blacklist hard des connexions entrantes et sortantes des utilisateurs blacklistés * Filtrage des ports en v4 et v6 sur les interfaces d'entrée de la zone crans * Limitation des connexions ssh entrantes pour éviter les attaques par bruteforce * Limitation des connexions tcp et udp en input (limit connexions dstip) afin d'éviter le flood de connexions (cf attaque sur le wiki par un adhérent) === Fonctions supplémentaires du parefeu de sortie (odlyd, sable et ipv6) === ==== Filter ==== * Blacklist hard des utilisateurs blacklistés en forward * Filtrage des ports en v4 et v6 sur les interfaces de sortie de la zone crans * Limitation des connexions ssh en forward pour éviter les attaques bruteforce * Pas sûr que ce soit vraiment notre soucis -- [[Wiki20-100]] <<DateTime(2018-05-17T13:46:48+0200)>> * Limitation des connexions sortantes tcp/udp pour éviter le flood d'une machine vérolée vers l'éxtérieur (limit connexions srcip) * Pareil -- [[Wiki20-100]] <<DateTime(2018-05-17T13:46:48+0200)>> ==== Nat ==== * NAT des ip privées filaires et wifi en v4 ==== Mangle ==== * Log de toutes les nouvelles connexions sur les interfaces de sortie et routables === Fonctions supplémentaires du parefeu adhérents === ==== Filter ==== * Interdiction de l'output vers adm pour non nounous/apprentis * Interdiction de l'output vers odlyd pour les non à jour de cotiz (todo) == Legacy - pour les divers parefeu du crans == |
Le pare-feu
Le pare-feu (en anglais firewall) se place entre la machine qui a accès à Internet et Internet lui-même. Il protège l'une de l'autre et inversement en limitant les types de connexions qui ont le droit d'entrer et de sortir.
Sommaire
:s règles sont générées par un script, qui termine en remplaçant le set de règles courant par celui qu'il a généré. Cette opération est atomique (on utilise iptables-restore, donc il n'y a pas de phase pendant laquelle tout est ouvert (ou fermé) le temps que la régénération se termine. La table est généré à partir des infos de re2o, cf re2o-services
Le nouveau parefeu
Utilisation
Il se lance avec /var/local/re2o-services/firewall/main.py restart (potentiellement avec l'option --force) et se coupe avec l'instruction stop. Celle dernière injectera un set de règles vide, avec policy ACCEPT.
Principes
Architecture générale
Le script est une classe iptables qui a différentes sous-fonctions selon ce qu'on veut générer. Le début contient les fonctions de base, d'intialisation des chaînes iptables, etc.
def __init__(self): self.nat4 = "\n*nat" self.mangle4 = "\n*mangle" self.filter4 = "\n*filter" self.nat6 = "\n*nat" self.mangle6 = "\n*mangle" self.filter6 = "\n*filter" self.subnet_ports = api_client.list("firewall/subnet-ports/") self.interface_ports = api_client.list("firewall/interface-ports/") self.normal_users = api_client.list("users/normaluser/") self.verbose = False self.action = None self.export = False self.role = getattr(firewall_config, 'role', None) self.interfaces_settings = getattr(firewall_config, 'interfaces_type', None) self.nat_settings = getattr(firewall_config, 'nat', None) self.portail_settings = getattr(firewall_config, 'portail', None) def commit(self, chain): self.add(chain, "COMMIT\n") def commit_filter(self): self.add("filter4", "COMMIT\n") self.add("filter6", "COMMIT\n") def commit_mangle(self): self.add("mangle4", "COMMIT\n") self.add("mangle6", "COMMIT\n") def commit_nat(self): self.add("nat4", "COMMIT\n") self.add("nat6", "COMMIT\n") def add(self, chain, value): setattr(self, chain, getattr(self, chain) + "\n" + value) def add_in_subtable(self, chain, subtable, value): if '4' in chain: self.add(chain, "-A " + subtable + " " + value) elif '6' in chain: self.add(chain, "-A " + subtable + " " + value) else: self.add(chain + '4', "-A " + subtable + " " + value) self.add(chain + '6', "-A " + subtable + " " + value)
On remarque donc déjà qu'il y a 6 attributs principaux à notre classe, filter4, filter6, nat4, nat6, mangle4 et mangle6.
Ainsi, au moment de l'injection des règles qui est faite au démarrage du parefeu, (iptables-restore) :
def restore_iptables(self, mode='4'): """Restoration de l'iptable générée""" if mode == '6': global_chain = self.nat6 + self.filter6 + self.mangle6 command_to_execute = ["sudo","-n","/sbin/ip6tables-restore"] else: global_chain = self.nat4 + self.filter4 + self.mangle4 command_to_execute = ["sudo","-n","/sbin/iptables-restore"] process = subprocess.Popen(command_to_execute, stdin=subprocess.PIPE, stdout=subprocess.PIPE) process.communicate(input=global_chain.encode('utf-8')) if self.export: print(global_chain)
Très simplement donc, on remet les règles ensembles pour le parefeu 6 d'un coté, le parefeu 4 de l'autre, et on restore. Savoir si on veut générer que le 4, le 6 ou les 2 est un argument de la fonction en question, on verra un peu plus tard comment c'est fait.
Ajout des chaines
L'idée a été de coder un parefeu unifié. Ainsi, on essaye de faire en sorte d'avoir le plus possible des tables compatibles avec iptables et ip6tables. Par exemple, l'acceptation des connexions déjà établies sera le même en v4 ou en v6
def accept_established(self, subtable='ESTABLISHED-CONN'): """Accepte les connexions déjà établies""" self.init_filter(subtable, decision="-") self.jump_all_trafic("filter", "FORWARD", subtable) self.jump_all_trafic("filter", "INPUT", subtable) self.add_in_subtable("filter", subtable, """-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
Ainsi l'appel à init_filter(subtable) va initialiser la sous table ESTABLISHED-CONN dans la chaîne filter. Mais, étant donné que cette chaine n'existe pas (rappellez-vous, c'est filter4 ou filter6), il va l'ajouter dans les 2. Idem pour jump_all_trafic, qui va attraper tout le trafic sur toutes les interfaces, en v4 ou en v6, dans le forward ou dans l'input, et l'envoyer vers la sous-table ESTABLISHED-CONN. Enfin, la dernière règle peuple la sous-table avec une règle acceptant tout le trafic déjà établi.
Génération du firewall en v4 , v6 ou les 2 ?
Vous l'avez compris, on ne va pas choisir les mêmes chaines suivant si c'est un routeur v4, un routeur v6 ou encore zamok.
Regardons comment est appelé restore-iptables :
def reload(self): """Recharge le parefeu""" self.gen_mangle() self.gen_nat() self.gen_filter() if any('6' in role for role in self.role): self.restore_iptables(mode='6') return if any('4' in role for role in self.role): self.restore_iptables(mode='4') return self.restore_iptables(mode='6') self.restore_iptables(mode='4')
Ca parait clair, on regarde donc self.roles pour savoir si c'est un v4, un v6 ou les 2, et on restore. Mais comment faire la différence par exemple entre le parefeu v6 de zamok et le parefeu v6 de la VM ipv6 du routage ?
Sélection des rôles
Les rôles sont spécifiés dans firewall_config.py installé par Bcfg2 (/var/local/bcfg2/Python/var/local/re2o-services/firewall/firewall_config.py
Exemple :
─( 15:34:36 )─< /var/local/re2o-services/firewall >───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────(git)─[firewall/crans]─[ 0 ]─ jacomme@gulp $ cat firewall_config.py #! role = ['routeur4'] ### Specify each interface role interfaces_type = { 'routable' : ['eno1.1', 'ens1f0.21', 'ens1f0.22', 'ens1f0.23', 'ens1f0.24'], 'sortie' : ['ens1f0.26', 'ens1f0.1132'], 'admin' : ['eno1.2', 'eno1.3'] } ### Specify nat settings: name, interfaces with range, and global range for nat ### WARNING : "interface_ip_to_nat' MUST contain /24 ranges, and ip_sources MUST ### contain /16 range nat = [ { 'name' : 'Wifi', 'interfaces_ip_to_nat' : { 'ens1f0.26' : '185.230.76.0/24', 'eno1.1' : '138.231.144.0/24', 'ens1f0.1132' : '138.231.144.0/24', }, 'ip_sources' : '10.53.0.0/16' }, { 'name' : 'Filaire', 'interfaces_ip_to_nat' : { 'ens1f0.26' : '185.230.77.0/24', 'eno1.1' : '138.231.145.0/24', 'ens1f0.1132' : '138.231.145.0/24', }, 'ip_sources' : '10.54.0.0/16' } ]
On spécifie donc ici les roles, ne pas mettre 4 ou 6 générera un parefeu v4 et v6. On spécifie également les interfaces non routables, routables, et si il y a lieu l'interface de sortie vers le monde extérieur.
Ne pas mettre de roles générera un parefeu minimal, cf plus bas.
Application des rôles
Regardons donc gen_filter :
def gen_filter(self, empty=False): self.init_filter("INPUT") self.init_filter("FORWARD") self.init_filter("OUTPUT") if not empty: if self.verbose: print("Filter : icmp") self.filter_icmp() if self.verbose: print("Filter : icmpv6") self.filter_icmpv6() if self.verbose: print("Filter : accept established") self.accept_established() for role in self.role: if hasattr(self, role): getattr(self, role)('filter') self.commit_filter()
On initialise donc ici les tables FILTER, FORWARD et OUTPUT de filter, en v4 et en v6. On ajoute des règles générales (accept established, filter_icmp) communes à tous les parefeu. Enfin, on appelle la fonction self."role" avec l'option filter, pour l'ensemble des roles définis pour self.
Sélections des chaînes à ajouter
Exemple pour le rôle routeur6 (role donc du routeur ipv6), on appelle base_filter (une factorisation de plusieurs règles, vous le trouverez dessous) et différentes fonctions necessaires, tel que le filtrage ports en v6, la limitation des connexions ssh, etc.
def routeur6(self, table): """Methode appelée spécifiquement pour le parefeu v6""" if table == "filter": self.base_filter() if self.verbose: print("Filter : interdit les machines blacklistées en forward") self.blacklist_hard_forward() if self.verbose: print("Filter : filtage ports v6") self.filtrage_ports(ip_type='6') if self.verbose: print("Filter : limit connexions forward") self.limit_ssh_connexion_forward() if self.verbose: print("Filter : Limit connexion src") self.limit_connexion_srcip() elif table == "mangle": self.log() else: pass
Base filter est appelée par pas mal de roles, (zamok, routeur etc) c'était donc plus joli de tout factoriser.
def base_filter(self): if self.verbose: print("Filter : reseaux non routables") self.reseaux_non_routables() if self.verbose: print("Filter : bl hard") self.blacklist_hard() if self.verbose: print("Filter : connexion input") if self.verbose: print("Limitation des connexions") self.limit_ssh_connexion_input() self.limit_connexion_dstip()
Voilà,a priori, là on a tout pour générer notre fichier iptables. Evidemment, se référer aux docstrings pour voir ce que chaque fonction fait.
Fonction des différents serveurs
Synchronisation en re2o-services
Certaines instances du parefeu (odlyd, gulp, ipv6 et zamok) ont besoin d'être regen, par ex à l'ajout d'un adhérent, ou d'ouvertures d'un port, en conséquence ils sont gérés dans la page machines/services; et regen par le cron re2o-services quand il est nécessaires.
Les autres instances (radius, routeur) sont purement statiques; et seulement générées au boot (donc cron @reboot --force dans leur etc/cron.d)
Routage principal (Odlyd, gulp et ipv6-zayo)
Gulp et odlyd ont la même instance de parefeu. Leur rôle est routeur4, ce qui signifie que seule la partie v4 donc iptables est générée et appliquée.
En plus des fonctions de base (filtrage icmp/ssh/etc); ce parefeu contient en gros la protection en forward de toute la zone crans. Il s'appuie uniquement sur les interfaces pour être souple. Il possède des chaines filter, nat et mangle.
def routeur4(self, table): """Methode appellée spécifiquement pour le parefeu v4""" if table == "filter": self.base_filter() if self.verbose: print("Filter : filtrage ports 4") self.filtrage_ports(ip_type='4') if self.verbose: print("Filter : limit ssh connexion forward") self.limit_ssh_connexion_forward() if self.verbose: print("Filter : limit connexion src ip") self.limit_connexion_srcip() elif table == "mangle": if self.verbose: print("Mangle : Mise en place des logs") self.log() if self.verbose: print("Mangle : Réglage correct du MSS") self.mss() elif table == "nat": for nat_to_do in self.nat_settings: if self.verbose: print("Nat : priv" + nat_to_do['name']) self.nat_prive_ip(nat_to_do)
Filter
Enfin il contient la fonction filtrage port, qui récupère auprès de re2o-server, les politiques par default de chaque range et les politiques particulières.
Ce serait fastidieux de print tout le code ici... disons que la chaine filtrage-port est automatiquement appellée pour tout paquet entrant et sortant de la zone crans (FORWARD). D'abord est appliquée la règle par default, puis les règles particulières, et si rien ne match, le paquet est rejeté.
Nat
Ce qui est remarquable ici est la chaine de nat, comme son nom l'indique qui va nater de manière statique et par plage de ports (25 ip privées sur 2000 ports chacun d'une ip publique). On a donc 25*255 ip privées potentiellement natées.
nat_prive_ip_plage = nat_type['ip_sources'] for nat_ip_range in range(1, 26): range_name = 'nat' + nat_prive_ip_plage.split('.')[1] + '_' + str("%02d" % nat_ip_range ) self.init_nat(range_name, decision="-") self.add_in_subtable("nat", subtable, '-s ' + '.'.join(nat_prive_ip_plage.split('.')[:2]) + '.' + str(nat_ip_range) + '.0/24 -j ' + range_name) for nat_ip_range in range(1, 26): range_name = 'nat' + nat_prive_ip_plage.split('.')[1] + '_' + str("%02d" % nat_ip_range) for nat_ip_subrange in range(16): subrange_name = range_name + '_' + str(hex(nat_ip_subrange)[2:]) self.init_nat(subrange_name, decision="-")
etc
Mangle
Dans cette chaine, on log tout ce qui rentre et sort de la zone + mise en place du mss pour éviter les prb de drop dû au MTU.
Cahier des charges
Fonctions de base commmunes
Filter
- Acceptation de toute connexion déjà établie
- Acceptation du ping v4 et v6 en input et forward
ping ⊊ ICMP. Réfléchir à si on veut tout l'ICMP (ne pas oublier que les "ça a pas marché", c'est aussi de l'ICMP, mais pas du ping). -- Wiki20-100 2018-05-17 13:46:48
- Blocage des connexions entrantes vers les réseaux admin (adm, admbornes etc) sur l'interface correspondante
Oui. Mais je pense qu'il manque la fin de la phrase. -- Wiki20-100 2018-05-17 13:46:48
- DROP du traffic illégitime venant de l'extérieur (broadcast et multicast qu'on n'est pas censés recevoir, IP non routables, etc.)
- Blacklist hard des connexions entrantes et sortantes des utilisateurs blacklistés
- Filtrage des ports en v4 et v6 sur les interfaces d'entrée de la zone crans
- Limitation des connexions ssh entrantes pour éviter les attaques par bruteforce
- Limitation des connexions tcp et udp en input (limit connexions dstip) afin d'éviter le flood de connexions (cf attaque sur le wiki par un adhérent)
Fonctions supplémentaires du parefeu de sortie (odlyd, sable et ipv6)
Filter
- Blacklist hard des utilisateurs blacklistés en forward
- Filtrage des ports en v4 et v6 sur les interfaces de sortie de la zone crans
- Limitation des connexions ssh en forward pour éviter les attaques bruteforce
Pas sûr que ce soit vraiment notre soucis -- Wiki20-100 2018-05-17 13:46:48
- Limitation des connexions sortantes tcp/udp pour éviter le flood d'une machine vérolée vers l'éxtérieur (limit connexions srcip)
Pareil -- Wiki20-100 2018-05-17 13:46:48
Nat
- NAT des ip privées filaires et wifi en v4
Mangle
- Log de toutes les nouvelles connexions sur les interfaces de sortie et routables
Fonctions supplémentaires du parefeu adhérents
Filter
- Interdiction de l'output vers adm pour non nounous/apprentis
- Interdiction de l'output vers odlyd pour les non à jour de cotiz (todo)
Legacy - pour les divers parefeu du crans