Thématiques principales

dimanche 13 octobre 2019

Reseau: Iptables: routeur logiciel

Nous revenons une nouvelle fois avec iptable mais plus pour faire du filtrage réseau mais pour du routage de trame.
Pour cela nous allons considérer l’exemple suivant: Imaginons un server sur lequel tourne un service. Ce service on le représentera par un service netcat (nc) [1]. Ce server se trouve dans le reseau privé 192.168.1.0/24. Nous, nous sommes dans un reseau externe en 192.168.0.0/24, nous ne pouvons donc pas y accéder directement. Comment allons nous nous y prendre pour que malgré tout nous puissions y parvenir?


Conf réseau de la passerelle

Tout d’abord on va installer une machine entre les deux réseaux, celle-ci servira de passerelle et de routeur étant dans les deux réseaux à la fois. On va donc lui assigner une adresse dans le 1er reseau, par exemple 192.168.1.10 et une seconde dans le second réseau 192.168.0.10.
Deja pour faire cela, on va assigner à notre interface reseau eth0 l’adresse ip externe (en 0.10) et on va creer une interface reseau virtuelle eth0:0 pour l’autre [7]:


root@routeur$ ip addr add 192.168.1.10/24 broadcast 192.168.1.255 dev eth0 label eth0:0

nous allons alors vérifier notre config

root@routeur$ ip a

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether b8:27:eb:b7:7f:be brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.10/24 brd 192.168.0.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 192.168.1.10/24 brd 192.168.1.255 scope global eth0:0

Conf réseau du server

Ok on à la passerelle, on reviendra sur la partie iptable plus tard, on va terminer d’abord la configuration réseau. On va donc affecter une adresse ip dans le reseau 192.168.1.0 à notre server:

root@server$ ip addr add 192.168.1.30/24 broadcast 192.168.1.255 dev eth0 label eth0:0
root@server$ ip a
[...]
inet 192.168.1.30/24 brd 192.168.1.255 scope global eth0:0
       valid_lft forever preferred_lft forever

Dans le serveur nous allons donc lancer un service avec netcat qui enverra une réponse à celui qui l'interroge en précisant un port d'écoute et une ip source:


root@server$ echo "reponse" | nc -s 192.168.1.30 -l -p 9999

Conf réseau du client

Du coté client, cela va etre assez similaire à la configuration du server à ceci pret qu’il se trouve dans le reseau 192.168.0.0/24

root@client$ ip addr add 192.168.0.60/24 broadcast 192.168.0.255 dev eth0 label eth0:0
root@client$ ip a
[...]
inet 192.168.0.60/24 brd 192.168.0.255 scope global eth0:0
       valid_lft forever preferred_lft forever

À ce stade nous pouvons verifier que la communication ne marche pas en envoyant sur la passerelle un message (on precise l’ip source par commodité et pour eviter tout implicite):

 root@client$ echo message | nc -s 192.168.0.60 192.168.0.10 8888

Pas de reponse… ok normal

Configuration Iptables de la passerelle

Maintenant que la conf réseau est en place, il faut que l’on construise les règles iptables adaptées au routage des messages.

Tout d’abord on va envoyer toute les trames à destination de la passerelle et du port 8888 sur le server sur son port d'écoute [2]:

root@rooteur$ sudo iptables -t nat -R OUTPUT 1 --dst 192.168.0.10 -p tcp --dport 8888 -j DNAT --to-destination 192.168.1.30:9999

si l’on essaye de voir su cela suffit à partir du server client:

root@client$ echo message | nc -s 192.168.0.60 192.168.0.10 8888

Pas de réponse…. qu’est ce qui se passe?
Pour mieux comprendre on va artificiellement ajouter encore une nouvelle interface réseau à la passerelle mais coté client et on refait le test depuis la passerelle en utilisant cette interface:

root@routeur$ ip addr add 192.168.0.15/24 broadcast 192.168.0.255 dev eth0 label eth0:1

