Para facilitar a criação dos certificados e chaves faremos uso do conjunto de scripts chamado easy-rsa, que é instalado juntamente com o pacote do OpenVPN.
Sendo assim, copie o diretório easy-rsa que encontra-se no diretório /usr/share/doc/openvpn-2.0.9 para dentro do diretório /etc/openvpn, em seguida acesse o diretório criado:
# cd /etc/openvpn/easy-rsa
Execute o script build-ca para procedermos com a criação da autoridade certificadora. Será gerado o certificado raiz que permitirá a partir dele, gerar os certificados utilizados pelo servidor e clientes durante o estabelecimento das conexões VPN.
Conforme Morimoto informa em seu livro “Servidores Linux – Guia Prático“, no capítulo sobre OpenVPN, muitos administradores realizam a etapa de criação do certificado raiz, certificados e chaves do servidor e clientes em uma estação de trabalho separada e sem conexão de rede, devido a importância que o certificado raiz possui dentro de uma infra-estrutura de certificados e chaves X509, ou seja, de posse dele você poderia gerar certificados adicionais e através deles realizar acesso a VPN.
Abra o arquivo vars, pois iremos inserir algumas informações que serão utilizadas na criação dos certificados:
Altere as últimas linhas deixando as informações como as expostas a seguir:
export KEY_PROVINCE=SP
export KEY_CITY=SAO_SIMAO
export KEY_ORG=CYBERDYNE
export KEY_EMAIL=dyson@cyberdyne.com
Execute o comando source para carregar o script vars e tornar as variáveis dele disponíveis para serem utilizadas pelos scripts que executaremos a seguir:
Execute o script a seguir para gerar o certificado raiz:
O script irá solicitar diversas informações que farão parte do certificado raiz, deste modo,
iremos confirmas várias informações previamente carregadas das variáveis de ambientes criadas durante a execução do script vars, deste modo, pressione ENTER uma a uma, mas com a devida atenção quando for solicitada a informação Common Name preenchendo-a, por exemplo, com: CA-Cyberdyne.
Deste modo, foram criados os arquivos ca.crt, ca.key, index.txt e serial, sendo que, os arquivos ca.crt e ca.key são utilizados durante a criação dos certificados e chaves, mas ao término do processo, apenas o arquivo ca.crt será utilizado no daemon do OpenVPN (na matriz e filial), copie ambos os arquivos para um local seguro (um pendrive com partição criptografada, por exemplo) em seguida exclua apenas o arquivo ca.key.
Realize agora a criação do certificado do servidor, executando o comando a seguir:
Serão solicitadas novamente, informações semelhantes as utilizadas na criação do certificado raiz da nossa autoridade certificadora, onde poderemos proceder da mesma forma que antes, mas preenchendo o campo Common Name:
A seguir será solicitada a senha para o certificado, neste caso pressione ENTER, pois o uso de uma senha iria prejudicar a automatização do carregamento dos daemons do OpenVPN na matriz e na filial, pois o uso do certificado exigiria a senha, envolvendo uma intervenção manual.
Na próxima informação requisitada (optional company name) pressione ENTER novamente.
Pressione “y” para assinar o certificado, e em seguida “y”novamente para efetivar a gravação das informações nos arquivos de certificado e chaves.
Agora iremos gerar o certificado e chave do servidor da filial:
Realize o preenchimento assim como ocorreu na criação do certificado do servidor, salientando que o campo Common Name seja preenchido, por exemplo, com o nome: server_filial.
Crie o arquivo de chave para o algoritmo de troca de chaves segura (Diffie-Hellman), através do comando:
Para finalizar a criação de certificados e chaves, geraremos uma chave estática que será utilizada pelo nosso firewall HMAC, como proteção a ataques do tipo DoS.
# openvpn -genkey -secret fhmac.key
Tanto no servidor da matriz como da filial, iremos necessitar de dois sub-diretórios para armazenar os certificados e as chaves (apenas como forma de organização), um deles já existe (o diretório keys), portanto criaremos o sub-diretório certs:
Mova os arquivos de certificados e chaves utilizados pelo servidor da matriz para os diretórios correspondentes aos informados no arquivo de configuração do OpenVPN:
# mv server_matriz.key fhmac.key /etc/openvpn/keys/.
# mv dh1024.pem /etc/openvpn/.
No servidor da matriz realize a cópia dos certificados, chaves e parametros Diffie-Hellman para o servidor da filial. Considerando que faremos isso pela Internet, portanto:
Copiando certificados para filial:
# scp /etc/openvpn/certs/ca.crt root@200.100.50.50:/etc/openvpn/certs/.
Copiando chaves para a filial:
# scp /etc/openvpn/keys/fhmac.key root@200.100.50.50:/etc/openvpn/keys/.
Copiando parametros Diffie-Hellman para a filial:
Criaremos o arquivo de configuração referente a VPN2 com o nome sugerido server_matriz_vpn2.ovpn.
Poderíamos criar chaves e certificados diferentes para o servidor matriz utilizar na VPN2, mas neste caso, iremos utilizar os mesmos certificados e chaves.
Utilizaremos o arquivo criado anteriormente como base para a VPN2.
# vi /etc/openvpn/server_matriz_vpn2.ovpn
Altere o conteúdo conforme a seguir:
# VPN2 – Link Secundário (ADSL)
# Interface VPN
dev tun1
…
# Endereço que o servidor matriz estará em listening (interface eth1)
local 200.100.50.50
# Porta Origem e Destino
port 63010
…
ifconfig 172.31.0.1 172.31.0.2
…
# Arquivos de log
status /var/log/openvpn-status-vpn2.log
log-append /var/log/openvpn-vpn2.log
Criaremos os shell scripts de inicialização dos daemons do OpenVPN para ambas as VPN’s.
Estarei considerando que o servidor já possui o roteamento de pacotes ativo, bem como, outro script de firewall aplicando outras regras, pois, o shell script abaixo garante apenas que a conexão ao daemon seja estabelecida na sua respectiva porta, bem como, permite que o roteamento através da interface VPN seja autorizado no firewall, ou seja, que o tráfefo vindo da LAN atrás do servidor da matriz, seja roteado das VPN’s para a LAN atrás do servidor da filial e vice-versa.
Shell script de inicialização do daemon OpenVPN para a VPN1:
# vi vpn1.sh
#!/bin/sh
vpn=”63000″
LAN_VPN=”tun0″
LAN_FILIAL=”192.168.1.0/24″
vpn_start(){
echo “Inserindo regras no Firewall…”
iptables -I INPUT -p udp –dport $vpn -j ACCEPT
iptables -I INPUT -i $LAN_VPN -j ACCEPT
iptables -I FORWARD -i $LAN_VPN -j ACCEPT
iptables -I FORWARD -o $LAN_VPN -j ACCEPT
echo “Inicializando daemon do OpenVPN”
/usr/local/sbin/openvpn –config /etc/openvpn/server_matriz_vpn1.ovpn
sleep 3
route add -net $LAN_FILIAL dev $LAN_VPN
}
vpn_stop(){
echo “Removendo regras no Firewall…”
iptables -D INPUT -p udp –dport $vpn -j ACCEPT
iptables -D INPUT -i $LAN_VPN -j ACCEPT
iptables -D FORWARD -i $LAN_VPN -j ACCEPT
#iptables -D FORWARD -o $LAN_VPN -j ACCEPT
echo “Finalizando daemon do OpenVPN”
pid=`netstat -a -u -n -p |grep :$vpn |awk -F: ‘{ print $3 }’ |cut -f2 -d* |cut -f1 -d/`
kill -9 $pid
}
vpn_restart(){
vpn_stop
vpn_start
}
case “$1” in
‘start’)
vpn_start
;;
‘stop’)
vpn_stop
;;
‘restart’)
vpn_restart
;;
*)
echo “Uso: $0 start|stop|restart”
esac
Shell script de inicialização do daemon OpenVPN para a VPN2:
Iremos aproveitar o conteúdo do arquivo vpn1.sh e alterar alguns trechos do novo arquivo vpn2.sh.
# cp vpn1.sh vpn2.sh
# vi vpn2.sh
#!/bin/sh
vpn=”63010″
LAN_VPN=”tun1″
…
/usr/local/sbin/openvpn –config /etc/openvpn/server_matriz_vpn2.ovpn
sleep 3
# route add -net $LAN_FILIAL dev $LAN_VPN
…
Repare que, diferente do script vpn1.sh, o script vpn2.sh teve a linha route add -net $LAN_FILIAL dev $LAN_VPN comentada. A idéia é que quando os scripts forem carregados, apenas o script vpn1.sh adicione uma rota para a rede da filial usando a interface tun0, ou seja, que exista apenas uma rota ativa para a LAN da filial, onde a mudança automática de rota para interface tun1 será executada pelo nosso script de alta disponibilidade, apenas quando ocorrer falha com a conexão referente a VPN1.
Criaremos agora o arquivo de script de alta disponibilidade:
# vi ha-matriz-filial.sh
# HA – Matriz -> Filial
#
# por Waldemar Dibiazi Junior <waldemar_jr@hotmail.com>
#
LAN_FILIAL=”192.168.1.0/24″
r=`type -p route`
p=`type -p ping`
log=”/var/log/ha_vpn-matriz-filial.log”
#Numero máximo de falhas consecutivas para poder realizar mudança de rota para outra interface
fail_max=”3″
# Numero minimo de respostas positivas consecutivas para retornar para a interface primaria
succ_min=”3″
#Intervalo de tempo para checagem do link primário (Heartbeat)
check_delay=”1.3″
#Intervalo de tempo para checagem de retorno do link primário (Heartbeat)
check_delay_after_fail=”0.7″
# Intervalo de envio de cada pacote ICMP (tipo echo request)
icmp_delay=”1″
# Contadores de falha e sucesso
fail_count=”0″
succ_count=”0″
# Interfaces VPN (matriz) e endereços IP das interfaces VPN (filial)
if_addr_server[0]=”tun0:172.16.0.2″
if_addr_server[1]=”tun1:172.31.0.2″
#Especifica qual das interfaces VPN é a primária
primary_route=”0″ # tun0
route=`echo $primary_route`
get_date(){
d=`date +%d/%m/%Y`
}
get_time(){
t=`date +%H:%M:%S`
}
get_ip(){
ip=`echo ${if_addr_server[$route]} |cut -f2 -d:`
}
get_tun(){
tun=`echo ${if_addr_server[$route]} |cut -f1 -d:`
}
drop_route(){
# Obtendo valor atual de Rota
get_tun
$r del -net $LAN_FILIAL dev $tun 2> /dev/null
}
add_route(){
# Obtendo valor atual da Rota
get_tun
$r add -net $LAN_FILIAL dev $tun 2> /dev/null
}
get_date
get_time
echo “($d – $t) – Iniciando daemon de monitoramento das conexoes VPN…” >> $log
# Obtendo valores iniciais de IP e Rota
get_ip
get_tun
while [ true ]; do
if [ $route -eq $primary_route ]; then
get_date; get_time
echo “($d – $t) – Rota $route ativa” >> $log
while [ $fail_count -lt $fail_max ]; do
$p $ip -s 1 -c 1 -i $icmp_delay 1> /dev/null 2> /dev/null
if (( $? != 0 )); then
((fail_count++))
get_date; get_time
echo “($d – $t) – Falha $fail_count na rota $route” >> $log
else
fail_count=”0″
fi
sleep $check_delay
done
get_date; get_time
echo “($d – $t) – Falhas na rota $route excedidas” >> $log
# Excluindo rota
drop_route
# Zerando contador de falhas
fail_count=0
# Setando para a rota 1
route=”1″
add_route
# adicionando rota 1
else
# checando retorno do link na rota primária
# setando IP para rota primária para ser utilizado no monitoramento de retorno do
# link
get_date; get_time
echo “($d – $t) – Aguardando retorno de conexão para rota $primary_route:” >> $log
# Aguardando numero de sucesso consecutivos mínimos ocorrer na rota primaria
while [ $succ_count -lt $succ_min ]; do
$p $ip -s 1 -c 1 -i $icmp_delay 1> /dev/null 2> /dev/null
if (( $? == 0 )); then
((succ_count=succ_count+1))
else
succ_count=”0″
fi
sleep $check_delay_after_fail
done
get_date; get_time
echo “($d – $t) – Rota $primary_route teve retorno de link” >> $log
# Excluindo rota para link secundário
drop_route
# Zerando contador de exito
succ_count=”0″
# Setando rota para rota primária
route=`echo $primary_route`
# Adicionando rota
add_route
fi
sleep $check_delay
done
A ideia geral do script é bastante simples, onde ele realiza o envio de pacotes ICMP echo request (ping) através da conexão VPN1 para o endereço IP do servidor da filial (IP da interface VPN1).
Caso ocorra um número de falhas (por exemplo, 3) o script irá excluir a rota para a LAN da filial através da VPN1, e adicionará uma rota para a LAN da filial através da VPN2.
Entretanto, após esse procedimento o script irá continuar enviando pings para o servidor da filial através da VPN1, e caso ocorra um número mínimo e consecutivo de eventos de sucesso (recebimento de respostas nesses pings), o script irá excluir a rota de contingência e adicionar novamente uma rota para LAN da filial através da VPN1 (estado inicial).
Procurei estruturar o script utilizando diversas funções e variáveis para facilitar sua adaptação.
Este script necessita estar em execução em ambos os servidores o que parece lógico, pois, de nada adiantaria o servidor da matriz adicionar uma rota para a LAN da filial por uma conexão que esteja funcional, e o servidor da filial não mudar a rota para a LAN da matriz também para uma conexão funcional.
Modifique as permissões dos três scripts criados (vpn1.sh, vpn2.sh e ha-matriz-filial.sh) para que possuam permissão de execução:
# chmod +x vpn1.sh vpn2.sh ha-matriz-filial.sh
Altere o arquivo /etc/rc.d/rc.local para que a partir dele os três scripts anteriores possam ser executados durante a inicialização do sistema.
sleep 1
/etc/rc.d/vpn1.sh start
sleep 2
/etc/rc.d/vpn2.sh start
sleep 5
sh /etc/rc.d/ha-matriz-filial.sh &
Agora iremos realizar a cópia dos seguintes arquivos para o servidor da filial:
- server_matriz_vpn1.ovpn
- vpn1.sh
- ha-matriz-filial.sh
- rc.local
# scp /etc/rc.d/vpn1.sh root@200.100.50.50:/etc/rc.d/vpn1.sh
# scp /etc/rc.d/ha-matriz.filial.sh root@200.100.50.50:/etc/rc.d/ha-filial-matriz.sh
# scp /etc/rc.d/rc.local root@200.100.50.50:/etc/rc.d/rc.local
Todo o processo de configuração do servidor matriz está terminado, deste modo, realizaremos a configuração do servidor filial, aproveitando a configuração realizada na matriz.
O arquivo de configuração do servidor OpenVPN (matriz) apresentará poucas diferenças em relação ao arquivo do cliente OpenVPN (filial).
Deixe seu comentário