Désactiver l'écoute de apache2 sur une des 2 interfaces

23 réponses
Avatar
Francois Lafont
Bonjour à tous,

J'ai une machine R sous Debian Wheezy à jour avec deux
interfaces :

- eth0 avec l'ip 192.168.0.45/24 qui est dans un certain VLAN 0
- eth1 avec l'ip 172.31.0.1/16 qui est dans un autre VLAN 1

L'ip forwarding n'est *pas* activé sur la machine R :

# cat /proc/sys/net/ipv4/ip_forward
0

J'ai une autre machine M (Debian Wheezy aussi) qui se trouve
dans le VLAN 0 avec une seule interface eth0 d'adresse
192.168.0.1/24.

J'installe apache2 sur R et je souhaite le configurer pour
qu'il ne réponde *que* sur l'interface eth1. Du coup, je
fais sur R :

apt-get install apache2
vim /etc/apache2/ports.conf

Et là je vois l'instruction "Listen" que je remplace par :

Listen 172.31.0.1:80

Je redémarre le daemon apache2, puis :

# netstat -l4tp | grep -i apache
tcp 0 0 172.31.0.1:http *:* LISTEN 3736/apache2

J'ai bien apache2 qui n'écoute a priori que sur eth1.
Mais pourtant, il semble que non. En effet, si, sur la
machine M, j'indique la route suivante :

sudo ip route add 172.31.0.0/16 via 192.168.0.45 dev eth0

J'indique donc à cet hôte M que pour atteindre les IPs du
VLAN 1, il faut passer par l'interface eth0 de l'hôte R, ce
qui ne devrait pas marcher vu que sur R l'ip forwarding n'est
pas activé. Et bien, à ma grande surprise, si j'ouvre alors
un navigateur sur M et que je consulte l'adresse :

http:// 172.31.0.1

je tombe bien sur la page Web par défaut de l'hôte R.
Si je fais un tcpdump de eth1 sur R, c'est le néant.
Rien ne s'affiche au niveau du tcpdump de eth1 quand
je consulte la page ci-dessus. En revanche, un tcpdump
sur eth0 de R me montre bien que c'est l'interface eth0
qui reçoit et répond aux requêtes http.

Comment cela se fait-il que je puisse consulter la
page http//172.31.0.1 en étant sur l'hôte M alors
que l'ip forwarding n'est même pas activé sur R ?
Est-ce que apache2 écoute toujours sur eth0 malgré
la conf que j'ai mise ? Si oui, comment le forcer
à n'écouter *que* sur l'interface eth1 ?

Dans le même ordre d'idée, je suis surpris que,
sur l'hôte M, je puisse réussir un :

ping -n 172.31.0.1
(une fois la route précédente ajoutée bien sûr)

Comment est-ce possible alors que, encore une fois,
l'ip forwarding n'est pas activé sur la machine R.
Pour moi, le paquet devrait arriver sur eth0 de R
et, ne pouvant être relayé à eth1 de R, le paquet
devrait être détruit avec du coup une absence de réponse
au ping. Pour le ping (comme pour http) je ne vois aucun
trafic sur eth1 (mais sur eth0 oui).

Je trouve ça quand même un peu fort de café d'arriver à
contacter l'IP de eth1 de R (via un ping ou via http) sans
voir le moindre trafic sur eth1 avec tcpdump.

Merci d'avance.

--
François Lafont

10 réponses

1 2 3
Avatar
Joe The Smoe
Le 26/05/2014 06:29, Francois Lafont a écrit :
Bonjour à tous,




Bonjour,

[...]
Comment cela se fait-il que je puisse consulter la
page http//172.31.0.1 en étant sur l'hôte M alors
que l'ip forwarding n'est même pas activé sur R ?



pas besoin d'IP forward pour qu'une machine accepte une session à
destination d'une de ses adresses IP, même si celle-ci se trouve "de
l'autre côté" (i.e.: l'IP cible n'est pas celle de l'interface par
laquelle la session arrive à la machine).

Pour un processus, n'écouter que sur telle ou telle interface, signifie
que le noyau ne lui enverra pas les demandes de session à destination
des autres interfaces, c'est tout.

Pour le noyau de bon nombre de systèmes (Linux, mais aussi des
routeurs), par défaut il n'y a "d'anti-spoofing", fonction qu'on trouve
classiquement sur les firewalls.

Pour linux, tu peux configurer cette fonction avec iptables, ici un
exemple très simplifié et aux erreurs de syntaxe probables près :

