Czy można zablokować (wychodzący) dostęp do sieci dla jednego procesu?
localhost
(do tego samego komputera) do wykonywania swoich zadań.
Czy można zablokować (wychodzący) dostęp do sieci dla jednego procesu?
localhost
(do tego samego komputera) do wykonywania swoich zadań.
Odpowiedzi:
W Linuksie 2.6.24+ (uważanym za eksperymentalny do 2.6.29) możesz do tego używać sieciowych nazw. Musisz mieć włączone sieciowe przestrzenie nazw w jądrze ( CONFIG_NET_NS=y
) i util-linux za pomocą tego unshare
narzędzia.
Następnie rozpoczęcie procesu bez dostępu do sieci jest tak proste, jak:
unshare -n program ...
Tworzy to pustą przestrzeń nazw sieci dla procesu. Oznacza to, że jest uruchamiany bez interfejsów sieciowych, w tym bez pętli zwrotnej . W poniższym przykładzie dodajemy -r, aby uruchomić program dopiero po zmapowaniu bieżącego efektywnego ID użytkownika i grupy do identyfikatora administratora (unikaj sudo):
$ unshare -r -n ping 127.0.0.1
connect: Network is unreachable
Jeśli Twoja aplikacja wymaga interfejsu sieciowego, możesz skonfigurować nowy:
$ 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
Pamiętaj, że spowoduje to utworzenie nowej lokalnej pętli zwrotnej. Oznacza to, że odrodzony proces nie będzie mógł uzyskać dostępu do otwartych portów hosta 127.0.0.1
.
Jeśli chcesz uzyskać dostęp do oryginalnej sieci w obszarze nazw, możesz użyć, nsenter
aby wprowadzić inną przestrzeń nazw.
Poniższy przykład działa ping
z przestrzenią nazw sieciowych używaną przez PID 1 (jest określony poprzez -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
wydaje się rzucać „Operacja niedozwolona” bez root
uprawnień, coś mi w tym brakuje?
sudo unshare -n
dziedziczy prawo root. Ponieważ potrzebuję sudo do wywołania nieudostępnionego, zastanawiam się, jak mogę się upewnić, że wywoływany program nie ma praw root.
sudo unshare -n sudo -u dude bash -c 'echo Hello, my name is $USER'
@ThorSummoner bbs.archlinux.org/viewtopic.php?id=205240
Linux ma funkcję zwaną sieciowymi przestrzeniami nazw, które pozwalają zasadniczo mieć wiele stosów sieciowych na tym samym komputerze i przypisać jeden do programu podczas jego uruchamiania. Jest to funkcja zwykle używana w kontenerach, ale możesz jej również użyć do osiągnięcia tego, co chcesz.
Polecenia ip netns
zarządzają tym. Tworzenie nowej sieciowej przestrzeni nazw bez dostępu do czegokolwiek jest łatwe, jest to domyślny stan nowej przestrzeni nazw:
root@host:~# ip netns add jail
Teraz, jeśli przełączysz się do tej przestrzeni nazw, możesz ją dość łatwo skonfigurować. Prawdopodobnie będziesz chciał porozmawiać o tym, i to wszystko:
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
Teraz, gdy chcesz uruchomić polecenie bez sieci, po prostu uruchom je w tym więzieniu:
root@host:~# ip netns exec jail su user -c 'ping 8.8.8.8'
connect: Network is unreachable
Sieć jest, zgodnie z życzeniem, nieosiągalna. (Możesz robić różne ciekawe rzeczy, ponieważ osobny stos sieciowy zawiera iptables
reguły itp.)
sudo ip
wykonać polecenia ip, kiedy byłem w bashu, właśnie wykonałem, su someuser
aby uzyskać nieuprzywilejowaną powłokę dla użytkownika „someuser”.
Możesz użyć iptables i przenieść ten proces do grupy cg:
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
(brak „bloku” na ścieżce)
Tak, z dostosowanym profilem apparmor, tj
/usr/bin/curl {
...
# block ipv4 acces
deny network inet,
# ipv6
deny network inet6,
# raw socket
deny network raw,
}
Ale w ten sposób musisz wygenerować listę dozwolonych plików, aby uzyskać dostęp, cała procedura może być nieco skomplikowana. I zobacz dokument pomocy tutaj
Możesz użyć piaskownicy Firejail (powinien działać na jądrach z funkcją seccomp).
Aby z niego skorzystać, po prostu zrób
firejail --noprofile --net=none <path to executable>
--noprofile
wyłącza domyślną piaskownicę
--net=none
wyłącza sieć
Wierzę, że większość dystrybucji już dostarcza pakiet, ale nawet jeśli nie ma firejail, nie ma praktycznie żadnych zależności innych niż budowanie toolchain i jądra obsługującego przestrzeń nazw / seccomp.
Istnieje kilka innych miłych cech firejail, które mogą być pokazywane firejail --help
w odniesieniu do sieci (jak tylko zapewnienie interfejsu pętli zwrotnej lub blokowanie IP / DNS itp) ale to powinno załatwić sprawę. Również to doesn't require root
.
Nie możesz tego zrobić tylko z iptables. Ta funkcja istniała krótko , ale nie można jej było uruchomić niezawodnie i została porzucona.
Jeśli możesz uruchomić proces jako dedykowany identyfikator użytkownika, iptables może to zrobić z owner
modułem:
iptables -A OUTPUT -m owner --uid-owner 1234 -j DROP
Zobacz przykłady w Iptables: dopasowanie ruchu wychodzącego do conntrack i właściciela. Działa z dziwnymi kroplami , reguła iptables / pf zezwala tylko na aplikację / użytkownika XY?
Jeśli możesz uruchomić proces we własnym kontenerze, możesz zaporę ogniową w tym kontenerze niezależnie (nawet całkowicie go odłączyć od sieci).
Moduł bezpieczeństwa może filtrować dostęp procesu do funkcji sieciowych. Odpowiedź warl0ck daje przykład z AppArmor.
Rozwiązanie 1: Zapora ogniowa:
Możemy użyć zapór ogniowych, takich jak Douane lub Opensnitch, ALE te aplikacje nie są w 100% wydajne lub są na wczesnym etapie rozwoju (mają dużo błędów itp. Od 2019 r.)
Rozwiązanie 2: MAC jądra:
MAC jądra można wykorzystywać jako zaporę ogniową, najbardziej znane to Tomoyo , Selinux i Apparmor. To rozwiązanie jest najlepsze, jeśli chodzi o stabilność i wydajność (rozwiązanie zapory ogniowej), ale ustawienie czasu jest w jakiś sposób skomplikowane.
Rozwiązanie 3: Firejail:
Firejail może być używany do blokowania dostępu do sieci dla aplikacji, która nie wymaga rootowania, każdy użytkownik może z niego skorzystać
firejail --noprofile --net=none command-application
Rozwiązanie 4: Unshare
Unshare może uruchomić aplikację na innym serwerze nazw bez sieci, ale wymaga to root Firejail rozwiązanie robi prawie dokładnie to samo, ale nie wymaga roota
unshare -r -n application-comand
Rozwiązanie 5: Sprawdź, czy:
Jednym z rozwiązań jest przybliżenie aplikacji do zerowego / fałszywego serwera proxy. Możemy użyć tsocks lub proxybound . Oto kilka szczegółów na temat konfiguracji
Rozwiązanie 6: Iptables:
Innym łatwym rozwiązaniem jest iptables, można go skonfigurować tak, aby blokował aplikację
groupadd no-internet
grep no-internet /etc/group
useradd -g no-internet username
usermod -a -G no-internet userName
sprawdź za pomocą: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. Sprawdź to, na przykład w przeglądarce Firefox, uruchamiając:
no-internet "firefox"
5. Jeśli chcesz zrobić wyjątek i zezwolić programowi na dostęp do sieci lokalnej :
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. Zrób to na stałe
Jednym ze sposobów zastosowania reguły iptables podczas rozruchu jest dodanie reguły jako usługi za pomocą 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
na razie.
Zależy to od używanej dystrybucji, ale jest to funkcja zwykle zawarta w systemie MAC systemu operacyjnego. Jak wspomniano wcześniej, Ubuntu lub SuSE's AppArmor mogą to zrobić. Jeśli używasz RHEL, możesz skonfigurować SELinux tak, aby zezwalał lub odmawiał dostępu do określonego numeru portu na podstawie etykiety procesu wykonawczego. To wszystko, co mogłem znaleźć po szybkim googlowaniu, ale prawdopodobnie znajdziesz więcej szczegółowych zasobów online, jeśli spojrzysz mocniej i daje to ogólny pomysł.
Możesz użyć seccomp-bpf, aby zablokować niektóre wywołania systemowe. Na przykład może chcieć zablokowaćsocket
wywołanie systemowe, aby uniemożliwić procesowi tworzenie gniazd FD.
Napisałem przykład tej approcah, która uniemożliwia socket
wywołanie systemowe do pracy przy użyciu libseccomp. Podsumowanie jest (bez sprawdzania błędów):
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);
Nie wymaga to uprawnień administratora.
Kompletna piaskownica jest jednak znacznie bardziej złożona, więc nie należy jej używać do blokowania niechętnych do współpracy / złośliwych programów.
Możesz użyć programu wiersza polecenia o nazwie „proxy” i wypróbować jedną z następujących możliwości:
Skonfiguruj, aby korzystał z ...
Nie testowałem tego sam, więc nie wiem, czy to działa ...