Acesso seguro à internet através do OpenVPN

openvpn_logo

Objetivo

Ao final deste texto você será capaz de acessar sites, e-mail, mensagens instantâneas e qualquer outro protocolo, através da internet, de modo possivelmente mais seguro.

A inspiração para escrever este texto provém dos pedidos feitos após o hands on que realizei durante a CriptoParty no PixaHC, no dia 04/07/2015.

Ambiente

Espera-se que você tenha acesso à um host rodando alguma distribuição GNU/Linux. Pode ser desde um servidor à um dispositivo embarcado (vale até aquele computador velho que foi transformado pelo seu desejo de dominar o mundo ou o Raspberry comprado na China). Se você não dispõe de algo no momento, uma VPS de cinco dólares mensais, na digital ocean, já é mais que o suficiente.

O meu ambiente é uma VPS, com as seguintes características:

root@ignucius:/home/tobias# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 8.1 (jessie)
Release:        8.1
Codename:       jessie
root@ignucius:/home/tobias# head -1 /proc/meminfo 
MemTotal:         506340 kB
root@ignucius:/home/tobias# head -5 /proc/cpuinfo 
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 62
model name      : Intel(R) Xeon(R) CPU E5-2630L v2 @ 2.40GHz

Softwares necessários

No Debian, os pacotes necessários são o openvpn e easy-rsa. O primeiro instala o servidor/cliente em si e o segundo disponibiliza scripts que facilitam a criação de certificados digitais.

root@ignucius:/home/tobias# apt-get install openvpn easy-rsa

Configuração do easy-rsa

Agora entramos no diretório do OpenVPN, utilizamos o comando make-cadir (disponibilizado pelo pacote easy-rsa) para criar um diretório chamado easy-rsa que conterá vários scripts úteis. Por fim, entramos no diretório easy-rsa e editamos o arquivos chamado vars.

root@ignucius:/etc/openvpn# cd /etc/openvpn/
root@ignucius:/etc/openvpn# make-cadir easy-rsa
root@ignucius:/etc/openvpn# cd easy-rsa
root@ignucius:/etc/openvpn# vim vars

Este arquivo contém variáveis/definições que serão utilizadas pelos outros scripts. Vá até o final dele e edite os valores seguindo o exemplo:

# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY="BR"
export KEY_PROVINCE="ES"
export KEY_CITY="Vitoria"
export KEY_ORG="tobias.ws"
export KEY_EMAIL="eu@meuprovedor.com.br"
export KEY_OU="tobias.ws"

Dica: você pode querer alterar a variável _KEYDIR, que define onde as chaves ficarão.

Após efetuar as alterações, salvar o arquivo e  voltar ao shell, inclua as variáveis do arquivo vars na sessão atual.

root@ignucius:/etc/openvpn/easy-rsa# source vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys
root@ignucius:/etc/openvpn/easy-rsa# ./clean-all

Atenção: execute ./clean-all apenas na primeira vez que realizar o procedimento. Se você executá-lo depois, poderá apagar os arquivos já gerados, como diz no NOTE.

Criando os certificados

Durante este processo você será questionado diversas vezes sobre valores para determinados campos. As opções padrão (que preenchemos no arquivo vars) ficarão entre colchetes e, caso você apenas dê enter, elas serão utilizadas. Quando for solicitado o Common Name, utilize o nome do host (hostname), que pode ser obtido com o comando hostname -s.

Gerando o certificado da sua própria unidade certificadora

