Mám program, který bych chtěl otestovat v režimu offline, aniž bych složil svou skutečnou síť. Tento program by se stále musel připojit k místním soketům, včetně soketů unixové domény a zpětné smyčky. Musí také naslouchat na smyčku a být viditelný pro ostatní aplikace.
Ale pokusy o připojení ke vzdálenému počítači by měly selhat.
Chtěl bych mít nástroj, který funguje jako strace
/unshare
/sudo
a jednoduše spustí příkaz se skrytým Internetem (a LAN) a vše ostatní stále funguje:
$ offline my-program-to-test
Tato otázka má tipy na odpověď:Blokovat síťový přístup procesu?
Existuje několik návrhů, jako je spuštění jako jiný uživatel a poté manipulace s iptables nebo unshare -n
. Ale v obou případech neznám zaklínadlo pro sdílení soketů unixové domény a zpětné smyčky s hlavním systémem – odpovědi na tuto otázku mi pouze říkají, jak zrušit sdílení celého síť.
Program, který testuji, se stále potřebuje připojit k mému X serveru a dbus a dokonce musí být schopen naslouchat ve smyčce pro připojení z jiných aplikací v systému.
V ideálním případě bych se rád vyhnul vytváření chrootů nebo uživatelů nebo virtuálních počítačů a podobně, protože to začíná být stejně otravné jako odpojování síťového kabelu. bodem otázky je, jak to mohu udělat tak jednoduché jako sudo
.
Byl bych rád, kdyby proces běžel 100% normálně, kromě toho, že by selhala síťová volání s uvedením jiné než místní adresy. V ideálním případě zachovat stejné uid, stejný homedir, stejné pwd, stejné vše kromě … offline.
Používám Fedoru 18, takže nepřenosné linuxové odpovědi jsou v pořádku (očekávané, dokonce).
Dokonce jsem rád, že to vyřeším napsáním programu C, pokud to je to, o co jde, takže odpovědi, které zahrnují psaní C, jsou v pořádku. Jen nevím, jaké systémové volání by program C musel provést, aby zrušil přístup k externí síti při zachování místní sítě.
Každý vývojář, který se snaží podporovat „režim offline“, by tuto pomůcku pravděpodobně ocenil!
Přijatá odpověď:
Tradiční odpovědí je spustit program jako jiný uživatel a použít iptables -m owner
. Tímto způsobem je konfigurace sítě sdílena. S příchodem jmenných prostorů však existuje jednodušší způsob.
Pomocí jmenných prostorů zrušíte sdílení sítě a poté vytvoříte propojení virtuální sítě, pokud potřebujete omezený přístup k síti.
Chcete-li sdílet sokety unixových domén, vše, co potřebujete, je mít dostatečně aktuální jádro po tomto patchi z roku 2010, tedy 2.6.36 nebo vyšší (což je případ všech současných distribucí v době psaní tohoto článku kromě RHEL/CentOS).
Spusťte program v jeho vlastním oboru názvů IP. Před spuštěním programu vytvořte virtuální ethernetové rozhraní. Zdá se, že neexistuje mnoho dokumentace; V několika blozích jsem našel to správné zaklínadlo:
- Linuxové jmenné prostory ve společnosti Arista
- Několik poznámek k rozhraním veth od waldnera
- Představujeme síťové jmenné prostory systému Linux od Scotta Lowe
Ve úryvku níže používám ns_exec
je tento obal kolem setns
uvedené v manuálové stránce, abyste vyvolali hostitelskou stranu síťového odkazu z procesu běžícího v omezeném jmenném prostoru. Ve skutečnosti to nepotřebujete:hostitelskou stranu odkazu můžete nastavit mimo omezený jmenný prostor. Dělat to zevnitř pouze usnadňuje řízení toku, jinak budete potřebovat nějakou synchronizaci k nastavení odkazu poté, co bylo vytvořeno, ale před spuštěním vašeho 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" "[email protected]"
' /path/to/program --argument
To vše musíte udělat jako root. Zavedení uživatelských jmenných prostorů v jádře 3.8 to může umožnit bez zvláštních oprávnění, kromě nastavení globálního konce síťového spojení.
Nevím, jak sdílet localhost mezi dvěma jmennými prostory. Virtuální ethernetová rozhraní vytvářejí most typu point-to-point. Můžete použít iptables
pravidla přesměrování pro přesměrování provozu z/do lo
v případě potřeby.