GNU/Linux >> Tutoriels Linux >  >> Linux

Linux - Commande pour exécuter un processus enfant "hors ligne" (pas de réseau externe) sous Linux ?

J'ai un programme que j'aimerais tester en mode hors ligne sans couper mon réseau actuel. Ce programme aurait toujours besoin de se connecter aux sockets locaux, y compris les sockets de domaine Unix et le bouclage. Il doit également écouter en boucle et être visible pour les autres applications.

Mais les tentatives de connexion à une machine distante doivent échouer.

J'aimerais avoir un utilitaire qui fonctionne comme strace /unshare /sudo et exécute simplement une commande avec Internet (et LAN) caché et tout le reste fonctionne toujours :

$ offline my-program-to-test

Cette question a des indices sur la réponse :Bloquer l'accès réseau d'un processus ?

Il y a quelques suggestions là-bas, comme exécuter en tant qu'un autre utilisateur puis manipuler iptables, ou unshare -n . Mais dans les deux cas, je ne connais pas l'incantation pour que les sockets de domaine Unix et le bouclage soient partagés avec le système principal - les réponses à cette question me disent seulement comment annuler le partage de l'intégralité réseau.

Le programme que je teste doit encore se connecter à mon serveur X et à dbus et même être capable d'écouter en boucle les connexions d'autres applications sur le système.

Idéalement, j'aimerais éviter de créer des chroots ou des utilisateurs ou des machines virtuelles ou similaires, car cela devient tout aussi ennuyeux que de débrancher le câble réseau. c'est-à-dire que le point de la question est de savoir comment puis-je rendre cela aussi simple qu'un sudo .

J'aimerais que le processus s'exécute normalement à 100 %, sauf que les appels réseau spécifiant une adresse non locale échoueraient. Idéalement en gardant le même uid, même homedir, même pwd, même tout sauf… hors ligne.

J'utilise Fedora 18, donc les réponses Linux non portables sont très bien (attendues, même).

Je suis même heureux de résoudre ce problème en écrivant un programme C, si c'est ce qui est impliqué, donc les réponses qui impliquent d'écrire C sont bonnes. Je ne sais tout simplement pas quels appels système ce programme C devrait effectuer pour révoquer l'accès au réseau externe tout en conservant le réseau local.

Tout développeur essayant de prendre en charge le "mode hors ligne" apprécierait probablement cet utilitaire !

Réponse acceptée :

La réponse traditionnelle est d'exécuter le programme en tant qu'autre utilisateur et d'utiliser iptables -m owner . De cette façon, la configuration réseau est partagée. Cependant, avec l'avènement des espaces de noms, il existe un moyen plus simple.

Avec les espaces de noms, vous annulez le partage du réseau, puis créez un lien de réseau virtuel si vous avez besoin d'un accès réseau limité.

Pour partager des sockets de domaine unix, il suffit d'avoir un noyau assez récent, après ce patch de 2010, donc 2.6.36 ou supérieur (ce qui est le cas sur toutes les distributions en cours au moment de la rédaction sauf RHEL/CentOS).

Exécutez le programme dans son propre espace de noms IP. Avant de démarrer le programme, établissez une interface Ethernet virtuelle. Il ne semble pas y avoir beaucoup de documentation; J'ai trouvé la bonne incantation dans quelques blogs :

  • Espaces de noms Linux chez Arista
  • Quelques notes sur les interfaces veth par waldner
  • Présentation des espaces de noms de réseau Linux par Scott Lowe
En relation :Centos – DNSMasq – Différentes réponses pour des adresses MAC spécifiques ?

Dans l'extrait ci-dessous, j'utilise le ns_exec est le this wrapper autour de setns répertorié dans la page de manuel pour afficher le côté hôte du lien réseau à partir du processus s'exécutant dans l'espace de noms restreint. Vous n'en avez pas réellement besoin :vous pouvez configurer le côté hôte du lien depuis l'extérieur de l'espace de noms restreint. Le faire de l'intérieur ne fait que faciliter le contrôle de flux, sinon vous avez besoin d'une certaine synchronisation pour configurer le lien après qu'il a été établi mais avant de démarrer votre programme.

unshare -n -- sh -c '
  # Create a virtual ethernet interface called "confined",
  # with the other end called "global" in the namespace of PID 1
  ip link add confined type veth peer name global netns 1

  # Bring up the confined end of the network link
  ip addr add 172.16.0.2/30 dev confined
  ip link set confined up

  # Bring up the global end of the network link
  ns_exec /proc/1/ns/net ifconfig global 172.16.0.1 netmask 255.255.255.252 up

  # Execute the test program
  exec sudo -E -u "$TARGET_USER" "$0" "[email protected]"
' /path/to/program --argument

Vous devez faire tout cela en tant que root. L'introduction d'espaces de noms d'utilisateurs dans le noyau 3.8 peut rendre cela faisable sans autorisations spéciales, à l'exception de la configuration de l'extrémité globale du lien réseau.

Je ne sais pas comment partager localhost entre les deux espaces de noms. Les interfaces Ethernet virtuelles créent un pont point à point. Vous pouvez utiliser iptables règles de transfert pour rediriger le trafic de/vers lo si vous le souhaitez.


Linux
  1. Linux - Bloquer l'accès réseau d'un processus ?

  2. kill Exemples de commandes sous Linux

  3. Options de commande nohup sous Linux

  4. Exemples de commandes renice sous Linux

  5. Exemples de commandes dsniff sous Linux

Commande Killall sous Linux avec des exemples

5 façons rapides de tuer un processus sous Linux

Comment tuer un processus sous Linux

10 exemples de commande Linux ss pour surveiller les connexions réseau

Exemples de commandes Linux ifconfig

Commande Linux nload