quarta-feira, 24 de setembro de 2008

OpenVPN - grafico de usuarios conectados e trafego VPN com Cacti, SNMP e Shell Script

Faz algum tempo fiz um artigo sobre como instalar a OpenVPN (OpenVPN para acesso remoto (road-warrior)) para acesso remoto e até então, eu não tinha visto nada para estar monitorando minha VPN, onde fosse possível ter informações de quantos usuários estão conectados em um determinado momento ou ainda quanto tráfego passou por ela. Não estou dizendo o tráfego da interface eth0, eth1, e sim o que é transmitido dentro dos túneis criptografados onde representará realmente o que um usuário utilizou.

Pensando neste cenário iniciei uma busca por alternativas, a interface de gerenciamento da OpenVPN não é muito amigável e também não ajuda muito para tirar informações utilizando algum script. Acabei encontrando que a própria OpenVPN escreve um arquivo seu status atual a cada determinado tempo. Em minha instalação encontrei este arquivo executando um ps para visualizar os processos e verifiquei o parâmetro abaixo:
--status /var/run/openvpn.openvpn.status 10
Isso indica que o arquivo será escrito no diretório acima e atualizado a cada 10 segundos. Creio que é tempo suficiente para ter um arquivo que possa refletir o estado atual da nossa VPN! Ele é assim:

OpenVPN CLIENT LIST
Updated,Tue Sep 23 14:17:25 2008
CN,Real Addr,Bytes Rece,Bytes Sent,Connected Since
andre,216.106.173.161:1772,24215,26619,Tue Sep 23 13:27:50 2008
ROUTING TABLE
Virtual Address,Common Name,Real Address,Last Ref
10.10.20.2,andre,216.106.173.161:1772,Tue Sep 23 13:27:59 2008
GLOBAL STATS
Max bcast/mcast queue length,0
END

A linha que nos interessa é a 4 (de cima para baixo) onde estão descritas informações sobre os usuários conectados. Ali é possível encontrar os bytes enviados/recebidos e podemos também saber quantos usuários estão conectados em um determinado momento, ou seja, temos as informações que necessitamos. Minha necessidade era a de disponibilizar esse gráfico da maneira mais fácil, e como aqui temos uma instalação do Cacti essa foi a melhor opção, porém ele não está instalado no mesmo servidor da VPN, obviamente, então eu precisava transmitir esses dados através da rede. A topologia neste caso era a seguinte:


Pesquisando na internet encontrei uma funcionalidade do agente snmpd onde é possível executar um Shell Script e retornar essas informações em um OID (Object IDentifier ou Identificador de Objeto) reservado para uso privado. Como meu servidor OpenVPN já possuía este instalado não foi necessário nenhum software adicional, só era necessário ajustar a configuração. O arquivo final ficou dessa forma:
rocommunity public
syslocation Brasil
syscontact Andre Zenun
extend .1.3.6.1.4.1.2021.50 vpnstats /bin/bash /etc/snmp/openvpn_statistics.sh
A linha responsável por fazer a transferência do resultado do script para o agente é a extend. O OID que está ali foi utilizado em um exemplo dentro do arquivo de configuração e sempre deve ser este. Após o identificador é necessário dar um nome, que no meu caso foi vpnstats um programa a ser executado, /bin/bash, e um parâmetro para ele /etc/snmp/openvpn_statistics.sh. É muito importante disponibilizar este arquivo em um local onde o usuário do daemon snmp possa executar. No meu caso precisei acrescentar uma entrada no arquivo sudoers para que fosse possível a execução do comando egrep. O script utilizado está disponibilizado neste link. A entrada no arquivo de configuração /etc/sudoers é muito simples:
snmp ALL = NOPASSWD:/bin/egrep
Muito bem, temos o script, configuramos o sudoers, acrescentamos a linha no arquivo de configuração do snmp e reiniciamos nosso agente. Com isso é possível executar um comando snmp verificando a saida do nosso script que será mais ou menos assim:
andre@linux:~$ snmpwalk -v2c -c public ipvpn -On .1.3.6.1.4.1.2021.50

.1.3.6.1.4.1.2021.50.2.1.2.8.118.112.110.115.116.97.116.115 = STRING: "/bin/bash"

