È possibile bloccare l'accesso alla rete (in uscita) di un singolo processo?
localhost
(alla stessa macchina) per svolgere il proprio lavoro.
È possibile bloccare l'accesso alla rete (in uscita) di un singolo processo?
localhost
(alla stessa macchina) per svolgere il proprio lavoro.
Risposte:
Con Linux 2.6.24+ (considerato sperimentale fino al 2.6.29), è possibile utilizzare gli spazi dei nomi di rete per questo. Devi avere gli 'spazi dei nomi di rete' abilitati nel tuo kernel ( CONFIG_NET_NS=y
) e util-linux con lo unshare
strumento.
Quindi, avviare un processo senza accesso alla rete è semplice come:
unshare -n program ...
Ciò crea uno spazio dei nomi di rete vuoto per il processo. Cioè, viene eseguito senza interfacce di rete, incluso il loopback . Nell'esempio seguente aggiungiamo -r per eseguire il programma solo dopo che gli ID utente e gruppo effettivi correnti sono stati mappati a quelli di 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 configurarne 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
Si noti che ciò creerà un nuovo loopback locale . Cioè, il processo generato non sarà in grado di accedere alle porte aperte dell'host 127.0.0.1
.
Se è necessario accedere alla rete originale all'interno dello spazio dei nomi, è possibile utilizzare nsenter
per accedere all'altro spazio dei nomi.
L'esempio seguente viene eseguito ping
con lo spazio dei nomi di rete utilizzato da PID 1 (è 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
unshare -n
sembra lanciare "Operazione non consentita" senza root
privilegi, qualcosa che mi manca al riguardo?
sudo unshare -n
eredita il diritto di root. Dato che ho bisogno del sudo per chiamare unshare, mi chiedo come posso assicurarmi che il programma chiamato non abbia i diritti di root.
sudo unshare -n sudo -u dude bash -c 'echo Hello, my name is $USER'
@ThorSummoner bbs.archlinux.org/viewtopic.php?id=205240
Linux ha una funzione chiamata spazi dei nomi di rete che consente essenzialmente di avere più stack di rete sullo stesso computer e assegnarne uno a un programma durante l'esecuzione. Questa è una funzionalità generalmente utilizzata per i contenitori, ma è anche possibile utilizzarla per ottenere ciò che si desidera.
I ip netns
sottocomandi lo gestiscono. La creazione di un nuovo spazio dei nomi di rete senza accesso a nulla è semplice, è lo stato predefinito di un nuovo spazio dei nomi:
root@host:~# ip netns add jail
Ora, se passi a quello spazio dei nomi, puoi configurarlo abbastanza facilmente. Probabilmente vorrai far apparire lo in esso, ed è tutto:
root@host:~# ip netns exec jail /bin/bash
root@host:~# ip addr add 127.0.0.1/8 dev lo
root@host:~# ip link set dev lo up
root@host:~# exit
Ora, quando si desidera eseguire il comando senza rete, è sufficiente eseguirlo in quel carcere:
root@host:~# ip netns exec jail su user -c 'ping 8.8.8.8'
connect: Network is unreachable
La rete è, come desiderato, irraggiungibile. (Puoi fare tutti i tipi di cose interessanti poiché uno stack di rete separato include iptables
regole, ecc.)
sudo ip
di eseguire i comandi ip, una volta entrato in bash, ho appena eseguito su someuser
per ottenere una shell senza privilegi per l'utente 'someuser'.
È possibile utilizzare iptables e spostare tale 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
/sys/fs/cgroup/net_cls/tasks
(nessun 'blocco' nel percorso)
Sì, con profilo apparmor personalizzato, ad es
/usr/bin/curl {
...
# block ipv4 acces
deny network inet,
# ipv6
deny network inet6,
# raw socket
deny network raw,
}
Ma in questo modo, dovrai generare anche un elenco di file consentiti per accedere, l'intera procedura può essere un po 'complicata. E vedi il documento di aiuto qui
È possibile utilizzare sandj firejail (dovrebbe funzionare su kernel con funzione seccomp).
Per usarlo basta
firejail --noprofile --net=none <path to executable>
--noprofile
disabilita il sandbox predefinito
--net=none
disabilita la rete
Credo che la maggior parte delle distribuzioni forniscano già pacchetti ma anche se non firejail non ha praticamente dipendenze diverse da build toolchain e kernel abilitato a namespace / seccomp.
Ci sono alcune altre belle funzionalità di Firejail che possono essere mostrate firejail --help
riguardo alla rete (come fornire solo un'interfaccia di loopback o bloccare ip / dns ecc.) Ma questo dovrebbe fare il lavoro. Inoltre doesn't require root
.
Non puoi farlo solo con iptables. Questa funzione esisteva brevemente , ma non poteva essere fatta funzionare in modo affidabile ed è stata abbandonata.
Se è possibile eseguire il processo come ID utente dedicato, iptables può farlo con il owner
modulo:
iptables -A OUTPUT -m owner --uid-owner 1234 -j DROP
Vedi esempi in Iptables: abbinare il traffico in uscita con conntrack e proprietario. Funziona con drop strani , regola iptables / pf per consentire solo l'applicazione / utente XY?
Se è possibile eseguire il processo nel proprio contenitore, è possibile firewall quel contenitore in modo indipendente (anche renderlo completamente disconnesso dalla rete).
Un modulo di sicurezza può filtrare l'accesso di un processo alle funzionalità di rete. La risposta di warl0ck fornisce un esempio con AppArmor.
Soluzione 1: Firewall:
Potremmo usare firewall come Douane o Opensnitch MA quelle applicazioni non sono efficienti al 100% o in una fase iniziale di sviluppo (hanno molti bug ecc. Dal 2019)
Soluzione 2: Kernel MAC:
I MAC del kernel possono essere utilizzati come firewall più noti sono Tomoyo , Selinux e Apparmor Questa soluzione è la migliore quando si tratta di stabilità ed efficienza (soluzione firewall) ma la maggior parte delle volte l'impostazione di questo è in qualche modo complicata.
Soluzione 3: Firejail:
Firejail può essere utilizzato per bloccare l'accesso alla rete per un'applicazione che non richiede il root da cui nessun utente può trarne vantaggio
firejail --noprofile --net=none command-application
Soluzione 4: non condividere
L'annullamento della condivisione può avviare un'applicazione su un altro namespace senza rete, ma ciò richiede che la soluzione di firejail di root faccia quasi esattamente la stessa cosa ma non richiede il root
unshare -r -n application-comand
Soluzione 5: Proxify:
Una soluzione è quella di delegare l'applicazione a un proxy nullo / falso . Possiamo usare tsocks o proxybound . Ecco alcuni dettagli sulla configurazione
Soluzione 6: iptabili:
Un'altra soluzione semplice è iptables, potrebbe essere impostata per bloccare un'applicazione
groupadd no-internet
grep no-internet /etc/group
useradd -g no-internet username
usermod -a -G no-internet userName
verifica con:sudo groups userName
nano /home/username/.local/bin/no-internet
chmod 755 /home/username/.local/bin/no-internet
#!/bin/bash
sg no-internet "$@"
iptables -I OUTPUT 1 -m owner --gid-owner no-internet -j DROP
4. Controllalo, ad esempio su Firefox eseguendo:
no-internet "firefox"
5. Nel caso in cui si desideri fare un'eccezione e consentire a un programma di accedere alla rete locale :
iptables -A OUTPUT -m owner --gid-owner no-internet -d 192.168.1.0/24 -j ACCEPT
iptables -A OUTPUT -m owner --gid-owner no-internet -d 127.0.0.0/8 -j ACCEPT
iptables -A OUTPUT -m owner --gid-owner no-internet -j DROP
6. Renderlo permanente
Un modo per applicare la regola iptables all'avvio è aggiungere la regola come servizio con systemd
cat /usr/lib/systemd/system/nonet.service
[Unit]
Description=Nonet group iptable update
After=network.target
After=xsession.target
After=iptables.service
After=shorewall.service
[Service]
Type=oneshot
RemainAfterExit=true
StandardOutput=journal
ExecStart=/bin/bash /home/user/Scripts/Nonet.iptables.sh
sg no-internet
per ora.
Dipende dalla distro che stai utilizzando, ma questa è una funzionalità solitamente inclusa nel sistema MAC del sistema operativo. Come affermato in precedenza, Ubuntu o AppArmor di SuSE possono farlo. Se stai usando RHEL puoi configurare SELinux per consentire o negare l'accesso a un determinato numero di porta in base all'etichetta del processo in esecuzione. Questo è tutto ciò che ho potuto trovare dopo un rapido googling, ma probabilmente ci sono risorse online più approfondite se guardi più duro e ti dà l'idea generale.
Puoi usare seccomp-bpf per bloccare alcune chiamate di sistema. Ad esempio, potrebbe essere necessario bloccare lasocket
chiamata di sistema per impedire al processo di creare socket FD.
Ho scritto un esempio di questo approcah che impedisce alla socket
chiamata di sistema di funzionare usando libseccomp. Il riepilogo è (senza controllo errori):
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
seccomp_arch_add(ctx, SCMP_ARCH_NATIVE);
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(socket), 1, SCMP_CMP(0, SCMP_CMP_EQ, pf));
seccomp_load(ctx);
execvp(argv[1], argv+1);
Questo non necessita di privilegi di root.
Una sandbox completa è molto più complessa, quindi non dovresti usarla per bloccare programmi non cooperativi / dannosi.
È possibile utilizzare un programma da riga di comando chiamato "proxychains" e provare una delle seguenti possibilità:
Impostalo che utilizza ...
Non l'ho provato da solo, quindi non so se funziona ...