Gerando certificados e chaves

Terminada a edição do arquivo de configuração do servidor VPN – Matriz referente a VPN1, iremos realizar a criação dos certificados e chaves que serão utilizados pelos servidores da matriz e filial.

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:

# cp -a /usr/share/doc/openvpn-2.0.9/easy-rsa /etc/openvpn
# 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:

# vi vars

Altere as últimas linhas deixando as informações como as expostas a seguir:

export KEY_COUNTRY=BR
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:

# source vars

Execute o script a seguir para gerar o certificado raiz:

# ./build-ca

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:

# ./build-key-server server_matriz

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:

– Common Name: server_matriz

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:

# ./build-key server_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:

# ./build-dh

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.

# cd /etc/openvpn/keys
# 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:

# mkdir /etc/openvpn/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 ca.crt server_matriz.crt /etc/openvpn/certs/.
# 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/easy-rsa/keys/server_filial.crt root@200.100.50.50:/etc/openvpn/certs/.
# scp /etc/openvpn/certs/ca.crt root@200.100.50.50:/etc/openvpn/certs/.

Copiando chaves para a filial:

# scp /etc/openvpn/easy-rsa/keys/server_filial.key root@200.100.50.50:/etc/openvpn/keys/.
# scp /etc/openvpn/keys/fhmac.key root@200.100.50.50:/etc/openvpn/keys/.

Copiando parametros Diffie-Hellman para a filial:

# scp /etc/openvpn/dh1024.pem root@200.100.50.50:/etc/openvpn/.

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.

# cp /etc/openvpn/server_matriz_vpn1.ovpn /etc/openvpn/server_matriz_vpn2.ovpn
# vi /etc/openvpn/server_matriz_vpn2.ovpn

Altere o conteúdo conforme a seguir:

# Server VPN (Matriz)
# 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:

# cd /etc/rc.d/
# 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.

# cd /etc/rc.d/
# 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:

# cd /etc/rc.d
# vi ha-matriz-filial.sh

#!/bin/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:

# cd /etc/rc.d
# 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.

# vi /etc/rc.d/rc.local

modprobe tun
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/openvpn/server_matriz_vpn1.ovpn root@200.100.50.50:/etc/openvpn/server_filial_vpn1.ovpn
# 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).

Sobre o Autor

Redes Sociais:

Deixe seu comentário

X