root@ignucius:/etc/openvpn/easy-rsa# ./build-ca 
Generating a 2048 bit RSA private key
....................................................................................................................................................................+++
........................................+++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [BR]:
State or Province Name (full name) [ES]:
Locality Name (eg, city) [Vitoria]:
Organization Name (eg, company) [tobias.ws]:
Organizational Unit Name (eg, section) [tobias.ws]:
Common Name (eg, your name or your server's hostname) [tobias.ws CA]:ignucius
Name [EasyRSA]:
Email Address [eu@meuprovedor.com.br]:
root@ignucius:/etc/openvpn/easy-rsa#

Gerando a chave para o servidor. Utilize o comando build-key-server seguido do home do servidor (hostname).

root@ignucius:/etc/openvpn/easy-rsa# ./build-key-server ignucius
Generating a 2048 bit RSA private key
..............................................................................................+++
...........................................+++
writing new private key to 'ignucius.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [BR]:
State or Province Name (full name) [ES]:
Locality Name (eg, city) [Vitoria]:
Organization Name (eg, company) [tobias.ws]:
Organizational Unit Name (eg, section) [tobias.ws]:
Common Name (eg, your name or your server's hostname) [ignucius]:
Name [EasyRSA]:
Email Address [eu@meuprovedor.com.br]:
 
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'BR'
stateOrProvinceName   :PRINTABLE:'ES'
localityName          :PRINTABLE:'Vitoria'
organizationName      :PRINTABLE:'tobias.ws'
organizationalUnitName:PRINTABLE:'tobias.ws'
commonName            :PRINTABLE:'ignucius'
name                  :PRINTABLE:'EasyRSA'
emailAddress          :IA5STRING:'eu@meuprovedor.com.br'
Certificate is to be certified until Jul  7 07:35:34 2025 GMT (3650 days)
Sign the certificate? [y/n]:y
 
 
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
root@ignucius:/etc/openvpn/easy-rsa#

Agora, execute o comando abaixo para gerar uma chave Diffie-Hellman, que será utilizada pelo cliente e servidor durante a troca de chaves. O processo pode durar um tempo.

Nota: devido a vulnerabilidades na troca de chaves com Diffie-Hellman, não utilize um arquivo com um número igual ou inferior a 1024 bits. Neste caso não há problema pois o script irá utilizar 2048 bits.

root@ignucius:/etc/openvpn/easy-rsa# ./build-dh
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
............................+..........................................+..................[...]

Gerando chaves para o cliente

É recomendado que cada cliente, isto é, cada dispositivo que irá acessar à VPN, tenha uma chave. Para gerar uma chave para um cliente, execute o comando build-key seguido do nome (hostname) do dispositivo. Em um ambiente GNU/Linux você pode descobrir qual o hostname através do comando hostname -s.

root@ignucius:/etc/openvpn/easy-rsa# ./build-key lothlorien
Generating a 2048 bit RSA private key
.....................................................................................................+++
......................+++
writing new private key to 'lothlorien.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [BR]:
State or Province Name (full name) [SP]:ES
Locality Name (eg, city) [SantoAndre]:Vitoria
Organization Name (eg, company) [tobias.ws]:
Organizational Unit Name (eg, section) [tobias.ws]:pessoal
Common Name (eg, your name or your server's hostname) [lothlorien]:
Name [EasyRSA]:
Email Address [eu@meuprovedor.com.br]:
 
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'BR'
stateOrProvinceName   :PRINTABLE:'ES'
localityName          :PRINTABLE:'Vitoria'
organizationName      :PRINTABLE:'tobias.ws'
organizationalUnitName:PRINTABLE:'pessoal'
commonName            :PRINTABLE:'lothlorien'
name                  :PRINTABLE:'EasyRSA'
emailAddress          :IA5STRING:'eu@meuprovedor.com.br'
Certificate is to be certified until Jul  7 07:48:49 2025 GMT (3650 days)
Sign the certificate? [y/n]:y
 
 
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Após efetuar estes processos, exclua os arquivos desnecessários com o comando rm keys/*.csr.

Cada dispositivo cliente deverá ter ter uma cópia dos arquivos cliente.crt, cliente.key, ca.crt, dh2048.pem que ficam no diretório /etc/openvpn/easy-rsa/keys/, sendo que ‘cliente’ corresponde ao nome do cliente que foi informado no comando build-key. Uma forma segura de copiar este arquivos para o cliente é através de ssh (sftp ou scp). Como exemplo, você fazer o seguinte no servidor:

root@ignucius:/etc/openvpn/easy-rsa# cd keys/
root@ignucius:/etc/openvpn/easy-rsa/keys# mkdir arquivos_cliente_tal
root@ignucius:/etc/openvpn/easy-rsa/keys# cp cliente.crt cliente.key ca.crt dh2048.pem arquivos_cliente_tal/

E no cliente você pode copiá-los com um software como o FileZilla (GNU/Linux, Windows, MacOS), WinSCP (para Windows), VX ConnectBot (para Android) ou com o comando scp:

tobias@lothlorien:~/Downloads$ scp root@meuServidor.com.br:/etc/openvpn/easy-rsa/keys/arquivos_cliente_tal .
root@meuServidor.com.br's password: 
cliente.crt                                                                                                                                        100%    0     0.0KB/s   00:00    
cliente.key                                                                                                                                        100%    0     0.0KB/s   00:00    
ca.crt                                                                                                                                             100%    0     0.0KB/s   00:00    
dh2048.pem                                                                                                                                         100%    0     0.0KB/s   00:00    
tobias@lothlorien:~/Downloads$

Nota: o exemplo acima é fictício. Não é uma boa prática deixar o login de root, ou qualquer usuário com permissões administrativas, habilitado no ssh.

Configurando o OpenVPN

No servidor

Crie o arquivo /etc/openvpn/server.conf com o seguinte conteúdo (está comentado para melhor entendimento):

###########################################################
#######                   OpenVPN                   #######
#######                       Server                #######
###########################################################
#
# Arquivo de configuracao para o servidor
# Criado por Tobias Sette <contato@tobias.ws>
# 27/03/2012 - v0.1 - Início
# 30/05/2012 - v0.2 - (OpenVPN 2.2.x)
# 10/07/2015 - v0.3 - reformulado com base no OpenVPN do Debian Jessie (OpenVPN 2.3.x)
#
# Este arquivo de configuração foi testado, sem modificações significativas,
# nas seguintes versões do OpenVPN:
#  -> OpenVPN 2.3.4 x86_64 (Debian 8.1)
 
 
##############################
#            Notas
##############################
 
# Carregue o module tun do kernel (modprobe tun) e
# certifique-se que ele está sendo carregado na
# inicializacao do sistema. O mais comum é ser
# chamado no arquivo /etc/modules
 
# Para testar os arquivos de configuracao:
# openvpn --config /etc/openvpn/arquivo.conf
 
# Para fazer NAT, execute algo semelhante à:
# sysctl -w net.ipv4.ip_forward=1
# iptables -t nat -s $IP_REDE/$MASCARA_REDE -A POSTROUTING -o $PORTA_INTERNET -j MASQUERADE
 
# Os hosts tem que estar com o horario correto; utilize
# ntpdate -u pool.ntp.org para atualizar
 
# Este arquivo deve funcionar em diversos sistemas. No windows,
# lembre-se de escapar nomes completos de arquivos, como em
# "C:\\Foo\\Bar\\foo.key"
 
 
##############################
#     Dados da conexão
##############################
 
# Em qual ip local o OpenVPN ficará escutando?
;local 192.168.20.1
 
# Define o protocolo a ser utilizado.
# Por padrao (e caso omtido) o protocolo udp é utilizado.
# Utilizar udp preferencialmente, pois este protocolo
# não faz correção/redundancia dos pacotes. O OpenVPN
# apenas cria a conexão, em cima dela rodarão os protocolos
# cabiveis (tcp, udp, etc), não sendo necessário utilizar
# correção de erros nesta camada.
# Para utiliza protocolo tcp:
;proto tcp-server
    proto udp
 
# Especifica a porta udp que na qual o openvpn ira rodar.
# Por padrao (e caso omitida) a porta 1194 é utilizada.
# Caso você já rodar múltiplas instâncias do OpenVPN, use
# uma porta diferente para cada.
    port 1194
 
 
##############################
#     Interface de rede
##############################
 
# Para executar as ações definidas nos comandos abaixo, pode ser necessário
# realizar NAT. Para isso vejo o comentário na seção NOTAS
 
# Define qual interface, e de qual tipo, ira responder
# pela VPN
# No tun o trafego da rede é roteado eliminando pacotes de
# broadcast, no tap é criado uma interface ethernet onde tudo é transmitido.
# No windows você deve especificar um número para a interface, como em tun0.
    dev tun
 
# No Windows é necessário especificar o nome do adapator TAP-Win32
# a partir do painel de conexões de rede, se você tiver mais de um.
;dev-node MyTap
 
## IP manual
# para interface tun (local, remoto)
# ifconfig 192.168.100.1 192.168.100.2
# para interface tap (local, mascara de rede)
# ifconfig 192.168.100.1 255.255.255.0
 
## Servidor de ips
# faixa de endereco e mascara
    server 10.8.0.0 255.255.255.0
#
# Armazena os ips utilizados pelos clientes e tenta reutilizá-los nas
# proximas conexões (não é necessário criar o arquivo)
    ifconfig-pool-persist /etc/openvpn/ips.txt
 
## Bridges. Ver [3] para mais informações
# Configura o modo para ethernet bridging
;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100
#
# Clientes utilizam DHCP do servidor
;server-bridge
 
 
##############################
#           Rotas
##############################
 
# Envia rotas da rede local do servidor para
# serem adicionados a tabela de roteamento do cliente. Possibilitando
# que este veja subrede atravás do servidor. Lembre-se que estas subredes
# também precisam saber como rotear para a subrede do OpenVPN
 
# Envia uma rota específica
;push "route 10.8.0.0 255.255.255.0"
 
# Faz com que todo o tráfego do cliente, direcionado ao seu gateway, passe pelo
# OpenVPN. Isso faz com que todo o tráfego IP, como sites e requisições DNS,
# passem pelo OpenVPN.
# Pode ser necessário fazer NAT ou bridge, para possibilitar que o cliente
# acesse à internet através deste servidor.
# Para NAT vejo o comentário na seção NOTAS.
push "redirect-gateway def1 bypass-dhcp"
 
# Algumas configurações específicas para Windows podem ser definidas, tais como
# DNS e WINS.
;push "dhcp-option DNS 208.67.222.222"
;push "dhcp-option DNS 208.67.220.220"
 
# Permite que os clientes possam se ver na rede. Por padrão eles veêm apenas o
# servidor.
# Para forçar os clientes à apenas verem o servidor, configure seu firewal
;client-to-client
 
 
##############################
#   Qualidade da conexão
##############################
 
# Pinga o host remoto a cada $x segundos sem atividade na rede, se ele
# nao responder por $z segundos a conexão é reiniciada.
# Quando a conexão é interrompida o cliente tenta restabelece-la
# periodicamente
# Uso: keepalive $x $z
    keepalive 10 120
 
# Compacta os dados da conexão utilizando o pacote lzo (deve estar
# instalado no host), com um pequeno aumento de processamento.
# Se estiver habilitado no servidor, o cliente também deve habilitar
    comp-lzo
 
# mantem as chaves carregadas mesmo durante o reinicio do serviço.
    persist-key
 
# mantem o tunel aberto mesmo durante o reinicio do serviço.
    persist-tun
 
# mantem o tunel aberto mesmo se o ip do outro host mudar
;float
 
# lmita a banda (soma de todos os clientes) de saida do Openvpn a N bytes.
;shaper 51200
 
# define numero de usuarios conectados simultaneamente ao OpenVPN
    max-clients 5
 
 
##############################
#      Autenticacao
##############################
 
# Permite que mais de um cliente se conecte com o mesmo certificado/chave.
# Não é uma boa prática habilitar esta funcionalidade.
;duplicate-cn
 
# Utilizando a mesma chave, estatica, nos dois hosts
# para gerar: openvpn --genkey --secret /etc/openvpn/keys/estatica.key
# depois copiar para o outro host
;secret estatica.key
 
# Define que as solicitações de conexão devem ser encriptadas
# com ta.key. É útil para bloquear ataques DoS e flood na porta UDP.
# O segundo parâmetro deve ser 0 no servidor e 1 no cliente.
# Copiar ta.key para cada host que vá se conectar.
# para gerar: openvpn --genkey --secret /etc/openvpn/keys/ta.key
;tls-auth /etc/openvpn/keys/ta.key 0
 
# Define qual a cifra criptográfica. Esta configuração deve ser igual no
# cliente.
;cipher BF-CBC        # Blowfish (padrão)
;cipher AES-128-CBC   # AES
;cipher DES-EDE3-CBC  # Triple-DES
 
 
##############################
#      Certificados X509
##############################
 
 
# Revogar certificados
# cd /etc/openvpn/easy-rsa; source vars; ./revoke-full $nomeCliente; systemctl reload openvpn
# crl-verify /etc/openvpn/easy-rsa/keys/crl.pem
 
# Parametro necessario para utilizar conexão com certificados X509
    tls-server
 
# Caminho para o arquivo contendo parametros Diffie Hellman
    dh /etc/openvpn/easy-rsa/keys/dh2048.pem
 
# Local do arquivo de certificado (.crt) da unidade certificadora
    ca /etc/openvpn/easy-rsa/keys/ca.crt
 
# Local do arquivo de certificado (.crt) do servidor
    cert /etc/openvpn/easy-rsa/keys/$nomeServidor.crt
 
# Local da chave (.key) do servidor. Este arquivo deve ser mantido secreto
    key /etc/openvpn/easy-rsa/keys/$nomeServidor.key
 
 
##############################
#           Outros
##############################
 
# É uma boa prática diminuir os privilégios do OpenVPN após a inicialização.
# Utilize estas opções em clientes não Windows.
# Note que as opções persist-key e persist-tun podem ser habilitadas
# para evitar erros de acesso a recursos que podem ficam indisponíveis depois
# da redução de privilégios
user nobody
group nogroup
 
# Grava um curto arquivo de status mostrando conexões atuais. O arquivo é
# truncado e reescrito a cada minuto.
status openvpn-status.log
 
# Por padrão as mensagens de log vão para o syslog (ou no Windows, se rodando
# como serviço, vão para o diretório "\Program Files\OpenVPN\log"). Utilize log
# ou log-append para sobrescrever este comportamento.
# log irá truncar o arquivo de log a cda inicialização do OpenVPN, enquanto
# log-append irá acrescentar nele. Use um dos dois.
;log         openvpn.log
;log-append  openvpn.log
 
# Define o quão verboso será o log.
# 0 é silencioso, exceto por erros fatais
# 4 é rasoável para o uso geral
# 5 e 6 podem ajudá-lo a debugar problemas de conexão
# 9 é extremamente verboso
verb 3
 
# Ignora mensagens repetidas. Até x mensagens sequenciais da mesma categoria
# serão escritas no log
;mute 20
 
#EOF

Lembre-se de substituir $nomeServidor pelo hostname do servidor nos parâmetros cert e key.

Agora pare o serviço do OpenVPN e execute diretamente o seu arquivo de configuração:

root@ignucius:/etc/openvpn# systemctl stop openvpn
root@ignucius:/etc/openvpn# openvpn /etc/openvpn/server.conf 
Thu Jul 16 05:03:21 2015 OpenVPN 2.3.4 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [MH] [IPv6] built on Dec  1 2014
Thu Jul 16 05:03:21 2015 library versions: OpenSSL 1.0.1k 8 Jan 2015, LZO 2.08
Thu Jul 16 05:03:21 2015 Diffie-Hellman initialized with 2048 bit key
Thu Jul 16 05:03:21 2015 Socket Buffers: R=[212992->131072] S=[212992->131072]
Thu Jul 16 05:03:21 2015 ROUTE_GATEWAY 103.121.102.1/255.255.224.0 IFACE=eth0 HWADDR=01:03:2c:d7:90:02
Thu Jul 16 05:05:34 2015 TUN/TAP device tun0 opened
Thu Jul 16 05:05:34 2015 TUN/TAP TX queue length set to 100
Thu Jul 16 05:05:34 2015 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Thu Jul 16 05:05:34 2015 /sbin/ip link set dev tun0 up mtu 1500
Thu Jul 16 05:05:34 2015 /sbin/ip addr add dev tun0 local 10.8.0.1 peer 10.8.0.2
Thu Jul 16 05:05:34 2015 /sbin/ip route add 10.8.0.0/24 via 10.8.0.2
Thu Jul 16 05:05:34 2015 GID set to nogroup
Thu Jul 16 05:05:34 2015 UID set to nobody
Thu Jul 16 05:05:34 2015 UDPv4 link local (bound): [undef]
Thu Jul 16 05:05:34 2015 UDPv4 link remote: [undef]
Thu Jul 16 05:05:34 2015 MULTI: multi_init called, r=256 v=256
Thu Jul 16 05:05:34 2015 IFCONFIG POOL: base=10.8.0.4 size=62, ipv6=0
Thu Jul 16 05:05:34 2015 IFCONFIG POOL LIST
Thu Jul 16 05:05:34 2015 Initialization Sequence Completed

Isso faz com que o OpenVPN jogue sua saída na tela, tornando possível verificar se algo deu errado. Caso sua saída tenha sido semelhante a de cima, presione control+c para terminar o processo e inicie-o novamente como um daemon usando:

root@ignucius:/etc/openvpn# systemctl start openvpn
root@ignucius:/etc/openvpn#

Por fim, é necessário compartilhar a internet do servidor. Para isso execute:

sysctl -w net.ipv4.ip_forward=1
root@ignucius:/etc/openvpn/# iptables -t nat -s 10.8.0.0/24 -A POSTROUTING -o eth0 -j MASQUERADE

Onde 10.8.0.0.0/24 é a rede da VPN e eth0 é a interface do servidor que está conectada à internet.

Para tornar essa ação permamente, isto é, fazer com que ela seja executada a cada boot, adicione as regras no seu script de firewall ou, se não houver um, adicione no arquivo /etc/rc.local, antes de exit 0.

No cliente

Para cada plataforma há vários clientes diferentes para o OpenVPN, mas geralmente eles vão ter a mesma necessidade: o arquivo client.ovpn e as chaves utilizadas por ele. A copia das chaves foi mencionada acima, de modo que, neste ponto, você deve ter os arquivos $nomeCliente.crt, $nomeCliente.key, ca.crt e dh2048.pem. Um arquivo client.ovpn de exemplo:

###########################################################
#######                   OpenVPN                   #######
#######                       Client                #######
###########################################################
#
# Arquivo de configuracao para o cliente
# Criado por Tobias Sette <contato@tobias.ws>
# xx/xx/2012 - v0.1 - Início
# xx/xx/2012 - v0.2 - 
# 01/06/2012 - v0.3 - reformulado com base no OpenVPN do Debian Squeeze (OpenVPN 2.2.x)
# 10/07/2015 - v0.4 - reformulado com base no OpenVPN do Debian Jessie (OpenVPN 2.3.x)
#
# Este arquivo de configuração foi testado, sem modificações significativas,
# nas seguintes versões do OpenVPN:
#  -> OpenVPN 2.3.4 x86_64 (Debian testing stretch)
 
 
##############################
#     Notas
##############################
 
# Carregue o module tun do kernel (modprobe tun) e
# certifique-se que ele está sendo carregado na
# inicializacao do sistema. O mais comum é ser
# chamado no arquivo /etc/modules
 
# Para testar os arquivos de configuracao:
# openvpn --config /etc/openvpn/arquivo.conf
 
# Os hosts tem que estar com o horario correto; utilize
# ntpdate -u pool.ntp.org para atualizar
 
# Este arquivo deve funcionar em diversos sistemas. No windows,
# lembre-se de escapar nomes completos de arquivos, como em
# "C:\\Foo\\Bar\\foo.key", e renomeie este arquivo para a extensao .ovpn
 
 
##############################
#     Dados da conexao
##############################
 
# Define que esta maquina é um cliente e que obterá configurações do servidor
    client
 
# Na maior parte das vezes o cliente não precisa utilizar uma porta local
# específica
nobind
 
# Endereco do host no qual se vai conectar. Especificar
# mais de um e remote-random faz com que o cliente escolha um
# servidor (ativo) aleatoriamente a cada conexao, criando redundância
# e balanceamento de carga. Não especificar remote-random faz com que
# a escolha do servidor ocorra na ordem em que foram especificados.
# O segundo parâmetro especifica a porta na qual o OpenVPN irá rodar.
# Por padrao (e caso omitida) a porta 1194 eh utilizada
    remote $meuServidor 1194
;remote-random
 
# Define o protocolo a ser utilizado.
# Por padrao (e caso omtido) o protocolo udp é utilizado.
# Utilizar udp preferencialmente, pois este protocolo
# não faz correção/redundancia dos pacotes. O OpenVPN
# apenas cria a conexão, em cima dela rodarão os protocolos
# cabiveis (tcp, udp, etc), não sendo necessário utilizar
# correção de erros nesta camada.
# Para utiliza protocolo tcp:
;proto tcp-server
    proto udp
 
# Se você está conetando à internet através de um proxy HTTP, defina o parâmetro
# http-proxy.
# http-proxy-retry faz com que uma nova tentativa seja feita em casa de falha
# de conexão
;http-proxy-retry
;http-proxy $ip $porta
 
 
##############################
#     Interface de rede
##############################
 
# Define qual interface, e de qual tipo, ira responder
# pela VPN
# No tun o trafego da rede é roteado eliminando pacotes de
# broadcast, no tap é criado uma interface ethernet onde tudo é transmitido.
# No windows você deve especificar um número para a interface, como em tun0.
    dev tun
 
# No Windows é necessário especificar o nome do adapator TAP-Win32
# a partir do painel de conexões de rede, se você tiver mais de um.
;dev-node MyTap
 
 
##############################
#   Qualidade da conexão
##############################
 
# Pinga o host remoto a cada $x segundos sem atividade na rede, se ele
# nao responder por $z segundos a conexão é reiniciada.
# Quando a conexão é interrompida o cliente tenta restabelece-la
# periodicamente
# Uso: keepalive $x $z
    keepalive 10 120
 
# Compacta os dados da conexão utilizando o pacote lzo (deve estar
# instalado no host), com um pequeno aumento de processamento.
# Se estiver habilitado no servidor, o cliente também deve habilitar
    comp-lzo
 
# mantem as chaves carregadas mesmo durante o reinicio do serviço.
    persist-key
 
# mantem o tunel aberto mesmo durante o reinicio do serviço.
    persist-tun
 
# Fica tentando, indefinidamente, resolver o nome do host do servidor. Útil
# em hosts que não estão permanentemente conectados à internet.
    resolv-retry infinite
 
# Tenta realizar a reconexao com host remoto por $x segundos
;inactive 3600
 
# mantem o tunel aberto mesmo se o ip do outro host mudar
    float
 
# lmita o trafego de saida do Openvpn a N bytes.
;shaper 51200
 
# Redes wireless frequentemente produzem muitos pacotes duplicados. O parâmetro
# abaixo faz com que os avisos de pacotes duplicados sejam silenciados
;mute-replay-warnings
 
 
##############################
#      Autenticacao
##############################
 
# Faz com que o cliente verifique se o certificado do servidor tem o campo
# nsCertType definido para "server". Precaução importante para evitar MITM [4]
    ns-cert-type server
 
# Utilizando a mesma chave, estatica, nos dois hosts
# para gerar: openvpn --genkey --secret /etc/openvpn/keys/estatica.key
# depois copiar para o outro host
;secret estatica.key
 
# Define que as solicitações de conexão devem ser encriptadas
# com ta.key. É útil para bloquear ataques DoS e flood na porta UDP.
# O segundo parâmetro deve ser 0 no servidor e 1 no cliente.
# Copiar ta.key para cada host que vá se conectar.
# para gerar: openvpn --genkey --secret /etc/openvpn/keys/ta.key
;tls-auth /etc/openvpn/keys/ta.key 1
 
# Define qual a cifra criptográfica. Esta configuração deve ser igual no
# cliente.
;cipher BF-CBC        # Blowfish (padrão)
;cipher AES-128-CBC   # AES
;cipher DES-EDE3-CBC  # Triple-DES
 
 
##############################
#      Certificados X509
##############################
 
 
# Parametro necessario para utilizar conexão com certificados X509
    tls-client
 
# Caminho para o arquivo contendo parametros Diffie Hellman
    dh dh2048.pem
 
# Local do arquivo de certificado (.crt) da unidade certificadora
    ca ca.crt
 
# Local do arquivo de certificado (.crt) do cliente
    cert $nomeCliente.crt
 
# Local da chave (.key) do cliente. Este arquivo deve ser mantido secreto
    key $nomeCliente.key
 
 
##############################
#           Outros
##############################
 
# É uma boa prática diminuir os privilégios do OpenVPN após a inicialização.
# Utilize estas opções em clientes não Windows.
# Note que as opções persist-key e persist-tun podem ser habilitadas
# para evitar erros de acesso a recursos que podem ficam indisponíveis depois
# da redução de privilégios
    user nobody
    group nogroup
 
# Grava um curto arquivo de status mostrando conexões atuais. O arquivo é
# truncado e reescrito a cada minuto.
    status openvpn-status.log
 
# Por padrão as mensagens de log vão para o syslog (ou no Windows, se rodando
# como serviço, vão para o diretório "\Program Files\OpenVPN\log"). Utilize log
# ou log-append para sobrescrever este comportamento.
# log irá truncar o arquivo de log a cda inicialização do OpenVPN, enquanto
# log-append irá acrescentar nele. Use um dos dois.
;log         openvpn.log
;log-append  openvpn.log
 
# Define o quão verboso será o log.
# 0 é silencioso, exceto por erros fatais
# 4 é rasoável para o uso geral
# 5 e 6 podem ajudá-lo a debugar problemas de conexão
# 9 é extremamente verboso
    verb 3
 
# Ignora mensagens repetidas. Até x mensagens sequenciais da mesma categoria
# serão escritas no log
;mute 20
 
#EOF

Lembre-se de colocar os arquivos das chaves no mesmo diretório do client.ovpn, substituir $nomeCliente pelo nome do cliente nos parâmetros cert e key e $meuServidor pelo endereço do seu servidor no parâmetro remote.

Como alternativa, é possível embutir os certificados e chaves dentro do arquivo de configuração. Assim o usuário precisará de apenas um arquivo para se conectar, tornando mais simples a distribuição e manipulação das configurações. Para fazer isso abra os arquivos .crt, .key e .pem, copie e o conteúdo que está entre o texto BEGIN e END e cole nas respectivas tags dentro do arquivo de configuração. Exemplo:

# Caminho para o arquivo contendo parametros Diffie Hellman
#    dh dh2048.pem
<dh>
-----BEGIN DH PARAMETERS-----
Texto aqui
-----END DH PARAMETERS-----
</dh>
 
# Local do arquivo de certificado (.crt) da unidade certificadora
#    ca ca.crt
<ca>
-----BEGIN CERTIFICATE-----
Texto aqui
-----END CERTIFICATE-----
</ca>
 
# Local do arquivo de certificado (.crt) do cliente
#    cert $nomeCliente.crt
<cert>
-----BEGIN CERTIFICATE-----
Texto aqui
-----END CERTIFICATE-----
</cert>
 
# Local da chave (.key) do cliente. Este arquivo deve ser mantido secreto
#    key $nomeCliente.key
<key>
-----BEGIN PRIVATE KEY-----
Texto aqui
-----END PRIVATE KEY-----
</key>

O arquivo de configuração completo ficará parecido com:

###########################################################
#######                   OpenVPN                   #######
#######                       Client                #######
###########################################################
#
# Arquivo de configuracao para o cliente
# Criado por Tobias Sette <contato@tobias.ws>
# xx/xx/2012 - v0.1 - Início
# xx/xx/2012 - v0.2 - 
# 01/06/2012 - v0.3 - reformulado com base no OpenVPN do Debian Squeeze (OpenVPN 2.2.x)
# 10/07/2015 - v0.4 - reformulado com base no OpenVPN do Debian Jessie (OpenVPN 2.3.x)
#
# Este arquivo de configuração foi testado, sem modificações significativas,
# nas seguintes versões do OpenVPN:
#  -> OpenVPN 2.3.4 x86_64 (Debian testing stretch)
 
 
##############################
#     Notas
##############################
 
# Carregue o module tun do kernel (modprobe tun) e
# certifique-se que ele está sendo carregado na
# inicializacao do sistema. O mais comum é ser
# chamado no arquivo /etc/modules
 
# Para testar os arquivos de configuracao:
# openvpn --config /etc/openvpn/arquivo.conf
 
# Os hosts tem que estar com o horario correto; utilize
# ntpdate -u pool.ntp.org para atualizar
 
# Este arquivo deve funcionar em diversos sistemas. No windows,
# lembre-se de escapar nomes completos de arquivos, como em
# "C:\\Foo\\Bar\\foo.key", e renomeie este arquivo para a extensao .ovpn
 
 
##############################
#     Dados da conexao
##############################
 
# Define que esta maquina é um cliente e que obterá configurações do servidor
    client
 
# Na maior parte das vezes o cliente não precisa utilizar uma porta local
# específica
nobind
 
# Endereco do host no qual se vai conectar. Especificar
# mais de um e remote-random faz com que o cliente escolha um
# servidor (ativo) aleatoriamente a cada conexao, criando redundância
# e balanceamento de carga. Não especificar remote-random faz com que
# a escolha do servidor ocorra na ordem em que foram especificados.
# O segundo parâmetro especifica a porta na qual o OpenVPN irá rodar.
# Por padrao (e caso omitida) a porta 1194 eh utilizada
    remote $meuServidor 1194
;remote-random
 
# Define o protocolo a ser utilizado.
# Por padrao (e caso omtido) o protocolo udp é utilizado.
# Utilizar udp preferencialmente, pois este protocolo
# não faz correção/redundancia dos pacotes. O OpenVPN
# apenas cria a conexão, em cima dela rodarão os protocolos
# cabiveis (tcp, udp, etc), não sendo necessário utilizar
# correção de erros nesta camada.
# Para utiliza protocolo tcp:
;proto tcp-server
    proto udp
 
# Se você está conetando à internet através de um proxy HTTP, defina o parâmetro
# http-proxy.
# http-proxy-retry faz com que uma nova tentativa seja feita em casa de falha
# de conexão
;http-proxy-retry
;http-proxy $ip $porta
 
 
##############################
#     Interface de rede
##############################
 
# Define qual interface, e de qual tipo, ira responder
# pela VPN
# No tun o trafego da rede é roteado eliminando pacotes de
# broadcast, no tap é criado uma interface ethernet onde tudo é transmitido.
# No windows você deve especificar um número para a interface, como em tun0.
    dev tun
 
# No Windows é necessário especificar o nome do adapator TAP-Win32
# a partir do painel de conexões de rede, se você tiver mais de um.
;dev-node MyTap
 
 
##############################
#   Qualidade da conexão
##############################
 
# Pinga o host remoto a cada $x segundos sem atividade na rede, se ele
# nao responder por $z segundos a conexão é reiniciada.
# Quando a conexão é interrompida o cliente tenta restabelece-la
# periodicamente
# Uso: keepalive $x $z
    keepalive 10 120
 
# Compacta os dados da conexão utilizando o pacote lzo (deve estar
# instalado no host), com um pequeno aumento de processamento.
# Se estiver habilitado no servidor, o cliente também deve habilitar
    comp-lzo
 
# mantem as chaves carregadas mesmo durante o reinicio do serviço.
    persist-key
 
# mantem o tunel aberto mesmo durante o reinicio do serviço.
    persist-tun
 
# Fica tentando, indefinidamente, resolver o nome do host do servidor. Útil
# em hosts que não estão permanentemente conectados à internet.
    resolv-retry infinite
 
# Tenta realizar a reconexao com host remoto por $x segundos
;inactive 3600
 
# mantem o tunel aberto mesmo se o ip do outro host mudar
    float
 
# lmita o trafego de saida do Openvpn a N bytes.
;shaper 51200
 
# Redes wireless frequentemente produzem muitos pacotes duplicados. O parâmetro
# abaixo faz com que os avisos de pacotes duplicados sejam silenciados
;mute-replay-warnings
 
 
##############################
#      Autenticacao
##############################
 
# Faz com que o cliente verifique se o certificado do servidor tem o campo
# nsCertType definido para "server". Precaução importante para evitar MITM [4]
    ns-cert-type server
 
# Utilizando a mesma chave, estatica, nos dois hosts
# para gerar: openvpn --genkey --secret /etc/openvpn/keys/estatica.key
# depois copiar para o outro host
;secret estatica.key
 
# Define que as solicitações de conexão devem ser encriptadas
# com ta.key. É útil para bloquear ataques DoS e flood na porta UDP.
# O segundo parâmetro deve ser 0 no servidor e 1 no cliente.
# Copiar ta.key para cada host que vá se conectar.
# para gerar: openvpn --genkey --secret /etc/openvpn/keys/ta.key
;tls-auth /etc/openvpn/keys/ta.key 1
 
# Define qual a cifra criptográfica. Esta configuração deve ser igual no
# cliente.
;cipher BF-CBC        # Blowfish (padrão)
;cipher AES-128-CBC   # AES
;cipher DES-EDE3-CBC  # Triple-DES
 
 
##############################
#      Certificados X509
##############################
 
 
# Parametro necessario para utilizar conexão com certificados X509
    tls-client
 
# Caminho para o arquivo contendo parametros Diffie Hellman
#    dh dh2048.pem
<dh>
-----BEGIN DH PARAMETERS-----
Texto aqui
-----END DH PARAMETERS-----
</dh>
 
# Local do arquivo de certificado (.crt) da unidade certificadora
#    ca ca.crt
<ca>
-----BEGIN CERTIFICATE-----
Texto aqui
-----END CERTIFICATE-----
</ca>
 
# Local do arquivo de certificado (.crt) do cliente
#    cert $nomeCliente.crt
<cert>
-----BEGIN CERTIFICATE-----
Texto aqui
-----END CERTIFICATE-----
</cert>
 
# Local da chave (.key) do cliente. Este arquivo deve ser mantido secreto
#    key $nomeCliente.key
<key>
-----BEGIN PRIVATE KEY-----
Texto aqui
-----END PRIVATE KEY-----
</key>
 
 
##############################
#           Outros
##############################
 
# É uma boa prática diminuir os privilégios do OpenVPN após a inicialização.
# Utilize estas opções em clientes não Windows.
# Note que as opções persist-key e persist-tun podem ser habilitadas
# para evitar erros de acesso a recursos que podem ficam indisponíveis depois
# da redução de privilégios
    user nobody
    group nogroup
 
# Grava um curto arquivo de status mostrando conexões atuais. O arquivo é
# truncado e reescrito a cada minuto.
    status openvpn-status.log
 
# Por padrão as mensagens de log vão para o syslog (ou no Windows, se rodando
# como serviço, vão para o diretório "\Program Files\OpenVPN\log"). Utilize log
# ou log-append para sobrescrever este comportamento.
# log irá truncar o arquivo de log a cda inicialização do OpenVPN, enquanto
# log-append irá acrescentar nele. Use um dos dois.
;log         openvpn.log
;log-append  openvpn.log
 
# Define o quão verboso será o log.
# 0 é silencioso, exceto por erros fatais
# 4 é rasoável para o uso geral
# 5 e 6 podem ajudá-lo a debugar problemas de conexão
# 9 é extremamente verboso
    verb 3
 
# Ignora mensagens repetidas. Até x mensagens sequenciais da mesma categoria
# serão escritas no log
;mute 20
 
#EOF

Acessando

Através da linha de comando

Entre no diretório onde estão os arquivos gerados no servidor, juntamente com o client.ovpn e execute openvpn client.ovpn. Exemplo:

root@lothlorien:/home/tobias/Downloads/arquivos_cliente_tal# openvpn client.ovpn
Thu Jul 16 05:37:28 2015 OpenVPN 2.3.4 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [PKCS11] [MH] [IPv6] built on Dec  1 2014
Thu Jul 16 05:37:28 2015 library versions: OpenSSL 1.0.2c 12 Jun 2015, LZO 2.08
Thu Jul 16 05:37:28 2015 Socket Buffers: R=[212992->131072] S=[212992->131072]
Thu Jul 16 05:37:28 2015 NOTE: UID/GID downgrade will be delayed because of --client, --pull, or --up-delay
Thu Jul 16 05:37:28 2015 UDPv4 link local: [undef]
Thu Jul 16 05:37:28 2015 UDPv4 link remote: [AF_INET]103.121.102.2:1194
Thu Jul 16 05:37:28 2015 TLS: Initial packet from [AF_INET]103.121.102.2:1194, sid=152e859a 7f1a70dd
Thu Jul 16 05:37:29 2015 VERIFY OK: depth=1, C=BR, ST=ES, L=Vitoria, O=tobias.ws, OU=tobias.ws, CN=ignucius, name=EasyRSA, emailAddress=eu@meuprovedor.com.br
Thu Jul 16 05:37:29 2015 VERIFY OK: nsCertType=SERVER
Thu Jul 16 05:37:29 2015 VERIFY OK: depth=0, C=BR, ST=ES, L=Vitoria, O=tobias.ws, OU=tobias.ws, CN=ignucius, name=EasyRSA, emailAddress=eu@meuprovedor.com.br
Thu Jul 16 05:37:31 2015 Data Channel Encrypt: Cipher 'BF-CBC' initialized with 128 bit key
Thu Jul 16 05:37:31 2015 Data Channel Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Thu Jul 16 05:37:31 2015 Data Channel Decrypt: Cipher 'BF-CBC' initialized with 128 bit key
Thu Jul 16 05:37:31 2015 Data Channel Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Thu Jul 16 05:37:31 2015 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 2048 bit RSA
Thu Jul 16 05:37:31 2015 [picard] Peer Connection Initiated with [AF_INET]103.121.102.2:1194
Thu Jul 16 05:37:34 2015 SENT CONTROL [picard]: 'PUSH_REQUEST' (status=1)
Thu Jul 16 05:37:34 2015 PUSH: Received control message: 'PUSH_REPLY,redirect-gateway def1 bypass-dhcp,route 10.8.0.1,topology net30,ping 10,ping-restart 120,ifconfig 10.8.0.6 10.8.0.5'
Thu Jul 16 05:37:34 2015 OPTIONS IMPORT: timers and/or timeouts modified
Thu Jul 16 05:37:34 2015 OPTIONS IMPORT: --ifconfig/up options modified
Thu Jul 16 05:37:34 2015 OPTIONS IMPORT: route options modified
Thu Jul 16 05:37:34 2015 ROUTE_GATEWAY 192.168.1.1/255.255.255.0 IFACE=wlan0 HWADDR=c7:35:1f:1d:12:ac
Thu Jul 16 05:37:34 2015 TUN/TAP device tun0 opened
Thu Jul 16 05:37:34 2015 TUN/TAP TX queue length set to 100
Thu Jul 16 05:37:34 2015 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Thu Jul 16 05:37:34 2015 /sbin/ip link set dev tun0 up mtu 1500
Thu Jul 16 05:37:34 2015 /sbin/ip addr add dev tun0 local 10.8.0.6 peer 10.8.0.5
Thu Jul 16 05:37:34 2015 /sbin/ip route add 103.121.102.2/32 via 192.168.1.1
Thu Jul 16 05:37:34 2015 /sbin/ip route add 0.0.0.0/1 via 10.8.0.5
Thu Jul 16 05:37:34 2015 /sbin/ip route add 128.0.0.0/1 via 10.8.0.5
Thu Jul 16 05:37:34 2015 /sbin/ip route add 10.8.0.1/32 via 10.8.0.5
Thu Jul 16 05:37:34 2015 GID set to nogroup
Thu Jul 16 05:37:34 2015 UID set to nobody
Thu Jul 16 05:37:34 2015 Initialization Sequence Completed

E está feito. A partir deste momento sua conexão à internet é redirecionada ao servidor (exceto o próprio acesso ao servidor, claro!). Você pode veririfar acessando este link e clicando em lookup. O site irá exibir seu ip (que deverá ser o do servidor) e informações geográficas sobre ele.

No Gnome ou Cinnamon

Instale o pacote network-manager-openvpn-gnome. Após isso será possível usar o gerenciador de redes para importar um arquivo de configuração do OpenVPN ou criar uma conexão do zero.

No Android

No Android, versão 4+, o acesso pode ser feito utilizado ao app OpenVPN for Android, que pode ser baixado no repositório do f-droid ou no google play. Exemplo:

OpenVPN android - 1

Nesta tela, toque no +, vá em importar e informe onde está o arquivo de configuração.

OpenVPN android - 2

O app exibe um aviso de que algumas das opções não foram mepadas para a interface gráfica, não há problema.

Depois de importado o arquivo, toque no nome da configuração (client, neste caso) e veja o aplicativo realizar o processo de conexão. Se a operação for bem sucedida, será exibida uma tela como em:

OpenVPN android - 3

Para desconectar basta tocar no ícone de opções (três pontos na vertical) e escolher “Desconectar VPN”.

No Windows

Se você estiver no Windows, baixe e instale o cliente para a sua versão do sistema operacional. Após isso vá à pasta “Arquivos de programas”, OpenVPN, e coloque os arquivos de configuração dentro dela. É possível também criar uma subpasta para cada servidor, mas lembre-se de não repetir o nome dos arquivos de configuração (.ovpn).

No MacOS

Neste sistema pode-se utilizar o software tunnelblick. Mais informações aqui.

Informações adicionais

Você pode obter outros arquivos de configuração através deste repositório no github.

Referências

Atualizações

  • 18/09/15 – atualizado informações de segurança sobre Diffie-Hellman
  • 09/10/15 – acrescentado uma dica e removido ./clean-all
  • 02/11/15 – inserido informações sobre a configuração no client: embutir certficados, configuração no gnome, android e windows.