O OpenVPN é uma ferramenta extremamente poderosa para permitir o acesso seguro à rede de sua empresa ou residência.

Você pode utilizá-lo para permitir que os funcionários da empresa trabalhem de casa ou de qualquer lugar com acesso a Internet, de forma segura e transparente.

Outro uso bastante comum é permitir a conexão de filiais à matriz da empresa, de forma a permitir o acesso das filiais aos arquivos e serviços disponibilizados pela matriz. Muitas empresas utilizam links dedicados justamente para fazer isso. Uma opção é, além de utilizar o link dedicado, usar um link ADSL como redundância e só conectar a VPN - pelo link ADSL - quando o link principal apresentar algum problema.

Este tutorial irá ensiná-lo a instalar e configurar um servidor OpenVPN no sistema operacional Ubuntu 12.04 LTS ou superior e também como configurar clientes Windows e Linux para acessar o servidor de VPN.

A topologia que estamos interessados esta ilustrada na figura abaixo, com um computador ligado à Internet e conectado à rede da empresa através da VPN, de forma que esse computador opere como se estivesse fisicamente conectado na rede da matriz.

Para a conexão OpenVPN é necessário a criação de chaves criptográficas, um par de chaves (pública e privada) para cada cliente, onde a chave pública fica no servidor de OpenVPN e a chave privada fica de posse do cliente. Para isso iremos criar nossa própria Autoridade Certificadora (CA).

Em outro tutorial irei ensinar como utilizar um certificado digital emitido por uma Autoridade Certificadora pública como Certisign, Verisign, Caixa Econômica Federal ou outra.

Você não precisa se preocupar em entender a fundo a questão da criptografia, mas se tiver interesse no tema, um bom começo é a Cartilha de Segurança disponibilizada pelo Centro de Estudos, Resposta e Tratamento de Incidentes de Segurança no Brasil.

Pré-Requisitos

O OpenVPN está disponível em duas versões: Access Server e Community. A versão Access Server necessita de uma licença paga para funcionar. Já a versão Community é gratuita e não oferece suporte. Este tutorial está focado na versão gratuita Community.

Você precisará:

  1. Servidor com Ubuntu 10.04/12.04 LTS ou superior (x86 ou amd64). Você pode utilizar a distribuição linux de sua preferência, inclusive utilizar um servidor Windows se desejar, pois o OpenVPN é muito versátil, porém, terá que fazer as adaptações necessárias para seu ambiente. Este tutorial vai focar na instalação do OpenVPN server no Ubuntu 12.04 LTS amd64. Este servidor pode ser - e é até recomendável que seja - o seu firewall.
  2. Cliente com Windows XP, Vista, 7, ou superior instalado. O cliente também pode ser uma estação Linux. Este tutorial irá tratar dos passos necessário para instalar e configurar o cliente da VPN em um computador executando WIndows.
  3. Endereço IP da rede VPN a ser criada. Você pode definir a rede que julgar mais apropriada, porém é bom que esta rede seja diferente da rede dos usuários. As redes mais comuns de uso doméstico são 192.168.0.0/24, 192.168.1.0/24 e 10.0.0.0/24. É melhor você escolher uma faixa diferente dessas, porém dentro da faixa de endereços privados. Neste tutorial vou usar o endereço da rede VPN como sendo 10.15.0.0/24. Você pode usar outra máscara de sub-rede, de acordo com suas necessidades. Optei pela máscara 24 (255.255.255.0) por ser uma das mais usuais.
  4. Definir qual a porta e protocolo (UDP ou TCP) a ser utilizado para a conexão VPN. A porta e protocolos padrão para o OpenVPN são 1194 e UDP. Neste tutorial irei utilizar esta porta e protocolo. Recomendo que o protocolo utilizado seja UDP, pois encapsular uma conexão TCP dentro de outra TCP pode trazer alguns problemas de desempenho devido aos algoritmos de retransmissão de pacotes e de janelas deslizantes do TCP. Vai funcionar, porém você poderá experimentar algum tipo de lentidão.
  5. Definir o tipo de interface a ser utilizada TUN ou TAP. A interface mais comum é a TUN, que opera em camada 3 do modelo OSI em modo roteamento. A Interface TAP trabalho em camada 2 do modelo OSI e é utilizada para modo bridge. Neste tutorial iremos usar modo roteamento com interface TUN.
  6. IP público de seu roteador de Internet. Se você não possui um IP fixo, pode utilizar algum serviço de DNS dinâmico para manter seu IP atualizado e permitir a conexão VPN. O que costumo usar é o No-IP.
  7. Regra de redirecionamento (NAT) em seu roteador Internet, encaminhando os pacotes destinados ao IP público de seu roteador na porta 1194 e protocolo UDP para o IP interno de seu servidor OpenVPN. A forma de fazer o NAT difere de roteador para roteador. Você pode pesquisar no Google por "como abrir portas" para o modelo de seu roteador. Se o seu servidor OpenVPN já estiver usando um IP público então esse NAT não é necessário.
  8. OpenVPN Community Windows - Cliente Windows com interface gráfica para o OpenVPN. Você pode obtê-lo aqui.
  9. A versão server do OpenVPN Community será obtida via apt-get no Ubuntu. Você pode obter o instalador ou código fonte para outras distribuições na página do OpenVPN Community.
  10. Privilégios administrativos no servidor Linux e no cliente Windows, permitindo a instalação de softwares e configuração dos equipamentos.

