I Introduction
Ce tuto va tenter de montrer pas à pas comment implémenter la fonction passerelle sur une VM Linux grace à Iptables. Ainsi il sera utilisé les tables filter et nat et tentera de montrer les liaisons qui existent ou non avec les chaines INPUT, OUTPUT et FORWARD.
La passerelle est dans notre une VM (mais peut être une machine physique) et elle :
- est basée sur une installation min de centos 7 ;
- comporte 2 cartes réseaux :
- une vers un lien internet ;
- une autre vers un réseau interne privé dans lequel plusieurs VM peuvent être présentes (VM qui devront utiliser donc la passerelle pour avoir internet).
II Avant de commencer
II.1 Présentation générale :
Ci dessous le schéma de principe qui va nous aider à mieux comprendre ce qui va être fait :
La VM PC PASSERELLE a donc 2 cartes réseaux :
- la première carte est branchée sur un réseau dont nous pouvons avoir internet (en passant via une autre passerelle).
- la deuxième carte est branchée sur un réseau fermé dans lequel il y a aura une ou plusieurs autres VM.
L’objectif est donc que les VM du réseau privé puissent avoir accès à internet via la VM PC PASSERELLE. C’est que nous verrons avec la VM PC TEST.
II.2 Préparation de son labo de test
Ce labo peut être mis en oeuvre sur un PC avec Virtual box par exemple.
La VM PC PASSERELLE aura une carte en mode « Accès par pont » qui permettra d’accéder à la box internet. L’autre carte sera en mode « Réseau interne »
Pour la VM PC TEST elle aura une carte déclarée en mode « Réseau interne ».
Pour les cartes branchées sur le réseau interne il faut le même sous-réseau. Il a été choisi le 192.168.1.0/24.
Pour retrouver les cartes réseaux sur la vm PC PASSERELLE je lance la commande nmcli d, ce qui donne :
DEVICE TYPE STATE CONNECTION enp0s3 ethernet connecté enp0s3 enp0s8 ethernet connecté System enp0s8
L’interface enp0S3 est la carte pouvant joindre la box internet
L’interface enp0S8 est la carte branchée sur le réseau privé
Ces cartes peuvent être configurées manuellement ou via l’outil graphique « nmtui ».
III Monter une passerelle
III.1 Introduction
La fonction passerelle sera assurée par iptables.
Pour avoir des précisions sur les options de la commandes IP voir ce lien très bien écrit : https://www.inetdoc.net/guides/iptables-tutorial/index.html .Je conseille de regarder ce guide qu’après avoir vu les quelques exemples ci-dessous pour mieux comprendre l’utilité et les options utilisées par iptables.
Si iptables est totalement inconnu je propose de suivre lien pour bien dégrossier la chose : http://debian-facile.org/doc:reseau:iptables-pare-feu-pour-un-client?&#sauvegarder-ses-reglest
III.2 Une première passerelle
Dans cet exemple il va être implémenté la manière la plus simple (et la plus rapide) de monter une passerelle.
Certains dirons que c’est une passerelle passoire car aucun filtre ne sera présent : tout passera de gauche à droite.
Tout d’abord crééons le fichier qui va contenir toutes nos commandes de configurations d’iptables.
echo "" > exemple_passerelle1.sh
Puis rendre se fichier executable
chmod +x exemple_passerelle1.sh
Nous allons donc utiliser iptables pour faire notre passerelle. Pour cela il faut :
- réinitialiser toutes les règles existantes des différentes chaines
- insérer nos règles.
Pour rappel :
- la table FILTER contient les chaines INPUT et OUPUT qui seront utilisées pour les flux entrants et sortants de services au sein de la VM.
- la table NAT avec les chaines PREROUTING et POSTROUTING qui vont permettre de manipuler la translations d’adresses. Dit autrement, tous les mécanismes qui vont permettre de faire du NAT. C’est grace à ces chaines que nous allons monter la passerelle en activant le routage.
- la table FILTER contient la chaine FORWARD qui va nous permettre d’implémenter des filtres sur la partie routage.
Il va être utilisé dans la chaine POSTROUTING la cible « MASQUERADE ». Cette cible nous permet de ne pas spécifier d’adresse IP sources et de transférer le flux du réseau interne vers le réseau internet ou de la carte n°2 vers la carte n°1.
Ce qui se traduit par activer la fonction routage
echo « 1 »> /proc/sys/net/ipv4/ip_forward
puis écrire la règle iptables suivantes :
iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
En d’autres termes, tous les flux (autre que la destination de la VM) qui passe par une interface réseau sont « nattés » sur l’interface « enp0S3 », interface réliée au réseau internet.
« sont nattés » signifie que :
- en sortie :
- tous les flux réseaux d’une interface réseau sont redirigés sur l’interface enp0S3
- en retour :
- le flux entrant arrive sur l’interface enp0S3. La trame est récupérée car elle est en lien avec la première emmision. Elle est émise sur l’interface enp0S8. Flux qui arrivera alors à destination sur le PC TEST.
Notre premier script ressemblera donc à celui-ci :
#!/bin/sh # Activer le mode routeur echo "1"> /proc/sys/net/ipv4/ip_forward # Réinitialisation des chaines iptables -F iptables -X iptables -t nat -F iptables -t nat -X # Politique par défaut des chaines iptables -P INPUT ACCEPT iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT # Active le snat spécial avec l'option masquerade iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
Pour vérifier, regardons l’état de la table FILTER : iptables -L
Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
Ainsi que l’état de la table NAT : iptables -t nat -L
Chain PREROUTING (policy ACCEPT) target prot opt source destination Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- anywhere anywhere
La machine test peut désormais communiquer vers l’extérieur via la passerelle « PC PASSERELLE ».
III.3 Une passerelle plus évoluée
La passerelle précédente fait son travail mais aucunes règles de sécurité ne sont implémentées. En somme tout est ouvert :
- pour tous les fluxs allant sur la VM PC PASSERELLE (le plus critique),
- pour tous les fluxs routés du réseau privé vers le réseau internet.
Pour corriger cela, nous allons passer la politique à DROP par défaut des chaines INPUT et FORWARD.
#!/bin/sh # Activer le mode routeur echo "1"> /proc/sys/net/ipv4/ip_forward # Réinitialisation des chaines iptables -F iptables -X iptables -t nat -F iptables -t nat -X # Politique par défaut des chaines iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT TRUE # Active le snat spécial avec l'option masquerade iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
Mais à ce stade plus rien ne rentre à destination de la VM et la fonction routage est bloquée. Nous verrons un peu plus tard les règles à implémenter quand la chaine OUTPUT sera à DROP.
Ainsi dans un premier temps nous allons nous occuper des flux entrants en direction de la VM puis après des fluxs routés entre les 2 réseaux.
Les régles qui vont suivre vont autoriser :
- la boucle locale ;
- toutes les réponses de flux sortant de la VM ;
- le protocole SSH en entrée pour prendre le contrôle de la VM à distance.
Pour cela nous allons travailler avec les chaines INPUT de la table filter :
# Boucle locale iptables -t filter -A INPUT -i lo -j ACCEPT iptables -t filter -A OUTPUT -o lo -j ACCEPT # Autoriser en entrée les session connectées iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Autorise les pings iptables -t filter -A INPUT -p icmp -j ACCEPT # Ouvre port ssh pour accès distant iptables -t filter -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
Ces règles s’appliquent sur toutes les interfaces réseaux.
Si nous voulions affiner nos réglages comme autoriser le ping sur la carte n°1 (enp0s3) et pas sur la carte n°2 (enp0s8) nous aurions procédé de la sorte :
iptables -t filter -A INPUT -i enp0s3 -p icmp -j ACCEPT
Maintenant nous allons travailler sur le filtrage concernant le routage. Pour cela nous allons manipuler la chaine « FORWARD ».
Ainsi il va être autorisé :
- le passage du ping ;
- les flux tcp pour les port 80 et 443 (WEB) ;
- les flux udp pour le port 53 (DNS).
Pour le ping :
iptables -t filter -A FORWARD -p icmp -j ACCEPT
Cela marche mais c’est trop généraliste. On peut réduire le filtre on sélectionnant par exemple les interfaces réseaux :
iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -p icmp -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -p icmp -j ACCEPT
En spécifiant les interfaces réseaux, il faut déclarer les autorisations pour le sens sortant de la trame icmp (ping) puis le sens revenant de la trame icmp. D’ou la présence des 2 lignes ci-dessus : la trame icmp qui part du PC TEST entre par enp0s3 et ressort par enp0s8 puis elle revient par enp0S3 et ressort par enp0S3 en direction du pc Test.
Il est possible de réduire encore les permissions en spécifiant :
- les adresses réseaux sources et destinations,
- les états de la trame icmp a accepté sur chaque sens de communication (NEW, ESTABLISSED, RELATED). Point très intéressant car il peut être accepté une trame de type nouvelle demande d’un côté du réseau et pas de l’autre ou pour le retour de la trame n’accepté que l’état ESTABLISSED ou RELATED.
Ce qui donne :
iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p icmp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT
On pourrait aller plus loin en n’acceptant que certains type de trames ICMP.
Ce principe d’autorisation de flux sortants et entrants est à répeter pour autant de protocoles que l’on souhaite autoriser à transiter entre les 2 cartes réseaux. Ce qui pourrait donner ceci :
# FORWARD : ping iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p icmp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT # FORWARD : udp dns iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p udp --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p udp --sport 53 -m state --state ESTABLISHED -j ACCEPT # FORWARD flux http iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p tcp --dport 80 -m state --state ESTABLISHED -j ACCEPT # FORWARD flux https iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p tcp --dport 443 -m state --state ESTABLISHED -j ACCEPT
Attention l’état RELATED ne vaut que pour l’icmp (ping)
Au final nous pouvons avoir le script suivant :
#!/bin/sh # Activer le mode routeur echo "1"> /proc/sys/net/ipv4/ip_forward # Réinitialisation des chaines iptables -F iptables -X iptables -t nat -F iptables -t nat -X # Politique par défaut des chaines iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT # Active le snat spécial avec l'option masquerade iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE ####################### # Chaine OUPUT / INPUT # Boucle locale iptables -t filter -A INPUT -i lo -j ACCEPT iptables -t filter -A OUTPUT -o lo -j ACCEPT # Session connectée iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Autorise les pings que sur la carte réseau n°1 (côté internet) iptables -t filter -A INPUT -i enp0s3 -p icmp -j ACCEPT # Ouvre port ssh pour accès distant iptables -t filter -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT ######################### # Chaine FORWARD # FORWARD : ping iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p icmp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT # FORWARD : udp dns iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p udp --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p udp --sport 53 -m state --state ESTABLISHED -j ACCEPT # FORWARD flux http iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p tcp --dport 80 -m state --state ESTABLISHED -j ACCEPT # FORWARD flux https iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p tcp --dport 443 -m state --state ESTABLISHED -j ACCEPT
Maintenant on vérifie les règles implémentées : iptables -L
Chain INPUT (policy DROP) target prot opt source destination ACCEPT all -- anywhere anywhere ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED ACCEPT icmp -- anywhere anywhere ACCEPT tcp -- anywhere anywhere tcp dpt:ssh Chain FORWARD (policy DROP) target prot opt source destination ACCEPT icmp -- 192.168.1.0/24 anywhere state NEW,RELATED,ESTABLISHED ACCEPT icmp -- anywhere 192.168.1.0/24 state RELATED,ESTABLISHED ACCEPT udp -- 192.168.1.0/24 anywhere udp dpt:domain state NEW,ESTABLISHED ACCEPT udp -- anywhere 192.168.1.0/24 udp spt:domain state ESTABLISHED ACCEPT tcp -- 192.168.1.0/24 anywhere tcp dpt:http state NEW,ESTABLISHED ACCEPT tcp -- anywhere 192.168.1.0/24 tcp dpt:http state ESTABLISHED ACCEPT tcp -- 192.168.1.0/24 anywhere tcp dpt:https state NEW,ESTABLISHED ACCEPT tcp -- anywhere 192.168.1.0/24 tcp dpt:https state ESTABLISHED Chain OUTPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere
Et également dans la table NAT : iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- anywhere anywhere
A ce stade nous avons une passerelle qui permet au PC test :
- sur le réseau internet :
- d’établir un traffic web (http et https) ;
- de résoudre des noms de dommaines (DNS) ;
- de « pinger » les machines ;
- sur le réseau interne
- d’établir une connexion ssh sur le PC PASSERELLE (également côté « internet »).
III.4 Le suivi d’état est fait avec « m state » alors que d’autres le font avec « m conntrack » ?
Quésako ?
Pour router des paquets d’une carte réseau vers une autre et gérés le retour nous avons ecris cela pour le ping :
# FORWARD : ping iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p icmp -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT
L’option -m state nous permet d’effectuer des contrôles sur la nature d’état du paquet : NEW,ESTABLISHED ou RELATED.
Ainsi nous autorisons la sortie du réseau privé vers le réseau internet d’un ping pour toute nouvelle demande par exemple (état NEW). Ce qui n’est pas le cas dans l’autre sens (du réseau internet au réseau privé).
Mais la commande m state est considérée comme obsolete par certains (bien qu’elle fonctionne). D’autres disent que c’est une version étendue de la correspondance d’état. Dans tous les cas elle propose plus d’options et permet par exemple la négation dans les expressions comme par ex : -m -conntrack ! –ctstate NEW,INVALID
Donc si nous devions utiliser la directive m conntrack, les 2 lignes s’écriraient de la manière suivante :
# FORWARD : ping iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p icmp -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p icmp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Le script récris sera donc celui (avec ajout de la réinitialisation de la table mangle) :
#!/bin/sh # Activer le mode routeur echo "1"> /proc/sys/net/ipv4/ip_forward # Réinitialisation des chaines iptables -F iptables -X iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X # Politique par défaut des chaines iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT # Active le snat spécial avec l'option masquerade iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE ####################### # Chaine OUPUT / INPUT # Boucle locale iptables -t filter -A INPUT -i lo -j ACCEPT iptables -t filter -A OUTPUT -o lo -j ACCEPT # Session connectée iptables -t filter -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Autorise les pings que sur la carte réseau n°1 (côté internet) iptables -t filter -A INPUT -i enp0s3 -p icmp -j ACCEPT # Ouvre port ssh pour accès distant iptables -t filter -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT ######################### # Chaine FORWARD # FORWARD : ping iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p icmp -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p icmp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # FORWARD : udp dns iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p udp --dport 53 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p udp --sport 53 -m conntrack --ctstate ESTABLISHED -j ACCEPT # FORWARD flux http iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p tcp --dport 80 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p tcp --dport 80 -m conntrack --ctstate ESTABLISHED -j ACCEPT # FORWARD flux https iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p tcp --dport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p tcp --dport 443 -m conntrack --ctstate ESTABLISHED -j ACCEPT
III.5 Passerelle avec les chaines à DROP pour la table filter
Nous allons passer toutes les chaines à DROP de la table FILTER. Ainsi nous controllerons exactement ce qui entre à destination de la VM et ce qui en sort.
Ainsi la politique par défaut des chaines de la table « FILTER » sera la suivante :
# Politique par défaut des chaines iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP
Si nous éxecutons notre script avec juste ces modifications :
- la chaine « FORWARD » n’est pas impactée donc la fonction passerelle fonctionne toujours. Le PC TEST peut faire des pings ou des résolutuions D?S
- en revanche la chaine « OUTPUT » ne contient aucune règle (sauf pour la boucle locale), toutes les sorties de la VM sont bloquées.
Donc dans la chaine OUTPUT il faut :
- autoriser ce que nous souhaitons en sortie (de l’OS de la VM vers l’extérieur)
- ping, résolution dns, navigation web, etc…
- autoriser les connexions établies en liaison avec la chaine INPUT :
- répondre à un ping
- répondre à un service supporté par la VM (serveur ssh, web, autres)
Pour répondre aux réponses d’un ping ou tout autre service nous pouvons écrire :
iptables -t filter -A OUTPUT -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
Ici tout est autorisé en sortie que ce soit pour une nouvelle connexion ou pour une connxion déjà établie.
Soit cette règle suffit, soit on décide alors d’affiner nos règles. C’est ce que nous allons faire.
Si on prend le cas du ping, nous pouvons écrire :
iptables -t filter -A OUTPUT -m conntrack -p icmp --ctstate ESTABLISHED,RELATED -j ACCEPT
Cette règle n’est pas complète. Mais elle est intéressante en terme de comportement. Elle permet que la VM PC PASSERELLE de répondre au ping mais elle bloque toute tentative de faire du ping à partir de cette VM.
En effet dans la chaine INPUT, il est autorisé le PING.
Mais dans la chaine OUTPUT on n’authorise que la réponse (il n’y a pas de NEW pour autoriser l’émission).
Donc pour répondre au ping et faire du ping à partir de la VM il faudra écrire :
iptables -t filter -A OUTPUT -m conntrack -p icmp --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
Ensuite on généralise sur tous les protocoles que l’on souhaite faire passer :
iptables -t filter -A OUTPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -t filter -A OUTPUT -p tcp --dport 80 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -t filter -A OUTPUT -p tcp --dport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
Enfin il faut que la chaine « OUTPUT » accepte toutes les trames qui ont été inscrites dans l’INPUT. Mais on ne connait pas forcément le port de réponse. Donc nous allons accepter tout les flux dont l’état correpond à une connexion établie (ESTABLISHED)
# flux autorisé à sortir si autorisé dans la chaine INPUT ... iptables -t filter -A OUTPUT -p TCP -m conntrack --ctstate ESTABLISHED -j ACCEPT
Ce qui donnera le script suivant :
#!/bin/sh # Activer le mode routeur echo "1"> /proc/sys/net/ipv4/ip_forward # Réinitialisation des chaines iptables -F iptables -X iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X # Politique par défaut des chaines iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT DROP # Active le snat spécial avec l'option masquerade iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE ####################### # Chaine OUPUT / INPUT # Boucle locale iptables -t filter -A INPUT -i lo -j ACCEPT iptables -t filter -A OUTPUT -o lo -j ACCEPT # Session connectée iptables -t filter -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Autorise les pings que sur la carte réseau n°1 (côté internet) iptables -t filter -A INPUT -i enp0s3 -p icmp -j ACCEPT # Ouvre port ssh pour accès distant iptables -t filter -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT #iptables -t filter -A OUTPUT -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT iptables -t filter -A OUTPUT -p icmp -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT # Protocole autorisés à consulter de la VM vers l'extérieur iptables -t filter -A OUTPUT -p udp --dport 53 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -t filter -A OUTPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -t filter -A OUTPUT -p tcp --dport 80 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -t filter -A OUTPUT -p tcp --dport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT # flux autorisé à sortir si entrée acceptée ... iptables -t filter -A OUTPUT -p TCP -m conntrack --ctstate ESTABLISHED -j ACCEPT ######################### # Chaine FORWARD # FORWARD : ping iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p icmp -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p icmp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # FORWARD : udp dns iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p udp --dport 53 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p udp --sport 53 -m conntrack --ctstate ESTABLISHED -j ACCEPT # FORWARD flux http iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p tcp --dport 80 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p tcp --dport 80 -m conntrack --ctstate ESTABLISHED -j ACCEPT # FORWARD flux https iptables -t filter -A FORWARD -i enp0s8 -o enp0s3 -s 192.168.1.0/24 -d 0.0.0.0/0 -p tcp --dport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -i enp0s3 -o enp0s8 -s 0.0.0.0/0 -d 192.168.1.0/24 -p tcp --dport 443 -m conntrack --ctstate ESTABLISHED -j ACCEPT
Après lancé ce script nous aurons le comportement suivant :
iptables -L
Chain INPUT (policy DROP) target prot opt source destination ACCEPT all -- anywhere anywhere ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED ACCEPT icmp -- anywhere anywhere ACCEPT tcp -- anywhere anywhere tcp dpt:ssh Chain FORWARD (policy DROP) target prot opt source destination ACCEPT icmp -- 192.168.1.0/24 anywhere ctstate NEW,RELATED,ESTABLISHED ACCEPT icmp -- anywhere 192.168.1.0/24 ctstate RELATED,ESTABLISHED ACCEPT udp -- 192.168.1.0/24 anywhere udp dpt:domain ctstate NEW,ESTABLISHED ACCEPT udp -- anywhere 192.168.1.0/24 udp spt:domain ctstate ESTABLISHED ACCEPT tcp -- 192.168.1.0/24 anywhere tcp dpt:http ctstate NEW,ESTABLISHED ACCEPT tcp -- anywhere 192.168.1.0/24 tcp dpt:http ctstate ESTABLISHED ACCEPT tcp -- 192.168.1.0/24 anywhere tcp dpt:https ctstate NEW,ESTABLISHED ACCEPT tcp -- anywhere 192.168.1.0/24 tcp dpt:https ctstate ESTABLISHED Chain OUTPUT (policy DROP) target prot opt source destination ACCEPT all -- anywhere anywhere ACCEPT icmp -- anywhere anywhere ctstate NEW,RELATED,ESTABLISHED ACCEPT udp -- anywhere anywhere udp dpt:domain ctstate NEW,ESTABLISHED ACCEPT tcp -- anywhere anywhere tcp dpt:ssh ctstate NEW,ESTABLISHED ACCEPT tcp -- anywhere anywhere tcp dpt:http ctstate NEW,ESTABLISHED ACCEPT tcp -- anywhere anywhere tcp dpt:https ctstate NEW,ESTABLISHED ACCEPT tcp -- anywhere anywhere ctstate ESTABLISHED
iptables -t nat -L
Chain PREROUTING (policy ACCEPT) target prot opt source destination Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- anywhere anywhere
III. Conclusion
Nous pourrions continuer le paramétrage iptables pour encore améliorer la configuration de la passerelle. En effet nous n’avons pas implémenté des règles de sécurité pour contrer des failles et certaines formes de type d’attaque. Dans un autre domaine, le procotole FTP en mode passif ou actif n’a pas été abordé. Nous n’avons pas également parler du monitoring en logguant les trames refusées par iptables. Ou bien encore l’intégration, de services comme un serveur DHCP pour le réseau interne ou un cache DNS. La liste est longue …
Néanmoins l’objectif premier était surtout de voir comment implémenter iptables pour router tout ou partie des paquets d’un réseau vers un autre. Soit, sous iptables, de manipuler les chaines INPUT, OUTPUT et FORWARD de la table FILTER et de voir leur interactions pour du flux « normal » et du flux dit « routés ».