.1.3.6.1.4.1.2021.50.2.1.3.8.118.112.110.115.116.97.116.115 = STRING: "/etc/snmp/openvpn_statistics.sh"

.1.3.6.1.4.1.2021.50.3.1.1.8.118.112.110.115.116.97.116.115 = STRING: "1 180156 986279"
Essa saída esta resumida porém a informação importante está em vermelho que é o OID que iremos utilizar e a resposta que iremos obter (número de usuários e bytes trafegados)! Bom, com isso feito, terminamos com a parte do lado do servidor OpenVPN, agora precisamos ir para o servidor onde está instalado o Cacti. Naquele lado criei outro script que irá executar a consulta SNMP e retornará a resposta. Eu disponibilizei o script neste link. No meu servidor eu o coloquei neste diretório /usr/share/cacti/site/scripts, verifique onde esta este diretório em sua instalação. Com tudo no lugar você pode fazer um teste executando o script na mão:
andre@linux:~#./vpn_stats.sh 10.10.10.1 public 1
vpnUsers:1 vpnBytesIn:180156 vpnBytesOut:986279
Essa será a resposta que o Cacti receberá. Para adicionar o script siga este tutorial disponível no site do Cacti onde é ensinado como partir de um Shell Script até chegar no gráfico. Algumas recomendações na hora de criar a base de dados rrd no Cacti é para o DS de usuários utilizar Gauge e para os bytes utilizar Derive com valor mínimo em zero. Com os procedimentos feitos, você poderá ter gráficos de sua vpn como esses:



Esses gráficos foram retirados do meu servidor Cacti mostrando trafego de testes em minha VPN e eu conectado ali! O Shell Script que é utilizado pelo Cacti pode facilmente ser adaptado para alimentar uma base de dados rrd. Não é necessário utilizar este front-end para o RRDTools. Caso você tenha alguma dificuldade com essa ferramenta não deixe de conferir este artigo RRDTool - Você sabe trabalhar com ele? para aprender um pouco mais sobre ele!

Caso você tenha alguma sugestão, dúvida, crítica por favor não deixe de entrar em contato! Sua opinião é importante! Espero que com este artigo tenha conseguido contribuir com idéias úteis para a administração de seu servidor!

sexta-feira, 19 de setembro de 2008

RRDTool - você sabe trabalhar com ele?

Esta é uma ferramenta que acredito eu ser uma das mais utilizadas em todo o mundo! Vemos sua utilização em muitos aplicativos open-source como Cacti, Munin, Zenoss, Torrus, Smokeping entre muitos outros. Você pode ver uma lista deles aqui! RRDTools foi desenvolvido por Tobias Oetiker.

Basicamente é possível criar uma base de dados onde serão armazenadas informações como temperatura ou os bytes trafegados por uma interface ao longo do tempo. Qualquer coisa que possui um valor numérico você pode guardar aqui. Primeiramente é necessário instalar esta ferramenta, caso ela já não esteja. Atualmente eu tenho servidores baseado em Debian, então minha instalação é feita com a ferramenta aptitude. Consulte a ferramenta de sua distribuição (yast, emerge, rpm) por este pacote!
aptitude install rrdtool
Com este comando será instalado o aplicativo e suas dependencias serão satisfeitas. Depois da instalação você verá que ele possui algumas funções. Aqui iremos falar de algumas somente que são:
  • create: cria uma nova base de dados rrd
  • update: atualiza com novos valores uma base de dados rrd
  • graph: cria um grafico apartir de uma base de dados rrd
  • fetch: possibilita extrair informação de uma base de dados rrd
  • info: mostra informações sobre uma base de dados rrd
Existem outras funções e elas estão descritas (em inglês) neste site. Uma característica muito importante deste tipo de base de dados é que possui um comportamento cíclico, isso faz com que ela mantenha seu tamanho fixo e permite um planejamento de espaço em disco. Claro que com isso se faz necessário a definição de quanto tempo se deseja guardar uma informação, pois quando não existir mais espaço disponível, automaticamente as informações mais antigas serão sobrescritas. Em minha opnião acredito ser uma forma bastante escalonável de se manter dados armazenados por um período.