iptables -I INPUT -i eth0 -d 192.168.0.0/24 -j ACCEPT
iptables -I INPUT -i eth1 -d 172.31.0.0/16 -j ACCEPT
iptables -I INPUT -j LOG --log-level 5 --log-prefix "Spoofing "
iptables -I INPUT -j DROP



Cordialement,
Joe the Shmoe
Avatar
Francois Lafont
Le 26/05/2014 08:34, Joe The Smoe a écrit :

pas besoin d'IP forward pour qu'une machine accepte une session à
destination d'une de ses adresses IP, même si celle-ci se trouve "de
l'autre côté" (i.e.: l'IP cible n'est pas celle de l'interface par
laquelle la session arrive à la machine).



Ben zut alors. J'ai appris quelque chose. Je ne trouve vraiment
pas ça logique. Pour moi, si l'interface eth0 reçoit un paquet
à destination de l'IP de eth1 qui n'est pas sur le même réseau
IP, il faut forcément router/forwarder le paquet de eth0 vers
eth1. Mais force est de constater que c'est toi qui as raison
bien sûr. Je trouve cela intellectuellement très perturbant.

Pour un processus, n'écouter que sur telle ou telle interface, signifie
que le noyau ne lui enverra pas les demandes de session à destination
des autres interfaces, c'est tout.



Ok. En revanche le terme de "session" m'échappe un peu.
C'est au sens du modèle OSI ou un truc dans le genre ?

Pour le noyau de bon nombre de systèmes (Linux, mais aussi des
routeurs), par défaut il n'y a "d'anti-spoofing", fonction qu'on trouve
classiquement sur les firewalls.

Pour linux, tu peux configurer cette fonction avec iptables, ici un
exemple très simplifié et aux erreurs de syntaxe probables près :

iptables -I INPUT -i eth0 -d 192.168.0.0/24 -j ACCEPT
iptables -I INPUT -i eth1 -d 172.31.0.0/16 -j ACCEPT
iptables -I INPUT -j LOG --log-level 5 --log-prefix "Spoofing "
iptables -I INPUT -j DROP



Ok, je vois l'idée.
Merci pour les explications, je crois que j'aurais pu chercher
longtemps tellement j'étais persuadé que l'IP forwarding était
nécessaire dans ce cas de figure.

--
François
Avatar
Joe The Smoe
Le 26/05/2014 12:58, Francois Lafont a écrit :
Le 26/05/2014 08:34, Joe The Smoe a écrit :

pas besoin d'IP forward pour qu'une machine accepte une session à
destination d'une de ses adresses IP, même si celle-ci se trouve "de
l'autre côté" (i.e.: l'IP cible n'est pas celle de l'interface par
laquelle la session arrive à la machine).



Ben zut alors. J'ai appris quelque chose. Je ne trouve vraiment
pas ça logique. Pour moi, si l'interface eth0 reçoit un paquet
à destination de l'IP de eth1 qui n'est pas sur le même réseau
IP, il faut forcément router/forwarder le paquet de eth0 vers
eth1. Mais force est de constater que c'est toi qui as raison
bien sûr. Je trouve cela intellectuellement très perturbant.



Oui, je partage ce point de vue. Il faudrait voir les contraintes
d'implémentation de la couche réseau au sein d'un noyau Unix pour
comprendre, car ce n'est pas propre à Linux.


Pour un processus, n'écouter que sur telle ou telle interface, signifie
que le noyau ne lui enverra pas les demandes de session à destination
des autres interfaces, c'est tout.



Ok. En revanche le terme de "session" m'échappe un peu.
C'est au sens du modèle OSI ou un truc dans le genre ?



Oui, c'est un abus de langage. J'aurais dû écrire "Pour un processus,
n'écouter que sur telle ou telle interface, signifie que le noyau ne lui
enverra pas les données issues des paquets d'une session TCP créée à
destination du même port mais dont l'adresse IP de destination est
celle d'une autre interface, c'est tout".

Je ne suis pas sûr que ce soit plus facile à comprendre mais c'est
probablement plus correct. :-)


Pour le noyau de bon nombre de systèmes (Linux, mais aussi des
routeurs), par défaut il n'y a "d'anti-spoofing", fonction qu'on trouve
classiquement sur les firewalls.

Pour linux, tu peux configurer cette fonction avec iptables, ici un
exemple très simplifié et aux erreurs de syntaxe probables près :

iptables -I INPUT -i eth0 -d 192.168.0.0/24 -j ACCEPT
iptables -I INPUT -i eth1 -d 172.31.0.0/16 -j ACCEPT
iptables -I INPUT -j LOG --log-level 5 --log-prefix "Spoofing "
iptables -I INPUT -j DROP



