Netzwerkzugriff eines Prozesses blockieren?

74

Ist es möglich, den (ausgehenden) Netzwerkzugriff eines einzelnen Prozesses zu blockieren?

Larkee
quelle
6
Wie wollen Sie den Prozess identifizieren? PID, Name, Pfad?
Marco
1
Welchen Zugang möchten Sie sperren? Einige Programme verwenden den Netzwerkzugriff über localhost(auf demselben Computer), um ihre Aufgaben zu erledigen.
Vonbrand
Siehe auch LD_PRELOAD oder ähnliches, um den Netzwerkzugriff zu verhindern , wenn der Prozess zusammenarbeitet.
Gilles

Antworten:

78

Ab Linux 2.6.24 (gilt als experimentell bis 2.6.29) können Sie dafür Netzwerk-Namespaces verwenden. Sie müssen die 'Netzwerk-Namespaces' in Ihrem Kernel ( CONFIG_NET_NS=y) und Util-Linux mit dem unshareTool aktiviert haben .

Das Starten eines Prozesses ohne Netzwerkzugriff ist dann so einfach wie:

unshare -n program ...

Dadurch wird ein leerer Netzwerknamespace für den Prozess erstellt. Das heißt, es wird ohne Netzwerkschnittstellen und ohne Loopback ausgeführt . Im folgenden Beispiel fügen wir -r hinzu, um das Programm erst auszuführen, nachdem die aktuellen effektiven Benutzer- und Gruppen-IDs den Superuser-IDs zugeordnet wurden (vermeiden Sie sudo):

$ unshare -r -n ping 127.0.0.1
connect: Network is unreachable

Wenn Ihre App eine Netzwerkschnittstelle benötigt, können Sie eine neue einrichten:

$ 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

Beachten Sie, dass dadurch ein neuer lokaler Loopback erstellt wird. Das heißt, der erzeugte Prozess kann nicht auf offene Ports des Hosts zugreifen 127.0.0.1.


Wenn Sie Zugriff auf das ursprüngliche Netzwerk im Namespace benötigen, können Sie nsenterden anderen Namespace eingeben.

