Encaminha o tráfego através de uma interface específica para um processo no linux

18

É possível rotear o tráfego usado por um processo em uma interface específica?

Por exemplo, o tráfego de rede por aplicativo de download deve sempre usar a interface wlan0 , enquanto todos os outros aplicativos na máquina devem usar eth0 .

É possível ter esse tipo de regra no Linux?

    
por Suresh 17.04.2011 / 13:38

5 respostas

20

Isso pode ser feito usando os namespaces de rede do Linux.

Aqui está um artigo que explica como. Basicamente, você cria um namespace de rede com uma rota padrão diferente e executa os processos que precisam dele. Você conecta o namespace de rede recém-criado ao adaptador físico com uma ponte (mas é claro que outras soluções são possíveis).

Atualização: do kernel 3.14 é ainda mais fácil usar grupos de controle, como descrito em este artigo . Você precisa:

1) defina um grupo de controle net_cls para anotar os pacotes de um determinado processo com um classid (ou grupo de processos, observe que não deve haver nenhum relacionamento pai-filho entre eles)

2) use o módulo iptables cgroup (adicionado no Linux 3.14) para marcar os pacotes

3) use o roteamento de políticas (ip rule add fwmark ....) para criar uma nova tabela de roteamento para os pacotes marcados

A vantagem é que não precisamos fazer a ponte e tudo é muito mais dinâmico graças aos cgroups.

    
por 15.11.2013 / 21:30
12

Eu tenho lutado muitíssimo com isso, então aqui está uma solução COMPLETA. É testado no Ubuntu 15 & 16. Você pode usá-lo especialmente com o OpenVPN para rotear certos aplicativos fora da interface do túnel da VPN.

A solução completa "cgroup"

Como isso funciona?

  • O kernel do Linux colocará o aplicativo em um grupo de controle . O tráfego de rede dos aplicativos neste cgroup será identificado por seu ID de classe no nível do controlador de rede.
  • iptables marcará esse tráfego e o obrigará a sair com o IP correto
  • O
  • ip route processará o tráfego marcado em uma tabela de roteamento diferente, com uma rota padrão para qualquer IP de gateway desejado.

Script automatizado

Eu fiz um script novpn.sh para automatizar as dependências install & corre. Testado no Ubuntu.

Inicie sua VPN primeiro.

wget https://gist.githubusercontent.com/kriswebdev/a8d291936fe4299fb17d3744497b1170/raw/cf8b37fbe6c3f50a0be825eb77cafa3e0134946f/novpn.sh
# If you don't use eth0, edit the script setting.
sudo chmod +x novpn.sh
./novpn.sh traceroute www.google.com
./novpn.sh --help

Manual HowTo

Primeiro, instale o suporte e as ferramentas do cgroup:

sudo apt-get install cgroup-lite cgmanager cgroup-tools

Reinicialize (pode não ser necessário).

Você precisa do iptables 1.6 .0+. Obtenha a fonte de lançamento do iptables 1.6.0 , extraia-a e execute-a ( --disable-nftables flag evitará erros ) do diretório de origem do iptables:

sudo apt-get install dh-autoreconf bison flex
./configure --prefix=/usr      \
            --sbindir=/sbin    \
            --disable-nftables \
            --enable-libipq    \
            --with-xtlibdir=/lib/xtables
make
sudo make install
iptables --version

Agora, a configuração real. Defina um grupo de controle denominado novpn . Processos neste cgroup terão um classid de 0x00110011 (11:11).

sudo su
mkdir /sys/fs/cgroup/net_cls/novpn
cd /sys/fs/cgroup/net_cls/novpn
echo 0x00110011 > net_cls.classid

Agora, suponhamos que a interface que você deseja usar para o aplicativo específico seja eth0 com um IP de gateway de 10.0.0.1 . Substitua por aquilo que você realmente deseja (obtenha as informações de ip route ). Execute ainda como root:

# Add mark 11 on packets of classid 0x00110011
iptables -t mangle -A OUTPUT -m cgroup --cgroup 0x00110011 -j MARK --set-mark 11

# Force the packets to exit through eth0 with NAT
iptables -t nat -A POSTROUTING -m cgroup --cgroup 0x00110011 -o eth0 -j MASQUERADE

# Define a new "novpn" routing table
# DO THIS JUST ONCE !
echo 11 novpn >> /etc/iproute2/rt_tables

# Packets with mark 11 will use novpn
ip rule add fwmark 11 table novpn

# Novpn has a default gateway to the interface you want to use
ip route add default via 10.0.0.1 table novpn

# Unset reverse path filtering for all interfaces, or at least for "eth0" and "all"
for i in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $i; done

Por fim, execute seu aplicativo na interface específica:

exit
sudo cgcreate -t $USER:$USER -a $USER:$USER -g net_cls:novpn
cgexec -g net_cls:novpn traceroute www.google.com
# Close all Firefox windows first
cgexec -g net_cls:novpn firefox

Ou se você quiser mover um processo já em execução para o cgroup, bem ... você não pode! Isso parece ser devido à função NAT (masquerade): iptables -nvL -t nat doesn não combina quando o cgroup é alterado, mas iptables -nvL -t mangle corresponde.

# Get PID of the process (we'll then suppose it's 1234)
pidof firefox
# Add to cgroup - THIS DOESN'T WORK! Silently fails to produce the final result.
sudo echo 1234 > /sys/fs/cgroup/net_cls/novpn/tasks
# Remove - but this works...
sudo echo 1234 > /sys/fs/cgroup/net_cls

Créditos: Nenhuma resposta estava funcionando como esperado, mas uma mistura deles fez: chripell answer evolware article Por processo de roteamento tomar 2: usando cgroups, iptables e roteamento de políticas , , Mude para o OpenVPN com base no iptables

    
por 05.03.2016 / 02:12
2

Combinando as excelentes respostas de mariusmatutiae e KrisWebDev Eu criei um excelente script novpn.sh da KrisWebDev. Enquanto o script do KrisWebDev é projetado para riscar uma coceira mais específica (executando e movendo processos dentro / fora de uma VPN), minha versão permite que você execute basicamente qualquer comando em um ambiente de rede que você especificar. Você pode especificar a interface a qual se vincular, a rota padrão, especificar suas próprias regras de iptables, rotas estáticas, especificar um "teste" para confirmar se tudo está funcionando como você deseja antes de executar o comando ... etc). Ele permite que você use vários arquivos de configuração para que você possa definir qualquer número de ambientes de rede específicos nos quais você possa executar comandos / processos.

Eu postei aqui como uma essência: link

Pode até mesmo limpar as tabelas de cgroup / iptables / routing depois!

Feedback bem-vindo.

PS - Ele é projetado para o Debian 8 (Jessie)

    
por 03.08.2016 / 23:36
0

Não por aplicativo, não. Você pode fazer isso por porta ou por endereço IP, etc, ou um aplicativo em si pode se ligar a (e usar) uma placa de rede específica.

Você não pode configurar uma regra para isso.

    
por 17.04.2011 / 14:34