On essaye:

root@rooteur$ echo message | nc -s 192.168.0.15 192.168.0.10 8888
reponse

La cela fonctionne… pourquoi?

Parce que l’on à mis notre regles DNAT [3] dans la chaîne OUTPUT, ainsi un message sortant même sur avec une ip dans un réseaux sera reecrit et retransmis dans l’autre réseau en suivant la règle.

Pour y voir plus clair on va ajouter une regle pour logger [4] les messages entrant venant du client:

root@rooteur$  sudo iptables -t nat -I PREROUTING 1 -s 192.168.0.60 -j LOG --log-level debug --log-prefix "PREROUTING:"
root@rooteur$  sudo iptables -t nat -I OUTPUT 1 -s 192.168.0.60 -j LOG --log-level debug --log-prefix "OUTPUT:"
root@rooteur$  sudo iptables -t nat -I POSTROUTING 1 -s 192.168.0.60 -j LOG --log-level debug --log-prefix "POSTROUTING:"

On emet un message depuis le client et on voir alors que seul la regle de log PREROUTING à reagit (voir /var/log/syslog):

Oct  7 09:38:24 picenter kernel: [1565014.478722] PREROUTING:IN=eth0 OUT= MAC=b8:27:eb:b7:7f:be:50:46:5d:dd:25:1c:08:00:45:00:00:3c:c9:f5:40:00:40:06:ef:2f SRC=192.168.0.60 DST=192.168.0.10 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=51701 DF PROTO=TCP SPT=53707 DPT=8888 WINDOW=64240 RES=0x00 SYN URGP=0

Par contre si on tente la même chose depuis le routeur (comme dans le cas où cela fonctionne) on modifie au passage la règle ouput pour modifier la source:

root@rooteur$  sudo iptables -t nat -R OUTPUT 1 -s 192.168.0.15 -j LOG --log-level debug --log-prefix "OUTPUT:"

on envoie un message:

Oct  7 09:42:27 picenter kernel: [1565257.332088] OUTPUT:IN= OUT=lo SRC=192.168.0.15 DST=192.168.0.10 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=37897 DF PROTO=TCP SPT=54595 DPT=8888 WINDOW=43690 RES=0x00 SYN URGP=0

Il faut donc mettre la regle dans la chaine prerouting

root@rooteur$ iptables -t nat -A PREROUTING --dst 192.168.0.10 -p tcp --dport 8888 -j DNAT --to-destination 192.168.1.30:9999

Et permettre au message retour de revenir en changeant l’adresse sources afin que le server sache qu’il doit s’adresse à la passerelle pour que celle ci route à nouveau ce dernier [6].

root@rooteur$ iptables -t nat -A POSTROUTING -p tcp -j SNAT --to 192.168.1.10

On tente de nouveau depuis le client et… ca marche ! et les messages ont reussi à faire l’allé retour...

root@client$ echo message | nc -s 192.168.0.60 192.168.0.10 8888
reponse
root@server$ echo "reponse" | nc -s 192.168.1.30 -l -p 9999
message

Ca ne marche pas? Retentez avec :


root@rooteur$ sudo sysctl -w net.ipv4.ip_forward=1

Références:


[1] https://www.commandlinux.com/man-page/man1/nc.1.html
[2] https://www.netfilter.org/documentation/HOWTO/fr/NAT-HOWTO-6.html
[3] https://www.inetdoc.net/guides/iptables-tutorial/dnattarget.html
[4] https://www.malekal.com/tutoriel-iptables/
[5] http://www.admin6.fr/2012/03/regles-de-routage-simple-avec-iptables/
[6] http://www.linux-france.org/prj/edu/archinet/systeme/ch62s03.html
[7] https://memo-linux.com/ip-la-commande-linux-pour-gerer-son-interface-reseau/

Aucun commentaire:

Enregistrer un commentaire