Das folgende Beispiel wird pingmit dem von PID 1 verwendeten Netzwerknamespace ausgeführt (angegeben durch -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
Michał Górny
quelle
4
unshare -nscheint zu werfen "Operation nicht erlaubt" ohne rootPrivilegien, etwas, was ich darüber vermisse?
Baldrs
1
Vielleicht eine blöde Frage ... Gilt dieser Namespace auch für untergeordnete Prozesse / so genannte Prozesse der nicht freigegebenen Anwendung?
Bonanza
3
Ja. Es wird von allen Kindern geerbt, die nach dem Wechsel des Namespaces erzeugt wurden.
Michał Górny
2
Ich sehe aus wie jedes Programm, das ich freigeben möchte, z. B. mit sudo unshare -nerbt das Root-Recht. Da ich brauche, dass das sudo unshare aufruft, frage ich mich, wie ich sicherstellen kann, dass das aufgerufene Programm nicht über die Root-Rechte verfügt.
Bonanza
3
Ein Liner, um den Prozess auf einen Benutzer zu beschränken. Nur zweimal 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 verfügt über eine Funktion namens Netzwerk-Namespaces, mit der Sie im Wesentlichen mehrere Netzwerkstapel auf demselben Computer haben und einem Programm bei dessen Ausführung einen zuweisen können. Dies ist eine Funktion, die normalerweise für Container verwendet wird. Sie können sie jedoch auch verwenden, um die gewünschten Ergebnisse zu erzielen.

Die ip netnsUnterbefehle verwalten es. Das Erstellen eines neuen Netzwerknamespaces ohne Zugriff auf irgendetwas ist einfach. Es ist der Standardstatus eines neuen Namespaces:

root@host:~# ip netns add jail

Wenn Sie jetzt in diesen Namespace wechseln, können Sie ihn ziemlich einfach konfigurieren. Sie werden wahrscheinlich wollen, um lo in es zu bringen, und das ist es:

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

Wenn Sie Ihren Befehl jetzt ohne Netzwerk ausführen möchten, führen Sie ihn einfach in diesem Gefängnis aus:

root@host:~# ip netns exec jail su user -c 'ping  8.8.8.8'
connect: Network is unreachable

Das Netzwerk ist wie gewünscht nicht erreichbar. (Sie können alle Arten von interessanten Dingen ausführen, da ein separater Netzwerkstapel iptablesRegeln usw. enthält.)

derobert
quelle
Obwohl ich sudo ipdie IP-Befehle ausführen musste, habe ich, als ich mich in der Bash befand, nur ausgeführt su someuser, um eine nicht privilegierte Shell für den Benutzer 'someuser' zu erhalten.
Salbei
11

Sie können iptables verwenden und diesen Prozess in eine cgroup verschieben:

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
Jan Mueller
quelle
1
Wie man die PID aus dieser Tasks-Datei entfernt Es gibt einen Fehler, wenn ich versuche, Daten aus dieser Datei zu entfernen oder zu löschen, obwohl ich mit root-Benutzer
bin
@pkm, um die Vernetzung wieder zu aktivieren, müssen Sie nur [pid] /sys/fs/cgroup/net_cls/tasks(kein "Blockieren" im Pfad)
Trauer
10

Ja, mit benutzerdefiniertem Apparmor-Profil

/usr/bin/curl {
    ...

    # block ipv4 acces
    deny network inet,
    # ipv6 
    deny network inet6,
    # raw socket
    deny network raw,

}

Auf diese Weise müssen Sie jedoch eine Liste der zulässigen Dateien erstellen, auf die auch zugegriffen werden kann. Der gesamte Vorgang kann etwas kompliziert sein. Das Hilfedokument finden Sie hier

Gänseblümchen
quelle
7

Sie können die FireJail-Sandbox verwenden (sollte auf Kernels mit Seccomp-Funktion funktionieren).

Um es zu benutzen, machen Sie es einfach

firejail --noprofile --net=none <path to executable>

--noprofileDeaktiviert die Standard-Sandbox. --net=noneDeaktiviert das Netzwerk

Ich glaube, dass die meisten Distributionen bereits Pakete bereitstellen, aber selbst wenn sie kein FireJail sind, gibt es praktisch keine anderen Abhängigkeiten als Build-Toolchain und Namespace / Seccomp-fähigen Kernel.

Es gibt einige andere nette Features von FireJail, die in firejail --helpBezug auf das Netzwerk gezeigt werden können (wie zum Beispiel nur das Bereitstellen einer Loopback-Schnittstelle oder das Blockieren von IP / DNS usw.), aber dies sollte den Job erledigen. Auch das doesn't require root.

pruzinat
quelle
5

Sie können es nicht alleine mit iptables machen. Diese Funktion existierte nur für kurze Zeit , konnte jedoch nicht zuverlässig zum Funktionieren gebracht werden und wurde aufgegeben.

Wenn Sie den Prozess als dedizierte Benutzer-ID ausführen können, kann iptables dies mit dem ownerModul tun :

iptables -A OUTPUT -m owner --uid-owner 1234 -j DROP

Siehe Beispiele in Iptables: Abgehenden Verkehr mit conntrack und Eigentümer abgleichen. Arbeitet mit seltsamen Tropfen , Iptables / PF-Regel, um nur XY-Anwendung / Benutzer zuzulassen?

Wenn Sie den Prozess in einem eigenen Container ausführen können, können Sie diesen Container unabhängig von der Firewall konfigurieren (sogar die vollständige Trennung vom Netzwerk).

Ein Sicherheitsmodul kann den Zugriff eines Prozesses auf Netzwerkfunktionen filtern. Die Antwort von warl0ck gibt ein Beispiel mit AppArmor.

Gilles
quelle
3

Lösung 1: Firewall:

Wir könnten Firewalls wie Douane oder Opensnitch verwenden, aber diese Anwendungen sind nicht zu 100% effizient oder befinden sich in einem frühen Entwicklungsstadium (haben viele Fehler usw. ab 2019).

Lösung 2: Kernel-MAC:

Kernel-MACs können als Firewall verwendet werden. Die bekanntesten sind Tomoyo , Selinux und Apparmor. Diese Lösung ist die beste, wenn es um Stabilität und Effizienz geht (Firewall-Lösung), aber die meiste Zeit ist das Einstellen etwas kompliziert.

Lösung 3: Feuergefängnis:

Firejail kann verwendet werden, um den Netzwerkzugriff für eine Anwendung zu blockieren, für die kein Root erforderlich ist. Jeder Benutzer kann davon profitieren

firejail --noprofile --net=none command-application

Lösung 4: Freigabe aufheben

Unshare kann eine Anwendung auf einem anderen Namesapece ohne Netzwerk starten, aber dafür muss die Lösung von root firejail fast genau dasselbe tun, erfordert jedoch kein root

unshare -r -n application-comand

Lösung 5: Proxify:

Eine Lösung besteht darin, die Anwendung einem NULL / Fake- Proxy zuzuweisen . Wir können tsocks oder proxybound verwenden . Hier einige Details zum Setup

Lösung 6: Iptables:

Eine andere einfache Lösung ist iptables. Sie kann so eingerichtet werden, dass eine Anwendung blockiert wird

  1. Neue Gruppe erstellen, validieren ; füge benötigte Benutzer zu dieser Gruppe hinzu:
    • Erstellen: groupadd no-internet
    • Bestätigen: grep no-internet /etc/group
    • Benutzer hinzufügen: useradd -g no-internet username

      Hinweis: Wenn Sie bereits vorhandene Benutzer ändern, sollten Sie Folgendes ausführen usermod -a -G no-internet userName :sudo groups userName

  2. Erstellen Sie ein Skript in Ihrem Pfad und machen Sie es ausführbar:
    • Erstellen: nano /home/username/.local/bin/no-internet
    • Ausführbar: chmod 755 /home/username/.local/bin/no-internet
    • Inhalt: #!/bin/bash
                    sg no-internet "$@"

  3. Fügen Sie die iptables-Regel zum Löschen der Netzwerkaktivität für die Gruppe no-internet hinzu :
    • iptables -I OUTPUT 1 -m owner --gid-owner no-internet -j DROP

      Hinweis: Vergessen Sie nicht, die Änderungen dauerhaft zu speichern, damit sie nach dem Neustart automatisch angewendet werden . Dies hängt von Ihrer Linux-Distribution ab.


   4. Überprüfen Sie es, zum Beispiel in Firefox, indem Sie Folgendes ausführen:

  • no-internet "firefox"

   5. Falls Sie eine Ausnahme machen und einem Programm den Zugriff auf das lokale Netzwerk erlauben möchten :

  • 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. Machen Sie es dauerhaft

   Eine Möglichkeit, die iptables-Regel beim Booten anzuwenden, besteht darin, die Regel als Dienst mit systemd hinzuzufügen

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
intika
quelle
1
Dies ist eine sehr gute Anleitung. Danke. Obwohl für mich mein Befehl no-internet den Parameter nie zu übergeben schien, verwende ich ihn sg no-internetfür den Moment.
Zach Bloomquist
@ Zach Ich habe meine Antwort aktualisiert. Sie könnten an FireJail interessiert sein;)
Intika
2

