web-dev-qa-db-fra.com

Bloquer l'accès réseau d'un processus?

Est-il possible de bloquer l'accès au réseau (sortant) d'un seul processus?

77
larkee

Avec Linux 2.6.24+ (considéré comme expérimental jusqu'au 2.6.29), vous pouvez utiliser des espaces de noms réseau pour cela. Vous devez activer les "espaces de noms réseau" dans votre noyau (CONFIG_NET_NS=y) et util-linux avec l'outil unshare .

Ensuite, démarrer un processus sans accès au réseau est aussi simple que:

unshare -n program ...

Cela crée un espace de noms réseau vide pour le processus. Autrement dit, il est exécuté sans interfaces réseau, y compris sans bouclage . Dans l'exemple ci-dessous, nous ajoutons -r pour exécuter le programme uniquement après que les ID d'utilisateur et de groupe effectifs actuels ont été mappés sur ceux du superutilisateur (évitez Sudo):

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

Si votre application a besoin d'une interface réseau, vous pouvez en configurer une nouvelle:

$ 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

Notez que cela créera un nouveau bouclage local . Autrement dit, le processus généré ne pourra pas accéder aux ports ouverts de l'hôte 127.0.0.1.


Si vous devez accéder à la mise en réseau d'origine à l'intérieur de l'espace de noms, vous pouvez utiliser nsenter pour entrer dans l'autre espace de noms.

L'exemple suivant exécute ping avec un espace de noms réseau utilisé par PID 1 (il est spécifié via -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
83
Michał Górny

Linux a une fonctionnalité appelée espaces de noms résea qui vous permet d'avoir essentiellement plusieurs piles réseau sur la même machine et d'en affecter une à un programme lors de son exécution. Il s'agit d'une fonctionnalité généralement utilisée pour les conteneurs, mais vous pouvez également l'utiliser pour accomplir ce que vous voulez.

Le ip netns les sous-commandes le gèrent. La création d'un nouvel espace de noms réseau sans accès à quoi que ce soit est facile, c'est l'état par défaut d'un nouvel espace de noms:

root@Host:~# ip netns add jail

Maintenant, si vous basculez vers cet espace de noms, vous pouvez le configurer assez facilement. Vous voudrez probablement en parler, et c'est tout:

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

Maintenant, lorsque vous souhaitez exécuter votre commande sans réseau, vous l'exécutez simplement dans cette prison:

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

Le réseau est, comme souhaité, inaccessible. (Vous pouvez faire toutes sortes de choses intéressantes car une pile réseau distincte inclut des règles iptables, etc.)

24
derobert

Vous pouvez utiliser iptables et déplacer ce processus dans un groupe de contrôle:

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
15
Jan Mueller

Oui, avec un profil d'apparmeur personnalisé, c'est-à-dire

/usr/bin/curl {
    ...

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

}

Mais de cette façon, vous devrez également générer une liste de fichiers autorisés à accéder, toute la procédure peut être un peu compliquée. Et voir le document d'aide ici

10
daisy

Vous pouvez utiliser sandbox firejail (devrait fonctionner sur les noyaux avec la fonction seccomp).

Pour l'utiliser, il suffit de faire

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

--noprofile désactive le sandbox par défaut --net=none désactive la mise en réseau

Je crois que la plupart des distributions fournissent déjà un paquet, mais même si elles ne font pas firejail, elles n'ont pratiquement aucune dépendance autre que la chaîne d'outils de construction et le noyau activé namespace/seccomp.

Il existe d'autres fonctionnalités intéressantes de Firejail qui peuvent être affichées avec firejail --help en ce qui concerne la mise en réseau (comme fournir uniquement une interface de bouclage ou bloquer ip/dns, etc.) mais cela devrait faire l'affaire. En outre, il doesn't require root.

7
pruzinat

Vous ne pouvez pas le faire avec iptables seul. Cette fonctionnalité existait brièvement , mais ne pouvait pas fonctionner de manière fiable et a été abandonnée.

Si vous pouvez exécuter le processus en tant qu'ID utilisateur dédié, iptables peut le faire avec le module owner:

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

Voir les exemples dans Iptables: faire correspondre le trafic sortant avec conntrack et le propriétaire. Fonctionne avec des gouttes étranges , règle iptables/pf pour autoriser uniquement l'application/utilisateur XY?

Si vous pouvez exécuter le processus dans son propre conteneur, vous pouvez pare-feu ce conteneur indépendamment (même le rendre complètement déconnecté du réseau).

Un module de sécurité peut filtrer l'accès d'un processus aux fonctionnalités de mise en réseau. réponse de warl0ck donne un exemple avec AppArmor.

Solution 1: Pare-feu:

Nous pourrions utiliser des pare-feu comme Douane ou Opensnitch MAIS ces applications ne sont pas efficaces à 100% ou à un stade précoce de développement (ont beaucoup de bogues, etc. à partir de 2019)

Solution 2: MAC du noyau:

Les MAC du noyau peuvent être utilisés comme pare-feu les plus connus sont Tomoyo , Selinux et Apparmor Cette solution est la meilleure en termes de stabilité et d'efficacité (solution de pare-feu) mais la plupart du temps, la configuration est en quelque sorte compliquée.

Solution 3: Firejail:

Firejail peut être utilisé pour bloquer l'accès au réseau pour une application cela ne nécessite pas de root, tout utilisateur peut en bénéficier

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

Solution 4: Annuler le partage

L'annulation du partage peut démarrer une application sur une autre appellation sans réseau, mais cela nécessite la solution root de firejail fait presque exactement la même chose mais ne nécessite pas root

unshare -r -n application-comand

Solution 5: Proxify:

Une solution consiste à proclamer l'application à un proxy null/faux . Nous pouvons utiliser tsocks ou proxybound . Voici quelques détails sur la configuration

Solution 6: Iptables:

Une autre solution simple est iptables, elle pourrait être configurée pour bloquer une application

  1. Créer, valider nouveau groupe; ajoutez les utilisateurs requis à ce groupe:
    • Créer: groupadd no-internet
    • Validez: grep no-internet /etc/group
    • Ajouter un utilisateur: useradd -g no-internet username

      Remarque: Si vous modifiez un utilisateur déjà existant, vous devez exécuter: usermod -a -G no-internet userName vérifier avec : Sudo groups userName

  2. Créez un script dans votre chemin et rendez-le exécutable:
    • Créer: nano /home/username/.local/bin/no-internet
    • Exécutable: chmod 755 /home/username/.local/bin/no-internet
    • Contenu: #!/bin/bash
      sg no-internet "$@"

  3. Ajoutez règle iptables pour supprimer l'activité réseau du groupe pas d'Internet:


4. Vérifiez-le, par exemple sur Firefox en exécutant:

  • no-internet "firefox"

5. Au cas où vous voudriez faire une exception et autoriser un programme à accéder à réseau local:

  • 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. Rendez-le permanent

Une façon d'appliquer la règle iptables au démarrage consiste à ajouter la règle en tant que service avec 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
4
intika

Cela dépend de la distribution que vous utilisez, mais c'est une fonctionnalité généralement incluse dans le système MAC du système d'exploitation. Comme indiqué précédemment, Ubuntu ou AppArmor de SuSE peuvent le faire. Si vous utilisez RHEL, vous pouvez configurer SELinux pour autoriser ou refuser l'accès à un numéro de port particulier en fonction de l'étiquette du processus d'exécution. This est tout ce que j'ai pu trouver après quelques recherches rapides sur Google, mais il y a probablement des ressources plus détaillées en ligne si vous regardez plus attentivement et cela vous donne une idée générale.

2
Bratchley

Vous pouvez utiliser seccomp-bpf pour bloquer certains appels système. Par exemple, vous voudrez peut-être bloquer l'appel système socket afin d'empêcher le processus de créer des sockets FD.

J'ai écrit un exemple de cette approbation qui empêche l'appel système socket de travailler avec libseccomp. Le résumé est (sans vérification d'erreur):

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

Cela n'a pas besoin de privilèges root.

Un sandbox complet est cependant beaucoup plus complexe, vous ne devez donc pas utiliser cette commande pour bloquer les programmes non coopératifs/malveillants.

2
ysdx

Depuis Systemd v235, il existe également une autre option très simple:

comptabilité IP et listes d'accès avec systemd

TL; DR: systemd peut désormais effectuer la comptabilité du trafic IP par service, ainsi que le contrôle d'accès pour les plages d'adresses IP.

0
Marco Gamberoni