sexta-feira, 5 de setembro de 2008

OpenVPN para acesso remoto (road-warrior)

Uma VPN nada mais é do que uma extensão de sua rede, onde é possível acessar os recursos nela disponíveis de forma remota! Nela podemos aplicar políticas de segurança e limitar acesso baseado em vários fatores que serão definidos pelo administrador de redes tentando refletir uma possível política de segurança da empresa. A sigla VPN significa Virtual Private Network, que em tradução livre é Rede Privada Virtual.

Em minha opnião este é um recurso muito importante para um administrador de redes. É a possibilidade de se ter acesso a ela de forma remota e pode ser feita de maneira segura, se assim for configurado! Quando precisei implementar minha primeira VPN pesquisei bastante para verificar qual software se adequaria melhor as minhas necessidades!

Básicamente eu encontrei o OpenVPN e softwares baseados em IPSec! Entre os dois acabei escolhendo o primeiro. Minha escolha foi baseada em alguns fatores que para minhas necessidades ele se encaixava melhor, como por exemplo:
  • Possui suporte a criptografia usando SSL.
  • Não tem problemas com NAT (IPSec precisa agregar um encapsulamento extra para que funcione corretamente, técnica conhecida como Nat-T )
Dentre estas o que mais me inclinou para que utilizasse OpenVPN foi a questão de funcionar sem problemas através de um NAT. Pois a principal utilização, pelo menos aqui em minha empresa, é dar acesso aos servidores para os diretores, CEOs e CTOs que estão sempre em viagem e concerteza estarão utilizando uma conexão dessas.

Aqui utilizei um Ubuntu 8.04 LTS para fazer a instalação! Preferi este por possuir a versão mais nova (2.x) em seu repositório! Como sempre a instalação foi simples e sem complicação e tomei por base para minhas configurações o site oficial deles OpenVPN.net. Para instalar o pacote executei o seguinte comando:
aptitude install openvpn openssl openssl-blacklist openvpn-blacklist liblzo2-2
Com o pacote instalado você terá um novo diretório localizado em /etc/openvpn. Porém instalar o programa nada fará, precisamos criar os certificados para o servidor, para os clientes e um extra que é o da Autoridade Certificadora (CA). O OpenVPN quando instalado possui um conjunto de scripts que se chama easy-rsa e será com eles que iremos gerar os certificados que precisamos para criar nossa VPN! Estes scripts estão localizados em /usr/share/doc/openvpn/examples/easy-rsa! Em minha instalação eu copiei o diretório para dentro do /etc/openvpn.

Antes de tudo é necessário editar um arquivo que esta localizado dentro do diretorio easy-rsa que se chama vars. Ali estão contidos alguns parâmetros essenciais para você criar os seus certificados. Então edite este arquivo e configure ele da forma que você precisar, normalmente estas serão as variáveis que você precisará modificar:
  • KEY_SIZE (Tamanho da chave, recomendado 1024)
  • CA_EXPIRE (Dias para a chave da CA expirar, padrão 3650)
  • KEY_EXPIRE (Dias para o certificado expirar, padrão 3650)
  • KEY_COUNTRY (Seu pais)
  • KEY_PROVINCE (Seu estado)
  • KEY_CITY (Sua cidade)
  • KEY_ORG (Nome da sua organização)
  • KEY_EMAIL (E-mail da pessoa)
Com isso configurado é necessário criar nossa CA, para fazer isso existe o script chamado build-ca porém eu recomendo acrescentar uma linha no inicio do script que é a:
. /etc/openvpn/easy-rsa/vars
Desta forma não será mais necessário executar este arquivo toda vez que for preciso criar este certificado, faremos o mesmo com os outros que usaremos! Feito isto é executar o script:
/etc/openvpn/easy-rsa$ sudo ./build-ca
Você verá a criação do certificado e será pedido que você forneça alguns dados, muitos dos quais foram configurados quando editamos o arquivo vars! A saída deve ser similar a esta:
Country Name (2 letter code) [BR]:
State or Province Name (full name) [SC]:
Locality Name (eg, city) [Florianopolis]:
Organization Name (eg, company) [SuaEmpresa]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:OpenVPN-CA
Email Address [admin@suaempresa.com.br]:

Agora temos nossa CA gerada e podemos seguir em frente criando o certificado para o servidor e para nossos clientes. Para o do servidor o procedimento é similar porém é necessário usar outro script que se chama build-key-server e é necessário acrescentar aquela linha no inicio do script. Feito isso execute o script passando como parâmetro o nome do certificado:
/etc/openvpn/easy-rsa$ sudo ./build-key-server servidor
Isso irá gerar mensagens como a anterior e é preciso configurar o CommonName que DEVE SER ÚNICO em todos os certificados gerados. Aqui neste passo (e com os clientes que veremos a frente) é necessário ainda confirmar positivamente duas perguntas extras:
Sign the certificate? [y/n]
1 out of 1 certificate requests certified, commit? [y/n]
Essas confirmações são importantes pois ali é feita a assinatura do certificado do servidor com a da nossa Autoridade Certificadora. Para os clientes é o mesmo procedimento do servidor porém agora use o script build-key e não esqueça de adicionar a linha mencionada anteriormente! O comando será como o seguinte:
/etc/openvpn/easy-rsa$ sudo ./build-key cliente{n}

Com esses certificados criados é necessário agora gerar os parâmetros de Diffie-Hellman, que é utilizado para a troca de chaves de forma segura quando não se possui um canal seguro. Este demora muuuito para ser gerado (pelo menos aqui em meu computador que possui um hardware bem simples para fazer a tarefa de VPN) então recomendo executa-lo e ir fazer outra coisa! O script a ser usado é este build-dh e sempre é necessário agregar a linha no inicio do arquivo antes de executa-lo:
/etc/openvpn/easy-rsa$ sudo ./build-dh
Com o Diffie-Hellman gerado é hora de gerar nossa última chave que será útil para agregar uma camada extra de segurança a nossa VPN que segundo o site oficial agrega os seguintes benefícios:
  • Evita ataques DoS ou ataque de flooding na porta do OpenVPN
  • Evita vulnerabilidades de buffer-overflow
  • Evita iniciação do handshake SSL/TLS em máquinas não autorizadas
  • Evita port scanning para determinar quais portas estão em listening
Para agregar esta nova camada de segurança a sua instalação execute o seguinte comando:
sudo openvpn --genkey --secret /etc/openvpn/easy-rsa/keys/ta.key
Finalmente temos tudo que precisamos para começar a configurar nossa VPN. Agora precisamos esclarecer algumas coisas sobre os arquivos criados até agora:
  • ca.crt - servidor e clientes devem possuir este arquivo
  • ca.key - secreto, melhor em um computador isolado
  • dh{n}.pem - somente o servidor
  • servidor.crt - somente o servidor
  • servidor.key - secreto, somente o servidor
  • cliente{n}.crt - somente este cliente
  • cliente{n}.key - secreto, somente este cliente