Ok, je vois l'idée.
Merci pour les explications, je crois que j'aurais pu chercher
longtemps tellement j'étais persuadé que l'IP forwarding était
nécessaire dans ce cas de figure.



le plus drôle c'est que ça doit pouvoir aussi fonctionner à destination
de 127.0.0.1 depuis une hôte qui ne dispose pas de cette plage d'adresse
en loopback mais possède une route statique 127.0.0.1/32 vers un
équipement avec lequel il partage un subnet IP. Il peut alors, si rien
n'est fait pour l'en empêcher ouvrir une session TCP vers un service qui
n'est en écoute que sur l'adresse 127.0.0.1 (lo0) de cette victime.

Si ça fonctionne, ce n'est pas possible à exploiter à travers Internet,
mais sur un réseau local, LAN Ethernet d'entreprise par exemple, ou un
hotspot WiFi si l'AP WiFi autorise les hôtes à communiquer entre eux,
j'en ai des frissons car peu de distro (Debian par exemple) ne
positionnent par défaut d'anti-spoofing tel décrit plus haut...


--
François
Avatar
Francois Lafont
Bonsoir,

Le 26/05/2014 19:44, Joe The Smoe a écrit :

Ok. En revanche le terme de "session" m'échappe un peu.
C'est au sens du modèle OSI ou un truc dans le genre ?



Oui, c'est un abus de langage. J'aurais dû écrire "Pour un processus,
n'écouter que sur telle ou telle interface, signifie que le noyau ne lui
enverra pas les données issues des paquets d'une session TCP créée à
destination du même port mais dont l'adresse IP de destination est
celle d'une autre interface, c'est tout".

Je ne suis pas sûr que ce soit plus facile à comprendre mais c'est
probablement plus correct. :-)



Ok, pour moi c'est plus clair comme ça. ;-)

le plus drôle c'est que ça doit pouvoir aussi fonctionner à destination
de 127.0.0.1 depuis une hôte qui ne dispose pas de cette plage d'adresse
en loopback mais possède une route statique 127.0.0.1/32 vers un
équipement avec lequel il partage un subnet IP. Il peut alors, si rien
n'est fait pour l'en empêcher ouvrir une session TCP vers un service qui
n'est en écoute que sur l'adresse 127.0.0.1 (lo0) de cette victime.



Ton idée pleine de perfidie ;-) m'a donné envie de tester car
effectivement, ça fait un peu peur cette histoire. Et globalement,
je ne suis pas arrivé à contacter l'hôte. Voici ce que j'ai fait :

Soit un hôte qui possède l'IP 172.31.0.1 sur lequel tourne un
apache2 qui écoute exclusivement sur localhost:80. Sur un autre
hôte (sur le même VLAN dans le même réseau IP) j'ai tenté un :

route add 127.0.0.1 via 172.31.0.1 dev eth0
curl http://127.0.0.1

Le curl au final ne fait qu'interroger le apache2 qui tourne sur
l'hôte lui-même mais pas celui de son voisin « 172.31.0.1 ». En
faisant un tcpdump sur l'hôte 172.31.0.1, j'ai pu voir qu'aucune
trame ne lui parvenait. J'ai viré la ligne "127.0.0.1 ..." dans
fichier /etc/hosts pour voir, même chose, je n'interroge pas
le apache2 du voisin mais celui en local. Après, j'ai fait un
ifdown de lo pour voir, et là je n'interrogerait plus personne.

On va dire que c'est plutôt rassurant même si au final je ne
peux pas dire grand chose vu que je n'ai pas réussi à faire
partir le moindre paquet avec 127.0.0.1 comme IP de destination.
Y aurait-il des mécanismes au sein du noyau qui empêcheraient
une telle chose... Là ça me dépasse.

Si ça fonctionne, ce n'est pas possible à exploiter à travers Internet,
mais sur un réseau local, LAN Ethernet d'entreprise par exemple, ou un
hotspot WiFi si l'AP WiFi autorise les hôtes à communiquer entre eux,
j'en ai des frissons car peu de distro (Debian par exemple) ne
positionnent par défaut d'anti-spoofing tel décrit plus haut...



Effectivement, ça fait un peu peur si ça peut marcher dans un LAN
Ethernet, je suis d'accord. Perso, j'ai pas réussi à le faire
marcher (ce qui ne prouve absolument rien).

On va dire pour l'instant que je retiens ceci :
- Même si l'ip forwarding n'est pas activé, il est
possible d'atteindre un service qui écoute sur une adresse
donnée même en passant par une interface qui ne possède pas
l'adresse en question.
- En revanche, ça ne semble pas possible quand le service
tourne sur une adresse appartenant à une interface de
loopback.

Voilà ce que je conclus de ces quelques tests.