Resumo

São esses os passos que iremos seguir:

  1. Instalação do Servidor OpenVpn e Criação da CA Local
  2. Criação do Certificado do Servidor
  3. Configuração do Servidor OpenVPN
  4. Regras de Firewall
  5. Criando Certificados para Clientes
  6. Instalando e configurando o OpenVPN nos Clientes
  7. Revogando Certificados de Clientes
  8. Informações Adicionais

Tutorial

Depois de conferido todos os pré-requisitos, vamos por a mão na massa.

1. Instalação do Servidor OpenVPN e Criação da CA Local

Para instalar o OpenVPN no Ubuntu execute:

apt-get install openvpn

Após a instalação, copie os arquivos de exemplo de configuração da pasta /usr/share/doc/openvpn/examples/easy-rsa/2.0/ para a pasta /etc/openvpn.

cp /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn

Renomeie ou crie uma cópia do arquivo /etc/openvpn/openssl-1.0.0.cnf para /etc/openvpn/openssl.cnf.

cp /etc/openvpn/openssl-1.0.0.cnf /etc/openvpn/openssl.cnf

Edite o arquivo /etc/openvpn/vars ajustando as últimas linhas iniciadas por KEY para refletir o seu ambiente.

É interessante, porém não obrigatório, que o parâmetro KEY_CN tenha o mesmo valor que o hostname do servidor OpenVPN.

Se existir, remova as últimas linhas referentes as chaves PKCS11_MODULE_PATH e PKCS11_PIN. Se existir uma chave duplicada KEY_EMAIL, remova-a também.

O tempo padrão para a expiração do certificado da CA e das chaves a serem geradas é de 10 anos (3650 dias). Se preferir altere estes valores editando os parâmetros CA_EXPIRE e KEY_EXPIRE.

O tamanho da chave de criptografia está definido como 1024 bits. Se quiser mudar este valor edite o parâmetro KEY_SIZE.O conteúdo de meu /etc/openvpn/vars segue abaixo:

# easy-rsa parameter settings
# NOTE: If you installed from an RPM,
# don't edit this file in place in
# /usr/share/openvpn/easy-rsa --
# instead, you should copy the whole
# easy-rsa directory to another location
# (such as /etc/openvpn) so that your
# edits will not be wiped out by a future
# OpenVPN package upgrade.

# This variable should point to
# the top level of the easy-rsa
# tree.
export EASY_RSA="`pwd`"

#
# This variable should point to
# the requested executables
#
export OPENSSL="openssl"
export PKCS11TOOL="pkcs11-tool"
export GREP="grep"

# This variable should point to
# the openssl.cnf file included
# with easy-rsa.
export KEY_CONFIG=`$EASY_RSA/whichopensslcnf $EASY_RSA`

# Edit this variable to point to
# your soon-to-be-created key
# directory.
#
# WARNING: clean-all will do
# a rm -rf on this directory
# so make sure you define
# it correctly!
export KEY_DIR="$EASY_RSA/keys"

# Issue rm -rf warning
echo NOTE: If you run ./clean-all, I will be doing a rm -rf on $KEY_DIR

# PKCS11 fixes
export PKCS11_MODULE_PATH="dummy"
export PKCS11_PIN="dummy"

# Increase this to 2048 if you
# are paranoid.  This will slow
# down TLS negotiation performance
# as well as the one-time DH parms
# generation process.
export KEY_SIZE=1024

# In how many days should the root CA key expire?
export CA_EXPIRE=3650

# In how many days should certificates expire?
export KEY_EXPIRE=3650

# 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="SP"
export KEY_CITY="São Paulo"
export KEY_ORG="Blog do Nerd"
export KEY_EMAIL="nerd@blogdonerd.email.com"
export KEY_CN="openvpn"
export KEY_NAME="Blog do Nerd CA"
export KEY_OU="Divisão de TI"

Agora execute os comandos abaixo:

source /etc/openvpn/vars
/etc/openvpn/clean-all
/etc/openvpn/build-ca
/etc/openvpn/build-dh

Confirme os valores solicitados pelo build-ca, que serão os mesmos definidos no arquivo /etc/openvpn/vars.

A saída dos comandos será semelhante a abaixo:

