Con Linux 2.6.24+ (considerato sperimentale fino alla 2.6.29), puoi usare gli spazi dei nomi di rete per questo. Devi avere i 'network namespaces' abilitati nel tuo kernel (CONFIG_NET_NS=y
) e util-linux con unshare
strumento.
Quindi, avviare un processo senza accesso alla rete è semplice come:
unshare -n program ...
Questo crea uno spazio dei nomi di rete vuoto per il processo. Cioè, viene eseguito senza interfacce di rete, incluso nessun loopback . Nell'esempio seguente aggiungiamo -r per eseguire il programma solo dopo che gli attuali ID utente e gruppo effettivi sono stati mappati a quelli del superutente (evitare sudo):
$ unshare -r -n ping 127.0.0.1
connect: Network is unreachable
Se la tua app necessita di un'interfaccia di rete, puoi impostarne una nuova:
$ 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
Nota che questo creerà un nuovo locale loopback. Cioè, il processo generato non sarà in grado di accedere alle porte aperte del 127.0.0.1
dell'host .
Se hai bisogno di ottenere l'accesso alla rete originale all'interno del namespace, puoi usare nsenter
per accedere all'altro spazio dei nomi.
L'esempio seguente esegue ping
con lo spazio dei nomi di rete utilizzato dal PID 1 (viene specificato tramite -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 ha una funzionalità chiamata spazi dei nomi di rete che ti consente essenzialmente di avere più stack di rete sulla stessa macchina e di assegnarne uno a un programma durante l'esecuzione. Questa è una funzionalità tipicamente utilizzata per i contenitori, ma puoi anche utilizzarla per realizzare ciò che desideri.
Il ip netns
i sottocomandi lo gestiscono. Creare un nuovo spazio dei nomi di rete senza accesso a nulla è facile, è lo stato predefinito di un nuovo spazio dei nomi:
[email protected]:~# ip netns add jail
Ora, se passi a quello spazio dei nomi, puoi configurarlo abbastanza facilmente. Probabilmente vorrai citare lo, e basta:
[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
Ora, quando vuoi eseguire il tuo comando senza rete, eseguilo semplicemente in quella prigione:
[email protected]:~# ip netns exec jail su user -c 'ping 8.8.8.8'
connect: Network is unreachable
La rete è, come si vuole, irraggiungibile. (Puoi fare ogni genere di cose interessanti poiché uno stack di rete separato include iptables
regole, ecc.)
Potresti usare iptables e spostare quel processo in 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