--
François Lafont
Avatar
Erwan David
Francois Lafont écrivait :


On va dire pour l'instant que je retiens ceci :
- Même si l'ip forwarding n'est pas activé, il est
possible d'atteindre un service qui écoute sur une adresse
donnée même en passant par une interface qui ne possède pas
l'adresse en question.
- En revanche, ça ne semble pas possible quand le service
tourne sur une adresse appartenant à une interface de
loopback.

Voilà ce que je conclus de ces quelques tests.



C'est plus compliqué que ça : là tu as constaté une limitation de ta
machine d'attaque.

Par contre si la machine attaquée reçoit un paquet sur une interface
externe à destination de 127.0.0.1, que se passe-t-il (on la supposera
configurée de manière standard)

1) en TCP : même si le SYN est accepté, le SYN-ACK ne repartira pas à
l'attaquant

2) en UDP : les réponses ne partiront pas à l'attaquant.

Le risque reste donc sur les attaques en UDP ne nécessitant pas de
réponse de l'attaqué, et il y en a (principalement des dénis de service,
mais rien n'empêche que ça laisse un service normalement sécurisé dans
un état vulnérable, permettant ensuite une exploitation d'une autre
faille).

Il faudrait donc voir en travaillant directement au niveau de la trame
ethernet (il faudra mettre la mac destinatioon à la main, arp ne
répondra pas pour un 127.0.0.1) pour envoyer à une machine un paquet
portant l'adresse destination 127.0.0.1 et voir s'il est droppé ou pas.

Personnellement je vais ajouter ça dans mes règles de firewall...

--
Les simplifications c'est trop compliqué
Avatar
Erwan David
Francois Lafont écrivait :


On va dire pour l'instant que je retiens ceci :
- Même si l'ip forwarding n'est pas activé, il est
possible d'atteindre un service qui écoute sur une adresse
donnée même en passant par une interface qui ne possède pas
l'adresse en question.
- En revanche, ça ne semble pas possible quand le service
tourne sur une adresse appartenant à une interface de
loopback.

Voilà ce que je conclus de ces quelques tests.



C'est plus compliqué que ça : là tu as constaté une limitation de ta
machine d'attaque.

Par contre si la machine attaquée reçoit un paquet sur une interface
externe à destination de 127.0.0.1, que se passe-t-il (on la supposera
configurée de manière standard)

1) en TCP : même si le SYN est accepté, le SYN-ACK ne repartira pas à
l'attaquant

2) en UDP : les réponses ne partiront pas à l'attaquant.

Le risque reste donc sur les attaques en UDP ne nécessitant pas de
réponse de l'attaqué, et il y en a (principalement des dénis de service,
mais rien n'empêche que ça laisse un service normalement sécurisé dans
un état vulnérable, permettant ensuite une exploitation d'une autre
faille).

Il faudrait donc voir en travaillant directement au niveau de la trame
ethernet (il faudra mettre la mac destinatioon à la main, arp ne
répondra pas pour un 127.0.0.1) pour envoyer à une machine un paquet
portant l'adresse destination 127.0.0.1 et voir s'il est droppé ou pas.

Personnellement je vais ajouter ça dans mes règles de firewall...


Suite sur fr.comp.securite pour discuter de ce type d'attaque.

Résumé pour les lecteurs de fr.comp.securite :
- on constate qu'une machine linux répond par défaut à toutes ses IP sur
toutes ses interfaces
- peut-on ainsi atteindre un service qui n'écouterait que sur
127.0.0.1 ?


--
Les simplifications c'est trop compliqué
Avatar
Joe The Smoe
Le 27/05/2014 01:41, Francois Lafont a écrit :
[...]

Ton idée pleine de perfidie ;-)



:)

m'a donné envie de tester car
effectivement, ça fait un peu peur cette histoire. Et globalement,
je ne suis pas arrivé à contacter l'hôte.



[...]

J'ai fait le teste suivant et ça marche:

ifconfig lo 128.0.0.1
route add -host 127.0.0.1 gw 192.168.6.1
telnet 127.0.0.1

et sur 192.168.6.1:
tcpdump -i eth0 -n tcp port 23
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
08:51:23.877745 IP 192.168.6.20.58974 > 127.0.0.1.23: Flags [S], seq
3693925555, win 14600, options [mss 1460,sackOK,TS val 3246587 ecr
0,nop,wscale 5], length 0
08:51:24.874771 IP 192.168.6.20.58974 > 127.0.0.1.23: Flags [S], seq
3693925555, win 14600, options [mss 1460,sackOK,TS val 3246837 ecr
0,nop,wscale 5], length 0

