Вопрос: Как запустить программу, обеспечив при этом доступ к сети через определенный сетевой интерфейс?
Случай: я хочу получить доступ к двум различным машинам с одинаковым IP (192.168.1.1), но доступным через два разных сетевых интерфейса (eth1 и eth2).
Пример:
net-bind -D eth1 -exec {Program 192.168.1.1}
net-bind -D eth2 -exec {Program 192.168.1.1}
Вышеприведенное является приблизительным примером того, что я хотел бы, основываясь на аппаратной привязке, выполняемой через primusrun и optirun .
Задача: Как предлагается в связанном потоке , используемые интерфейсы выбираются не программой, а ядром (отсюда и синтаксис предварительной привязки в приведенном выше примере).
Я нашел некоторые связанные решения, которые являются неудовлетворительными. Они основаны на связывании сетевых интерфейсов посредством внесения в черный список пользовательских сетей; то есть запуск процесса от имени пользователя, который может получить доступ только к одному конкретному сетевому интерфейсу.
источник
Ответы:
Для Linux на Superuser уже ответили - как использовать разные сетевые интерфейсы для разных процессов? ,
Самый популярный ответ использует
LD_PRELOAD
хитрость, чтобы изменить сетевую привязку для программы, но современные ядра поддерживают гораздо более гибкую функцию, называемую «пространства имен сети», которая предоставляется черезip
программу. Этот ответ показывает, как использовать это. Из моих собственных экспериментов я сделал следующее (как root):Также можно управлять сетевыми пространствами имен в какой - то степени с
unshare
иnsenter
команд. Это позволяет вам также создавать отдельные пространства для PID, пользователей и точек монтирования. Для получения дополнительной информации см .:источник
wvdial
например, кажется, не устанавливает его вообще ... поэтому он должен быть определен в самом пространстве именip netns remove test_ns
хотите вернуться к нормальной жизни? Или ты должен сделать что-то особенное?Я принимаю ответ Грэма; это просто продолжение, чтобы объяснить изменения, которые я внес в его предложение, чтобы решить мою проблему.
Вместо того чтобы связывать физический интерфейс внутри пространства имен, я создал пару виртуальных сетевых интерфейсов с одним концом в сетевом пространстве имен и одним концом в корне. Пакеты затем направляются через эту виртуальную сеть из пространства имен в корневое пространство имен и затем в физический интерфейс. - Таким образом, я могу запускать все свои обычные передачи данных и, кроме того, запускать процессы, которые могут получить доступ только к определенному интерфейсу.
Как только интерфейсы настроены для eth0 и eth1 с соответствующими им пространствами имен eth0_ns и eth1_ns, программы могут быть выполнены на указанном интерфейсе через;
источник
dhclient <bridge>
на здесь .Решение I: Предварительная загрузка конкретной библиотеки
App-Route-Jail : используйте ld_preload для принудительной настройки интерфейсного шлюза (отличная идея, но требуются возможности root или меток). Подробное описание приведено ниже.
Proxybound : используйте ld_preload для принудительной установки прокси в конкретном приложении (вместо интерфейса используется прокси)
Force-Bind : имеет много функций, но утечки привязки (не надежны)
Bind-Interface-IP : слишком простые и неплотные соединения (не надежно)
Bind-IP : слишком прост и утечка соединений (не надежно)
Решение II: пользовательское пространство Linux
Классическое пользовательское пространство linux ip-netns : отличное решение, но требуется root, и интерфейс может существовать только в одном пользовательском пространстве
Firejail : Firejail может заставить приложение использовать определенную сеть, но совместимость ограничена (например, она не совместима с интерфейсами tun). firejail не требует рута
firejail --dns=8.8.8.8 --noprofile --net=eth0 --ip=192.168.1.1 app-command
Firejail с netns : Firejail может заставить приложение использовать определенное пространство пользователя, которое было создано отдельно, это позволяет нам использовать пространства имен без root
firejail --dns=8.8.8.8 --noprofile --netns=nameOfyourNS app-command
Firejail с маскарадом и мостом : Firejail может заставить приложение использовать определенный интерфейс с маскарадом iptables , это здорово и не требует root, но это требует ip_forward и может означать влияние на безопасность
firejail --net=br0 firefox
Решение III: Linux iptables
Iptables можно использовать для этой цели, но это требует ip_forward и может подразумевать влияние на безопасность, если оно настроено неправильно, пример 1 , пример 2 , пример 3 , пример 4
Решения (I, II и III) примечания:
Wireguard
Если вы используете VPN (особенно wireguard) и хотите применить это решение к интерфейсу wireguard ( wireguard с пользовательским пространством ), вы можете следовать инструкциям по ссылке, чтобы создать пространство пользователя, содержащее интерфейс wg (и, следовательно, ограниченное интерфейсом vpn). ) также это можно сочетать с
firejail --netns=container
возможностью использования пространства пользователя без рута.Как найти интерфейсный шлюз
Существует множество решений для поиска шлюза, здесь приведены некоторые команды, позволяющие найти используемый шлюз
Как использовать App-Route-Jail
192.168.1.1
используется в качестве принудительного шлюза, это правило маршрута не повлияет на другие приложения, например, эту манипуляцию нужно выполнять только один раз при загрузке системы, если вы хотите используйте это решение ежедневноисточник