Es hängt davon ab, welche Distribution Sie verwenden, aber diese Funktion ist normalerweise im MAC-System des Betriebssystems enthalten. Wie bereits erwähnt, können dies Ubuntu oder SuSEs AppArmor. Wenn Sie RHEL verwenden, können Sie SELinux so konfigurieren, dass der Zugriff auf eine bestimmte Portnummer basierend auf der Bezeichnung des ausführenden Prozesses entweder zugelassen oder verweigert wird. Das ist alles, was ich nach einigem schnellen Googeln finden konnte, aber es gibt wahrscheinlich mehr detaillierte Online-Ressourcen, wenn Sie genauer hinsehen und Ihnen die allgemeine Idee geben.

Bratchley
quelle
2

Mit seccomp-bpf können Sie einige Systemaufrufe blockieren. Möglicherweise möchten Sie beispielsweise densocket Systemaufruf blockieren , um zu verhindern, dass der Prozess Sockets FD erstellt.

Ich habe ein Beispiel für diese Approcah geschrieben, das den socketSystemaufruf für die Arbeit mit libseccomp verhindert. Die Zusammenfassung lautet (ohne Fehlerprüfung):

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);

Hierfür sind keine Root-Rechte erforderlich.

Eine vollständige Sandbox ist jedoch viel komplexer. Verwenden Sie diese Option nicht, um nicht kooperative / bösartige Programme zu blockieren.

ysdx
quelle
Könnten Sie ein Beispiel geben, wie man das benutzt? Benötigt es Root-Rechte, um zu funktionieren?
Bonanza
-4

Sie können ein Befehlszeilenprogramm namens "proxychains" verwenden und eine der folgenden Möglichkeiten ausprobieren:

Richten Sie es so ein, dass es verwendet ...

  • ... einen Proxy, den es nicht gibt? (Ich weiß nicht, ob es mit einem "ungültigen" Proxy ausgeführt wird)
  • ... ein lokaler Proxy (wie "tinyproxy", "squid", "privoxy", ...), der den Zugang zum Internet einschränkt? (Verwenden Sie einfach ACLs)

Ich habe es nicht selbst getestet, daher weiß ich nicht, ob es funktioniert ...

drkhsh
quelle
Das Posten nicht getesteter Lösungen ist im Allgemeinen keine gute Idee.
Twirrim
Proxy-Ketten mit einem nicht vorhandenen Proxy (wie localhost: 1234 oder ähnliches) könnten jedoch tatsächlich ein solider Ansatz sein
phil294