Polecenie uruchomienia procesu potomnego „offline” (bez sieci zewnętrznej) w systemie Linux

15

Mam program, który chciałbym przetestować w trybie offline bez usuwania mojej faktycznej sieci. Ten program nadal musiałby łączyć się z gniazdami lokalnymi, w tym gniazdami domeny unix i sprzężeniem zwrotnym. Musi także nasłuchiwać w pętli zwrotnej i być widoczny dla innych aplikacji.

Ale próby połączenia ze zdalnym komputerem powinny zakończyć się niepowodzeniem.

Chciałbym mieć narzędzie, które działa jak strace/ unshare/ sudoi po prostu uruchamia polecenie z ukrytym Internetem (i LAN) i wszystko inne nadal działa:

$ offline my-program-to-test

To pytanie zawiera wskazówki na odpowiedź: Zablokować dostęp procesu do sieci?

Istnieje kilka sugestii, takich jak uruchamianie jako inny użytkownik, a następnie manipulowanie iptables lub unshare -n. Ale w obu przypadkach nie znam inkantacji, aby uzyskać gniazda domeny unix i sprzężenie zwrotne do wspólnego systemu - odpowiedzi na to pytanie mówią mi tylko, jak udostępnić całą sieć.

Program, który testuję, wciąż musi połączyć się z moim serwerem X i dbus, a nawet móc słuchać w pętli zwrotnej połączeń z innych aplikacji w systemie.

Idealnie chciałbym uniknąć tworzenia chrootów, użytkowników, maszyn wirtualnych itp., Ponieważ staje się to tak samo denerwujące jak odłączanie kabla sieciowego. tzn. chodzi o to, jak mogę to uczynić tak prostym jak sudo.

Chciałbym, aby proces przebiegał w 100% normalnie, z wyjątkiem tego, że połączenia sieciowe określające adres nielokalny zakończyłyby się niepowodzeniem. Idealnie zachowując ten sam identyfikator użytkownika, ten sam katalog domowy, ten sam plik pwd, to samo wszystko oprócz ... offline.

Korzystam z Fedory 18, więc nieportowalne odpowiedzi na Linuksa są w porządku (nawet spodziewane).

Z przyjemnością rozwiązuję ten problem, pisząc program w języku C, jeśli o to chodzi, więc odpowiedzi dotyczące pisania w języku C są w porządku. Po prostu nie wiem, jakie wywołania systemowe musiałby wykonać program C, aby odwołać dostęp do sieci zewnętrznej przy jednoczesnym zachowaniu sieci lokalnej.

Każdy programista próbujący obsługiwać „tryb offline” prawdopodobnie doceniłby to narzędzie!

Havoc P
źródło

Odpowiedzi:

9

Tradycyjną odpowiedzią jest uruchamianie programu jako inny użytkownik i używanie go iptables -m owner. W ten sposób konfiguracja sieci jest współdzielona. Jednak wraz z pojawieniem się przestrzeni nazw istnieje łatwiejszy sposób.

Dzięki przestrzeniom nazw nie udostępniasz sieci, a następnie tworzysz wirtualne łącze sieciowe, jeśli potrzebujesz ograniczonego dostępu do sieci.

Aby współużytkować gniazda domeny unix, wystarczy mieć najnowszą wersję jądra, po tej łatce z 2010 r. , Czyli 2.6.36 lub nowszej (tak jest w przypadku wszystkich obecnych dystrybucji w momencie pisania, z wyjątkiem RHEL / CentOS).

Uruchom program we własnej przestrzeni nazw IP. Przed uruchomieniem programu utwórz wirtualny interfejs Ethernet. Wydaje się, że nie ma dużo dokumentacji; Właściwe zaklęcie znalazłem na kilku blogach:

W fragmencie poniżej, używam ns_execjest to wrapper wokółsetns wymienionych w manualu, aby otworzyć stronę hosta łącza sieciowego z procesu uruchomionego w ograniczonej przestrzeni nazw. Tak naprawdę nie jest to potrzebne: możesz skonfigurować stronę hosta łącza spoza ograniczonej przestrzeni nazw. Wykonanie tego od wewnątrz jedynie ułatwia kontrolę przepływu, w przeciwnym razie potrzebujesz synchronizacji, aby skonfigurować łącze po jego ustanowieniu, ale przed uruchomieniem programu.

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" "$@"
' /path/to/program --argument

Musisz to wszystko zrobić jako root. Wprowadzenie nazw użytkowników w jądrze 3.8 może zrobić to wykonalne bez specjalnych uprawnień, z wyjątkiem ustanowienia globalnego koniec łącza sieciowego.

Nie wiem, jak współdzielić localhost między dwiema przestrzeniami nazw. Wirtualne interfejsy ethernetowe tworzą most punkt-punkt. W razie potrzeby możesz użyć iptablesreguł przekazywania, aby przekierować ruch z / do lo.

Gilles „SO- przestań być zły”
źródło
Dobra dodatkowa informacja, dzięki. Myślę, że veth daje mi link do „poza” przestrzenią nazw, ale moja nowa przestrzeń nazw wciąż stanowi osobny węzeł sieci, a nie ten sam węzeł sieci minus interfejsy nielokalne. Konsekwencjami są (?): Domeny uniksowe / gniazda abstrakcyjne nadal by się nie udawały, a sprzężenie zwrotne może być przekazywane za pośrednictwem iptables, ale przekazywanie nie zapewnia udostępniania - to znaczy, że zarówno oryginalna, jak i ograniczona przestrzeń nazw mogą nasłuchiwać w pętli zwrotnej i oba zestawy (dynamicznie -zmiana) porty musiałyby być widoczne w obu przestrzeniach nazw ... zaczynam zgadywać, czego chcę, tutaj jest niemożliwe: - /
Havoc P
1

Można to również osiągnąć za pomocą grup dopasowujących reguły iptables. Napisałem narzędzie do streszczenia kroków. Chociaż wymaga początkowych uprawnień do początkowej konfiguracji, a poza tym jest setuidową wersją binarną, myślę, że oferuje dość prosty sposób radzenia sobie z problemem w pytaniu. Wymaga wersji iptables, która jest wystarczająco aktualna i że dostępne są odpowiednie moduły netfilter.

https://github.com/quitesimpleorg/qsni

crtxcr
źródło
0

/ !! \ To prawdopodobnie nie jest poprawna odpowiedź, ponieważ spowoduje to zmniejszenie całego ruchu, a nie tylko pojedynczego pid.

Nie korzystałem z niego, ale myślę, że potencjalnie możesz użyć Comcast:

https://github.com/tylertreat/Comcast

ustawiona na 100% utratę pakietów

Ponownie nie testowałem tego, ale teoretycznie zmodyfikowałem z ich pliku Readme, możesz:


Linux

W systemie Linux można użyć iptablesdo upuszczania pakietów przychodzących i wychodzących.

$ iptables -A INPUT -m statistic --mode random --probability 1 -j DROP
$ iptables -A OUTPUT -m statistic --mode random --probability 1 -j DROP

Alternatywnie możesz użyć, tcktóry obsługuje niektóre dodatkowe opcje.

$ tc qdisc change dev eth0 root netem reorder 0 duplicate 0 corrupt 1

Zresetować:

$ tc qdisc del dev eth0 root netem
ThorSummoner
źródło