Avec Linux 2.6.24+ (considéré comme expérimental jusqu'à 2.6.29), vous pouvez utiliser des espaces de noms réseau pour cela. Vous devez avoir les 'espaces de noms réseau' activés dans votre noyau (CONFIG_NET_NS=y
) et util-linux avec le unshare
outil.
Ensuite, démarrer un processus sans accès au réseau est aussi simple que :
unshare -n program ...
Cela crée un espace de noms réseau vide pour le processus. C'est-à-dire qu'il est exécuté sans interface réseau, y compris sans bouclage . Dans l'exemple ci-dessous, nous ajoutons -r pour exécuter le programme uniquement après que les identifiants d'utilisateur et de groupe effectifs actuels ont été mappés sur ceux du superutilisateur (évitez sudo) :
$ unshare -r -n ping 127.0.0.1
connect: Network is unreachable
Si votre application a besoin d'une interface réseau, vous pouvez en configurer une nouvelle :
$ unshare -n -- sh -c 'ip link set dev lo up; ping 127.0.0.1'
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=32 time=0.066 ms
Notez que cela créera un nouveau fichier local bouclage. Autrement dit, le processus généré ne pourra pas accéder aux ports ouverts du 127.0.0.1
de l'hôte .
Si vous avez besoin d'accéder au réseau d'origine à l'intérieur de l'espace de noms, vous pouvez utiliser nsenter
pour saisir l'autre espace de noms.
L'exemple suivant exécute ping
avec l'espace de noms de réseau utilisé par le PID 1 (il est spécifié via -t 1
):
$ nsenter -n -t 1 -- ping -c4 example.com
PING example.com (93.184.216.119) 56(84) bytes of data.
64 bytes from 93.184.216.119: icmp_seq=1 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=2 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=3 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=4 ttl=50 time=139 ms
--- example.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 134.621/136.028/139.848/2.252 ms
Linux a une fonctionnalité appelée espaces de noms réseau qui vous permet essentiellement d'avoir plusieurs piles réseau sur la même machine et d'en attribuer une à un programme lors de son exécution. Il s'agit d'une fonctionnalité généralement utilisée pour les conteneurs, mais vous pouvez également l'utiliser pour accomplir ce que vous voulez.
Le ip netns
les sous-commandes le gèrent. Créer un nouvel espace de noms réseau sans accès à quoi que ce soit est facile, c'est l'état par défaut d'un nouvel espace de noms :
[email protected]:~# ip netns add jail
Maintenant, si vous basculez vers cet espace de noms, vous pouvez le configurer assez facilement. Vous voudrez probablement en parler, et c'est tout :
[email protected]:~# ip netns exec jail /bin/bash
[email protected]:~# ip addr add 127.0.0.1/8 dev lo
[email protected]:~# ip link set dev lo up
[email protected]:~# exit
Désormais, lorsque vous souhaitez exécuter votre commande sans réseau, il vous suffit de l'exécuter dans cette prison :
[email protected]:~# ip netns exec jail su user -c 'ping 8.8.8.8'
connect: Network is unreachable
Le réseau est, comme souhaité, inaccessible. (Vous pouvez faire toutes sortes de choses intéressantes car une pile réseau séparée comprend iptables
règles, etc.)
Vous pouvez utiliser iptables et déplacer ce processus dans un cgroup :
mkdir /sys/fs/cgroup/net_cls/block
echo 42 > /sys/fs/cgroup/net_cls/block/net_cls.classid
iptables -A OUTPUT -m cgroup --cgroup 42 -j DROP
echo [pid] > /sys/fs/cgroup/net_cls/block/tasks