A forma que você utilizará para "alimentar" esta base de dados de informações (Data Sources) depende do que você possui e da forma que você julgar mais prático. O mais comum creio eu é por consultas SNMP (Simple Network Management Protocol) onde é possível verificar a memória utilizada por um sistema, quantos usuários estão conectados em um sistema operacional, e muitas outras possibilidades. Para isso pode-se usar um Script Shell, Perl, PHP. O fato é você conseguir passar valores para esta ferramenta, a forma você decide! :D

Tudo muito simples e muito bonito, porém as diversas informações que você possui em geral podem representar tipos de dados distintos, como por exemplo, temperatura de uma cpu e os bytes trafegados em uma interface! Isso é muito importante no momento de criar uma base de dados rrd pois definirá o comportamento de como esses dados serão interpretados e consolidados dentro dela. Com isso em mente, temos disponível para trabalhar os seguintes tipos de dados com características específicas:
  • COUNTER - Este tipo espera que o valor sempre aumente, ou seja, a diferença do valor atual e o anterior é maior que zero, e salva a variação deste sobre o tempo.
  • DERIVE - Este é muito similar ao comportamento do COUNTER porém ele permite valores negativos.
  • ABSOLUTE - Este tambem salva a variação de valores porém ele sempre considera que o anterior é zero.
  • GAUGE - Este possui um comportamento diferente e não faz nenhum tipo de matematica com o valor recebido, ele simplesmente insere o valor como ele chega!
  • COMPUTE - Este armazena um valor oriundo de uma fórmula que usa valores de outros dados definidos dentro de um arquivo rrd.
As informações dentro de um arquivo rrd são armazenadas efetivamente em arquivos RRA (Round Robing Archive). São estas estruturas que terão os espaços para armazenar dados. Antes de avançarmos um pouco mais é necessário entender duas definições utilizadas pelo RRDTools que são os PDPs (Primary Data Point) e CDPs (Consolidated Data Point). Quando um novo valor é inserido ele recebe a classificação de PDP, ou seja, enviamos um determinado valor para essa base de dados e se cria um PDP, porém um CDP é composto por um número pré determinado de PDPs. Uma nova informação só é inserida quando se torna um CDP!

Com estas informações que temos até agora podemos entender um pouco sobre essa poderosa ferramenta de armazenamento de dados, porém, existem alguns detalhes importantes que são utilizados antes de inserir definitivamente uma nova informação dentro de um arquivo rrd que são as funções de consolidação, o fator xff, steps e rows:
  • step: aqui é definido quantos PDPs são necessários para formar um CDP.
  • função de consolidação: é uma função aplicada nos valores quando atingir o número necessário de PDPs para criar um CDP. Ela pode ser AVERAGE, MIN, MAX, LAST.
  • fator xff: é a razão entre a quantidade de informação desconhecida (UNKN) e a de conhecida em um determinado intervalo (step), ou seja, quantos PDPs podem ser desconhecidos para formar um CDP.
  • rows: aqui é informado quantos CDPs serão armazenados.
Passando por tudo isso, uma informação consegue ser armazenada em um RRA e posteriormente plotada em um gráfico. Com isto entendido podemos passar dois novos conceitos usados nesta ferramenta que é o step (não é o mesmo que o anterior) e o heart beat. Como explicamos acima, esta é uma base de dados que guarda informação ao longo do tempo e ela recebe informações em intervalos de tempo pré determinados, o mais comum são 300 segundos (5min). Este step é utilizado na hora da criação da base de dados e é definido em segundos. O heart beat é utilizado no momento de se definir um DS (Data Source) e ele representa o tempo máximo que se esperará por um valor antes de inserir um valor desconhecido (UNKN) e geralmente esta configurado para 600 segundos (10min). Abaixo esta um exemplo para criar uma base de dados rrd que irá armazenar valores das variáveis SNMP ifInOctets e ifOutOctets:
rrdtool create interface.rrd \
--step 300 \
DS:in:COUNTER:600:0:U \
DS:out:COUNTER:600:0:U \
RRA:AVERAGE:0.5:12:24 \
RRA:MAX:0.5:12:24
Com este comando estamos dizendo algumas coisas:
  1. Crie (rrdtool create) um arquivo chamado interface.rrd
  2. Receberá informações a cada 300 segundos (--step 300)
  3. Com um Data Source chamado in, de tipo COUNTER, receberá informações com no máximo 600 segundos (se não UNKN), com valor mínimo em 0 e o valor máximo é desconhecido (U). O mesmo ocorrerá com o Data Source chamado out.
  4. Crie um RRA com função de consolidação AVERAGE, com um xff de 0.5%, forme um CDP quando acumular 12 PDPs e armazene 24 vezes.
  5. Crie um RRA com função de consolidação MAX com um xff de 0.5%, forme um CDP quando acumular 12 PDPs e armazene 24 vezes.
Ok!!!! Vamos traduzir um pouco isso ai, criaremos um arquivo com aquele nome, irá receber novos valores a cada 5 minutos e esperará no máximo até 10 minutos. Não recebendo nenhum valor novo irá colocar um valor especial chamado UNKN. Estamos criando dois arquivos RRA com funções de consolidação diferentes. Com o xff configurado para 0.5 e o step em 12, estamos dizendo que até 6 valores (12*0.5) podem conter UNKN. Com estes 12 valores aplicaremos uma função de média (AVERAGE) e armazenarei o resultado e com outra aplicarei a função de máxima (MAX) e também armazenarei o resultado. Os dois armazenarão 24 valores. Fazendo as contas 300*12*24 chegamos ao valor 86400 segundos ou 1 dia. Será necessário um dia completo para encher este arquivo rrd. Se você criar uma base de dados com esta configuração levará uma hora (300*12) para que seja possível ter alguma informação dentro da base de dados e que apareça em um gráfico.

Bom já temos bastante informação sobre as base de dados rrd até agora, porém ainda não vimos como inserir informações nela. É um procedimento bem simples e iremos usar a segunda função que apresentamos acima que é a update. Com esta função iremos inserir novos dados a cada 5 minutos (nossa base de dados espera isso, mas pode ser diferente). O comando para fazer isso é o seguinte:
rrdtool update interface.rrd N:32378634:U
O que isto fará é o seguinte, atualizará o arquivo interface.rrd com um valor conhecido e outro desconhecido (fiz assim só para dar um exemplo) e a hora de atualização será a atual (N). Com isso teremos um novo PDP dentro desta base de dados. Cada RRA irá receber estes valores e acumulará até alcançar o número de steps configurado, aplicando então sua função de consolidação.

Se você quiser criar uma base de dados para armazenar um tempo específico são necessários alguns passos e cálculos. Vamos simular aqui que precisamos de uma base de dados que guarde informação por um ano completo e que antes de criar uma entrada nova (CDP) dentro do nosso RRA serão necessários 4 PDPs (steps) e a coleta será a cada 300 segundos ou 5 minutos. Vamos primeiro descobrir quantos segundos possui um ano:
1 ano -> 365 dias -> 8760 horas -> 525600 segundos
Um ano é isso ai, 525600 segundos, então podemos chegar na seguinte fórmula:
((525600)/(4*300)) = 438
O resultado desta fórmula nos permite criar uma base de dados para nossa necessidade:
rrdtool create interface2.rrd \
--step 300 \
DS:in:COUNTER:600:0:U \
DS:out:COUNTER:600:0:U \
RRA:AVERAGE:0.5:4:438
Este é um assunto bastante comprido e só estamos no começo de sua abordagem porém acredito que o básico e o início teórico são muito importantes para se avançar. Espero estar mostrando mais desta ferramenta pois é muito poderosa e útil para o dia a dia de um administrador de sistemas.

Como sempre, se existir qualquer sugestão, crítica, dúvida ou ainda uma correção, podem entrar em contato comigo!

terça-feira, 9 de setembro de 2008

Iptables - marcação de pacotes para qos e/ou roteamento

Neste artigo irei mostrar como utilizar o iptables para marcar pacotes (qualquer um que você consiga enquadrar em uma regra de iptables) para usar uma determinada tabela de roteamento do linux, no caso de você ter mais de um link, ou ainda que use algumas regras definidas de QoS. Com este documento não tenho o objetivo de mostrar como criar as regras de qualidade de serviço, este será tema de um outro artigo.

Existe um tutorial muito bom que foi escrito em inglês e hospedado no site Linux Advanced Routing and Traffic Control onde ele ensina técnincas de roteamento, manipulação das tabelas e a criação de regras para alocar um certo tipo de trafego a um link específico. É uma excelente fonte de pesquisa e foi deste site onde aprendi muito do conteúdo que sei hoje sobre este tema.

O linux permite que você coloque uma marcação no pacote para posterior uso como roteamento, qos ou ainda os dois juntos! Esta marca só esta presente a nível de kernel, ou seja, quando o pacote é enviado para o meio de rede ela já não existe! Então não adianta querer marcar os pacotes com a técnica que vamos explicar aqui para identificar o pacote em um outro servidor em sua rede. Uma marca que persiste no meio de rede é o do ToS.

Com o iptables podemos fazer uma serie de comparações nos pacotes como já vimos em outros artigos e as marcas que usaremos podem ser verificadas ou "escritas" em um determinado pacote. Quando queremos verificar qual marca um pacote possui é possível faze-lo em qualquer tabela do iptables, porém para marca-lo só na mangle como veremos a seguir:
iptables -t mangle -A PREROUTING -i eth0 -j MARK --set-mark 0x1
iptables -t filter -A FORWARD -m mark --mark 0x1 -j ACCEPT

Se alguma tentativa de marcar um pacote fora da tabela mangle for feito um erro de argumento inválido será emitido. Fiz alguns testes para tentar descobrir qual o número máximo de marcas que se pode utilizar e cheguei a conclusão de que não pode ter mais do que 8 dígitos, ou seja 0x99999999 seria um valor máximo! Acho que é suficiente! Hehehe

Com essas possibilidades você pode criar uma estrutura de roteamento e/ou qos para sua rede podendo priorizar pacotes de serviços como http, smtp/pop, ftp, voip e deixar outros com menor prioridade utilizar regras mais restritas. Um comando importante neste cenário é o ip. Este comando faz parte do pacote iproute do linux e esta presente por padrão em quase todas as distribuições, se não estiver procure por este pacote! Com ele temos a possibilidade de mudar/configurar a tabela de roteamento do kernel do linux.

Como vimos, com o ip podemos trabalhar com as regras de roteamento do nosso linux e para gerenciarmos as regras de qos temos o tc. Com ele podemos criar filas de qos especializadas, diferentes da padrão utilizada pelo linux que é a pfifo_fast:
2: eth1: mtu 1500 qdisc pfifo_fast
Utilizando a marcação acima (0x1) podemos dizer que este pacote use uma tabela de roteamento específica e que use uma configuração de qos especial:
ip rule add from all fwmark 0x1 table link1
tc filter add dev eth1 protocol all parent 1:0 handle 0x1 fw classid 1:112
Eu tenho usado este tipo de configuração para ajustar regras de qos em minha rede pois aqui temos vários clientes usando um mesmo link de internet. Claro que aqui estou usando muitas regras e até scripts para gerar um bloco grande automaticamente. Este comando ip é muito poderoso e você pode fazer roteamento baseado na origem, destino, campo ToS e conseguir um controle bastante interessante em sua rede!

Outra forma de classificar os pacotes e aloca-los em uma regra de qos específica é utilizando o próprio iptables! Ele possui um alvo (target) especial que já coloca os pacotes em uma fila especial de qos que você criou! O comando é assim:
iptables -t mangle -A POSTROUTING -p tcp --dport 80 -j CLASSIFY 1:112
Uma ressalva é importante de ser feita aqui, esta regra só pode ser utilizada na tabela mangle na chain POSTROUTING! Este comando é bastante explicativo e irá se enquadrar com pacotes que usem tcp e tenham por destino a porta 80 (web) colocando este em uma regra de qos. Eu já fiz testes das duas formas, usando mark e classify, e obtive resultados melhores quando usando a primeira técnica (mark) para realizar qos.

Com participo do fórum da Under-linux.org, sempre vejo pessoas perguntando se é possível realizar qos para um determinado computador e/ou serviço que ele esta servindo, com estas técnicas é possível garantir/limitar banda, alocar tráfego em um determinado link para recursos em sua rede, ai é só questão de criatividade para estar criando as regras e fazer algo bem interessante!

Como sempre, se existir alguma dúvida, crítica ou sugestão por favor postem aqui neste fórum ou mesmo no meu perfil no site da Under-linux.org.


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!