você está aqui: Home  → Arquivo de Mensagens Programação Shell Linux: Inscrições Abertas

OpenVPN com os clientes na mesma rede

Colaboração: Tiago Cruz

Data de Publicação: 07 de Agosto de 2009

Um tempo atrás escrevi um artigo sobre VPNs que abordava as vantagens e desvantagens do PPTP, e também um passo-a-passo para subir um OpenVPN autenticando com certificados e etc.

O artigo ainda está disponível na Web, e chama-se Implementando soluções de VPN. O que eu não sabia era que, embora o artigo seja meio antigo (Março de 2006) ele ainda continua funcional! Eu fui seguindo-o passo-a-passo, copiando e colando os comandos e em 15 minutos eu estava conectado à uma VPN usando roteamento com o device tun !

O modo de como esta VPN funciona é bem bacana, pois separa a sua rede servidora (ex: 192.168.0.x) da rede do cliente conectado via OpenVPN, criando uma rede como inválida qualquer como 10.8.0.x. O acesso de uma rede para a outra é feita via roteamento, descantando toda aquela nhaca de broadcast, netbios e etc.

Porém, desta vez a necessidade era diferente. Eu precisava realmente estar dentro da rede servidora, pois de dentro da rede era possível o acesso à uma outra rede, no caso uma LP com o México. A lambança era mais ou menos assim:

Rede_Mexico = 10.95.0.0/16
Rede_Servidor = 10.10.10.0/24
Rede_VPN = 10.8.0.0/24

Utilizando o device tun a rede VPN até chegava na rede do Servidor, porém, não chegava até a rede do México. Não duvido que seja possível de ser feito usando alguns roteamentos malucos, porém consegui resolver o problema apelando para bridges no Linux, usando o device tap .

O Carlos Morimoto havia postado um artigo chamado Criando bridges no OpenVPN, o qual me foi muito útil, pois assim o OpenVPN conectava diretamente na rede 10.10.10.0/24 me enviando um IP que eu mesmo posso escolher via DHCP:

server-bridge 10.10.10.200 255.255.255.0 10.10.10.210 10.10.10.220

No exemplo acima, 10.10.10.200/24 será o IP do servidor, e 10.10.10.210 até 10.10.10.220 será o range oferecido aos clientes remotos que conectarem usando o OpenVPN.

Porém, para que tudo funcione a contento é necessário criar uma Bridge entre as interfaces eth0 e tap0, para que todo mundo se converse e se enxergue:

# brctl show
bridge name    bridge id               STP enabled     interfaces
br0            8000.00188be16805       no              eth0

Neste caso, o IP não ficará nem na eth0 e nem na tap0, mas sim na br0:

# ifconfig
br0       Link encap:Ethernet  HWaddr 00:28:0b:ef:58:75
        inet addr:10.10.10.2  Bcast:10.10.10.255  Mask:255.255.255.0
        inet6 addr: fe80::218:8bff:fee1:6805/64 Scope:Link

Bom, chega de teoria. Os links acima possuem todo o background necessário para que você entenda a coisa passo-a-passo. Vamos logo para o que interessa: Os arquivos de configuração:

Arquivo openvpn.conf no servidor:

# /etc/openvpn/openvpn.conf
# Objetivo: Clientes remotos conectarem no mesmo range da LAN local sem roteamento
proto udp
port 1194

# bridge utiliza a interface "tap" em vez da "tun"
# (o tap transmite pacotes de broadcast e o tun não)
dev tap0

# Faixa de IPs para os clientes
server-bridge 10.10.10.200 255.255.255.0 10.10.10.210 10.10.10.220

# No cliente eh necessário um
# route add -net 10.95.0.0 netmask 255.255.0.0 gw 10.10.10.1 tap0
# para acessar a LP no Mexico 10.95.x.x
push "route 10.95.0.0 255.255.0.0 10.10.10.1"

# Compressão e persistência
comp-lzo
keepalive 10 120
ifconfig-pool-persist /etc/openvpn/ipp.txt

# Certificados
tls-server
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem

# Logs e etc
status      /var/log/openvpn-status.log
log         /var/log/openvpn.log
log-append  /var/log/openvpn.log
verb 3

# Bridges para simular um mesmo switch entre a tap0 e a eth0
up /etc/openvpn/bridge-start
down /etc/openvpn/bridge-stop

Arquivo bridge-start:

#!/bin/bash
# /etc/openvpn/bridge-start

br="br0"
tap="tap0"
eth="eth0"
eth_ip="10.10.10.2"
eth_gw="10.10.10.1"
eth_netmask="255.255.255.0"
eth_broadcast="10.10.10.255"

for t in $tap; do
openvpn --mktun --dev $t
done

brctl addbr $br
brctl addif $br $eth

for t in $tap; do
brctl addif $br $t
done

for t in $tap; do
ifconfig $t 0.0.0.0 promisc up
done

ifconfig $eth 0.0.0.0 promisc up
ifconfig $br $eth_ip netmask $eth_netmask broadcast $eth_broadcast
#route add default gw $eth_gw dev $br
route add -net 10.95.0.0 netmask 255.255.0.0 gw 10.10.10.1 br0

iptables -A INPUT -i tap0 -j ACCEPT
iptables -A INPUT -i br0 -j ACCEPT
iptables -A FORWARD -i br0 -j ACCEPT

Arquivo bridge-stop:

#!/bin/bash
# /etc/openvpn/bridge-stop

br="br0"
tap="tap0"
ifconfig $br down
brctl delbr $br

for t in $tap; do
openvpn --rmtun --dev $t
done

route del -net 10.95.0.0 netmask 255.255.0.0 gw 10.10.10.1 br0
ifdown eth0
ifup eth0
route add -net 10.95.0.0 netmask 255.255.0.0 gw 10.10.10.1 eth0

Arquivo no cliente:

# Cliente pode ser Linux ou Windows
remote 200.200.200.100
proto udp
port 1194
client
pull
dev tap
comp-lzo
keepalive 10 120
tls-client
ca ca.crt
cert tiagocruz.crt
key tiagocruz.key
ns-cert-type server
verb 3

O resultado pode ser visto nos screnshoots abaixo:

Como você deve ter percebido, apenas alguns ajustes foram necessários nos scripts que iniciam e derrubam as bridges. A parte mais chata foi automatizar a criação de rotas estáticas nos clientes, para que não fosse necessário usar o route add em toda a conexão. A linha do push resolveu este problema, inclusive apontando a rota para um host que diferente do servidor de VPN, que é o padrão.

Segue uma screnshoot mostrando o antes, o durante e o depois do super device tap :)

Nos testes foram utilizadas as versões OpenVPN 2.1_rc7 x86_64-pc-linux-gnu no servidor rodando Ubuntu 8.04.3 LTS e o cliente OpenVPN 2.1_rc11 i486-pc-linux-gnu em um Ubuntu 9.04.

Também foi possível conectar usando a GUI do OpenVPN para Windows.

Abraços e até o próximo post! 8)

Publicado originalmente em http://everlinux.com/blog/2009/07/18/openvpn-com-os-clientes-na-mesma-rede


Veja a relação completa dos artigos de Tiago Cruz