Я пытаюсь определить, возможно ли выборочно направлять IP-пакеты из процесса или группы процессов через определенный интерфейс, в то время как все остальные пакеты направляются через другой интерфейс. То есть, я хочу, чтобы весь трафик из /usr/bin/testapp
направлялся через , eth1
в то время как все остальные пакеты проходят через eth0
. Пакеты в этом случае могут быть TCP, UDP, ICMP и т. д. и могут быть настроены конечными пользователями для использования различных портов.
Поскольку я не могу легко заставить рассматриваемый процесс привязаться к определенному интерфейсу, я пытаюсь добиться того же результата через маршрутизацию. Возможно ли это?
--- редактировать ---
Полезное предложение здесь и во многих других местах — маркировать пакеты на основе UID; это не совсем цель. Цель — маркировать/фильтровать/маршрутизировать на основе процессанезависимо от пользователя. То есть, если alice
, bob
и charlie
все запускают свои собственные экземпляры /usr/bin/testapp
; все пакеты из всех трех экземпляров должны пройти, eth1
в то время как все остальные пакеты из системы должны пройти через eth0
.
Обратите внимание, что маркировка по порту источника/назначения, имени пользователя/UID и т. д. недостаточна, поскольку могут работать разные пользователи testapp
, и они могут устанавливать разные порты в своих собственных ~/.config/testapp.conf
или как угодно. Вопрос в фильтрации по процессу.
Один из доступных вариантов, хотя я и не знаю, насколько он полезен, — это использование /bin/(ba|z)?sh
оболочки на основе .exe вокруг собственного двоичного файла.
--- редактировать ---
Я имею в виду маршрутизацию в системе, работающей на современном ядре Linux, скажем, 4.0 или выше. Если есть программные зависимости за пределами iproute2
, nftables
, conntrack
и подобных инструментов, я готов рассмотреть решения с открытым исходным кодом, хотя базовые инструменты предпочтительнее.
решение1
Ваша маршрутизация пакетов через eth1 или eth0. таблицы mangle должны решить эту проблему. Для этого мне пришлось пометить пакеты и настроить правила для их обработки. Сначала добавьте правило, которое заставит ядро маршрутизировать пакеты, помеченные 2, через таблицу
ip rule add fwmark 2 table 3
Добавьте маршрут для перенаправления трафика через другой интерфейс, предположив, что шлюз — 10.0.0.1:
ip route add default via 10.0.0.1 table 3
Очистите кэш маршрутизации.
ip route flush cache
Теперь установите правило брандмауэра для маркировки определенных пакетов:
iptables -t mangle -A OUTPUT -p tcp --dport 465 -j MARK --set-mark 2
Наконец, ослабьте проверку источника обратного пути. Некоторые предлагают вам установить его на 0, но 2 кажется лучшим выбором согласно https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
. Если вы пропустите это, вы будете получать пакеты (это можно подтвердить с помощью tcpdump -i tap0 -n
), но пакеты не будут приниматься. Команда для изменения настройки, чтобы пакеты принимались:
sysctl -w net.ipv4.conf.tap0.rp_filter=2
Ссылка :http://serverfault.com/questions/345111/iptables-target-to-route-packet-to-specific-interface
решение2
Вы можете запустить процесс с определенным пользователем и сопоставить пакеты с расширением iptable owner
. После сопоставления вы можете пометить его и использовать с другой таблицей маршрутизации, использовать POSTROUTING
или любое другое решение, которое вам может понравиться.
Этотпост лучше объясняет сопоставление пакетов с owner
.
решение3
Это возможно с помощью сетевых пространств имен для изоляции процесса, виртуального соединения Ethernet для соединения этого сетевого пространства имен с вашим основным пространством имен. Затем вы можете использовать iptables для маршрутизации на основе этого источника.
Вот пример. Я использую сетевой менеджер для некоторых команд, но вы можете сделать это напрямую
# Create a namespace
ip netns add ns1
# create a bridge between them
nmcli connection add type veth ifname virt0 peer virt1
ip link set virt1 netns ns1
ip addr add 192.168.69.1/24 dev virt0
ip netns exec ns1 ip addr add 192.168.69.2/24 dev virt1
ip netns exec ns1 ip link up virt1
echo 1 > sudo tee /proc/sys/net/ipv4/ip_forward
# At this point traffic from ns1 will appear in your main network namespace as coming from ip 192.168.69.2 dev virt0, so you can handle it from there. You will need NAT to make it go somewhere useful.
# In this case I want the traffic to go out through interface vpn1, which is not a default route on my system.
# Add your process-specific routing rules in a non-default table (12345 in this case)
ip route add default dev vpn1 table 12345 proto static scope link metric 50
# Set up a rule to use that table for the traffic coming from that IP, with lower priority than the default table's rule.
ip rule add priority 30000 from 192.168.69.0/24 lookup 12345
# Add the nat, so that the traffic can actually exist on your outbound interface
iptables -t nat -A POSTROUTING -o vpn1 -j MASQUERADE
# At this point traffic from ns1 will go out through interface vpn1. Now you can run command sin that netns to utilize this.
nsenter --net=/var/run/netns/ns1 your_program
решение4
Ну, учитывая, что вы нам сказали:
Поскольку я не могу легко заставить рассматриваемый процесс привязаться к определенному интерфейсу, я пытаюсь добиться того же результата через маршрутизацию. Возможно ли это?
мы можем начать помогать вам прямо с этого момента. Когда-то давно в FreeBSD jail
появился системный вызов, целью которого было ограничить процесс или группу процессов некоторым подразделом системных ресурсов. В частности, можно было указать IP-адрес, который эти «изолированные» процессы будут использовать для своей сетевой активности. Это было так удобно, что мне очень не хватало этой функции в Linux. Но в Linux тоже есть несколько способов добиться похожих результатов:
или, наиболее легковесным вариантом было бы просто вручную поработать с пространствами имен:https://unix.stackexchange.com/questions/155446/linux-есть-удобный-способ-к-исполнению-программы-привязки-ее-к-IP-адресу-по-выбору