Agora precisamos criar o arquivo de configuração do servidor e o do nosso usuário. O exemplo que estamos criando aqui pode conter múltiplos usuários. Basicamente o arquivo de configuração do servidor deverá ser assim:
mode server - identifica como servidor e habilita multi-cliente
local 2.2.2.2 - endereço no qual o software deve escutar (opcional)
port 1194 - porta udp/tcp local/remota para conexões
proto udp - protocolo utilizado, udp possibilita maior desempenho
dev tun - vamos usar roteado, então tun
user nobody - usuário no qual será executado o programa
group nogroup - grupo no qual será executado o programa
client-config-dir /etc/openvpn/ccd - diretório dos clientes
ca /etc/openvpn/easy-rsa/keys/ca.crt - certificado ca
cert /etc/openvpn/easy-rsa/keys/servidor.crt - certificado
key /etc/openvpn/easy-rsa/keys/servidor.key - chave servidor
dh /etc/openvpn/easy-rsa/keys/dh1024.pem - diffie hellman
tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0 - servidor = "0"
cipher AES-128-CBC - algoritmo de criptografia
comp-lzo - habilita compressão dos pacotes, melhora desempenho
persist-key - (ver manual)
persist-tun - (ver manual)
server 11.12.13.0 255.255.255.0 - rede clientes
route 14.15.16.0 255.255.255.0 - rede clientes extra (opcional)
push "route 17.18.19.0 255.255.255.0" - rede interna exportada
push "route 20.21.22.0 255.255.255.0" - rede interna exportada
keepalive 10 120 - mantém conexões ativas
verb 2 - nivel de logs gerados
O arquivo do cliente não difere muito e deve ser parecido com este:
client - identifica como cliente
resolv-retry 20 - reintentar por n segundos
nobind - (ver manual)
mute-replay-warnings - (ver manual)
ns-cert-type server - (ver manual)
port 1194 - porta udp/tcp local/remota para conexões
proto udp - protocolo utilizado, udp possibilita maior desempenho
dev tun - vamos usar roteado, então tun
cert suaempresa/cliente1.crt - certificado
key suaempresa/cliente1.key - chave cliente
ca suaempresa/ca.crt - certificado ca
tls-auth suaempresa/ta.key 1 - cliente = "1"
keepalive 10 120 - mantém conexões ativas
cipher AES-128-CBC - algoritmo de criptografia
comp-lzo - habilita compressão dos pacotes, melhora desempenho
persist-key - (ver manual)
persist-tun - (ver manual)
verb 2 - nivel de logs gerados
remote 2.2.2.2 1194 - servidor e porta para conexão
Estes arquivos são totalmente funcionais, porém ainda falta configurar o endereço ip que seu cliente terá, os endereços ip do servidor e cliente devem ser escolhidos de forma a refletir uma mascara /30 como esta representado por esta tabela:
[ 1, 2] [ 5, 6] [ 9, 10] [ 13, 14] [ 17, 18]
[ 21, 22] [ 25, 26] [ 29, 30] [ 33, 34] [ 37, 38]
[ 41, 42] [ 45, 46] [ 49, 50] [ 53, 54] [ 57, 58]
[ 61, 62] [ 65, 66] [ 69, 70] [ 73, 74] [ 77, 78]
[ 81, 82] [ 85, 86] [ 89, 90] [ 93, 94] [ 97, 98]
[101,102] [105,106] [109,110] [113,114] [117,118]
[121,122] [125,126] [129,130] [133,134] [137,138]
[141,142] [145,146] [149,150] [153,154] [157,158]
[161,162] [165,166] [169,170] [173,174] [177,178]
[181,182] [185,186] [189,190] [193,194] [197,198]
[201,202] [205,206] [209,210] [213,214] [217,218]
[221,222] [225,226] [229,230] [233,234] [237,238]
[241,242] [245,246] [249,250] [253,254]
Dentro do diretório de configuração dos clientes, definido no arquivo de configuração do servidor, é preciso criar um arquivo com o mesmo CommonName escolhido na hora de gerar os certificados dos clientes. No nosso caso deverá existir um arquivo chamado /etc/openvpn/ccd/cliente1. Dentro deste arquivo iremos colocar a configuração ip e futuramente iremos usar este arquivo para incrementar as possibilidades de nossa VPN:
ifconfig-push 11.12.13.2 11.12.13.1
O valor da esquerda (par) é o ip que será entregue ao cliente e o da direita (impar) ip correspondente do servidor. Com este novo arquivo no lugar é necessário reiniciar o servidor para que as novas informações entrem em vigor! Com este tipo de configuração é possível criar regras de acesso aos recursos compartilhados de sua rede utilizando iptables.

Para o cliente é necessário copiar os certificados gerados para ele que são:
  1. cliente1.crt
  2. cliente1.key
  3. ta.key
  4. ca.crt
Com estes e o arquivo de configuração é possível estabelecer uma conexão VPN até seu servidor você estando em qualquer lugar onde possua um acesso a internet! Se você precisar de mais clientes é só repetir o mesmo procedimento para o cliente, obviamente, e distribuir os arquivos ali citados! Os programas que eu utilizei para os computadores do pessoal aqui foram citados no inicio deste artigo. Usando estas configurações será possível criar uma topologia similar a que esta representada pela figura abaixo:



Pretendo estar escrevendo outros artigos sobre OpenVPN com o intúito de ajudar as pessoas a criarem suas próprias VPNs. Quero descrever como conectar outros servidores OpenVPN que possuam rede interna e que esta possa usar os recursos compartilhados do servidor principal (caso matriz-filial), como possibilitar que vários clientes conectados a um servidor principal possam se comunicar diretamente. Creio que estes temas podem ser úteis e de interesse para várias pessoas.

Uma última consideração é que se o servidor onde você instalou a VPN não for o gateway de sua rede é necessário configurar rotas adicionais nos servidores para que eles saibam como retornar os pacotes!

Caso exista alguma dúvida, crítica ou sugestão para este ou outros artigos por favor deixe um comentário ou me envie um e-mail!

Nenhum comentário: