Permitir apenas determinado tráfego de saída em determinadas interfaces

13

Eu tenho um problema estranho. Eu tenho um servidor com duas interfaces de rede eth0 e eth1 . Cada um deles está conectado a uma rede diferente. Cada rede tem um gateway de internet. O servidor tem várias conexões de saída : http (alguns scripts nos sites de raspar do servidor), cliente nfs, cliente samba, cliente dns e um buscador de email para citar apenas alguns.

Por motivos que não entro, preciso dividir esses clientes de saída para que o tráfego de saída de http, nfs, samba e dns seja solicitado somente sobre eth0 , enquanto todo o resto passa para eth1 .

Eu li algumas pesquisas no Google e parece que iptables é o que eu preciso, mas eu realmente não tenho a menor ideia. Estou apenas acostumado a gerenciar regras de firewall de entrada por meio de ufw .

Alguém poderia começar com algumas regras de exemplo e me dizer como fazer o sistema adotar essas regras na inicialização? Idealmente, sem me tirar da minha conexão SSH (eu posso obter acesso físico, mas prefiro não).

Editar Eu posso dividir os clientes em dois usuários se for possível limitar todo o tráfego de saída de uma conta para uma interface. no papel que parece ser mais fácil.

    
por Oli 27.04.2011 / 00:41

3 respostas

12

Eu configuraria uma tabela de roteamento separada e uma política para rotear os pacotes marcados usando essa tabela e fazer com que o iptables / netfilter marque certos pacotes.

Crie uma tabela: echo 1 known >> /etc/iproute2/rt_tables

Crie uma regra de roteamento (o comando ip é de iproute2 ): ip rule add from all fwmark 1 table known

Criamos uma tabela chamada "known" e criamos uma regra de roteamento que diz que qualquer pacote com uma marca igual a 1 é roteado de acordo com a tabela "conhecida". Eu só o chamava conhecido porque é para a lista de protocolos conhecidos - você pode nomear como quiser. Agora nós configuramos a tabela conhecida para rotear o caminho correto.

ip route add default dev eth0 table known

Crie regras de iptables:

iptables -t mangle -I PREROUTING -p tcp --dport 111 -j MARK --set-mark 1
iptables -t mangle -I PREROUTING -p tcp --dport 2049 -j MARK --set-mark 1

O exemplo marca os pacotes nas portas NFS (111, 2049) com um 1. Estamos adicionando esta regra ao 'mangle' iptable. Isso é diferente das tabelas de roteamento e não é alterável; a tabela mangle é especificamente para alterar pacotes de qualquer outra forma que não o NAT.

Agora, para rotear todo o resto através da outra interface, adicionamos uma rota à tabela de roteamento padrão.

ip route add default dev eth1

Para entender isso, leia as seções 4 e 11 do guia do LARTC .

    
por 27.04.2011 / 14:31
5

Bem, a maneira " mais fácil " deve ser instruir os programas individuais a usar uma interface específica (ou o ip da interface. Por exemplo:

ping -I eth1 8.8.8.8

instrui o ping a usar a eth1 como uma interface de origem, enquanto

wget --bind-address 10.0.0.1 http://www.google.it/

instrui o wget a percorrer a interface que tem 10.0.0.1 como endereço IP.

Honestamente, não sei se é possível com todos os programas que você precisa, mas é um começo para reduzir as regras que você precisa escrever para iptables e os programas iproute .

Para começar, você deve ler este tutorial em várias conexões de internet . Uma boa leitura também é um dos milhares de tutoriais do iptables, especialmente em outbound filtering , process / pid filtering e port filtering .

    
por 27.04.2011 / 10:59
4

O caminho adequado para isso é vincular () à interface que você deseja usar para pacotes de saída. Desde então você pode configurar rotas com os comandos ip route e ip rule para controlar como os pacotes são roteados com base em sua interface de saída. Para o meu exemplo, vou assumir a seguinte rede:

  • eth0:
    • Endereço: 192.168.0.2/24
    • Gateway padrão: 192.168.0.1
  • eth1:
    • Endereço: 192.168.1.2/24
    • Gateway padrão: 192.168.1.1

Vou criar duas tabelas de roteamento, uma para o tráfego de saída para eth0 chamado alternate e uma tabela para eth1 chamada main. O principal da tabela de roteamento sempre existe e é a tabela normal usada pelos comandos route e ip route . A maioria das pessoas nunca lida com outras tabelas. Para criar a tabela chamada alternada, adicionaremos a seguinte linha a /etc/iproute2/rt_tables :

10    alternate

O main da tabela tem uma prioridade padrão de 254. As regras para as quais a tabela de roteamento está em vigor são controladas pelo comando ip rule . Por padrão, esse comando irá imprimir uma lista de regras existentes que devem ser algo como isto:

0:      from all lookup local 
32766:  from all lookup main 
32767:  from all lookup default 

Isso basicamente diz que ele procurará uma rota na tabela local , que é uma tabela especial mantida pelo kernel para rotas locais, como meu próprio endereço IP. Em seguida, ele tentará o padrão main e table da tabela. O padrão da tabela é normalmente em branco, portanto, se não houver correspondência na principal, não haverá rota para hospedar. Primeiro, vamos preencher tabela alternativa com regras para eth0.

sudo ip route add table alternate 192.168.0.0/24 dev eth0
sudo ip route add table alternate 192.168.1.0/24 dev eth1
sudo ip route add table alternate default via 192.168.0.1

Normalmente, você deseja que a tabela alternate seja semelhante à tabela main . As únicas diferenças são quando o roteamento deve ser diferente. Você pode querer não incluir a segunda linha acima se você quer literalmente que todo o tráfego NFS, HTTP, etc. vá através do gateway padrão na eth0, mesmo que seja destinado à rede na eth1. O próximo passo é adicionar uma regra para quando usar essa tabela de roteamento alternativa:

sudo ip rule add from 192.168.0.0/24 pref 10 table alternate

Esta regra diz que qualquer tráfego proveniente de um endereço na rede 192.168.0 usará a tabela de roteamento alternate em vez da tabela main normal. O último passo é garantir que todos os clientes que devem usar eth0 se vinculem a ele. Com wget , por exemplo, defina --bind-address=192.168.0.2 , para o NFS defina a opção clientaddr=192.168.0.2 mount. Se estiver usando LibWWW com Perl, você pode definir a opção localaddr em LWP :: UserAgent para controlar a interface local à qual se liga. Se acontecer de você ter um cliente que você não pode controlar a vinculação e compilar a fonte não é uma opção, você poderá usar uma regra iptables para modificar seu endereço, mas isso é mais um hack e pode não funcionar. Você precisaria de uma regra SNAT configurada na cadeia PREROUTING da tabela nat ou da tabela mangle. Você ainda precisará das tabelas de roteamento modificadas fornecidas acima para que isso funcione.

    
por 27.04.2011 / 23:53