root@openvpn:/etc/openvpn# source /etc/openvpn/vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/keys
root@openvpn:/etc/openvpn# /etc/openvpn/clean-all
root@openvpn:/etc/openvpn# /etc/openvpn/build-ca
Generating a 1024 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) [SP]:
Locality Name (eg, city) [São Paulo]:
Organization Name (eg, company) [Blog do Nerd]:
Organizational Unit Name (eg, section) [Divisão de TI]:
Common Name (eg, your name or your server's hostname) [openvpn]:
Name [Blog do Nerd CA]:
Email Address [nerd@blogdonerd.email.com]:
root@openvpn:/etc/openvpn# /etc/openvpn/build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
...............+.........................+..................................
.................................+..........................................
.......+....................................................................
....................+............................................+..........
+............+..............................................................
................................+.................................+.........
..................+......................+...........+.....+................
............................................................................
+....................................+................+.....+...............
.............................+............................................+.
......................+.............+..+....................................
................+...................................................+......+
.......+..............................+.....................................
..................................................+.++*++*++*
root@openvpn:/etc/openvpn# 

A pasta /etc/openvpn/keys será gerada e dentro dela, 5 arquivos referentes a nova CA criada:

  1. ca.crt - Certificado Público de sua CA.
  2. ca.key - Chave Privada de sua CA.
  3. dh1024.pem - Parâmetros do Diffie-Hellman.
  4. index.txt - Controle das chaves geradas pela nova CA.
  5. serial - Controle de número serial das chaves geradas pela nova CA.

2. Criação do Certificado do Servidor

É necessário a geração de um certificado para o servidor OpenVPN.
Para fazer isso execute:
/etc/openvpn/build-key-server server
Você pode substituir a palavra server por outra que desejar, só que se fizer isso, lembre-se de fazer os devidos ajustes no arquivo /etc/openvpn/server.conf que será configurado no próximo passo.
A saída do comando será semelhante a abaixo.
Ajuste o parâmetro Name para o nome que julgar mais apropriado para seu servidor.
Recomendo não atribuir um challenge password.
Confirme a assinatura e a atualização do certificado com a tecla 'y'.
root@openvpn:/etc/openvpn# /etc/openvpn/build-key-server server
Generating a 1024 bit RSA private key
...............++++++
..++++++
writing new private key to 'server.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]:
Locality Name (eg, city) [São Paulo]:
Organization Name (eg, company) [Blog do Nerd]:
Organizational Unit Name (eg, section) [Divisão de TI]:
Common Name (eg, your name or your server's hostname) [server]:
Name [Blog do Nerd CA]:Blog do Nerd - OpenVPN Server
Email Address [nerd@blogdonerd.email.com]:

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/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           : PRINTABLE:'BR'
stateOrProvinceName   : PRINTABLE:'SP'
localityName          : T61STRING:'Sao Paulo'
organizationName      : PRINTABLE:'Blog do Nerd'
organizationalUnitName: T61STRING:'Divisao de TI'
commonName            : PRINTABLE:'server'
name                  : PRINTABLE:'Blog do Nerd - OpenVPN Server'
emailAddress          : IA5STRING:'nerd@blogdonerd.email.com'
Certificate is to be certified until Jun 18 18:57:10 2022 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@openvpn:/etc/openvpn#
Dois arquivos serão gerados na pasta /etc/openvpn/keys:
  • server.crt - Certificado público do servidor OpenVPN.
  • server.key - Chave privada do servidor OpenVPN.

3. Configuração do Servidor OpenVPN

Gere uma chave TLS (opcional) para aumentar ainda mais a segurança da conexão VPN, permitindo a verificação de integridade de cada pacote TLS, digitando o seguinte comando:

openvpn --genkey --secret /etc/openvpn/keys/ta.key

A configuração do OpenVPN é realizada em qualquer arquivo que termine em .conf, localizado na pasta /etc/openvpn/. Neste tutorial iremos usar o arquivo /etc/openvpn/server.conf. Você pode alterar este arquivo para o nome que desejar, desde que ele termine em .conf. Você pode inclusive ter mais de um serviço OpenVPN ouvindo em outras portas, basta configurar outro arquivo .conf.

Crie um /etc/openvpn/server.conf vazio e preencha-o conforme segue.

Se preferir, você pode iniciar usando o arquivo de configuração de exemplo do OpenVPN, bastando para isso copiar e descomprimir o arquivo /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz para /etc/openvpn/server.conf:

zcat /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server.conf

Ajuste o arquivo /etc/openvpn/server.conf conforme abaixo, tomando o cuidado de alterar as linhas destacadas para refletir a realidade de seu ambiente.

  • A linha local 10.0.0.1 indica o IP local do servidor em que OpenVPN irá ouvir por novas conexões.
  • A configuração server 10.15.0.0 255.255.255.0 informa ao servidor OpenVPN que a rede VPN será 10.15.0.0/24. Altere para a rede que definiu durante a fase de pré-requisitos. O primeiro IP dessa rede será o IP do servidor OpenVPN.
  • Se desejar você pode ajustar a linha push "route 10.0.0.0 255.0.0.0" informando ao OpenVPN para adicionar uma rota na tabela de rotas dos clientes VPN no momento da conexão. Neste caso todo o tráfego para a rede 10.0.0.0/8 será redirecionado pela VPN. Você pode ser mais radical e direcionar todo o tráfego de rede pela VPN, incluindo o tráfego de Internet. Para fazer isso, substitua a linha push "route 10.0.0.0 255.0.0.0" por push "redirect-gateway def1".
  • As configurações push "dhcp-option" são opcionais e relativas aos parâmetros de DNS a serem informados para o computador cliente. Você pode informar os servidores de DNS locais da rede da sede para que os clientes possam resolver nomes de domínio e acessar os serviços internos com maior facilidade.
Muitos dos parâmetros são opcionais e o OpenVPN é extremamente versátil e se adapta a praticamente qualquer ambiente. Você pode verificar o manual do OpenVPN para explorar outras configurações.
O arquivo /etc/openvpn/server.conf sugerido é o seguinte:
######################################################################################
# OpenVPN 2.0 - Arquivo de configuração do servidor
######################################################################################

# Which local IP address should OpenVPN
# listen on? (optional)
local 10.0.0.1

# Which TCP/UDP port should OpenVPN listen on?
port 1194

# TCP or UDP server?
proto udp

# "dev tun" will create a routed IP tunnel,
# "dev tap" will create an ethernet tunnel.
dev tun0

# SSL/TLS root certificate (ca), certificate
# (cert), and private key (key).  Each client
# and the server must have their own cert and
# key file.  The server and all clients will
# use the same ca file.
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key  # This file should be kept secret

# Diffie hellman parameters.
dh /etc/openvpn/keys/dh1024.pem

# Configure server mode and supply a VPN subnet
# for OpenVPN to draw client addresses from.
server 10.15.0.0 255.255.255.0

# Maintain a record of client  virtual IP address
# associations in this file.  If OpenVPN goes down or
# is restarted, reconnecting clients can be assigned
# the same virtual IP address from the pool that was
# previously assigned.
ifconfig-pool-persist ipp.txt

# Push routes to the client to allow it
# to reach other private subnets behind
# the server.  Remember that these
# private subnets will also need
# to know to route the OpenVPN client
# address pool (10.8.0.0/255.255.255.0)
# back to the OpenVPN server.
push "route 10.0.0.0 255.0.0.0"

# Certain Windows-specific network settings
# can be pushed to clients, such as DNS
# or WINS server addresses.  CAVEAT:
# http://openvpn.net/faq.html#dhcpcaveats
push "dhcp-option DNS 10.0.0.10"
push "dhcp-option DNS 10.0.0.11"
push "dhcp-option DOMAIN blogdonerd.com.br"

# The keepalive directive causes ping-like
# messages to be sent back and forth over
# the link so that each side knows when
# the other side has gone down.
# Ping every 10 seconds, assume that remote
# peer is down if no ping received during
# a 120 second time period.
keepalive 10 120

# For extra security beyond that provided
# by SSL/TLS, create an "HMAC firewall"
# to help block DoS attacks and UDP port flooding.
tls-auth /etc/openvpn/keys/ta.key 0 # This file is secret

# Select a cryptographic cipher.
# This config item must be copied to
# the client config file as well.
cipher AES-128-CBC   # AES

# Enable compression on the VPN link.
# If you enable it here, you must also
# enable it in the client config file.
comp-lzo

# The maximum number of concurrently connected
# clients we want to allow.
max-clients 100

# It's a good idea to reduce the OpenVPN
# daemon's privileges after initialization.
user nobody
group nogroup

# The persist options will try to avoid
# accessing certain resources on restart
# that may no longer be accessible because
# of the privilege downgrade.
persist-key
persist-tun

# Output a short status file showing
# current connections, truncated
# and rewritten every minute.
status /var/log/openvpn/openvpn-status.log

# By default, log messages will go to the syslog (or
# on Windows, if running as a service, they will go to
# the "\Program Files\OpenVPN\log" directory).
log-append /var/log/openvpn/openvpn.log

# Set the appropriate level of log
# file verbosity.
verb 3

Crie a pasta /var/log/openvpn para manter os logs do OpenVPN:

mkdir /var/log/openvpn

Se desejar crie o arquivo /etc/logrotate.d/openvpn com o conteúdo a seguir para fazer uma rotação automática dos logs do OpenVPN:

/var/log/openvpn/*.log {
    daily
    rotate 365
    compress
    missingok
    create 0640 root adm
    missingok
    postrotate
        service openvpn reload
    endscript
}

Inicie o OpenVPN executando:

service openvpn start

Verifique se o serviço está em execução com o comando:

 service openvpn status

Se tudo ocorreu com sucesso, a saída será semelhante a seguinte:

root@openvpn:/etc/openvpn# service openvpn start
 * Starting virtual private network daemon(s)...
 *   Autostarting VPN 'server'
root@openvpn:/etc/openvpn# service openvpn status
 * VPN 'server' is running
root@openvpn:/etc/openvpn#

Se ocorreu algum problema, verifique o arquivo /var/log/openvpn.log:

root@openvpn:/etc/openvpn# cat /var/log/openvpn/openvpn.log
Wed Jun 20 16:16:40 2012 OpenVPN 2.2.1 x86_64-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [eurephia] [MH] [PF_INET6] [IPv6 payload 20110424-2 (2.2RC2)] built on Mar 30 2012
Wed Jun 20 16:16:40 2012 NOTE: OpenVPN 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables
Wed Jun 20 16:16:40 2012 Diffie-Hellman initialized with 1024 bit key
Wed Jun 20 16:16:40 2012 Control Channel Authentication: using '/etc/openvpn/keys/ta.key' as a OpenVPN static key file
Wed Jun 20 16:16:40 2012 Outgoing Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
Wed Jun 20 16:16:40 2012 Incoming Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
Wed Jun 20 16:16:40 2012 TLS-Auth MTU parms [ L:1558 D:166 EF:66 EB:0 ET:0 EL:0 ]
Wed Jun 20 16:16:40 2012 Socket Buffers: R=[229376->131072] S=[229376->131072]
Wed Jun 20 16:16:40 2012 ROUTE default_gateway=10.0.0.1
Wed Jun 20 16:16:40 2012 TUN/TAP device tun0 opened
Wed Jun 20 16:16:40 2012 TUN/TAP TX queue length set to 100
Wed Jun 20 16:16:40 2012 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Wed Jun 20 16:16:40 2012 /sbin/ifconfig tun0 10.15.0.1 pointopoint 10.15.0.2 mtu 1500
Wed Jun 20 16:16:40 2012 /sbin/route add -net 10.15.0.0 netmask 255.255.255.0 gw 10.15.0.2
Wed Jun 20 16:16:40 2012 Data Channel MTU parms [ L:1558 D:1450 EF:58 EB:135 ET:0 EL:0 AF:3/1 ]
Wed Jun 20 16:16:40 2012 GID set to nogroup
Wed Jun 20 16:16:40 2012 UID set to nobody
Wed Jun 20 16:16:40 2012 UDPv4 link local (bound): [AF_INET]10.9.0.172:1194
Wed Jun 20 16:16:40 2012 UDPv4 link remote: [undef]
Wed Jun 20 16:16:40 2012 MULTI: multi_init called, r=256 v=256
Wed Jun 20 16:16:40 2012 IFCONFIG POOL: base=10.15.0.4 size=62, ipv6=0
Wed Jun 20 16:16:40 2012 IFCONFIG POOL LIST
Wed Jun 20 16:16:40 2012 Initialization Sequence Completed

Uma nova interface de rede (tun0) será criada, conforme ilustra a execução do comando ifconfig abaixo.

root@openvpn:/etc/openvpn# ifconfig
eth0      Link encap:Ethernet  HWaddr 00:50:56:be:46:45
          inet addr:10.0.0.1  Bcast:10.0.0.255  Mask:255.255.255.0
          inet6 addr: fe80::250:56ff:febe:4645/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:135820 errors:0 dropped:0 overruns:0 frame:0
          TX packets:58093 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:149189479 (149.1 MB)  TX bytes:5400632 (5.4 MB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:14 errors:0 dropped:0 overruns:0 frame:0
          TX packets:14 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1176 (1.1 KB)  TX bytes:1176 (1.1 KB)

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:10.15.0.1  P-t-P:10.15.0.2  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

root@openvpn:/etc/openvpn#

O servidor já está no ar. Agora precisamos configurar regras de firewall, se necessário, criar as chaves para os clientes e configurá-los.

4. Regras de Firewall

Se seu servidor OpenVPN está configurado no mesmo equipamento que seu firewall, ou se a comunicação precisa atravessar por um firewall para chegar até o servidor OpenVPN, é importante configurar as regras adequadamente.

Não vou ensinar aqui a criar as regras para um ambiente específico, pois existe uma diversidade enorme de ferramentas para gerenciar regras de firewall e cada caso é um caso.

Vou tratar apenas de regras de uma forma genérica.

Vamos ao pontos importantes:

  1. O primeiro IP definido no parâmetro server do /etc/openvpn/server.conf é o IP local do OpenVPN e o segundo IP é o endereço considerado remoto. No exemplo deste tutorial:
    1. O endereço da rede é 10.15.0.0 com máscara 255.255.255.0.
    2. O endereço 10.15.0.0 é o endereço da rede e, por definição, não pode ser atribuído a nenhum equipamento.
    3. O IP 10.15.0.1 é o IP atribuído a interface tun0 local
    4. O IP 10.15.0.2 é um IP lógico, atribuído genericamente ao gateway dos clientes. Você pode utilizar este IP para fazer regras de roteamento, por exemplo, se seu cliente está na rede 10.2.0.0/24, você pode criar uma regra de roteamento que encaminhe todos os pacotes destinados a rede 10.2.0.0/24 para o gateway 10.15.0.2: route add -net 10.2.0.0/24 gw 10.15.0.2 dev tun0
  2. É necessário criar uma regra que permita que comunicação oriundas da internet e destinadas ao IP do seu servidor OpenVPN na porta 1194 UDP sejam aceitas. Uma regra iptables seria: iptables -A INPUT -i eth0 -d 10.0.0.1/32 -p udp -m udp --dport 1194 -j ACCEPT
  3. Uma vez permitida a conexão é necessário criar regras que permitam que seu cliente converse com os serviços de sua rede e vice-versa. Neste caso, cada rede vai ter suas particularidades. Por exemplo, para permitir que qualquer cliente da rede OpenVPN (10.15.0.0/24) acesse um servidor de DNS de IP 10.0.0.15 em sua rede, as regras iptables seriam:
    1. iptables -A FORWARD -i tun0 -s 10.15.0.0/24 -d 10.0.0.15/32 -p tcp -m tcp --dport 53 -j ACCEPT
    2. iptables -A FORWARD -i tun0 -s 10.15.0.0/24 -d 10.0.0.15/32 -p udp -m udp --dport 53 -j ACCEPT
  4. Lembre-se de que para estas regras funcionarem é importante permitir o roteamento entre as interfaces. Isto pode ser feito atribuindo o valor 1 ao parâmetro /proc/sys/net/ipv4/ip_forward. Você pode colocar uma linha com o comando a seguir em algum script de inicialização de seu servidor, ou ajustar este parâmetro diretamente no seu firewall, se ele assim o permitir: echo 1 > /proc/sys/net/ipv4/ip_forward

5. Criando Certificados para Clientes

Para cada novo cliente VPN de sua rede, é necessário criar um certificado exclusivo. Isto é feito através do comando /etc/openvpn/build-key ou /etc/openvpn/build-key-pass:

/etc/openvpn/build-key-pass nome-do-cliente

Troque nome-do-cliente por um nome único e exclusivo para cada cliente. Ele será o Common Name do certificado gerado. É importante que no nome-do-cliente não haja espaços em branco, nem caracteres especiais ou acentuados. Até é possível, mas se você não usá-los, terá menos problemas. Você pode usar números, a matricula dos funcionários, CPF, ou o Nome completo, lembrando de trocar o separador do nome por _ ou simplesmente suprimi-lo. Por exemplo, a Caixa Econômica Federal costuma emitir seus certificados usando o nome completo do solicitante, seguido do caracter : e dos números do CPF.

Antes de executar o build-key é importante executar source /etc/openvpn/vars para atribuir as informações de sua CA às variáveis de ambiente da sessão corrente.

Lembre-se de responder as perguntas adequadamente. Elas já virão pré-preenchidas pelos valores de /etc/openvpn/vars. Você pode colocar qualquer informação no campo name, inclusive espaços em branco e caracteres acentuados.

É recomendável usar o build-key-pass ao invés do build-key, visto que o primeiro irá solicitar uma senha secreta para cada cliente. Essa senha sera utilizada em cada conexão OpenVPN. Isso é importante pois caso um notebook que contenha as configurações e certificados de determinado usuário seja perdido ou furtado um meliante não seria capaz de fechar a conexão VPN sem ter a senha. É claro que nestes casos recomenda-se ainda revogar o certificado do cliente.

Para gerar um novo certificado para o usuário João da Silva você pode digitar o seguinte:

root@openvpn:/etc/openvpn# source /etc/openvpn/vars
NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/keys
root@openvpn:/etc/openvpn# /etc/openvpn/build-key joao_da_silva
Generating a 1024 bit RSA private key
..............++++++
.........................++++++
writing new private key to 'joao_da_silva.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]:
Locality Name (eg, city) [São Paulo]:
Organization Name (eg, company) [Blog do Nerd]:
Organizational Unit Name (eg, section) [Divisão de TI]:
Common Name (eg, your name or your server's hostname) [joao_da_silva]:
Name [Blog do Nerd CA]:João da Silva
Email Address [nerd@blogdonerd.email.com]:joao@blogdonerd.email.com

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/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           : PRINTABLE:'BR'
stateOrProvinceName   : PRINTABLE:'SP'
localityName          : T61STRING:'S\0xFFFFFFC3\0xFFFFFFA3o Paulo'
organizationName      : PRINTABLE:'Blog do Nerd'
organizationalUnitName: T61STRING:'Divis\0xFFFFFFC3\0xFFFFFFA3o de TI'
commonName            : T61STRING:'joao_da_silva'
name                  : T61STRING:'Jo\0xFFFFFFC3\0xFFFFFFA3o da Silva'
emailAddress          : IA5STRING:'joao@blogdonerd.email.com'
Certificate is to be certified until Jun 19 14:04:54 2022 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@openvpn:/etc/openvpn#

Três novos arquivos serão gerados na pasta /etc/openvpn/keys:

  • joao_da_silva.csr - Solicitação do novo certificado
  • joao_da_silva.crt - Certificado público
  • joao_da_silva.key - Chave privada
Será necessário copiar estes arquivos para o computador do cliente no próximo passo.

6. Instalando e configurando o OpenVPN nos Clientes Windows ou Linux

Baixe e instale a versão mais recente do OpenVPN. Para clientes Ubuntu basta executar apt-get install openvpn.

No Windows se aparecer uma mensagem solicitando para sua permissão para instalar um novo adaptador de rede TAP-Win32 (conforme abaixo), clique no botão Instalar.

No Windows, um ícone do OpenVPN GUI será instalado na área de trabalho.

Se seu sistema operacional for Windows Vista ou 7, clique com o botão direito do mouse nesse ícone e escolha Propriedades. Na guia Atalho clique no botão Avançados e na nova janela marque a opção Executar como administrador.

Isto é importante porque as regras de roteamento enviadas pelo servidor OpenVPN só serão atribuídas se o cliente OpenVPN possuir privilégios administrativos.

Se o sistema operacional for Windows XP execute o seguinte procedimento para que a resolução de DNS funcione corretamente:

  1. Clique em Iniciar, clique em Executar..., digite regedit na caixa de diálogo aberta e então clique OK.
  2. Navegue até a chave de registro: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Linkage
  3. No painel da direita, clique duas vezes no item Bind.
  4. Na caixa que se abre selecione o item "\Device\NdisWanIp", pressione CTRL + X, clique no topo da lista de dispositivos, e pressione CTRL + V. Em outras palavras: o que deve ser feito é passar o item "\Device\NdisWanIp" para o primeiro da lista.
  5. Clique OK e feche o Editor do Registro.
  6. Reinicialize o computador.

Agora vamos configurar o cliente OpenVPN.

Vá até o servidor e copie os seguintes arquivos da pasta /etc/openvpn/keys:

  • ca.crt - Certificado público de sua CA
  • ta.key - Chave privada para assinatura de pacotes TLS de forma a aumentar a segurança na comunicação
  • joao_da_silva.crt - Certificado público do usuário a ser configurado
  • joao_da_silva.key - Certificado privado do usuário a ser configurado

Talvez você tenha dificuldades para copar os arquivos .key que são privados e não possuem permissão de leitura para usuários comuns. Se necessário, copie os arquivos para uma pasta temporária (/tmp por exemplo) e altere as permissões com o comando chmod: chmod 644 /tmp/joao_da_silva.key.

ATENÇÃO: Lembre-se o arquivo joao_da_silva.key contém a chave privada do João e não deve ser distribuida livremente para não comprometer a segurança, especialmente se ele não possuir uma challenge password.

Copie estes arquivos para a pasta C:\Program Files\OpenVPN\config para o cliente Windows ou para /etc/openvpn no caso de um cliente Linux.

Renomeie os arquivos joao_da_silva.crt e joao_da_silva.key no cliente, conforme segue:

  • joao_da_silva.crt -> client.crt
  • joao_da_silva.key -> client.key
Se preferir, ao invés de renomear estes arquivos, você pode ajustar os parâmetros cert e key no arquivo openvpn.conf (Linux) ou openvpn.ovpn (Windows) que será configurado no próximo passo.

7.1. Particularidades do Cliente Windows

Para um cliente Windows, crie o arquivo C:\Program Files\OpenVPN\config\openvpn.ovpn com o conteúdo abaixo.

Ajuste o parâmetro remote para o endereço público IP ou FQDN se seu servidor OpenVPN seguido da porta de conexão com o servidor. No meu exemplo usei o FQDN blogdonerd.no-ip.com. Se você configurou o servidor como TCP, então ajuste o parâmetro proto.

#####################################################################</pre>
# OpenVPN 2.0 - Arquivo de configuração do cliente Windows
#####################################################################

# Specify that we are a client and that we
# will be pulling certain config file directives
# from the server.
client

# Use the same setting as you are using on
# the server.
dev tun

script-security 2

# Are we connecting to a TCP or
# UDP server? Use the same setting as
# on the server.
proto udp

# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote blogdonerd.no-ip.com 1194

# Keep trying indefinitely to resolve the
# host name of the OpenVPN server. Very useful
# on machines which are not permanently connected
# to the internet such as laptops.
resolv-retry infinite

# Most clients don't need to bind to
# a specific local port number.
nobind

# Try to preserve some state across restarts.
persist-key
persist-tun

# If you are connecting through an
# HTTP proxy to reach the actual OpenVPN
# server, put the proxy server/IP and
# port number here. See the man page
# if your proxy server requires
# authentication.
;http-proxy-retry # retry on connection failures
;http-proxy [proxy server] [proxy port #]

# Wireless networks often produce a lot
# of duplicate packets. Set this flag
# to silence duplicate packet warnings.
mute-replay-warnings

# SSL/TLS parms.
# See the server config file for more
# description. It's best to use
# a separate .crt/.key file pair
# for each client. A single ca
# file can be used for all clients.
ca ca.crt
cert client.crt
key client.key

# Verify server certificate by checking
# that the certicate has the nsCertType
# field set to "server". This is an
# important precaution to protect against
# a potential attack discussed here:
# http://openvpn.net/howto.html#mitm
ns-cert-type server

# If a tls-auth key is used on the server
# then every client must also have the key.
tls-auth ta.key 1

# Select a cryptographic cipher.
# If the cipher option is used on the server
# then you must also specify it here.
cipher AES-128-CBC

# Enable compression on the VPN link.
# Don't enable this unless it is also
# enabled in the server config file.
comp-lzo

# Set log file verbosity.
verb 3
A pasta C:\Program Files\OpenVPN\config ficará assim:

Execute o OpenVPN GUI. Um ícone de dois computadores com uma tela vermelha aparecerá no canto próximo ao relógio.

Clique duas vezes neste ícone ou clique com o botão direito no ícone e em seguida clique em Connect.

A tela de conexão e logs do OpenVPN será mostrada. Se você configurou uma challenge password para o certificado do cliente ela deveria ser solicitada agora. Se tudo ocorreu bem o ícone passara de vermelho para verde e uma mensagem informando que a conexão foi bem sucedida será apresentada.

Para desconectar é só clicar com o direito no ícone dos computadores verdes e escolher a opção Disconnect.

7.2. Particularidades do Cliente Linux

Crie o arquivo /etc/openvpn/openvpn.conf com o conteúdo abaixo.

Ajuste o parâmetro remote para o endereço público IP ou FQDN se seu servidor OpenVPN seguido da porta de conexão com o servidor. No meu exemplo usei o FQDN blogdonerd.no-ip.com. Se você configurou o servidor como TCP, então ajuste o parâmetro proto.

#####################################################################</pre>
# OpenVPN 2.0 - Arquivo de configuração do cliente Linux
#####################################################################

# Specify that we are a client and that we
# will be pulling certain config file directives
# from the server.
client

# Use the same setting as you are using on
# the server.
dev tun0

script-security 2

# Are we connecting to a TCP or
# UDP server? Use the same setting as
# on the server.
proto udp

# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote blogdonerd.no-ip.com 1194

# Keep trying indefinitely to resolve the
# host name of the OpenVPN server. Very useful
# on machines which are not permanently connected
# to the internet such as laptops.
resolv-retry infinite

# Most clients don't need to bind to
# a specific local port number.
nobind

# Try to preserve some state across restarts.
persist-key
persist-tun

# If you are connecting through an
# HTTP proxy to reach the actual OpenVPN
# server, put the proxy server/IP and
# port number here. See the man page
# if your proxy server requires
# authentication.
;http-proxy-retry # retry on connection failures
;http-proxy [proxy server] [proxy port #]

# Wireless networks often produce a lot
# of duplicate packets. Set this flag
# to silence duplicate packet warnings.
mute-replay-warnings

# SSL/TLS parms.
# See the server config file for more
# description. It's best to use
# a separate .crt/.key file pair
# for each client. A single ca
# file can be used for all clients.
ca /etc/openvpn/ca.crt
cert /etc/openvpn/client.crt
key /etc/openvpn/client.key

# Verify server certificate by checking
# that the certicate has the nsCertType
# field set to "server". This is an
# important precaution to protect against
# a potential attack discussed here:
# http://openvpn.net/howto.html#mitm
ns-cert-type server

# If a tls-auth key is used on the server
# then every client must also have the key.
tls-auth /etc/openvpn/ta.key 1

# Select a cryptographic cipher.
# If the cipher option is used on the server
# then you must also specify it here.
cipher AES-128-CBC

# Enable compression on the VPN link.
# Don't enable this unless it is also
# enabled in the server config file.
comp-lzo

# Set log file verbosity.
verb 3
A pasta /etc/openvpn ficará assim:
root@openvpn:/etc/openvpn# ls /etc/openvpn/
ca.crt       client.crt        client.key      openvpn.conf       ta.key
root@openvpn:/etc/openvpn#

Agora basta executar service openvpn start para que a conexão com o servidor seja realizada.
Para encerrar a conexão execute service openvpn stop.
Para controlar se a conexão será executada automaticamente na inicialização do computador, edite o arquivo /etc/default/openvpn.
Descomente ou inclua a linha abaixo para que a conexão seja realizada automaticamente na inicialização:

AUTOSTART="all"

Para impedir a inicialização automática do openvpn descomente ou inclua a seguinte linha:

AUTOSTART="none"

7. Revogando Certificados de Clientes

Caso um computador contendo um certificado seja perdido, ou ainda para impedir que determinado usuário realize a conexão VPN você deve revogar o certificado.

Uma vez revogado, não há volta, você terá que gerar um novo certificado para permitir a conexão de detreminado cliente.

A lista de certificados revogados é armazenada no arquivo /etc/openvpn/keys/crl.pem. O problema é que o OpenVPN, após entrar em execução, não possui permissão de leitura para essa pasta. Então teremos ainda que copiar o arquivo /etc/openvpn/keys/crl.pem para a pasta /etc/openvpn, que é o motivo da última linha dos comandos abaixo.

Para revogar o certificado de joao_da_silva execute os seguintes comandos:

source /etc/openvpn/vars
/etc/openvpn/revoke-full joao_da_silva
cp /etc/openvpn/keys/crl.pem /etc/openvpn

A saída será a seguinte:

root@openvpn:/etc/openvpn# /etc/openvpn/revoke-full joao_da_silva
Using configuration from /etc/openvpn/openssl.cnf
Revoking Certificate 04.
Data Base Updated
Using configuration from /etc/openvpn/openssl.cnf
joao_da_silva.crt: C = BR, ST = SP, L = Sao Paulo, O = Blog do Nerd, OU = Divisao de TI, CN = joao3, name = Joao da Silva, emailAddress = joao@blogdonerd.email.com
error 23 at 0 depth lookup:certificate revoked
root@openvpn:/etc/openvpn# cp /etc/openvpn/keys/crl.pem /etc/openvpn/
root@openvpn:/etc/openvpn#

Precisamos ainda informar ao servidor OpenVPN para considerar esse arquivo na verificação das conexões.

Para fazer isso, edite o arquivo /etc/openvpn/server.conf e inclua a seguinte linha no final do arquivo:

crl-verify /etc/openvpn/crl.pem

Reinicie o OpenVPN para que esta nova configuração entre em ação:

service opevpn reload

Você não precisará reiniciar ou recarregar o OepnVPN a cada vez que revogar um certificado. Somente na primeira vez em que configurar a diretiva crl-verify.

Para gerar um arquivo crl.pem inicial você pode executar o comando revoke-full com um nome qualquer:

/etc/openvpn/revoke-full teste

8. Informações Adicionais

Para controlar se o servidor OpenVPN será inicializado automaticamente junto com a inicialização do computador, edite o arquivo /etc/default/openvpn.

Descomente ou inclua a linha abaixo para que o servidor OpenVPN inicie automaticamente na inicialização:

AUTOSTART="all"

Para impedir a inicialização automática do OpenVPN descomente ou inclua a seguinte linha:

AUTOSTART="none"

Desculpe pelo artigo extremamente longo. Espero que ele seja útil. Qualquer dúvida, sugestão ou relato de erros é só postar nos comentários.


Referências

OpenVPN How To - http://openvpn.net/index.php/open-source/documentation/howto.html