Unindo as duas redes

É possível também unir as duas redes, permitindo que os PCs dos dois lados se enxerguem mutuamente. O procedimento é similar, mas passa a ser necessário criar o bridge dos dois lados da conexão para que as redes sejam unificadas.

Imagine o caso de duas redes, conectadas à web através de links ADSL. Elas seguem a configuração clássica, onde o servidor tem duas placas de rede (eth0 para o ADSL e eth1 para a rede local) e compartilha a conexão para os micros da rede. No exemplo, a rede do servidor A usa a faixa “192.168.0.x”, enquanto a rede do servidor B usa a faixa “192.168.1.x”.

O primeiro passo seria instalar o pacote “bridge-utils” nos dois servidores e configurá-los para ativar a interface br0 durante o boot, como fizemos no exemplo anterior.

O script “/etc/init.d/bridge” no servidor A seria:

#!/bin/sh
ifconfig eth1 0.0.0.0 up
brctl addbr br0
brctl addif br0 eth0
ifconfig br0 192.168.0.254 netmask 255.255.255.0 broadcast 192.168.0.255 up

No servidor B o script seria idêntico, mudando apenas os endereços na última linha:

#!/bin/sh
ifconfig eth1 0.0.0.0 up
brctl addbr br0
brctl addif br0 eth0
ifconfig br0 192.168.1.254 netmask 255.255.255.0 broadcast 192.168.1.255 up

Em ambos os casos, você precisaria fazer com que o script fosse executado durante o boot, como em:

# cd /etc/rc5.d
# ln -sf ../init.d/bridge S99bridge

Nesse ponto, você terá a interface “br0” configurada com o endereço de rede local em ambos os servidores. O próximo passo é criar o túnel no servidor A, aproveitando para já subir a interface tap0 e adicioná-la ao bridge no servidor B:

# ssh -f -w 0:0 -o Tunnel=ethernet root@servidorB “ifconfig
tap0 0.0.0.0; brctl addif br0 tap0″

Ainda no servidor A, rode os comandos para subir a interface tap0 e também adicioná-la ao bridge:

# ifconfig tap0 0.0.0.0 up
# brctl addif br0 tap0

Com isso, você terá uma interface br0 em cada um dos servidores, englobando a interface de rede local e a interface tap0 do túnel. A interface br0 no servidor A usará o endereço “192.168.0.1” e a br0 no servidor B usará o endereço “192.168.1.1”. Como os dois estão em faixas de endereços diferentes, ambos não se enxergarão, embora a conexão entre os dois já esteja funcional.

Para solucionar este último empecilho, criamos um alias para a interface br0 do servidor A, atribuindo a ela um endereço IP vago (qualquer um) dentro da rede do servidor B, como em:

# ifconfig br0:1 192.168.1.253

Em seguida fazemos o mesmo no servidor B, criando o alias para a interface br0 e atribuindo a ele um endereço IP vago dentro da rede do servidor A, como em:

# ifconfig br0:1 192.168.0.253

Com isso, ambos os servidores terão duas interfaces locais, uma com um endereço dentro da sua própria faixa local e a outra com um endereço dentro da faixa usada pelo outro servidor. A interface bridge é esperta o suficiente para transmitir os frames destinados à outra rede usando a interface tap0 e os destinados à rede local usando a eth1 e, como ambos os servidores são os gateways padrão de suas respectivas redes, todos os demais clientes serão capazes de acessar as duas redes através deles. A única observação é que pode demorar alguns minutos até que todos os micros tenham acesso a todos da outra rede, pois os bridges levam algum tempo para criar a tabela com os endereços MAC das duas redes.

Note que em nenhum momento precisei mexer na configuração da interface eth0, onde está o link ADSL. Isso permite que você faça toda a configuração a partir do servidor A, logando-se no servidor B via SSH, sem precisar de ninguém do outro lado.

O script para automatizar a criação da VPN no servidor A pode ficar então com o seguinte conteúdo:

#!/bin/sh
ssh -f -w 0:0 -o Tunnel=ethernet root@servidorB “ifconfig
tap0 0.0.0.0; brctl addif br0 tap0; ifconfig br0:1 192.168.0.253″
sleep 10
ifconfig tap0 0.0.0.0 up
brctl addif br0 tap0
ifconfig br0:1 192.168.1.253

Veja que o comando do SSH incorporou mais um comando, o “ifconfig br0:1 192.168.0.3”, que cria o alias para a interface br0, novamente evitando que você precise abrir uma conexão separada só para executar o comando.

No exemplo, usei redes com faixas locais distintas. Naturalmente, é possível também unir duas redes que utilizem a mesma faixa de endereços. A configuração seria a mesma, com a exceção de que você não precisaria criar os aliases no final. Entretanto, usar a mesma faixa de IPs nas duas redes traria dois problemas:

a) Você precisaria certificar-se de que os PCs nas duas redes não estão usando endereços repetidos e usar um único servidor DHCP.

b) Os pacotes de broadcast das duas redes seriam transmitidos de um lado para o outro usando o link de internet, o que poderia reduzir substancialmente o desempenho do link.

