Pergunta: Como inicio um programa, assegurando que seu acesso à rede seja vinculado por meio de uma interface de rede específica?
Caso: desejo acessar duas máquinas distintas com o mesmo IP (192.168.1.1), mas acessíveis por duas interfaces de rede diferentes (eth1 e eth2).
Exemplo:
net-bind -D eth1 -exec {Program 192.168.1.1}
net-bind -D eth2 -exec {Program 192.168.1.1}
A descrição acima é uma aproximação do que eu gostaria, inspirada na ligação de hardware feita via primusrun e optirun .
Desafio: Conforme sugerido em um encadeamento relacionado , as interfaces usadas não são escolhidas pelo programa, mas pelo kernel (daí a sintaxe de pré-ligação no exemplo acima).
Encontrei algumas soluções relacionadas que são insatisfatórias. Eles são baseados em interfaces de rede vinculadas por meio de lista negra de rede específica do usuário; ou seja, executando o processo como um usuário que pode acessar apenas uma única interface de rede específica.
fonte
Respostas:
Para Linux, isso já foi respondido no Superusuário - Como usar diferentes interfaces de rede para diferentes processos? .
A resposta mais popular usa um
LD_PRELOAD
truque para alterar a ligação de rede para um programa, mas os kernels modernos oferecem suporte a um recurso muito mais flexível chamado 'namespaces de rede', que é exposto peloip
programa. Esta resposta mostra como usar isso. De minhas próprias experiências, fiz o seguinte (como root):Também é possível gerenciar os namespaces da rede em certa medida com os comandos
unshare
ensenter
. Isso permite também criar espaços separados para PIDs, usuários e pontos de montagem. Para mais informações, consulte:fonte
wvdial
por exemplo, não parece configurá-lo de maneira alguma ... portanto, ele deve ser definido no próprio espaço para nome #ip netns remove test_ns
volta ao normal? Ou você tem que fazer algo especial?Estou aceitando a resposta de Graeme; isso é simplesmente um acompanhamento para explicar as alterações que fiz na sugestão dele para resolver meu problema.
Em vez de vincular a interface física ao espaço para nome, criei um par de interfaces de rede virtual, com uma extremidade no espaço para nome da rede e outra na raiz. Os pacotes são roteados por essa rede virtual a partir do namespace, para o namespace raiz e depois para a interface física. - Como tal, sou capaz de executar todas as minhas transferências de dados comuns e, além disso, iniciar processos que só podem acessar uma interface específica.
Depois que as interfaces são configuradas para eth0 e eth1, com seus respectivos namespaces eth0_ns e eth1_ns, os programas podem ser executados na interface especificada via;
fonte
dhclient <bridge>
por aqui .Solução I: pré-carregando uma biblioteca específica
App-Route-Jail : use ld_preload para forçar o gateway da interface (ótima idéia, mas requer recursos de raiz ou de marcas) o uso é detalhado nas notas abaixo
Proxybound : use ld_preload para forçar um proxy para um aplicativo específico (isso está usando proxy em vez de interface)
Force-Bind : possui muitos recursos, mas o bind vaza (não é confiável)
Bind-Interface-IP : conexões muito simples e vazadas (não confiáveis)
Bind-IP : conexões muito simples e vazamento (não confiáveis)
Solução II: espaço de usuário do Linux
IP-netns clássicos do espaço para usuário linux : a melhor solução, mas requer raiz e interface, só pode existir em um único espaço de usuário
Firejail : o Firejail pode forçar um aplicativo a usar uma rede específica, mas a compatibilidade é limitada (por exemplo, não é compatível com as interfaces tun). firejail não requer root
firejail --dns=8.8.8.8 --noprofile --net=eth0 --ip=192.168.1.1 app-command
Firejail com netns : o Firejail pode forçar um aplicativo a usar um espaço de usuário específico que foi criado separadamente. Isso permite nomear espaços sem raiz
firejail --dns=8.8.8.8 --noprofile --netns=nameOfyourNS app-command
Firejail com mascarada e ponte : o Firejail pode forçar um aplicativo a usar uma interface específica com o mascarada de iptables , isso é ótimo e não requer raiz, mas exige ip_forward e pode implicar em impacto na segurança
firejail --net=br0 firefox
Solução III: Linux iptables
Os iptables podem ser usados para essa finalidade, mas isso requer ip_forward e pode implicar em um impacto na segurança se não estiver configurado corretamente, exemplo 1 , exemplo 2 , exemplo 3 , exemplo 4
Soluções (I, II e III) observa:
Wireguard
Se você estiver usando uma VPN (especialmente wireguard) e quiser aplicar esta solução a uma interface wireguard ( wireguard com espaço do usuário ), poderá seguir o link instruído para criar um espaço de usuário contendo uma interface wg (e, portanto, limitado a uma interface VPN) ) também pode ser combinado com isso
firejail --netns=container
para poder usar o espaço do usuário sem raiz.Como encontrar o gateway de interface
Existem muitas soluções para encontrar o gateway. Aqui estão alguns comandos que permitem encontrar o gateway usado
Como usar o App-Route-Jail
192.168.1.1
é usado como gateway forçado; essa regra de rota não afeta outros aplicativos; essa manipulação deve ser feita apenas uma vez na inicialização do sistema, por exemplo, se você desejar use esta solução diariamentefonte