Je n'ai pas pu aller plus loin du fait de la configuration iptables qui
interdit justement ce type d'usurpation, mais j'ai bien réussi à faire
sortir des paquets d'une machine Linux à destination de 127.0.0.1. Reste
à savoir si une telle victime répondra normalement à de tels paquets (?)

Sinon, je te confirme que faire un shutdown de l'interface loopback ne
permet pas à la route statique 127.0.0.1 ajoutée d'être utilisé, il faut
bien changer l'adresse IP de l'interface loopback pour que cette route
soit utilisée.

On va dire que c'est plutôt rassurant même si au final je ne
peux pas dire grand chose vu que je n'ai pas réussi à faire
partir le moindre paquet avec 127.0.0.1 comme IP de destination.
Y aurait-il des mécanismes au sein du noyau qui empêcheraient
une telle chose... Là ça me dépasse.



J'ai noté que contrairement à une interface physique, ajouter un
sous-réseau sur une interface loopback tel 127.0.0.0/8 n'induit aucune
nouvelle route dans la table de routage. Il y a bien au niveau du noyau
un comportement différent vis à vis de ce type d'interface.

[...]

Cordialement,
Joe the Perfide ;-)
Avatar
Pascal Hambourg
Joe The Smoe a écrit :
Le 26/05/2014 06:29, Francois Lafont a écrit :

Comment cela se fait-il que je puisse consulter la
page http//172.31.0.1 en étant sur l'hôte M alors
que l'ip forwarding n'est même pas activé sur R ?



pas besoin d'IP forward pour qu'une machine accepte une session à
destination d'une de ses adresses IP, même si celle-ci se trouve "de
l'autre côté" (i.e.: l'IP cible n'est pas celle de l'interface par
laquelle la session arrive à la machine).



Cf. weak vs. strong host model.
<http://en.wikipedia.org/wiki/Host_model> (pas de page fr désolé)

Modèle fort : l'adresse appartient à l'interface.
Modèle faible : l'adresse appartient au noeud.

Le modèle "faible" est plus robuste en cas de coupure d'un lien : les
paquets à destination de l'adresse correspondante peuvent encore arriver
par un autre lien.

Pour un processus, n'écouter que sur telle ou telle interface, signifie
que le noyau ne lui enverra pas les demandes de session à destination
des autres interfaces, c'est tout.



La plupart des processus utilisateur ouvrent des sockets "normales" qui
écoutent sur des adresses, pas des interfaces.

Pour le noyau de bon nombre de systèmes (Linux, mais aussi des
routeurs), par défaut il n'y a "d'anti-spoofing", fonction qu'on trouve
classiquement sur les firewalls.



Cela n'a pas grand-chose à voir avec le spoofing (usurpation d'adresse
source).
Avatar
Pascal Hambourg
Joe The Smoe a écrit :

le plus drôle c'est que ça doit pouvoir aussi fonctionner à destination
de 127.0.0.1



Non, pas avec Linux. Sa couche IP élimine les paquets avec une source ou
destination dans 127.0.0.0/8 reçus ou émis sur une interface non
loopback, en conformité avec les RFC disant que ce genre de paquet ne
devrait jamais apparaître en dehors d'un hôte. Il me semble qu'il y a eu
des patches pour désactiver ce comportement, notamment dans le cas
d'utilisation de machines virtuelles (on ne sort pas vraiment de l'hôte
dans ce cas).

En revanche il y a assez longtemps j'avais constaté que l'adresse de
loopback ::1 en IPv6 n'était pas limitée de la même façon. Je n'ai pas
revérifié avec un noyau plus récent.
Avatar
Pascal Hambourg
Francois Lafont a écrit :
Le 26/05/2014 08:34, Joe The Smoe a écrit :

pas besoin d'IP forward pour qu'une machine accepte une session à
destination d'une de ses adresses IP, même si celle-ci se trouve "de
l'autre côté" (i.e.: l'IP cible n'est pas celle de l'interface par
laquelle la session arrive à la machine).



Ben zut alors. J'ai appris quelque chose. Je ne trouve vraiment
pas ça logique. Pour moi, si l'interface eth0 reçoit un paquet
à destination de l'IP de eth1 qui n'est pas sur le même réseau
IP, il faut forcément router/forwarder le paquet de eth0 vers
eth1.



J'ai oublié de répondre à ce point.
Le "forwarding" c'est le fonctionnement d'un routeur, c'est-à-dire le
fait de retransmettre vers l'extérieur les paquets reçus qui ne sont pas
destinés à la machine. Ce n'est clairement pas le cas ici, donc rien à
voir avec le forwarding.
1 2 3