Zablokować dostęp procesu do sieci?


74

Czy można zablokować (wychodzący) dostęp do sieci dla jednego procesu?


6
Jak zamierzasz zidentyfikować proces? PID, nazwa, ścieżka?
Marco

1
Jaki dostęp chcesz zablokować? Niektóre programy używają dostępu do sieci za pośrednictwem localhost(do tego samego komputera) do wykonywania swoich zadań.
vonbrand

Zobacz także LD_PRELOAD lub podobny, aby uniemożliwić dostęp do sieci , jeśli proces współpracuje.
Gilles

Odpowiedzi:


78

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 unsharenarzę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ć, nsenteraby wprowadzić inną przestrzeń nazw.

Poniższy przykład działa pingz 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

4
unshare -nwydaje się rzucać „Operacja niedozwolona” bez rootuprawnień, coś mi w tym brakuje?
baldrs

1
Może głupie pytanie ... czy ta przestrzeń nazw dotyczy również procesów potomnych / nazywanych procesami nieudostępnionej aplikacji?
bonanza

3
Tak. Jest dziedziczony przez wszystkie dzieci odradzające się po zmianie przestrzeni nazw.
Michał Górny

2
Wygląda na to, że każdy program, który chciałbym udostępnić np. Z sudo unshare -ndziedziczy prawo root. Ponieważ potrzebuję sudo do wywołania nieudostępnionego, zastanawiam się, jak mogę się upewnić, że wywoływany program nie ma praw root.
bonanza

3
Jedna wkładka, aby ograniczyć proces do użytkownika. Tylko dwa razy sudo: sudo unshare -n sudo -u dude bash -c 'echo Hello, my name is $USER'@ThorSummoner bbs.archlinux.org/viewtopic.php?id=205240
Jakub Bochenski

21

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 netnszarzą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 iptablesreguły itp.)


Chociaż musiałem sudo ipwykonać polecenia ip, kiedy byłem w bashu, właśnie wykonałem, su someuseraby uzyskać nieuprzywilejowaną powłokę dla użytkownika „someuser”.
mędrzec

11

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

1
jak usunąć pid z tego pliku zadań, co powoduje błąd przy próbie usunięcia lub usunięcia danych z tego pliku przez użytkownika root
pkm

@pkm, aby umożliwić powrót do sieci, wystarczy echo [pid] na /sys/fs/cgroup/net_cls/tasks(brak „bloku” na ścieżce)
Żal

10

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


7

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>

--noprofilewyłącza domyślną piaskownicę --net=nonewyłą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 --helpw 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.


5

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 ownermoduł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.


3

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ę

  1. Utwórz, sprawdź poprawność nowej grupy ; dodaj wymaganych użytkowników do tej grupy:
    • Stwórz: groupadd no-internet
    • Uprawomocnić: grep no-internet /etc/group
    • Dodaj użytkownika: useradd -g no-internet username

      Uwaga: Jeśli modyfikujesz już istniejącego użytkownika, powinieneś uruchomić: usermod -a -G no-internet userName sprawdź za pomocą:sudo groups userName

  2. Utwórz skrypt na swojej ścieżce i spraw, aby był wykonywalny:
    • Stwórz: nano /home/username/.local/bin/no-internet
    • Plik wykonywalny: chmod 755 /home/username/.local/bin/no-internet
    • Zawartość: #!/bin/bash
                    sg no-internet "$@"

  3. Dodaj regułę iptables, aby porzucić aktywność sieciową dla grupy bez internetu :


   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

1
To naprawdę doskonały przewodnik. Dziękuję Ci. Chociaż dla mnie moje polecenie bez internetu nigdy nie zdawało się przekazać parametru, więc używam sg no-internetna razie.
Zach Bloomquist

@Zach zaktualizowałem moją odpowiedź, możesz być zainteresowany firejail;)
intika

2

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ł.


2

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 socketwywoł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.


Czy możesz podać przykład, jak tego użyć? Czy do działania potrzebne są uprawnienia roota?
bonanza

-4

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 ...

  • ... serwer proxy, który nie istnieje? (Nie wiem, czy będzie działać z „nieprawidłowym” proxy)
  • ... lokalny serwer proxy (np. „tinyproxy”, „kałamarnica”, „privoxy”…), który ogranicza dostęp do Internetu? (Wystarczy użyć list ACL)

Nie testowałem tego sam, więc nie wiem, czy to działa ...


Publikowanie niesprawdzonych rozwiązań zasadniczo nie jest dobrym pomysłem.
Twirrim,

proxy z nieistniejącym proxy (jak localhost: 1234 lub podobny) może być jednak solidnym podejściem
phil294
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.