Roteie o tráfego IP com base no processo para diferentes rotas/interfaces padrão

Roteie o tráfego IP com base no processo para diferentes rotas/interfaces padrão

Estou tentando determinar se é possível rotear seletivamente pacotes IP de um processo ou grupo de processos por meio de uma interface específica, enquanto todos os outros pacotes são roteados por outra interface. Ou seja, quero que todo o tráfego /usr/bin/testappseja roteado eth1enquanto todos os outros pacotes passam eth0. Os pacotes, neste caso, podem ser TCP, UDP, ICMP, etc. e podem ser configurados pelos usuários finais para usar várias portas.

Como não consigo forçar facilmente o processo em questão a se vincular a uma interface específica, estou tentando obter o mesmo resultado por meio de roteamento. Isso é possível?

--- editar ---

Uma sugestão útil aqui, e em muitos outros lugares, é marcar pacotes com base no UID; esse não é realmente o objetivo. O objetivo é marcar/filtrar/rotear com base no processoindependentemente do usuário. Isto é, if alicee bobtodos charlieexecutam sua própria instância de /usr/bin/testapp; todos os pacotes de todas as três instâncias devem passar eth1enquanto todos os outros pacotes do sistema devem passar eth0.

Observe que a marcação por porta de origem/destino, nome de usuário/UID, etc. não é suficiente, pois vários usuários podem executar testappe configurar portas diferentes por conta própria ~/.config/testapp.confou qualquer outra coisa. A questão é sobre a filtragem por processo.

Uma opção disponível, embora eu não saiba quão útil é, é usar um /bin/(ba|z)?shwrapper baseado em - em torno do binário nativo.

--- editar ---

Estou me referindo ao roteamento em um sistema executando um kernel Linux moderno, digamos 4.0 ou melhor. Se houver dependências de software além de , iproute2e ferramentas semelhantes, estou disposto a explorar soluções de código aberto, embora ferramentas básicas sejam preferíveis.nftablesconntrack

Responder1

Você está roteando os pacotes por meio de eth1 ou eth0. tabelas mangle devem resolver isso. Para fazer isso, tive que marcar pacotes e definir regras para lidar com eles. Primeiro, adicione uma regra que faça o kernel rotear pacotes marcados com 2 através da tabela

ip rule add fwmark 2 table 3

Adicione uma rota para redirecionar o tráfego através de uma interface diferente, assumindo que o gateway seja 10.0.0.1:

ip route add default via 10.0.0.1 table 3

Limpe seu cache de roteamento.

ip route flush cache

Agora, defina uma regra de firewall para marcar pacotes designados:

iptables -t mangle -A OUTPUT -p tcp --dport 465 -j MARK --set-mark 2

Finalmente, relaxe a validação da fonte do caminho reverso. Alguns sugerem que você defina como 0, mas 2 parece uma escolha melhor de acordo com https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt. Se você pular isso, você receberá pacotes (isso pode ser confirmado usando tcpdump -i tap0 -n), mas os pacotes não serão aceitos. O comando para alterar a configuração para que os pacotes sejam aceitos:

sysctl -w net.ipv4.conf.tap0.rp_filter=2

Referência:http://serverfault.com/questions/345111/iptables-target-to-route-packet-to-specific-interface

Responder2

Você pode executar o processo com um usuário específico e combinar os pacotes com a ownerextensão do iptable. Uma vez combinado, você pode marcá-lo e usá-lo com outra tabela de roteamento, use POSTROUTINGou qualquer solução que desejar.

Essepost explica melhor a correspondência de pacotes com owner.

Responder3

Isso é possível usando namespaces de rede para isolar o processo, uma conexão Ethernet virtual para conectar esse namespace de rede ao seu namespace principal. Você pode então usar o iptables para rotear com base nessa fonte.

Então aqui está um exemplo. Estou usando o gerenciador de rede para alguns comandos, mas você poderia fazer isso bruto

# 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

Responder4

Bem, dado que você nos disse:

Como não consigo forçar facilmente o processo em questão a se vincular a uma interface específica, estou tentando obter o mesmo resultado por meio de roteamento. Isso é possível?

podemos começar a ajudá-lo a partir deste ponto. Era uma vez no FreeBSD jailuma chamada de sistema que aparecia com o propósito de restringir um processo, ou grupo de processos, a alguma subseção dos recursos do sistema. Particularmente, pode-se especificar um endereço IP que esses processos "isolados" usariam para suas atividades de rede. Isso foi tão útil que eu realmente senti muita falta desse recurso no Linux. Mas o Linux também tem algumas maneiras de obter resultados semelhantes:

ou o mais leve seria apenas mexer nos namespaces manualmente:https://unix.stackexchange.com/questions/155446/linux-is-there-handy-way-to-exec-a-program-binding-it-to-ip-address-of-choice

informação relacionada