Ou seja, você até pode usar a mesma faixa caso as duas redes tenham poucos micros e o link seja rápido, mas esta é uma situação a se evitar. É preferível usar duas faixas separadas.

Continuando, o script executado no servidor A ainda vai pedir a senha antes de efetuar a conexão, o que vai ser um problema que você quiser que ele seja executado automaticamente durante o boot.

A solução mais simples nesse caso é gerar uma chave de autenticação sem passphrase no servidor A, e usá-la para fazer login no servidor B:

# ssh-keygen -t rsa

(pressione enter três vezes, deixando a passphrase em branco)

E em seguida instale a chave no servidor B usando o ssh-copy-id:

# ssh-copy-id -i ~/.ssh/id_rsa.pub root@servidorB

Ao usar a passphrase em branco, é importante restringir as permissões de acesso ao arquivo “/root/.ssh/id_rsa” no servidor A, já que qualquer um que consiga copiá-lo (e saiba para que ele serve) poderá usá-lo para se logar no servidor B.

O túnel pode sobreviver a quedas temporárias na conexão, mas vai ser interrompido caso a queda seja acompanhada pela mudança do endereço IP do servidor, o que pode ser um problema em conexões ADSL instáveis.

Quando o túnel é interrompido, são necessários alguns passos adicionais para que você consiga restabelecê-lo em seguida. O primeiro é finalizar o processo no cliente (caso você tenha adicionado o parâmetro “-f” ao comando); para isso, use o comando “ps aux” para descobrir o número do processo seguido de um “kill <processo>” para finalizá-lo.

Em seguida, é necessário desativar a interface tap0 do servidor, rodando os comandos “brctl delif br0 tap0; ifconfig tap0 down”. É possível fazer isso a partir do próprio cliente, usando o comando: ssh -f root@servidor “brctl delif br0 tap0; ifconfig tap0 down”

Se você estiver acessando o servidor através de um domínio virtual, será necessário esperar o tempo de atualização até que o domínio passe a apontar para o novo IP. Para minimizar isso, configure o cliente do serviço para atualizar o IP do servidor a cada 1 minuto (ou o tempo mínimo permitido).

Se, mesmo depois de finalizado o processo no cliente e desativado a interface tap0 no servidor, você continuar recebendo um erro como este ao tentar restabelecer o túnel:

channel 1: open failed: administratively prohibited: open failed

… experimente reiniciar o serviço do SSH (no servidor). Esse erro acontece quando a instância anterior do SSH, usada para criar o túnel inicial continua ativa, bloqueando o endereço da interface mesmo depois que o cliente já foi desconectado.

Este é um exemplo de script (a ser executado no servidor A) que pode ser usado para criar uma VPN permanente. Depois de feita a configuração inicial, ele verifica periodicamente a conexão entre os dois servidores usando o ping e tenta restabelecer a conexão automaticamente. Mesmo que o modem ADSL do servidor B seja desligado e ele troque de endereço IP, o script faz com que o túnel seja restabelecido depois que o endereço do DNS dinâmico for atualizado.

#!/bin/sh

# Faz a configuração inicial
ssh -f -w 0:0 -o Tunnel=ethernet root@servidorB “ifconfig
tap0 0.0.0.0; brctl addif br0 tap0; ifconfig br0:1 192.168.0.253
sleep 10
ifconfig tap0 0.0.0.0 up
brctl addif br0 tap0
ifconfig br0:1 192.168.1.253

sleep 60

# Loop eterno, que verifica a conexão usando o ping
while [ “1” = “1” ]; do
# Cria o arquivo temporário, roda o ping, verifica, destrói o temporário
TMP=`mktemp /tmp/arq.XXXXXX`
ping -c 1 192.168.0.253 > $TMP
error=`cat $TMP | grep “100% packet loss”`
rm -f $TMP

# Restabelece o link em caso de interrupção
if [ -n “$error” ]; then
# Mata o processo no servidor A
id=`ps aux | grep “ssh -f -w 0:0″ | head -n 1 | sed -r ‘s/ +/ /g’ | cut -f 2-2 -d ” “`
kill $id
# Desativa a interface tap0 no servidor B
ssh root@servidorB “brctl delif br0 tap0; ifconfig tap0 down; /etc/init.d/ssh restart”
# Desativa a tap0 no servidor A
brctl delif br0 tap0; ifconfig tap0 down
sleep 2
# Recria o túnel
ssh -f -w 0:0 -o Tunnel=ethernet root@servidorB “ifconfig
tap0 0.0.0.0; brctl addif br0 tap0″
sleep 10
ifconfig tap0 0.0.0.0 up
brctl addif br0 tap0
ifconfig br0:1 192.168.1.253
# Este ping faz com que o bridge detecte a presença do servidor
ping -c 1 192.168.0.253
# Gera um log com os horários em que a conexão foi restabelecida

date >> /var/log/vpn.log
fi

sleep 60
done

Você pode notar que o script inclui vários sleeps e verificações redundantes, já que a idéia é que ele seja o mais confiável possível, tentando prever muitas coisas que podem dar errado. Ao usá-lo, você pode adaptá-lo às suas necessidades e ao seu gosto pessoal.

Sobre o Autor

Redes Sociais:

Deixe seu comentário

X