I Introduction
Ce tuto va tenter de montrer pas à pas comment implémenter la reverse Proxy avec Iptables.
Le reverse proxy est implémenté dans une VM (mais qui peut être une machine physique) et elle :
- est basée sur une installation min de centos 7 ;
- comporte 1 carte réseau (ce tuto marche également pour 2 cartes réseaux)
II Avant de commencer
Soit le schéma suivant :
L’objectif est que le client s’adresse au serveur (192.168.0.10) seulement. Enfin suivant le port d’interrogation, le serveur va renvoyer la question au PC de type PC Dest. La réponse sera retransmise au serveur qui à son tour retransmettra la réponse au client.
Ainsi dans le cas d’une interrogation du serveur sur le port :
- 8080 : c’est le résultat de PC Dest1 qui sera retourné au « client 1 »,
- 443 : c’est le résultat du PC Dest2 qui sera retourné au « client 1 ».
Schématiquement, nous cherchons donc à produire ceci :
III Mise en oeuvre
III.1 Introduction
Nous allons donc mettre en oeuvre la notion de « port forwarding », c’est à dire la redirection de paquets réseaux recus sur une machine vers une autre.
La solution sera implémentée avec Iptables.
Mais avant revenons sur le schéma d’iptables (simplifié) ci-dessous :
Pour faire du « port forwarding » nous allons devoir utiliser les chaines suivantes :
- PREROUTING de la table Nat
- FORWARD de la table Filter
- POSTROUTING de la table Nat
Il faut aussi activer la fonction « routage ».
III.2 Mise en oeuvre simple
Ce premier exemple vise à rester simple pour bien comprendre les mécanismes de bases à implémenter.
Dans un premier temps :
- on active la fonction routage ;
- on vide les règles existantes ;
- on ouvre tout par défaut pour les chaines INPUT, OUTPUT 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 de la table filter iptables -t filter -P INPUT ACCEPT iptables -t filter -P FORWARD ACCEPT iptables -t filter -P OUTPUT ACCEPT
Nous devons maintenant donner des directives pour les chaines PREROUTING et POSTROUTING.
Si nous utilisons l’option MASQUERADE de la chaine POSTROURING, il ne sera plus nécessaire de définir de règles supplémentaire sur la chaine POSTROUTING.
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Enfin il faut spécifier la chaine PREROUTING. C’est dans cette chaine qu’il sera spécifié :
- l’@IP source [directive -s 192.168.0.1]
- le type de protocole [-p tcp]
- le port à traiter [directive –dport 8080]
- l’@IP sur laquelle il faut rediriger les paquets [directive -j DNAT –to 10.2.36.110]
Ce qui donne :
iptables -t nat -A PREROUTING -s 192.168.0.1 -p tcp --dport 8080 -j DNAT --to 192.168.0.100
Cette règle fonctionne donc pour ce cas de figure :
Pour le deuxième cas, la règle sera la suivante :
iptables -t nat -A PREROUTING -s 192.168.0.1 -p tcp --dport 443-j DNAT --to 192.168.0.101
Avec le deuxième cas de figure ci-dessous :
Ce qui donne le script final 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 de la table filter iptables -t filter -P INPUT ACCEPT iptables -t filter -P FORWARD ACCEPT iptables -t filter -P OUTPUT ACCEPT # Chaine POSTROUTING en mode MASQUERADE iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # Règle DNAT à mettre en oeuvre iptables -t nat -A PREROUTING -s 192.168.0.1 -p tcp --dport 8080 -j DNAT --to 192.168.0.100 iptables -t nat -A PREROUTING -s 192.168.0.1 -p tcp --dport 443 -j DNAT --to 192.168.0.101
III.3 Mise en oeuvre avancée
L’idée est d’avoir une politique à DROP par défaut pour la table FILTER.
Ainsi l’initialisation d’iptables sera la suivante :
#!/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 de la table filter
iptables -t filter -P INPUT DROP
iptables -t filter -P FORWARD DROP
iptables -t filter -P OUTPUT DROP
Les fonctions de routages sont les mêmes :
# Chaine POSTROUTING en mode MASQUERADE iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # Règle DNAT à mettre en oeuvre iptables -t nat -A PREROUTING -s 192.168.0.1 -p tcp --dport 8080 -j DNAT --to 192.168.0.100 iptables -t nat -A PREROUTING -s 192.168.0.1 -p tcp --dport 443 -j DNAT --to 192.168.0.101
Mais à ce stade cela ne marchera pas car la chaine FORWARD bloque tout les paquets par défaut (Rappel, la politique par defaut est à drop).
Ainsi la ligne suivante autorise le paquet dans la chaine FORWARD :
iptables -t filter -A FORWARD -s 192.168.0.1 -d 192.168.0.100 -p tcp --dport 8080 -j ACCEPT
Pour être encore plus fin nous pouvons également définir les états de connexions : ce qui alors se traduit par ces 2 lignes :
iptables -t filter -A FORWARD -s 192.168.0.1 -d 192.168.0.100 -p tcp --dport 8080 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -s 192.168.0.1 -d 192.168.0.100 -p tcp -m conntrack --ctstate ESTABLISHED -j ACCEPT
Enfin une troisième ligne serait interessante si nous souhaitons logguer toute nouvelle connexion :
iptables -t filter -A FORWARD -s 192.168.0.1 -d 192.168.0.100 -p tcp --dport 8080 -m conntrack --ctstate NEW -j LOG --log-prefix '[8080 --> 192.168.0.1->192.168.0.100] : '
Pour le deuxième PC les règles seront les suivantes :
iptables -t filter -A FORWARD -s 192.168.0.1 -d 192.168.0.101 -p tcp --dport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -s 192.168.0.1 -d 192.168.0.101 -p tcp -m conntrack --ctstate ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -s 192.168.0.1 -d 192.168.0.100 -p tcp --dport 443 -m conntrack --ctstate NEW -j LOG --log-prefix '[443 --> 192.168.0.1->192.168.0.101] : '
Soit le script final 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 de la table filter iptables -t filter -P INPUT DROP iptables -t filter -P FORWARD DROP iptables -t filter -P OUTPUT DROP # Chaine POSTROUTING en mode MASQUERADE iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # Règle DNAT à mettre en oeuvre 8080 vers pc dest 1 iptables -t nat -A PREROUTING -s 192.168.0.1 -p tcp --dport 8080 -j DNAT --to 192.168.0.100 iptables -t filter -A FORWARD -s 192.168.0.1 -d 192.168.0.100 -p tcp --dport 8080 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -s 192.168.0.1 -d 192.168.0.100 -p tcp -m conntrack --ctstate ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -s 192.168.0.1 -d 192.168.0.100 -p tcp --dport 8080 -m conntrack --ctstate NEW -j LOG --log-prefix '[8080 --> 192.168.0.1->192.168.0.100] : ' # Règle DNAT à mettre en oeuvre 443 vers pc dest 2 iptables -t nat -A PREROUTING -s 192.168.0.1 -p tcp --dport 443 -j DNAT --to 192.168.0.101 iptables -t filter -A FORWARD -s 192.168.0.1 -d 192.168.0.101 -p tcp --dport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -s 192.168.0.1 -d 192.168.0.101 -p tcp -m conntrack --ctstate ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -s 192.168.0.1 -d 192.168.0.100 -p tcp --dport 443 -m conntrack --ctstate NEW -j LOG --log-prefix '[443 --> 192.168.0.1->192.168.0.101] : '