Artigos e tutoriais
   OpenVPN - Guia de uso completo
Autor: Patrick Brandão, patrickbrandao@gmail.com
Cópia autorizada somente quando preservar a referência ao autor.


Fontes:

Introdução

Este artigo inclui todo conhecimento prático que eu reuni sobre OpenVPN e servirá como base para mim no futuro e para todos que desejam aprender sobre VPNs de maneira objetiva.

Para escrever esse artigo (misto de tutorial) eu li todos os livros de OpenVPN disponíveis em inglês e português, alem da documentação oficial do OpenVPN.

Vou focar o conteúdo nos exemplos bem práticos, ao praticá-los com calma e atenção você aprenderá e dominará o OpenVPN tanto quanto eu.
Irei explicar a finalidade de cada argumento sempre que o usar pela primeira vez apenas.


Instalação

Instalando em Ubuntu / Debian

# Instalando softwares: OpenSSL e OpenVPN:
apt-get -y install openssl
apt-get -y install openvpn

# Criar pasta de configuracao:
mkdir -p /etc/openvpn

# Ativando modulos do kernel
grep tun /etc/modules || echo "tun" >> /etc/modules
grep tap /etc/modules || echo "tap" >> /etc/modules
modprobe tun
modprobe tap

# Garantir existencia de ponteiro dev
[ -e /dev/net/tun ] || mknod /dev/net/tun c 10 200

# Instalando ferramentas
apt-get -y install fping wget curl mtr tcpdump nmap





Capítulo 1 - PtP entre dois hosts Linux com OpenVPN

Neste primeiro capítulo vou exemplificar o uso de OpenVPN para estabelecer uma VPN ponto-a-ponto simples (ptp) entre dois hosts Linux, também conhecida como site-to-site.

O servidor está na Internet e possui IPv4 e IPv6 fixos, globalmente alcançáveis.

O cliente estará em diferentes redes (meu notebook), atras de firewall e NAT pelo roteador de Internet local.

Abordarei nesse capítulo as VPNs em modo camada 3 (driver TUN), esse tipo de VPN transporta apenas pacotes IP (IPv4 e/ou IPv6).

O diagrama abaixo exibe a topologia de rede dos exemplos desse capítulo.



Observação: ao rodar o openvpn no lado servidor (abre portas para escuta, --bind), a porta do openvpn é aberta em IPv4 e em IPv6 por padrão.


1.1 - Linux Servidor, Linux client, ptp simples

Este é o modo mais simples, curto e rápido de fazer uma VPN L3 entre dois hosts Linux:

# - Linux Servidor:
openvpn --ifconfig 10.200.0.1 10.200.0.2 --dev tun

# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn --ifconfig 10.200.0.2 10.200.0.1 --dev tun --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


1.2 - Linux Servidor, Linux client, MTU 1500

No exemplo anterior um pacote de 1500 bytes foi transmitido pelo tunnel mas devido o overhead (ssl+udp+ip sobre IP) o pacote UDP resultante é grande demais para o MTU local/internet e foi fragmentando (transporte fragmentado pelo IP do HOST).

Firewalls no caminho descartando fragmentação podem causar problemas deletando os fragmentos, forçando o uso da VPN em MTU menor. O OpenVPN pode resolver isso transportando o pacote original fragmentado dentro do UDP (dois pacotes UDP/IP na rede real/internet levando um pacote IP dentro da VPN), a remontagem do pacote original será feita pelo OpenVPN em vez da camada IP do HOST, para isso:

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --dev tun \
    --tun-mtu 1500 \
    --fragment 1300 \
    --mssfix

# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --dev tun \
    --tun-mtu 1500 \
    --fragment 1300 \
    --mssfix \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1

Da forma acima, um pacote de 1500 bytes a ser enviado pelo tunnel será fragmentado, colocado em dois pacotes UDP e transmitido pela internet. O OpenVPN prefere sempre dividir o tamanho do pacote por 2 (1500/2=750), assim cada pacote UDP transportara 750 bytes.
A opcao --tun-mtu define o MTU do tunnel (1500 por padrão).
A opcao --fragment define o tamanho máximo de cada pedaço a ser transportado pelo OpenVPN no tunnel, subtraído do overhead máximo possível (casos com criptografia).


1.3 - Especificando a interface de rede a ser criada no linux

Para facilitar o monitoramento da interfaces (nome constante) e outras finalidades, você pode especificar o nome da interface do tunnel.

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301

# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1

A opção --dev-type é por padrão TUN (tunnel L3, transporta pacotes IPv4/IPv6).
A opção --persist-tun mantem a interface criada no Linux mesmo se a comunicação entre client/servidor for interrompida.
A opção --dev especifica que o nome da interface será vtun301 (evite informar nome com mais de 15 bytes).



1.4 - Ativando ping keepalive de gestão do tunel

A opção de ping mantem a atividade do tunnel, util para manter o mapeamento de NAT dos roteadores no caminho sempre ativo e detectar incidentes que interrompem o funcionamento do tunnel.

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --ping 10 \
    --ping-restart 60

# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --ping 10 \
    --ping-restart 60 \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1

A opção --ping especifica o intervalo em segundos que o teste de ping será realizado.
A opção --ping-restart especifica o intervalo em segundos para considerar falha no tunnel.



1.5 - Modo daemon, logs e pid

Nos exemplos acima o software rodou em primeiro plano (foreground), bom para analise, testes, rodar via systemd/supervisor.

Para deixar o processo em background (daemon), precisamos enviar para background e desassociar processo do console (permitindo logout/fechar e manter rodando conectado) e registrar o log de eventos e erros.
Usando --log-append o arquivo de log é incrementado a cada execução.
Usando --log o arquivo de log é zerado no inicio de cada execução.
Usando --writepid para registrar PID do processo (para envio de sinais e matar processo especifico).

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --daemon ovpnsrv301 \
    --writepid /var/run/ovpnsrv301.pid \
    --log-append /var/log/ovpnsrv301.log

# - Analisar log:
cat /var/log/ovpnsrv301.log

#- Parar processo no lado servidor:
kill $(head -1 /var/run/ovpnsrv301.pid)
rm -f /var/run/ovpnsrv301.pid

# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --daemon ovpncli301 \
    --writepid /var/run/ovpncli301.pid \
    --log-append /var/log/ovpncli301.log \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1

# - Analisar log:
cat /var/log/ovpncli301.log

#- Parar processo no lado cliente:
kill $(head -1 /var/run/ovpncli301.pid)
rm -f /var/run/ovpncli301.pid


1.6 - Porta e protocolo

Por padrão o OpenVPN utiliza UDP na porta 1194. Essa porta pode ser bloqueada em alguns provedores ou redes corporativas. Você pode mudar de porta assim:

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --proto udp \
    --port 2001


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --proto udp \
    --port 2001 \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


1.7 - Portas locais e remotas diferentes

Por padrão os pacotes UDP usam a mesma porta de origem e destino. Você pode escolher usar o servidor em uma porta e o cliente em outra, observe:

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --proto udp \
    --lport 2020 \
    --rport 4040


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --proto udp \
    --lport 4040 \
    --rport 2020 \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


1.8 - IP de origem em ambientes com multiplas WANs ou VPNs baseadas em ips de loopback

Por padrão o OpenVPN não define o IP de origem, assim, o IP de origem será obtido automaticamente pelo socket UDP.

O cliente, por exemplo, se conecta ao IP 45.255.128.2 que está na loopback do servidor, mas a WAN (IP de origem padrão do servidor) é o IP 8.67.119.253, assim, pacotes respondidos pelo servidor utilizarão o ip 8.67.119.253 e por consequência serão rejeitadas pelo cliente. A solução é simples: explicitar o IP de origem no lado servidor.

A opção --connect-retry alterada para 1 segundo (o padrão são 5 segundos) define o tempo de tentativas de reconexão em caso de queda da conectividade do cliente com o servidor (lado cliente apenas).

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --proto udp \
    --port 5050 \
    --local 45.255.128.2


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --proto udp \
    --port 5050 \
    --connect-retry 1 \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


1.9 - Usando endereções IPv6 na interface do tunnel

Configurar endereços IPv6 no tunnel:

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --ifconfig-ipv6 2001:db8:10:200::1 2001:db8:10:200::2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --ifconfig-ipv6 2001:db8:10:200::2 2001:db8:10:200::1 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1
fping -M -b 1452 2001:db8:10:200::1


1.10 - VPN baseada em endereços IPv6 (UDP6)

Usar IPv6 entre os hosts para estabelecer uma VPN (transporte: IPv6), e configurar IPv4 privado e IPv6 Doc nas interfaces do tunnel:

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --ifconfig-ipv6 2001:db8:10:200::1 2001:db8:10:200::2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --port 6006 \
    --proto-force udp6 \
    --local ::


# - Linux Client (usando servidor no IPv6 2804:cafe:ff00:1030::180):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --ifconfig-ipv6 2001:db8:10:200::2 2001:db8:10:200::1 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --port 6006 \
    --remote 2804:cafe:ff00:1030::180

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1
fping -M -b 1452 2001:db8:10:200::1


1.11 - Tunel VPN usando transporte em TCP

Por padrão usa-se UDP, o que pode causar problemas em túneis de MTU 1500 com fragmentação UDP, uma solução é usar TCP para repetição dos pedaços transportados, como consequência as perdas/repetições são percebidas com aumento da latência no túnel.

Uma das vantagens é a dispensa o uso de --local no lado servidor com múltiplos IPs de WAN ou ancoragem em loopback, passando a ter apenas o efeito de informar em qual IP local o OpenVPN deve abrir a porta tcp.

Detalhe: o argumento "--dev tun" orienta o uso do driver TUN (L3), o nome da interface sera tun + número sequêncial.

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --dev tun \
    --proto tcp-server


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --dev tun \
    --proto tcp-client \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


1.12 - Tunel VPN usando transporte em TCP com nome de interface manual

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --dev-type tun \
    --dev vtun301 \
    --proto tcp-server


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --dev-type tun \
    --dev vtun301 \
    --proto tcp-client \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


1.13 - Tunel VPN usando transporte em TCP - Config completa IPv4 e IPv6

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --ifconfig-ipv6 2001:db8:10:200::1 2001:db8:10:200::2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --port 7771 \
    --proto tcp-server


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --ifconfig-ipv6 2001:db8:10:200::2 2001:db8:10:200::1 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --port 7771 \
    --proto tcp-client \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1
fping -M -b 1452 2001:db8:10:200::1


1.14 - VPN em TCP6 (transporte TCP sobre IPv6)

Usar IPv6 (Transporte IPv6) entre os hosts baseado em TCP para estabelecer uma VPN, e configurar IPv4 privado e IPv6 Doc nas interfaces do tunnel.

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --ifconfig-ipv6 2001:db8:10:200::1 2001:db8:10:200::2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --port 6006 \
    --proto tcp-server \
    --local ::


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --ifconfig-ipv6 2001:db8:10:200::2 2001:db8:10:200::1 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --port 6006 \
    --proto tcp-client \
    --remote 2804:cafe:ff00:1030::180

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1
fping -M -b 1452 2001:db8:10:200::1


1.15 - Tunel PtP com chave compartilhada

O uso de chave pre-compartilhada é um método de segurança para autenticação. Obviamente, a mesma chave precisa estar presente em ambos os lados.

# A - Criar pasta para salvar as chaves (ambos os lados):
mkdir -p /etc/openvpn/safe
chmod 700 /etc/openvpn/safe

# B - Gerar chave openvpn (lado servidor, copie para lado cliente):
openvpn --genkey --secret /etc/openvpn/safe/shared-key-001.key

# C - Verificar se o arquivo da chave foi gerado corretamente:
openvpn --test-crypto --secret /etc/openvpn/safe/shared-key-001.key --verb 9
echo "# ERRNO: $?"

# D - Verificar chave criada:
cat /etc/openvpn/safe/shared-key-001.key

-----BEGIN OpenVPN Static key V1-----
121de519946171140c5a670532113df5
7ca5adf7c8f3407352332b57a2c6a43f
1d4621c01849afe0dec924936da0f59b
d0db01f977d7c5647b98664ae2652982
c58cc1df3d7cf7d025a15a3815c1fc7f
a5e10ac0c4ebee8034683569ff1b4271
5475cf626433107f558bcf766447e9f6
56324a44765e212a91a16514123b8863
d15b0c7a8c63359f32452a871d34b15b
55e40249f454cf1d26d019fbe66a7ce2
ec7d9a552eca9ec67b1e389642b333bf
b961ed59b2b1496f131258b9143f6e00
b26d02ae7c638a923e8f88fa7fabaeb9
6003d4d068c2e07baa0742e4fda808e7
5f4c653653589dcc6b7456f8b95dc816
11987c81ee58a68b05a3a47b2b649cd7
-----END OpenVPN Static key V1-----

Repito: você não pode gerar uma chave para cada lado (servidor e cliente), você deve gerar uma única chave e copiá-la para a outra ponta. A chave precisa ser a mesma em ambos os lados.

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --ifconfig-ipv6 2001:db8:10:200::1 2001:db8:10:200::2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --secret /etc/openvpn/safe/shared-key-001.key \
    --verb 7


# - Linux Client (usando servidor no ip 45.255.128.2):

mkdir -p /etc/openvpn/safe
chmod 700 /etc/openvpn/safe
(
echo '#'
echo '# 2048 bit OpenVPN static key'
echo '#'
echo '-----BEGIN OpenVPN Static key V1-----'
echo '121de519946171140c5a670532113df5'
echo '7ca5adf7c8f3407352332b57a2c6a43f'
echo '1d4621c01849afe0dec924936da0f59b'
echo 'd0db01f977d7c5647b98664ae2652982'
echo 'c58cc1df3d7cf7d025a15a3815c1fc7f'
echo 'a5e10ac0c4ebee8034683569ff1b4271'
echo '5475cf626433107f558bcf766447e9f6'
echo '56324a44765e212a91a16514123b8863'
echo 'd15b0c7a8c63359f32452a871d34b15b'
echo '55e40249f454cf1d26d019fbe66a7ce2'
echo 'ec7d9a552eca9ec67b1e389642b333bf'
echo 'b961ed59b2b1496f131258b9143f6e00'
echo 'b26d02ae7c638a923e8f88fa7fabaeb9'
echo '6003d4d068c2e07baa0742e4fda808e7'
echo '5f4c653653589dcc6b7456f8b95dc816'
echo '11987c81ee58a68b05a3a47b2b649cd7'
echo '-----END OpenVPN Static key V1-----'
) > /etc/openvpn/safe/shared-key-001.key
chmod 600 /etc/openvpn/safe/shared-key-001.key

openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --ifconfig-ipv6 2001:db8:10:200::2 2001:db8:10:200::1 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --secret /etc/openvpn/safe/shared-key-001.key \
    --verb 7 \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1
fping -M -b 1452 2001:db8:10:200::1

A opção --verb define o nível de detalhamento de logs (0=somente erros fatais, 11=debug máximo).
A opção --secret define o caminho para o arquivo contendo a chave OpenVPN.


1.16 - Túnel PtP com chave compartilhada e cifra especial

Listar cifras disponíveis:

# - Listar cifras:
openvpn --show-ciphers

The following ciphers and cipher modes are available for use
with OpenVPN.  Each cipher shown below may be used as a
parameter to the --data-ciphers (or --cipher) option.  The
default key size is shown as well as whether or not it can be
changed with the --keysize directive.  Using a GCM or CBC mode
is recommended.  In static key mode only CBC mode is allowed.

AES-128-CBC       (128 bit key, 128 bit block)
AES-128-CFB       (128 bit key, 128 bit block, TLS client/server mode only)
AES-128-CFB1      (128 bit key, 128 bit block, TLS client/server mode only)
AES-128-CFB8      (128 bit key, 128 bit block, TLS client/server mode only)
AES-128-GCM       (128 bit key, 128 bit block, TLS client/server mode only)
AES-128-OFB       (128 bit key, 128 bit block, TLS client/server mode only)
AES-192-CBC       (192 bit key, 128 bit block)
AES-192-CFB       (192 bit key, 128 bit block, TLS client/server mode only)
AES-192-CFB1      (192 bit key, 128 bit block, TLS client/server mode only)
AES-192-CFB8      (192 bit key, 128 bit block, TLS client/server mode only)
AES-192-GCM       (192 bit key, 128 bit block, TLS client/server mode only)
AES-192-OFB       (192 bit key, 128 bit block, TLS client/server mode only)
AES-256-CBC       (256 bit key, 128 bit block)
AES-256-CFB       (256 bit key, 128 bit block, TLS client/server mode only)
AES-256-CFB1      (256 bit key, 128 bit block, TLS client/server mode only)
AES-256-CFB8      (256 bit key, 128 bit block, TLS client/server mode only)
AES-256-GCM       (256 bit key, 128 bit block, TLS client/server mode only)
AES-256-OFB       (256 bit key, 128 bit block, TLS client/server mode only)
ARIA-128-CBC      (128 bit key, 128 bit block)
ARIA-128-CFB      (128 bit key, 128 bit block, TLS client/server mode only)
ARIA-128-CFB1     (128 bit key, 128 bit block, TLS client/server mode only)
ARIA-128-CFB8     (128 bit key, 128 bit block, TLS client/server mode only)
ARIA-128-OFB      (128 bit key, 128 bit block, TLS client/server mode only)
ARIA-192-CBC      (192 bit key, 128 bit block)
ARIA-192-CFB      (192 bit key, 128 bit block, TLS client/server mode only)
ARIA-192-CFB1     (192 bit key, 128 bit block, TLS client/server mode only)
ARIA-192-CFB8     (192 bit key, 128 bit block, TLS client/server mode only)
ARIA-192-OFB      (192 bit key, 128 bit block, TLS client/server mode only)
ARIA-256-CBC      (256 bit key, 128 bit block)
ARIA-256-CFB      (256 bit key, 128 bit block, TLS client/server mode only)
ARIA-256-CFB1     (256 bit key, 128 bit block, TLS client/server mode only)
ARIA-256-CFB8     (256 bit key, 128 bit block, TLS client/server mode only)
ARIA-256-OFB      (256 bit key, 128 bit block, TLS client/server mode only)
CAMELLIA-128-CBC  (128 bit key, 128 bit block)
CAMELLIA-128-CFB  (128 bit key, 128 bit block, TLS client/server mode only)
CAMELLIA-128-CFB1 (128 bit key, 128 bit block, TLS client/server mode only)
CAMELLIA-128-CFB8 (128 bit key, 128 bit block, TLS client/server mode only)
CAMELLIA-128-OFB  (128 bit key, 128 bit block, TLS client/server mode only)
CAMELLIA-192-CBC  (192 bit key, 128 bit block)
CAMELLIA-192-CFB  (192 bit key, 128 bit block, TLS client/server mode only)
CAMELLIA-192-CFB1 (192 bit key, 128 bit block, TLS client/server mode only)
CAMELLIA-192-CFB8 (192 bit key, 128 bit block, TLS client/server mode only)
CAMELLIA-192-OFB  (192 bit key, 128 bit block, TLS client/server mode only)
CAMELLIA-256-CBC  (256 bit key, 128 bit block)
CAMELLIA-256-CFB  (256 bit key, 128 bit block, TLS client/server mode only)
CAMELLIA-256-CFB1 (256 bit key, 128 bit block, TLS client/server mode only)
CAMELLIA-256-CFB8 (256 bit key, 128 bit block, TLS client/server mode only)
CAMELLIA-256-OFB  (256 bit key, 128 bit block, TLS client/server mode only)
CHACHA20-POLY1305 (256 bit key, stream cipher, TLS client/server mode only)
SEED-CBC          (128 bit key, 128 bit block)
SEED-CFB          (128 bit key, 128 bit block, TLS client/server mode only)
SEED-OFB          (128 bit key, 128 bit block, TLS client/server mode only)
SM4-CBC           (128 bit key, 128 bit block)
SM4-CFB           (128 bit key, 128 bit block, TLS client/server mode only)
SM4-OFB           (128 bit key, 128 bit block, TLS client/server mode only)

The following ciphers have a block size of less than 128 bits, 
and are therefore deprecated.  Do not use unless you have to.

BF-CBC            (128 bit key by default, 64 bit block)
BF-CFB            (128 bit key by default, 64 bit block, TLS client/server mode only)
BF-OFB            (128 bit key by default, 64 bit block, TLS client/server mode only)
CAST5-CBC         (128 bit key by default, 64 bit block)
CAST5-CFB         (128 bit key by default, 64 bit block, TLS client/server mode only)
CAST5-OFB         (128 bit key by default, 64 bit block, TLS client/server mode only)
DES-CBC           (64 bit key, 64 bit block)
DES-CFB           (64 bit key, 64 bit block, TLS client/server mode only)
DES-CFB1          (64 bit key, 64 bit block, TLS client/server mode only)
DES-CFB8          (64 bit key, 64 bit block, TLS client/server mode only)
DES-EDE-CBC       (128 bit key, 64 bit block)
DES-EDE-CFB       (128 bit key, 64 bit block, TLS client/server mode only)
DES-EDE-OFB       (128 bit key, 64 bit block, TLS client/server mode only)
DES-EDE3-CBC      (192 bit key, 64 bit block)
DES-EDE3-CFB      (192 bit key, 64 bit block, TLS client/server mode only)
DES-EDE3-CFB1     (192 bit key, 64 bit block, TLS client/server mode only)
DES-EDE3-CFB8     (192 bit key, 64 bit block, TLS client/server mode only)
DES-EDE3-OFB      (192 bit key, 64 bit block, TLS client/server mode only)
DES-OFB           (64 bit key, 64 bit block, TLS client/server mode only)
DESX-CBC          (192 bit key, 64 bit block)
RC2-40-CBC        (40 bit key by default, 64 bit block)
RC2-64-CBC        (64 bit key by default, 64 bit block)
RC2-CBC           (128 bit key by default, 64 bit block)
RC2-CFB           (128 bit key by default, 64 bit block, TLS client/server mode only)
RC2-OFB           (128 bit key by default, 64 bit block, TLS client/server mode only)
RC5-CBC           (128 bit key by default, 64 bit block)
RC5-CFB           (128 bit key by default, 64 bit block, TLS client/server mode only)
RC5-OFB           (128 bit key by default, 64 bit block, TLS client/server mode only)


Rodando VPN com cifra desejada:

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --secret /etc/openvpn/safe/shared-key-001.key \
    --cipher AES-256-CBC \
    --verb 7


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --secret /etc/openvpn/safe/shared-key-001.key \
    --cipher AES-256-CBC \
    --verb 7 \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


1.17 - Túnel PtP com chave compartilhada por criptografia assimétrica

Ao usar a chave compartilhada é póssivel gerar chaves temporárias diferentes para cada difereção do fluxo (cliente para servidor, servidor para cliente). Basta, para isso, informar '0' e '1' a frente do argumento da chave, no servidor e no cliente respectivamente:

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --secret /etc/openvpn/safe/shared-key-001.key 0 \
    --cipher AES-256-CBC \
    --verb 7


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --secret /etc/openvpn/safe/shared-key-001.key 1 \
    --cipher AES-256-CBC \
    --verb 7 \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


1.18 - Túnel PtP com chave compartilhada, criptografia e autenticação personalizada

# Listar algoritmos de autenticação:

The following message digests are available for use with
OpenVPN.  A message digest is used in conjunction with
the HMAC function, to authenticate received packets.
You can specify a message digest as parameter to
the --auth option.

MD5 128 bit digest size
RSA-MD5 128 bit digest size
SHA1 160 bit digest size
RSA-SHA1 160 bit digest size
MD5-SHA1 288 bit digest size
RSA-SHA1-2 160 bit digest size
RIPEMD160 160 bit digest size
RSA-RIPEMD160 160 bit digest size
MD4 128 bit digest size
RSA-MD4 128 bit digest size
RSA-SHA256 256 bit digest size
RSA-SHA384 384 bit digest size
RSA-SHA512 512 bit digest size
RSA-SHA224 224 bit digest size
SHA256 256 bit digest size
SHA384 384 bit digest size
SHA512 512 bit digest size
SHA224 224 bit digest size
whirlpool 512 bit digest size
BLAKE2b512 512 bit digest size
BLAKE2s256 256 bit digest size
SHA512-224 224 bit digest size
SHA512-256 256 bit digest size
SHA3-224 224 bit digest size
SHA3-256 256 bit digest size
SHA3-384 384 bit digest size
SHA3-512 512 bit digest size
SHAKE128 128 bit digest size
SHAKE256 256 bit digest size
id-rsassa-pkcs1-v1_5-with-sha3-224 224 bit digest size
id-rsassa-pkcs1-v1_5-with-sha3-256 256 bit digest size
id-rsassa-pkcs1-v1_5-with-sha3-384 384 bit digest size
id-rsassa-pkcs1-v1_5-with-sha3-512 512 bit digest size
SM3 256 bit digest size
RSA-SM3 256 bit digest size
RSA-SHA512/224 224 bit digest size
RSA-SHA512/256 256 bit digest size

Ao usar a chave compartilhada é póssivel gerar chaves temporárias diferentes para cada difereção do fluxo (cliente para servidor, servidor para cliente). Basta, para isso, informar '0' e '1' a frente do argumento da chave, no servidor e no cliente respectivamente:

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --secret /etc/openvpn/safe/shared-key-001.key 0 \
    --cipher AES-256-CBC \
    --auth SHA512 \
    --verb 7


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --secret /etc/openvpn/safe/shared-key-001.key 1 \
    --cipher AES-256-CBC \
    --auth SHA512 \
    --verb 7 \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


1.19 - Anexando rota ao túnel

Anexar rota ao túnel faz com que o OpenVPN cria uma rota apontando um prefixo para a outra ponta. A rota pode ser configurada em qualquer lado (cliente ou servidor, ou ambos). Exemplo:

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --route 172.19.2.0 255.255.255.0


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --route 192.168.20.0 255.255.255.0 \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


1.20 - Arquivo de configuração

Você já observou que ao combinar todas as opções aprendidas até aqui resultaram em uma linha de comando muito grande, uma solução para isso
é colocar todos os argumentos em um arquivo, retirando o duplo hífem '--' que precede cada argumento e mantendo um par "argumento valor" por linha:

No servidor:

# Arquivo /etc/openvpn/srv301.conf
proto udp
fragment 1300
port 7788
daemon
writepid /var/run/ovpnsrv301.pid
log-append /var/log/ovpnsrv301.log
ping 10
ping-restart 60
ifconfig 10.200.0.1 10.200.0.2
route 172.19.2.0 255.255.255.0
ifconfig-ipv6 2001:db8:10:200::1 2001:db8:10:200::2
dev-type tun
persist-tun
dev vtun301
tun-mtu 1500
secret /etc/openvpn/safe/shared-key-001.key
cipher AES-256-CBC
auth SHA512
verb 7

# - Linux Servidor:
openvpn --config /etc/openvpn/srv301.conf


No cliente:

# Arquivo /etc/openvpn/cli301.conf
proto udp
fragment 1300
port 7788
daemon
writepid /var/run/ovpncli301.pid
log-append /var/log/ovpncli301.log
ping 10
ping-restart 60
ifconfig 10.200.0.2 10.200.0.1
route 192.168.20.0 255.255.255.0
ifconfig-ipv6 2001:db8:10:200::2 2001:db8:10:200::1
dev-type tun
persist-tun
dev vtun301
tun-mtu 1500
secret /etc/openvpn/safe/shared-key-001.key
cipher AES-256-CBC
auth SHA512
verb 7

remote 45.255.128.2

# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn --config /etc/openvpn/cli301.conf

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1

Observe que entre a config do servidor e do cliente, mudou apenas a inversão dos IPs em cada lado no ifconfig, e no lado cliente possui o argumento 'remote' informando o ip do servidor.



1.21 - VPN com configuração IP provisionada por script

Túneis PtP de camada 3 (roteamento) não precisam de IPs nas pontas (interfaces do tunnel), visto que o próximo salto dos pacotes é interface do túnel em si, assim, para fazer um túnel sem IP ou com configuração provisionada por script, use:

# - Preparar script para subir o tunel (ambos os lados):
touch /etc/openvpn/up.sh
chmod +x /etc/openvpn/up.sh

# Arquivo /etc/openvpn/up.sh
#!/bin/sh

ip link set up $1
ip -4 addr add local $4/32 remote $5 dev $1
ip -6 addr add local $ifconfig_ipv6_local/128 remote $ifconfig_ipv6_remote dev $1

exit 0

Exemplicando:

# - Argumentos passados para o script up.sh:
 
$1 - nome da interface do tunel
$2 - MTU do tunel
$3 - MTU do link
$4 - ifconfig-local-ip
$5 - ifconfig-remote-ip
$6 - cmd "init"


# - Variáveis de ambiente durante execução do script::

$link_mtu=1500
$proto_1=udp
$script_type=up
$local_port_1=1194
$route_netmask_1=255.255.255.0
$script_context=init
$PWD=/root
$dev=vtun301
$daemon=0
$ifconfig_ipv6_local=2001:db8:10:200::1
$route_gateway_1=10.200.0.2
$ifconfig_ipv6_remote=2001:db8:10:200::2
$tun_mtu=1500
$remote_port_1=1194
$verb=1
$route_vpn_gateway=10.200.0.2
$ifconfig_local=10.200.0.1
$route_network_1=172.19.2.0
$daemon_pid=93022
$daemon_start_time=1605577760
$SHLVL=1
$route_net_gateway=170.247.23.177
$ifconfig_remote=10.200.0.2
$ifconfig_ipv6_netbits=64
$daemon_log_redirect=0
$dev_type=tun


# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --ifconfig-ipv6 2001:db8:10:200::1 2001:db8:10:200::2 \
    --ifconfig-noexec \
    --up /etc/openvpn/up.sh \
    --script-security 2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --route 172.19.2.0 255.255.255.0


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --ifconfig-ipv6 2001:db8:10:200::2 2001:db8:10:200::1 \
    --ifconfig-noexec \
    --up /etc/openvpn/up.sh \
    --script-security 2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1

O argumento "--up" também poderá ser usado para disparar quaisquer outros scripts e acionadores de eventos relacionados à VPN e ao host remoto envolvido. Use a criatividade.



1.22 - VPN sem IP - Simples

Túneis de camada 3 (driver tun) sem IP podem ser bons para uso normal e simples, além de IPv6 Link-Local, OSPFv3, BABEL, BGP por Interface (FRR) e rotas estáticas associadas à interface.


# - Preparar script para subir o tunel (ambos os lados):
touch /etc/openvpn/tun-up.sh
chmod +x /etc/openvpn/tun-up.sh

# Arquivo /etc/openvpn/tun-up.sh
#!/bin/sh

ip link set up $1

exit 0

# - Linux Servidor:
openvpn \
    --ifconfig-noexec \
    --up /etc/openvpn/tun-up.sh \
    --script-security 2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig-noexec \
    --up /etc/openvpn/tun-up.sh \
    --script-security 2 \
    --dev-type tun \
    --persist-tun \
    --dev vtun301 \
    --remote 45.255.128.2

# Teste usando IPv6-LL (lado cliente):
ping6 ff02::1%vtun301


1.23 - Túnel com compressão de dados

Uma opção interessante é adicionar à VPN a capacidade de comprimir (compactar) os dados (quadros ethernet/802 ou pacotes IP).

A compressão possui algumas considerações a serem feitas, enviar 1 megabyte pela VPN consumirá 1 megabyte no link de Internet entre os hosts da VPN, já com compressão ativada os dados são processados de maneira a ocupar menos espaço, 1 MB pode ser reduzido a 80 kb, o que reduziria tambem o consumo de link entre os hosts.

Deve-se considerar que o uso de compressão, assim como o uso de criptografia, leva ao aumento do consumo de CPU. Decidir entre usar ou não usar compressão e criptografia será uma escolha baseado no que você tem menos: pouca CPU ou pouco link.

Vale lembrar que a entropia dos dados a serem comprimidos afeta na economia gerada pela compressão, por exemplo, dados já criptografados previamente e transportados em pacotes IP dentro da VPN (IPSec, SSH, camada SSL da aplicação como HTTPs) terão ganho próximo a zero, onerando CPU em vão.

Por outro lado, rodar uma intranet com HTTP (texto puro) por uma OpenVPN com compressão dará uma noção de rapidez e baixo consumo de banda.

A opção de ativar compressão está marcada como descontinuada (DEPRECATED) pelos desenvolvedores do OpenVPN e deve ser removida das próximas versões (2.5+).

No exemplo abaixo o ping de teste com 1472 bytes de ICMP (pacote IP com 1500 bytes, pois são 8 bytes de cabeçalho ICMP e 20 bytes de cabeçalho IP) será reduzido para 138 bytes transmitidos. Uma econômia de 90%.

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --dev-type tun \
    --dev vtun301 \
    --tun-mtu 1500 \
    --fragment 1300 \
    --mssfix \
    --comp-lzo yes \
    --allow-compression yes


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --dev-type tun \
    --dev vtun301 \
    --tun-mtu 1500 \
    --fragment 1300 \
    --mssfix \
    --comp-lzo yes \
    --allow-compression yes \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


1.24 - VPN Topology

Embora não seja muito claro o uso de topology em túneis L3 ptp, segue exemplo:

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 255.255.255.0 \
    --dev tun \
    --topology subnet


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 255.255.255.0 \
    --dev tun \
    --topology subnet \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


1.25 - VPN simples sem criptografia e sem autenticação (desativadas explicitamente)

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --dev tun \
    --cipher none \
    --auth none


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --dev tun \
    --cipher none \
    --auth none \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


1.25 - VPN site-to-site, sintaxe completa

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 10.200.0.2 \
    --ifconfig-ipv6 2001:db8:10:200::1 2001:db8:10:200::2 \
    --dev-type tun \
    --persist-tun \
    --dev vpns2s \
    --tun-mtu 1500 \
    --fragment 1300 \
    --mssfix \
    --keepalive 10 60 \
    --daemon ovpn-s2s-srv \
    --writepid /var/run/ovpn-s2s-srv.pid \
    --log-append /var/log/ovpn-s2s-srv.log \
    --proto udp \
    --port 22001 \
    --bind \
    --cipher AES-256-CBC \
    --auth SHA512


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
openvpn \
    --ifconfig 10.200.0.2 10.200.0.1 \
    --ifconfig-ipv6 2001:db8:10:200::2 2001:db8:10:200::1 \
    --dev-type tun \
    --persist-tun \
    --dev vpns2s \
    --tun-mtu 1500 \
    --fragment 1300 \
    --mssfix \
    --keepalive 10 60 \
    --daemon ovpn-s2s-cli \
    --writepid /var/run/ovpn-s2s-cli.pid \
    --log-append /var/log/ovpn-s2s-cli.log \
    --proto udp \
    --port 22001 \
    --nobind \
    --cipher AES-256-CBC \
    --auth SHA512 \
    --cipher none \
    --auth none \
    --data-ciphers-fallback none \
    --connect-retry 1 \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


Capítulo 2 - Crianto PtP para transporte L2 (ethernet)

O OpenVPN também permite o uso do driver TAP para VPNs em camada 2.

A camada 2 transporta quadros, que são unidades de informações que identificam destinatário e remetente em uma rede local, mais conhecidos como endereços MAC. Pacotes IP (IPv4 e IPv6) são transportados dentro de quadros quando transmitidos em redes locais.

A principal vantagem de uma VPN em camada 2 é possibilitar a transmissão de quaisquer protocolos de rede local (LLC, LLDP, multicast, IPv4, IPv6, etc...).

Interligar matriz-filial usando L2 é sem sombra de dúvidas a forma mais simples de dar suporte a todos os protocolos e softwares.




2.1 - Tunel VPN L2 simples

Este é o modo mais simples, curto e rápido de fazer uma VPN L2 entre dois hosts Linux:

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 255.255.255.0 \
    --dev tap

# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 255.255.255.0 \
    --dev tap \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


2.2 - Túnel VPN L2 simples com interface nomeada

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 255.255.255.0 \
    --dev-type tap \
    --persist-tun \
    --dev taph0


# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 255.255.255.0 \
    --dev-type tap \
    --persist-tun \
    --dev taph0 \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1


2.3 - Túnel VPN L2 simples com interface nomeada e chave secreta

# A - Criar pasta para salvar as chaves (ambos os lados):
mkdir -p /etc/openvpn/safe
chmod 700 /etc/openvpn/safe

# B - Gerar chave openvpn (lado servidor, copie para lado cliente):
openvpn --genkey --secret /etc/openvpn/safe/shared-key-002.key

# C - Verificar se o arquivo da chave foi gerado corretamente:
openvpn --test-crypto --secret /etc/openvpn/safe/shared-key-002.key --verb 9
echo "# ERRNO: $?"

# D - Verificar chave criada:
cat /etc/openvpn/safe/shared-key-002.key

-----BEGIN OpenVPN Static key V1-----
121de519946171140c5a670532113df5
7ca5adf7c8f3407352332b57a2c6a43f
1d4621c01849afe0dec924936da0f59b
d0db01f977d7c5647b98664ae2652982
c58cc1df3d7cf7d025a15a3815c1fc7f
a5e10ac0c4ebee8034683569ff1b4271
5475cf626433107f558bcf766447e9f6
56324a44765e212a91a16514123b8863
d15b0c7a8c63359f32452a871d34b15b
55e40249f454cf1d26d019fbe66a7ce2
ec7d9a552eca9ec67b1e389642b333bf
b961ed59b2b1496f131258b9143f6e00
b26d02ae7c638a923e8f88fa7fabaeb9
6003d4d068c2e07baa0742e4fda808e7
5f4c653653589dcc6b7456f8b95dc816
11987c81ee58a68b05a3a47b2b649cd7
-----END OpenVPN Static key V1-----



# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 255.255.255.0 \
    --ifconfig-ipv6 2001:db8:10:200::1/64 2001:db8:10:200::2 \
    --dev-type tap \
    --persist-tun \
    --dev taph0 \
    --secret /etc/openvpn/safe/shared-key-002.key


# - Linux Client (usando servidor no ip 45.255.128.2):

mkdir -p /etc/openvpn/safe
chmod 700 /etc/openvpn/safe
(
echo '#'
echo '# 2048 bit OpenVPN static key'
echo '#'
echo '-----BEGIN OpenVPN Static key V1-----'
echo '121de519946171140c5a670532113df5'
echo '7ca5adf7c8f3407352332b57a2c6a43f'
echo '1d4621c01849afe0dec924936da0f59b'
echo 'd0db01f977d7c5647b98664ae2652982'
echo 'c58cc1df3d7cf7d025a15a3815c1fc7f'
echo 'a5e10ac0c4ebee8034683569ff1b4271'
echo '5475cf626433107f558bcf766447e9f6'
echo '56324a44765e212a91a16514123b8863'
echo 'd15b0c7a8c63359f32452a871d34b15b'
echo '55e40249f454cf1d26d019fbe66a7ce2'
echo 'ec7d9a552eca9ec67b1e389642b333bf'
echo 'b961ed59b2b1496f131258b9143f6e00'
echo 'b26d02ae7c638a923e8f88fa7fabaeb9'
echo '6003d4d068c2e07baa0742e4fda808e7'
echo '5f4c653653589dcc6b7456f8b95dc816'
echo '11987c81ee58a68b05a3a47b2b649cd7'
echo '-----END OpenVPN Static key V1-----'
) > /etc/openvpn/safe/shared-key-002.key
chmod 600 /etc/openvpn/safe/shared-key-002.key

openvpn \
    --ifconfig 10.200.0.2 255.255.255.0 \
    --ifconfig-ipv6 2001:db8:10:200::2/64 2001:db8:10:200::1 \
    --dev-type tap \
    --persist-tun \
    --dev taph0 \
    --secret /etc/openvpn/safe/shared-key-002.key \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1
fping -M -b 1452 2001:db8:10:200::1


2.4 - Túnel VPN L2, interface nomeada e chave secreta assíncrona

Este é o modo mais simples, curto e rápido de fazer uma VPN L2 entre dois hosts Linux:

# - Linux Servidor:
openvpn \
    --ifconfig 10.200.0.1 255.255.255.0 \
    --ifconfig-ipv6 2001:db8:10:200::1/64 2001:db8:10:200::2 \
    --dev-type tap \
    --persist-tun \
    --dev taph0 \
    --secret /etc/openvpn/safe/shared-key-002.key 0

# - Linux Client (usando servidor no ip 45.255.128.2):
openvpn \
    --ifconfig 10.200.0.2 255.255.255.0 \
    --ifconfig-ipv6 2001:db8:10:200::2/64 2001:db8:10:200::1 \
    --dev-type tap \
    --persist-tun \
    --dev taph0 \
    --secret /etc/openvpn/safe/shared-key-002.key 1 \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1
fping -M -b 1452 2001:db8:10:200::1


2.5 - Túnel VPN em L2 com Bridge unindo rede local com VPN

Em ambos os lados, execute:

# - Modulo no kernel:
modprobe tap

# - Criar interface L2 permanente:
openvpn --mktun --dev taph0
ip link set up dev taph0


# - Criar bridge:
brctl addbr brt0
ip link set up dev brt0

#  - Desativar STP:
brctl stp brt0 off

# - Colocar interface TAP na bridge:
brctl addif brt0 taph0
ip link set up dev taph0

# - Colocar interface de rede local (exemplo: eth2) na bridge.
# - Voce pode colocar qualquer interface L2 na bridge (eth, veth, outras VPNs L2)
brctl addif brt0 eth2
ip link set up dev eth2

Preparar lado servidor:

ip addr add 10.111.0.2/24 dev taph0
ip -6 addr add 2001:db8:10:111::2/64 dev taph0

openvpn \
    --dev-type tap \
    --persist-tun \
    --dev taph0 \
    --proto udp \
    --port 9991 \
    --daemon openvpn-l2 \
    --writepid /var/run/openvpn-l2.pid \
    --log-append /var/log/openvpn-l2.log

Preparar lado cliente:

ip addr add 10.111.0.3/24 dev taph0
ip -6 addr add 2001:db8:10:111::3/64 dev taph0

openvpn \
    --dev-type tap \
    --persist-tun \
    --dev taph0 \
    --proto udp \
    --port 9991 \
    --daemon openvpn-l2 \
    --writepid /var/run/openvpn-l2.pid \
    --log-append /var/log/openvpn-l2.log \
    \
    --remote 45.255.128.2

# Teste (lado cliente):
fping -M -b 1472 10.111.0.2
fping -M -b 1452 2001:db8:10:111::2

Ao concluir seus testes, você pode destruir a bridge e a VPN assim (em ambos os lados):

# Finalizar OpenVPN:
kill $(head -1 /var/run/openvpn-l2.pid)

# Desbruir bridge:
ifconfig brt0 down
brctl delif brt0 taph0
brctl delif brt0 eth2
brctl delbr brt0

# Remover interface TAP persistente:
openvpn --rmtun --dev taph0



Até aqui abordamos o uso do OpenVPN para VPNs ptp, independente de ser em camada 2 ou 3, os argumentos e o princípio é o mesmo: simples, objetivo e específico para casa caso.

Você pode interligar seus servidores em full-mesh N-to-N, na formula T=N*(N-1), assim, se você tem 10 servidores serão necessárias 90 configurações, o que não é nada prático.


Capítulo 4 - OpenVPN em conjunto com PKI

Uma das formas de configurar o OpenVPN é com camada SSL para criptografia de dados, um nível super profissional e dominante no uso de VPNs corporativas e militares.

O uso de SSL (Socket Secure Layer) envolve o uso de criptografia assimétrica, onde cada lado possui sua chave pública e privada.

A chave pública serve apenas para criptografar dados. A chave privada serve apenas para descriptografar dados, assim, a chave pública pode ser distribuída livremente, quando dois HOSTs desejam se comunicar cada um envia para o outro lado sua chave pública.


O hacker no caminho pode até capturar as chaves públicas e os dados, mas jamais conseguirá descriptografar haja visto que a chave privada jamais é transmitida pela rede.


Esse modelo no entando é fragil a um tipo de ataque: Man-in-the-middle, onde o hacker cria um servidor para atender o cliente, e um cliente para se conectar ao servidor real, passando a rotear os dados (como a chave pública enviada ao cliente pelo falso servidor, o cliente irá criptografar os dados para uma chave que o hacker gerou).


Obviamente que com o uso de chave compartilhada provida pelo OpenVPN (argumento --secret) esse tipo de ataque pode ser inibido facilmente, uma vez que o hacker jamais terá acesso a chave compartilhada. Infelizmente enviar a mesma chave compartilhada para todos os clientes de seu servidor VPN é inseguro e poderá levar o hacker a obtê-la.

Para evitar esse trabalho e essa possibilidade de ataque, o modelo de criptografia assimétrica usando chaves públicas e privadas deve ser capaz de implementar algum modelo de inibição ao Man-in-the-Middle, e de fato, implementa, com recursos do sistema PKI.

Existem dois tipos de pessoas no mundo: as que sabem PKI e as que vão ser obrigadas a aprender PKI. No futuro próximo, absolutamente tudo envolverá criptografia e esse nível de segurança.

PKI - public key infrastructure (infraestrutura de chave pública) é um modelo de organização onde as chaves públicas são representadas em forma de certificados, esses certificados são gerados por uma CA - certificate authority (autoridade certificadora) devidamente assinado, adicionando nele atributos que são usados para garantir a segurança do uso de criptografia assimétrica.

Em termos mais práticos, a CA é a entidade (administrador de sistemas de alguma empresa por exemplo) que gera a chave pública devidamente assinada com a chave privada da CA.

Para que todos os elementos de software na empresa usem criptografia assimétrica, será necessário solicitar um certificado a CA.

No OpenVPN, você precisará de um certificado para o servidor e um certificado para o cliente. Quando o cliente se conectar ao servidor, o servidor irá verificar se o certificado do cliente é válido e corretamente assinado, recusando o cliente por qualquer discrepância (CA discrepante, certificado revogado, certificado vencido).


Observe o diagrama acima: a CA possui sua chave privada e seu certificado, auto-assinado.

Quando alguma entidade dentro da estrutura precisa usar SSL será necessário que ele, o solicitante, gere sua chave privada (e a mantenha segura), e em seguida, gere um arquivo CSR - Certificate Signing Request (requisição de certificado assinado) e envie-o a CA. Esse CSR contêm a chave pública e os atributos desejados pelo requerente.

Em posse do CSR, a CA poderá então gerar um certificado assinado por ela com os atributos solicitados pelo requerente (ou não, a CA quem decide os atributos). O resultado é um certificado - arquivo CRT - que contêm a chave pública, a assinatura da CA e os atributos do certificado.


4.1 - CA e confiança

Criar a própria CA é uma solução simples para manter uma PKI privada, no entanto, como a sua CA pode ter a chave privada roubada ou gerar certificados a esmo, ela não conta com confiança (fé pública), os computadores do resto do planeta não a conhecem e nem podem confiar nela.

Se algum computador acessar um servidor cujo certificado seja gerado pela sua CA auto-assinada ele exibirá erros de alerta de segurança.

Existem duas formas de contornar esse erro: instalando o certificado da sua CA nos dispositivos que usarão o serviço ou obter um certificado de CA assinado por uma CA que goza de confiança global (e portanto está reconhecida em todos os sistemas operacionais).

A segunda forma é com certeza a melhor, mas não a mais barata. As CAs globais cobram caro para gerar um certificado de sub-CA. Vamos ficar com o primeiro método mesmo!


Na figura acima temos um detalhe interessante: a CA "DST Root CA X3" goza de fé pública e é reconhecida globalmente. Ela por sua vez assinou uma sub-CA chamada "R3", que por sua vez gerou um certificado para mim (meu site, www.patrickbrandao.com).

Se eu apenas configurar meu certificado em algum servidor (servidor http por exemplo) meu certificado não será reconhecido como confiável, pois foi assinado pela desconhecida "R3". Para resolver isso o arquivo de certificado deve ser "full-chain" (corrente completa), incluindo meu certificado reconhecido pela "R3", e o certificado "R3" reconhecido pela "DST Root CA X3". Lembre-se disso sempre que utilizar certificados assinados dentro da cadeia global de confiança.

Você pode acessar as CAs globais nesse link:
https://hg.mozilla.org/mozilla-central/raw-file/tip/security/nss/lib/ckfw/builtins/certdata.txt


4.2 - Criando uma CA própria auto-assinada

No servidor onde ficará armazenado os arquivos (chaves, certificados) da CA, prepare o arquivo de configuração do openssl abaixo em todos os computadores onde você irá gerar chaves e certificados (CA, servidor, cliente/usuário)

# Arquivo /etc/ssl/openvpn.cnf
[ ca ]
default_ca  = CA_default

[ CA_default ]
dir     = /etc/ssl/nuva-ca
certs       = $dir
crl_dir     = $dir
database    = $dir/index.txt
new_certs_dir   = $dir
certificate = $dir/nuva-ca.crt
serial      = $dir/serial
crl     = $dir/nuva-crl.pem
private_key = $dir/nuva-ca.key
RANDFILE    = $dir/.rand
x509_extensions = basic_exts
crl_extensions  = crl_ext

default_days    = 3650
default_crl_days= 30
default_md  = sha256
preserve    = no

policy      = policy_anything

[ policy_anything ]
countryName     = optional
stateOrProvinceName = optional
localityName        = optional
organizationName    = optional
organizationalUnitName  = optional
commonName      = supplied
name            = optional
emailAddress        = optional

[ req ]
default_bits        = 2048
default_keyfile     = nuva-ca.key
default_md      = sha256
distinguished_name  = cn_only
x509_extensions     = easyrsa_ca

[ cn_only ]
commonName      = Common Name (eg: your user, host, or server name)
commonName_max      = 64
commonName_default  = changeme

[ org ]
countryName         = Country Name (2 letter code)
countryName_default     = BR
countryName_min         = 2
countryName_max         = 2

stateOrProvinceName     = State or Province Name (full name)
stateOrProvinceName_default = Minas Gerais

localityName            = Locality Name (eg, city)
localityName_default        = Belo Horizonte

0.organizationName      = Organization Name (eg, company)
0.organizationName_default  = Nuva Solucoes em TIC

organizationalUnitName      = Organizational Unit Name (eg, section)
organizationalUnitName_default  = Nuva Solucoes

commonName          = Common Name (eg: your user, host, or server name)
commonName_max          = 64
commonName_default      = nuva.com.br

emailAddress            = Email Address
emailAddress_default        = contato@nuva.com.br
emailAddress_max        = 64

[ basic_exts ]
basicConstraints    = CA:FALSE
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid,issuer:always

[ easyrsa_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints = CA:true
keyUsage = cRLSign, keyCertSign

[ crl_ext ]
authorityKeyIdentifier=keyid:always,issuer:always

[ server ]
basicConstraints       = CA:FALSE
nsCertType             = server
nsComment              = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer:always
extendedKeyUsage       = serverAuth
keyUsage               = digitalSignature, keyEncipherment

Preparando arquivos da CA:

# - Diretorio com arquivos da CA:
mkdir -p /etc/ssl/nuva-ca

# - Indice:
touch /etc/ssl/nuva-ca/index.txt

# - Serial da CA atual:
echo 202101170001 > /etc/ssl/nuva-ca/serial

Criar CA:

cd /etc/ssl/nuva-ca

# - Gerando chave privada da CA (sem proteção de senha):
[ -f nuva-ca.key ] || openssl genrsa \
    -out nuva-ca.key 4096

# - Gerando certificado auto-assinado da CA:
COUNTRY=BR
PROVINCE="Minas Gerais"
CITY="Belo Horizonte"
COMPANY="Nuva Solucoes em TIC"
ORG_UNIT="Nuva Solucoes"
COMMONNAME="nuva.com.br"
EMAIL=contato@nuva.com.br
VALIDDAYS=3650

ARG_SUBJ="/C=$COUNTRY/ST=$PROVINCE/L=$CITY/O=$COMPANY/OU=$ORG_UNIT/CN=$COMMONNAME"
ARG_CN="/CN=$COMMONNAME"

openssl req \
    -new \
    -nodes \
    -x509 \
    -days $VALIDDAYS \
    -key nuva-ca.key \
    -out nuva-ca.crt \
    -subj "$ARG_SUBJ" \
    -config /etc/ssl/openvpn.cnf


Verificando arquivos: chave e certificado

# - Arquivos da CA:
cd /etc/ssl/nuva-ca
ls -lah /etc/ssl/nuva-ca

total 16K
drwxr-xr-x 2 root root 4.0K Nov 24 02:43 ./
drwxr-xr-x 9 root root 4.0K Nov 24 03:18 ../
-rw-r--r-- 1 root root 2.1K Nov 24 02:43 nuva-ca.crt
-rw------- 1 root root 3.2K Nov 24 02:43 nuva-ca.key


# - Verificar chave privada:
openssl rsa -noout -text    -in nuva-ca.key
openssl rsa -noout -modulus -in nuva-ca.key
openssl rsa -noout -modulus -in nuva-ca.key | md5sum

# - Verificar certificado:
openssl x509 -noout -text -in nuva-ca.crt
openssl x509 -noout -modulus -in nuva-ca.crt
openssl x509 -noout -modulus -in nuva-ca.crt | md5sum

O certificado (chave pública) gerado a partir de uma chave privada tem o mesmo "modulus", portanto, esses comandos devem retornar o mesmo resultado (MD5 do modulus da chave privada e do certificado correspondente):

cd /etc/ssl/nuva-ca

# - modulus da chave privada:
openssl rsa -noout -modulus -in nuva-ca.key | md5sum

# - modulus da certificado:
openssl x509 -noout -modulus -in nuva-ca.crt | md5sum

A discrepância desses valores significa que a chave e o certificado não tem relação entre si e não funcionarão nas aplicações.

Fique sempre atendo a validade do certificado, no exemplo acima eu gerei um certificado de CA válido por 10 anos (variável VALIDDAYS). Quando esse tempo expirar toda a cadeia abaixo desse certificado será invalidada (todos os certificados de usuários, servidores e sub-CAs gerados com esse certificado).

# - Funcao de analise vencimento de arquivo CRT:

crt_expire_check(){
    argcrt="$1"

    EXPIREUNIXDT=$(openssl x509 -enddate -noout -in $argcrt | cut -d= -f 2)
    EXPIREDAY=$(date --date="$EXPIREUNIXDT"  --iso-8601)
    EXPIRETS=$(date --date="$EXPIREUNIXDT" "+%s")
    NOWTS=$(date "+%s")
    SEC_LEFT=$(($EXPIRETS-$NOWTS))

    echo "# - ExpireDate......: $EXPIREDAY"
    echo "#   ExpireUnixDate..: $EXPIREUNIXDT"
    echo "#   ExpireTimeStamp.: $EXPIRETS"
    echo "#   Expire in.......: $SEC_LEFT seconds"

    if [ "$SEC_LEFT" -lt 60 ]; then
        echo "#   Certificate ERROR - Expired"
        return 1
    else
        echo "#   Certificate OK"
        return 0
    fi

}

crt_expire_check /etc/ssl/nuva-ca/nuva-ca.crt



4.3 - Gerando chave privada e CSR para usuário/host cliente OpenVPN

Em uma PKI o usuário gera sua própria chave privada.

Se você ja trabalhou com certificados e-CPF você foi obrigado a usar uma senha. Tal senha é necessária para proteger a chave privada de uso indevido (chave privada protegida com DES-EDE3-CBC - criptografia simétrica onde a mesma senha é usada para criptografar e descriptografar o conteúdo).

Os passos a seguir são executados no dispositivo do usuário solicitante (a CA não tem acesso a chave privada do usuário).

# - Diretorio com arquivos da CA:
mkdir -p /etc/openvpn/user-patrickbrandao
cd /etc/openvpn/user-patrickbrandao

PRIV_KEY_PASSWORD="tulipa2021"

[ -f patrickbrandao-enc.key ] || openssl genrsa \
    -passout "pass:$PRIV_KEY_PASSWORD" \
    -des3 -out patrickbrandao-enc.key 4096

Sem informar os argumentos '-passout "pass:$PRIV_KEY_PASSWORD"' a senha será solicitada na linha de comando interativa do terminal.

A chave privada gerada acima no arquivo patrickbrandao-enc.key está criptografada com RSA, usando a senha. Toda vez que a chave for utilizada a senha será requerida.

Embora a senha para proteger a chave privada seja uma ótima medida de segurança, ela não é compatível com o uso em softwares, visto que toda vez que o software quiser usar a chave privada ele deverá requisitar a senha da chave privada para usá-la. Vamos gerar um arquivo com a chave privada sem senha:

cd /etc/openvpn/user-patrickbrandao

PRIV_KEY_PASSWORD="tulipa2021"

openssl rsa \
    -in patrickbrandao-enc.key \
    -passin "pass:$PRIV_KEY_PASSWORD" \
    -out patrickbrandao.key

Falta agora gerar o arquivo CSR, que será enviado para a CA gerar nosso certificado.

Reafirmando: o usuário final não gera o proprio certificado. O arquivo CSR não é um certificado.

cd /etc/openvpn/user-patrickbrandao

COUNTRY=BR
PROVINCE="Minas Gerais"
CITY="Belo Horizonte"
COMPANY="Patrick Brandao - Consultor"
ORG_UNIT="Patrick Brandao"
COMMONNAME="patrickbrandao.com"
EMAIL=patrickbrandao@gmail.com

ARG_SUBJ="/C=$COUNTRY/ST=$PROVINCE/L=$CITY/O=$COMPANY/OU=$ORG_UNIT/CN=$COMMONNAME"
ARG_CN="/CN=$COMMONNAME"

# Gerar arquivo CSR (requisicao de certificado assinado):
openssl req \
    -new \
    -nodes \
    -key patrickbrandao.key \
    -out patrickbrandao.csr \
    -subj "$ARG_SUBJ" \
    -config /etc/ssl/openvpn.cnf

# Verificando dados do arquivo CSR:
openssl req -text -noout -verify -in patrickbrandao.csr
openssl req -noout -modulus -in patrickbrandao.csr
openssl req -noout -modulus -in patrickbrandao.csr | md5sum

O último passo antes de enviar a requisição para assinar certificado (CSR) para a CA é conferir se nossa chave privada e o arquivo CSR possuem o mesmo 'modulus', pois é mandatório a coerência entre chave privada (KEY), requisição de certificado (CSR) e certificado assinado (CRT).

cd /etc/openvpn/user-patrickbrandao

# Modulus da chave privada
openssl rsa \
    -noout \
    -modulus \
    -in patrickbrandao.key | md5sum

# Modulus do CSR:
openssl req -noout -modulus -in patrickbrandao.csr | md5sum

Ambos os comandos acima devem retornar o mesmo MD5.

Envie somente o arquivo CSR para a CA (via pastebin, e-email, SCP, chat, etc...). Esse arquivo não é sigiloso!


4.4 - Gerando certificado assinado baseado na requisição (CSR) do usuário

Com o arquivo CSR do usuário em mãos (no servidor da CA), vamos gerar o certificado.

Observação: no servidor da CA, colocaremos os arquivos de CSR enviado pelos requerentes na pasta /etc/ssl/nuva-ca/requests

mkdir -p /etc/ssl/nuva-ca/requests
mkdir -p /etc/ssl/nuva-ca/certs

# Caminho do arquivo com a chave privada da CA:
CA_KEY=/etc/ssl/nuva-ca/nuva-ca.key

# Caminho do arquivo do certificado da CA:
CA_CRT=/etc/ssl/nuva-ca/nuva-ca.crt


# Caminho do arquivo CSR enviado pelo requetente (usuário):
USER_CSR=/etc/ssl/nuva-ca/requests/patrickbrandao.csr

# Caminho onde será gravado o arquivo CRT (certificado) do requetente (usuário):
USER_CERT=/etc/ssl/nuva-ca/certs/patrickbrandao.crt
USER_CERT_FULLCHAIN=/etc/ssl/nuva-ca/certs/patrickbrandao-fullchain.crt

# Número de série do certificado que será gerado para o usuário:
USER_SERIAL=202101152354

# Validade do certificado do usuário (dias a partir da data de geração):
USER_VALIDDAYS=3650

openssl x509 \
    -req \
    -days $USER_VALIDDAYS \
    -in $USER_CSR \
    -CA $CA_CRT \
    -CAkey $CA_KEY \
    -set_serial $USER_SERIAL \
    -out $USER_CERT

# Unir certificado da CA com o certificado do usuário em um arquivo completo (full-chain):
cat $CA_CRT $USER_CERT > $USER_CERT_FULLCHAIN

Com os passos acima o certificado do usuário será gerado no arquivo /etc/ssl/nuva-ca/certs/patrickbrandao.crt e o arquivo contendo a cadeia de certificação no arquivo /etc/ssl/nuva-ca/certs/patrickbrandao-fullchain.crt.

Envie de volta ao requerente (usuário) os certificados envolvidos:

# Certificado da CA:
/etc/ssl/nuva-ca/nuva-ca.crt

# Certificado gerado baseado no requerimento:
/etc/ssl/nuva-ca/certs/patrickbrandao.crt

# Arquivo com cadeia de certificados:
/etc/ssl/nuva-ca/certs/patrickbrandao-fullchain.crt

Devolva os arquivos acima ao requerente. É importante colocar o certificado (CRT) na mesma pasta da chave privada (no host do usuário, pasta /etc/openvpn/user-patrickbrandao).

Se no futuro você implementar uma CA matriz e criar sub-CAs para as filiais, será necessário incluir os certificados da CA e da sub-CA no full-chain. Se você criar uma estrutura com muitos estágios de sub-CAs, toda a árvore deve ser incluída.

É muito importante ficar atendo à validade dos certificados em toda a árvore de confiança, você deverá criar e distribuir novos certificados antes que os certificados atuais expirem, desde a CA raiz até as partes mais baixas da hierarquia.


4.5 - Arquivos do usuário

Uma vez que a CA enviou os arquivos CRT ao usuário ele estará pronto para uso.

# Entrar na pasta de arquivos do usuário:
cd /etc/openvpn/user-patrickbrandao

ls -lah 

total 32K
drwxr-xr-x 2 root root 4.0K Jan 17 00:15 ./
drwxr-xr-x 9 root root 4.0K Jan 16 23:22 ../
-rw-r--r-- 1 root root 2.1K Jan 17 00:15 nuva-ca.crt
-rw-r--r-- 1 root root 4.1K Jan 17 00:15 patrickbrandao-fullchain.crt
-rw-r--r-- 1 root root 2.0K Jan 17 00:15 patrickbrandao.crt
-rw-r--r-- 1 root root 1.8K Jan 16 23:35 patrickbrandao.csr
-rw------- 1 root root 3.3K Jan 16 23:32 patrickbrandao.key
-rw------- 1 root root 3.3K Jan 16 23:32 patrickbrandao-enc.key



4.6 - Requerimento de certificado para o servidor OpenVPN

Você deverá criar agora um certificado para o servidor OpenVPN semelhante ao que foi feito para o usuário.

# Entrar na pasta de arquivos do servidor:
mkdir -p /etc/openvpn/srv-ovpn01
cd /etc/openvpn/srv-ovpn01

# Gerar chave privada do servidor OpenVPN 01:
[ -f ovpn01.key ] || openssl genrsa \
    -out ovpn01.key 4096

# Gerar requisição de certificado para o servidor OpenVPN 01:
COUNTRY=BR
PROVINCE="Minas Gerais"
CITY="Belo Horizonte"
COMPANY="Nuva Solucoes em TIC"
ORG_UNIT="OpenVPN Server 01"
COMMONNAME="ovpn01.intranet.br"
EMAIL=contato@nuva.com.br

ARG_SUBJ="/C=$COUNTRY/ST=$PROVINCE/L=$CITY/O=$COMPANY/OU=$ORG_UNIT/CN=$COMMONNAME"
ARG_CN="/CN=$COMMONNAME"

# Gerar arquivo CSR (requisicao de certificado assinado):
openssl req \
    -new \
    -sha256 \
    -nodes \
    -key ovpn01.key \
    -out ovpn01.csr \
    -subj "$ARG_SUBJ" \
    -config /etc/ssl/openvpn.cnf \
    -extensions server

# Verificando dados do arquivo CSR:
openssl req -text -noout -verify -in ovpn01.csr
openssl req -noout -modulus -in ovpn01.csr

# Verificando coerencia entre chave e CSR:
openssl req -noout -modulus -in ovpn01.csr | md5sum
openssl rsa -noout -modulus -in ovpn01.key | md5sum

Seguindo o padrão, vamos enviar o arquivo CSR (ovpn01.csr) para a CA.


4.7 - Gerando Certificado para o servidor OpenVPN na CA

Com o CSR do servidor OpenVPN (ovpn01.csr) no servidor da CA, na pasta /etc/ssl/nuva-ca/requests, continuamos.

Gerar certificado do servidor OpenVPN:

mkdir -p /etc/ssl/nuva-ca/requests
mkdir -p /etc/ssl/nuva-ca/certs

# Caminho do arquivo com a chave privada da CA:
CA_KEY=/etc/ssl/nuva-ca/nuva-ca.key

# Caminho do arquivo do certificado da CA:
CA_CRT=/etc/ssl/nuva-ca/nuva-ca.crt


# Caminho do arquivo CSR enviado pelo requetente (usuário):
SRV_CSR=/etc/ssl/nuva-ca/requests/ovpn01.csr

# Caminho onde será gravado o arquivo CRT (certificado) do requetente (usuário):
SRV_CERT=/etc/ssl/nuva-ca/certs/ovpn01.crt
SRV_CERT_FULLCHAIN=/etc/ssl/nuva-ca/certs/ovpn01-fullchain.crt

# Número de série do certificado que será gerado para o usuário:
SRV_SERIAL=202101170002

# Validade do certificado do usuário (dias a partir da data de geração):
SRV_VALIDDAYS=3650

openssl ca \
    -batch \
    -config /etc/ssl/openvpn.cnf \
    -extensions server \
    -cert $CA_CRT \
    -key $CA_KEY \
    -out $SRV_CERT \
    -in $SRV_CSR

# Unir certificado da CA com o certificado do usuário em um arquivo completo (full-chain):
cat $CA_CRT $SRV_CERT > $SRV_CERT_FULLCHAIN

# Conferindo certificado do servidor:
openssl x509 -noout -text -in $SRV_CERT
openssl x509 -noout -modulus -in $SRV_CERT
openssl x509 -noout -modulus -in $SRV_CERT | md5sum

Nota: ao gerar um certificado usando a CA, o arquivo de índice /etc/ssl/nuva-ca/index.txt será atualizado para registrar o serial do certificado gerado.

Com os passos acima o certificado do servidor será gerado no arquivo /etc/ssl/nuva-ca/certs/ovpn01.crt e o arquivo contendo a cadeia de certificação no arquivo /etc/ssl/nuva-ca/certs/ovpn01-fullchain.crt.

Envie de volta ao requerente (usuário) os certificados envolvidos:

# Certificado da CA:
/etc/ssl/nuva-ca/nuva-ca.crt

# Certificado gerado baseado no requerimento:
/etc/ssl/nuva-ca/certs/ovpn01.crt

# Arquivo com cadeia de certificados:
/etc/ssl/nuva-ca/certs/ovpn01-fullchain.crt

Devolva os arquivos acima ao requerente (servidor). É importante colocar o certificado (CRT) na mesma pasta da chave privada (no host do servidor, pasta /etc/openvpn/srv-ovpn01).



4.8 - Arquivos do servidor

Uma vez que a CA enviou os arquivos CRT ao servidor OpenVPN ele estará pronto para uso.

# Entrar na pasta de arquivos do usuário:
cd /etc/openvpn/srv-ovpn01

ls -lah 

total 32K
drwxr-xr-x 2 root root 4.0K Jan 17 00:15 ./
drwxr-xr-x 9 root root 4.0K Jan 16 23:22 ../
-rw-r--r-- 1 root root 2.1K Jan 17 00:15 nuva-ca.crt
-rw-r--r-- 1 root root 4.1K Jan 17 00:15 ovpn01-fullchain.crt
-rw-r--r-- 1 root root 2.0K Jan 17 00:15 ovpn01.crt
-rw-r--r-- 1 root root 1.8K Jan 16 23:35 ovpn01.csr
-rw------- 1 root root 3.3K Jan 16 23:32 ovpn01.key

Agora que temos certificados assinados dentro da nossa estrutura de segurança (PKI), podemos trabalhar com OpenVPN + SSL.



Capítulo 5 - OpenVPN com camada SSL

Vamos abordar agora o uso de OpenVPN e camada de criptografia SSL, o fruto dessa junção é uma VPN de alta segurança, indicada para empresas que desejam confiança e sigilo nas comunicações pela Internet.



De agora em diante, todos os exemplos serão orientados a execução do OpenVPN em background, como serviço. A configuração ficará em arquivo.

Antes de iniciar, no lado servidor é necessário gerar um arquivo DH (Diffie-Hellman key-exchange):

# - No servidor OpenVPN, gerar arquivo DH:
openssl dhparam -out /etc/openvpn/dh2048.pem 2048



5.1 - VPN de camada 3 (ptp) com SSL

No servidor, configure:

# Arquivo /etc/openvpn/openvpn-ssl-srv-001.conf

proto udp
port  22001

dev-type  tun
dev       vpn001
persist-tun

tun-mtu  1500
fragment 1300

tls-server
ifconfig      10.200.0.1 10.200.0.2
ifconfig-ipv6 2001:db8:10:200::1 2001:db8:10:200::2

cipher AES256
auth   SHA512

dh       /etc/openvpn/dh2048.pem
ca       /etc/openvpn/srv-ovpn01/nuva-ca.crt
cert     /etc/openvpn/srv-ovpn01/ovpn01.crt
key      /etc/openvpn/srv-ovpn01/ovpn01.key
persist-key

keepalive 10 60
daemon

user  nobody
group nogroup

writepid   /var/run/openvpn-ssl-srv-001.pid
log-append /var/log/openvpn-ssl-srv-001.log
verb       3


# - Rodar processo servidor:
openvpn --config /etc/openvpn/openvpn-ssl-srv-001.conf



No lado cliente (certificado do usuário patrickbranado), configure:

# Arquivo /etc/openvpn/openvpn-ssl-cli-001.conf

proto  udp
port   22001
remote 45.255.128.2

dev-type  tun
dev       vpn001
persist-tun

tun-mtu  1500
fragment 1300

tls-client
ifconfig      10.200.0.2 10.200.0.1
ifconfig-ipv6 2001:db8:10:200::2 2001:db8:10:200::1

cipher AES256
auth   SHA512

ca       /etc/openvpn/user-patrickbrandao/nuva-ca.crt
cert     /etc/openvpn/user-patrickbrandao/patrickbrandao.crt
key      /etc/openvpn/user-patrickbrandao/patrickbrandao.key
persist-key

keepalive 10 60
daemon

user  nobody
group nogroup

writepid   /var/run/openvpn-ssl-cli-001.pid
log-append /var/log/openvpn-ssl-cli-001.log
verb       3


# - Rodar processo cliente:
openvpn --config /etc/openvpn/openvpn-ssl-cli-001.conf

# Teste (lado cliente):
fping -M -b 1472 10.200.0.1
fping -M -b 1452 2001:db8:10:200::1



5.2 - VPN de camada 2 (ptp) com SSL

No servidor, configure:

# Arquivo /etc/openvpn/openvpn-ssl-srv-002.conf

proto udp
port  22002

dev-type  tap
dev       vpn002
persist-tun

tun-mtu  1500
fragment 1300

tls-server
ifconfig      10.202.0.1 255.255.255.0
ifconfig-ipv6 2001:db8:10:202::1/64 2001:db8:10:202::2

cipher AES256
auth   SHA512

dh       /etc/openvpn/dh2048.pem
ca       /etc/openvpn/srv-ovpn01/nuva-ca.crt
cert     /etc/openvpn/srv-ovpn01/ovpn01.crt
key      /etc/openvpn/srv-ovpn01/ovpn01.key
persist-key

keepalive 10 60
daemon

user  nobody
group nogroup

writepid   /var/run/openvpn-ssl-srv-002.pid
log-append /var/log/openvpn-ssl-srv-002.log
verb       3


# - Rodar processo servidor:
openvpn --config /etc/openvpn/openvpn-ssl-srv-002.conf



No lado cliente (certificado do usuário patrickbranado), configure:

# Arquivo /etc/openvpn/openvpn-ssl-cli-002.conf

proto  udp
port   22002
remote 45.255.128.2

dev-type  tap
dev       vpn002
persist-tun

tun-mtu  1500
fragment 1300

tls-client
ifconfig      10.202.0.2 255.255.255.0
ifconfig-ipv6 2001:db8:10:202::2/64 2001:db8:10:202::1

cipher AES256
auth   SHA512

ca       /etc/openvpn/user-patrickbrandao/nuva-ca.crt
cert     /etc/openvpn/user-patrickbrandao/patrickbrandao.crt
key      /etc/openvpn/user-patrickbrandao/patrickbrandao.key
persist-key

keepalive 10 60
daemon

user  nobody
group nogroup

writepid   /var/run/openvpn-ssl-cli-002.pid
log-append /var/log/openvpn-ssl-cli-002.log
verb       3


# - Rodar processo cliente:
openvpn --config /etc/openvpn/openvpn-ssl-cli-002.conf

# Teste (lado cliente):
fping -M -b 1472 10.202.0.1
fping -M -b 1452 2001:db8:10:202::1

Você pode adicionar a opção "--secret" informando o arquivo com a chave compartilhada para criar uma camada adicional de segurança (paranôica).



Capítulo 6 - OpenVPN como servidor multiponto em camada 3

Vamos entrar agora num uso mais amplo do OpenVPN em modo servidor, que é a capacidade de atender múltiplos clientes. Aqui teremos vários usuários se conectando a um ponto central (hub).

Nossos clientes podem usar quaisquer sistemas operacionais (Linux, Windows, MacOS, Android, iPhone).



6.1 - Arquivo de configuração all-in-one OVPN

Se você observou a forma como o arquivo de configuração faz referência aos arquivos de chaves e certificados já deve ter imaginado como isso deve ser um problema sério nos clientes, como especificar o caminho no arquivo de configuração e colocar os arquivos no dispositivo cliente de acordo e todos os problemas por erros de usuários que isso deve gerar.

Para sua sorte o arquivo de configuração permite incluir o conteúdo dos arquivos referênciados (chaves compartilhadas, chaves privadas, certificado da CA e certificado do cliente) para gerar um único arquivo completo: arquivo OVPN.

Diferente das configurações aprendidas até aqui, onde cada linha do arquivo é composto de argumento seguido de valor, a sintaxe para incluir conteúdo de arquivos é feito por meio de TAGs (igual XML). As tags são:

<secret> e </secret>, entre elas o conteúdo da chave compartilhada, iniciando e incluindo -----BEGIN OpenVPN Static key V1----- e -----END OpenVPN Static key V1-----

<ca> e </ca>, entre elas o conteúdo do certificado da CA, iniciando e incluindo -----BEGIN CERTIFICATE----- e -----END CERTIFICATE-----

<cert> e </cert>, entre elas o conteúdo do certificado do cliente/usuário, iniciando e incluindo -----BEGIN CERTIFICATE----- e -----END CERTIFICATE-----

<key> e </key>, entre elas o conteúdo da chave privada do cliente/usuário, iniciando e incluindo -----BEGIN RSA PRIVATE KEY----- e ------END RSA PRIVATE KEY-----, ou -----BEGIN PRIVATE KEY----- e -----END PRIVATE KEY-----

Segue exemplo de configuração cliente completa (arquivo obtido nos confins da dark-web):

# Arquivo /tmp/internet-opengw-net-122.ovpn
dev    tun
proto  tcp
remote public-vpn-122.opengw.net 443

cipher AES-128-CBC
auth   SHA1

resolv-retry infinite
nobind
persist-key
persist-tun
client

verb 3
#auth-user-pass

<ca>
-----BEGIN CERTIFICATE-----
MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
jjxDah2nGN59PRbxYvnKkKj9
-----END CERTIFICATE-----
</ca>


<cert>
-----BEGIN CERTIFICATE-----
MIICxjCCAa4CAQAwDQYJKoZIhvcNAQEFBQAwKTEaMBgGA1UEAxMRVlBOR2F0ZUNs
aWVudENlcnQxCzAJBgNVBAYTAkpQMB4XDTEzMDIxMTAzNDk0OVoXDTM3MDExOTAz
MTQwN1owKTEaMBgGA1UEAxMRVlBOR2F0ZUNsaWVudENlcnQxCzAJBgNVBAYTAkpQ
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5h2lgQQYUjwoKYJbzVZA
5VcIGd5otPc/qZRMt0KItCFA0s9RwReNVa9fDRFLRBhcITOlv3FBcW3E8h1Us7RD
4W8GmJe8zapJnLsD39OSMRCzZJnczW4OCH1PZRZWKqDtjlNca9AF8a65jTmlDxCQ
CjntLIWk5OLLVkFt9/tScc1GDtci55ofhaNAYMPiH7V8+1g66pGHXAoWK6AQVH67
XCKJnGB5nlQ+HsMYPV/O49Ld91ZN/2tHkcaLLyNtywxVPRSsRh480jju0fcCsv6h
p/0yXnTB//mWutBGpdUlIbwiITbAmrsbYnjigRvnPqX1RNJUbi9Fp6C2c/HIFJGD
ywIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQChO5hgcw/4oWfoEFLu9kBa1B//kxH8
hQkChVNn8BRC7Y0URQitPl3DKEed9URBDdg2KOAz77bb6ENPiliD+a38UJHIRMqe
UBHhllOHIzvDhHFbaovALBQceeBzdkQxsKQESKmQmR832950UCovoyRB61UyAV7h
+mZhYPGRKXKSJI6s0Egg/Cri+Cwk4bjJfrb5hVse11yh4D9MHhwSfCOH+0z4hPUT
Fku7dGavURO5SVxMn/sL6En5D+oSeXkadHpDs+Airym2YHh15h0+jPSOoR6yiVp/
6zZeZkrN43kuS73KpKDFjfFPh8t4r1gOIjttkNcQqBccusnplQ7HJpsk
-----END CERTIFICATE-----
</cert>


<key>
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA5h2lgQQYUjwoKYJbzVZA5VcIGd5otPc/qZRMt0KItCFA0s9R
wReNVa9fDRFLRBhcITOlv3FBcW3E8h1Us7RD4W8GmJe8zapJnLsD39OSMRCzZJnc
zW4OCH1PZRZWKqDtjlNca9AF8a65jTmlDxCQCjntLIWk5OLLVkFt9/tScc1GDtci
55ofhaNAYMPiH7V8+1g66pGHXAoWK6AQVH67XCKJnGB5nlQ+HsMYPV/O49Ld91ZN
/2tHkcaLLyNtywxVPRSsRh480jju0fcCsv6hp/0yXnTB//mWutBGpdUlIbwiITbA
mrsbYnjigRvnPqX1RNJUbi9Fp6C2c/HIFJGDywIDAQABAoIBAERV7X5AvxA8uRiK
k8SIpsD0dX1pJOMIwakUVyvc4EfN0DhKRNb4rYoSiEGTLyzLpyBc/A28Dlkm5eOY
fjzXfYkGtYi/Ftxkg3O9vcrMQ4+6i+uGHaIL2rL+s4MrfO8v1xv6+Wky33EEGCou
QiwVGRFQXnRoQ62NBCFbUNLhmXwdj1akZzLU4p5R4zA3QhdxwEIatVLt0+7owLQ3
lP8sfXhppPOXjTqMD4QkYwzPAa8/zF7acn4kryrUP7Q6PAfd0zEVqNy9ZCZ9ffho
zXedFj486IFoc5gnTp2N6jsnVj4LCGIhlVHlYGozKKFqJcQVGsHCqq1oz2zjW6LS
oRYIHgECgYEA8zZrkCwNYSXJuODJ3m/hOLVxcxgJuwXoiErWd0E42vPanjjVMhnt
KY5l8qGMJ6FhK9LYx2qCrf/E0XtUAZ2wVq3ORTyGnsMWre9tLYs55X+ZN10Tc75z
4hacbU0hqKN1HiDmsMRY3/2NaZHoy7MKnwJJBaG48l9CCTlVwMHocIECgYEA8jby
dGjxTH+6XHWNizb5SRbZxAnyEeJeRwTMh0gGzwGPpH/sZYGzyu0SySXWCnZh3Rgq
5uLlNxtrXrljZlyi2nQdQgsq2YrWUs0+zgU+22uQsZpSAftmhVrtvet6MjVjbByY
DADciEVUdJYIXk+qnFUJyeroLIkTj7WYKZ6RjksCgYBoCFIwRDeg42oK89RFmnOr
LymNAq4+2oMhsWlVb4ejWIWeAk9nc+GXUfrXszRhS01mUnU5r5ygUvRcarV/T3U7
TnMZ+I7Y4DgWRIDd51znhxIBtYV5j/C/t85HjqOkH+8b6RTkbchaX3mau7fpUfds
Fq0nhIq42fhEO8srfYYwgQKBgQCyhi1N/8taRwpk+3/IDEzQwjbfdzUkWWSDk9Xs
H/pkuRHWfTMP3flWqEYgW/LW40peW2HDq5imdV8+AgZxe/XMbaji9Lgwf1RY005n
KxaZQz7yqHupWlLGF68DPHxkZVVSagDnV/sztWX6SFsCqFVnxIXifXGC4cW5Nm9g
va8q4QKBgQCEhLVeUfdwKvkZ94g/GFz731Z2hrdVhgMZaU/u6t0V95+YezPNCQZB
wmE9Mmlbq1emDeROivjCfoGhR3kZXW1pTKlLh6ZMUQUOpptdXva8XxfoqQwa3enA
M7muBbF0XN7VO80iJPv+PmIZdEIAkpwKfi201YB+BafCIuGxIF50Vg==
-----END RSA PRIVATE KEY-----
</key>


6.2 - Configuração do servidor multiponto em camada 3

Uma nova técnica que iremos apresentar são as rotas servidas via VPN, o argumento "push" tem como finalidade enviar uma configuração ao lado remoto (todos que se conectarem ao servidor), iremos usá-lo a principio para orientar nossos clientes a respeito das redes (prefixos IP) que devem ser acessados pela VPN.

O argumento ifconfig-pool-persist servirá como base de dados de usuários e o IP obtido no POOL (IP dentro do prefixo do argumento server) para que nas próximas conexões seja dado o mesmo IP.

O argumento status mantem um arquivo com o relatório do servidor OpenVPN (rotas, lista de usuários conectados, etc...).

O argumento server serve o prefixo a ser usado pelo servidor, normalmente o primeiro IP é do servidor e os demais são usados como POOL DHCP para configuração dos usuários que se conectarem. O argumento server-ipv6 tem o mesmo propósito em IPv6.

O argumento topology em modo subnet fará com que cada cliente da VPN receba um IP em faixa consecutiva (no exemplo abaixo, no mesmo /24), mas devido ao driver TUN que provisiona túneis L3 a comunicação entre clientes não será possível, visto que pacotes unicast enviados para o lado servidor não serão roteados pela ausência de resolução de camada 2 (não tem ARP). Eu vejo isso como desejável, simplifica a configuração e impede comunicação entre clientes (previnindo invasões).


Esse modo parcial, quando a VPN é usada apenas para serviços específicos, é mais eficiente para serviços corporativos, nele, o usuário trabalha remotamente, navega na Internet pelo roteador local e usa a VPN apenas para rotas específicas servidas pelo servidor OpenVPN.


# - Preparando:
mkdir -p /var/lib/openvpn
touch /var/lib/openvpn/pmtp-srv-001.dat
chown nobody:nogroup /var/lib/openvpn/pmtp-srv-001.dat

Arquivo de configuração do servidor:

# Arquivo /etc/openvpn/openvpn-pmtp-srv-001.conf

proto udp
port  33001

dev-type  tun
dev       ovpns01
persist-key
persist-tun

topology              subnet
server                10.210.0.0 255.255.255.0
server-ipv6           2001:db8:ffff:cafe::/64
push                  "route 10.222.222.0  255.255.255.0"
push                  "route 192.168.200.0 255.255.255.0"
push                  "route-ipv6 2001:db8:f200::/64"
status                /var/log/openvpn-pmtp-srv-001.dat
ifconfig-pool-persist /var/lib/openvpn/pmtp-srv-001.dat

tls-server

cipher AES-256-CBC
auth   SHA512

dh       /etc/openvpn/dh2048.pem
ca       /etc/openvpn/srv-ovpn01/nuva-ca.crt
cert     /etc/openvpn/srv-ovpn01/ovpn01.crt
key      /etc/openvpn/srv-ovpn01/ovpn01.key
persist-key

keepalive 10 60
daemon

user  nobody
group nogroup

writepid   /var/run/openvpn-pmtp-srv-001.pid
log-append /var/log/openvpn-pmtp-srv-001.log
verb       3

explicit-exit-notify 1


6.3 - Configuração dos clientes/usuários em camada 3

O primeiro desafio é envolver os usuários nas regras de PKI (usuários geram chave privada e CSR, CA gera certificado), visto que é bem complicado ensinar usuários finais leigos a manipular esses arquivos.

Temos como opções:
A) Ignorar os certificados dos clientes;
B) Usar o mesmo certificado para todos;
C) Gerar nós mesmo todos os arquivos (chave privada, CSR e certificado).

Vou demonstrar a terceira opção (C) pois afinal o cara de TI acaba fazendo todo o trabalho sozinho.

Já temos a CA e o certificado do servidor, vamos gerar alguns chaves/certificados para nossos usuários empresariais remotos.

No servidor da CA, execute:

# - Pasta para chaves e certificados:
mkdir -p /etc/ssl/nuva-ca/users
cd /etc/ssl/nuva-ca/users

TOTAL=100

# Variavies
COUNTRY=BR
PROVINCE="Minas Gerais"
CITY="Belo Horizonte"
COMPANY="Nuva Solucoes em TIC"
ORG_UNIT="RH"
USER_VALIDDAYS=3650

# Arquivos da CA:
CA_KEY=/etc/ssl/nuva-ca/nuva-ca.key
CA_CRT=/etc/ssl/nuva-ca/nuva-ca.crt

# Lista de usuários
USERS="
   patrickbrandao
   suporte1
   suporte2
   suporte3
   gerente
   secretaria
   morcegao
   portaria
   guest
"

# Gerar
for user in $USERS; do

    # Variaveis por certificado
    EMAIL=$user@nuva.com.br

    ARG_SUBJ="/C=$COUNTRY/ST=$PROVINCE/L=$CITY/O=$COMPANY/OU=$ORG_UNIT"
    ARG_CN="CN=$user/emailAddress=$EMAIL"

    # Arquivos
    UKEY="/etc/ssl/nuva-ca/users/$user.key"
    UCSR="/etc/ssl/nuva-ca/users/$user.csr"
    UCRT="/etc/ssl/nuva-ca/users/$user.crt"

    echo "# - Gerando $user de $TOTAL - $UKEY -- $UCRT"

    # Gerar chave
    echo "# [$user] > Gerando chave privada"
    [ -f "$UKEY" ] || openssl genrsa -out "$UKEY" 4096

    # Gerar CSR
    echo "# [$user] > Gerando requisicao de certificado"
    [ -f "$UCSR" ] || openssl req \
        -new \
        -nodes \
        -key "$UKEY" \
        -out "$UCSR" \
        -subj "$ARG_SUBJ/$ARG_CN" \
        -config /etc/ssl/openvpn.cnf

    # Gerar certificado
    echo "# [$user] > Gerando certificado"
    [ -f "$UCRT" ] || openssl ca \
        -batch \
        -config /etc/ssl/openvpn.cnf \
        -cert $CA_CRT \
        -key $CA_KEY \
        -out $UCRT \
        -in $UCSR

done

Geramos chave e certificado para cada um dos usuários (veriável $USERS do script).

Vamos produzir o arquivo OVPN para cada usuário em lote. Prepare o arquivo de configuração abaixo, que contêm as configurações em comum para todos os usuários:

# Arquivo /etc/openvpn/openvpn-pmtp-client-001-shared.conf

proto udp
port  33001

dev-type  tun
dev       tuns1
persist-tun

resolv-retry infinite
nobind
client

keepalive  10 60
daemon
verb       3

cipher AES-256-GCM
auth   SHA512
persist-key

Agora vamos produzir o arquivo OVPN de cada usuário embutindo o certificado da CA e a chave e certificado do usuário.

A variável REMOTE deve ser alterada para apontar para seu servidor OpenVPN, no exemplo abaixo vou apontar para o ip fictício 45.255.128.2


# Endereço do servidor:
REMOTE=45.255.128.2

# Certificado da CA:
CA_CERT=/etc/ssl/nuva-ca/nuva-ca.crt

# Arquivos de argumentos comuns:
SHARED_CONF=/etc/openvpn/openvpn-pmtp-client-001-shared.conf

# Lista de usuários
USERS="
   patrickbrandao
   suporte1
   suporte2
   suporte3
   gerente
   secretaria
   morcegao
   portaria
   guest
"

# Gerar arquivo OVPN
for user in $USERS; do

    UOVPN="/etc/ssl/nuva-ca/users/$user.ovpn"

    UCRT="/etc/ssl/nuva-ca/users/$user.crt"
    UKEY="/etc/ssl/nuva-ca/users/$user.key"

    # Agregar
    (
        echo "# Gerado automaticamente - $(date)"
        echo
        echo "# Config comum:" 
        cat $SHARED_CONF
        echo

        echo "# Servidor:" 
        echo remote $REMOTE
        echo

        echo "<ca>" 
        egrep -A 1000 BEGIN $CA_CERT
        echo "</ca>" 
        echo

        echo "<cert>" 
        egrep -A 1000 BEGIN $UCRT
        echo "</cert>" 
        echo

        echo "<key>" 
        egrep -A 1000 BEGIN $UKEY
        echo "</key>" 
        echo

        echo

    ) > $UOVPN

done


Dentro da pasta /etc/ssl/nuva-ca/users estarão os arquivos com extensão .ovpn de cada usuário. Vamos testar usando o guest.ovpn, veja como ficou o arquivo gerado automaticamente:

# Arquivo /etc/ssl/nuva-ca/users/guest.ovpn
# Gerado automaticamente - Tue Jan 19 16:08:08 GMT 2021

# Config comum:
proto udp
port  33001

dev-type  tun
dev       tuns1
persist-tun

resolv-retry infinite
nobind
client

keepalive  10 60
daemon
verb       3

cipher AES-256-GCM
auth   SHA512
persist-key


# Servidor:
remote 45.255.128.2

<ca>
-----BEGIN CERTIFICATE-----
MIIGmTCCBIGgAwIBAgIJAJ49DzwRMASdMA0GCSqGSIb3DQEBCwUAMIGKMQswCQYD
VQQGEwJCUjEVMBMGA1UECAwMTWluYXMgR2VyYWlzMRcwFQYDVQQHDA5CZWxvIEhv
cml6b250ZTEdMBsGA1UECgwUTnV2YSBTb2x1Y29lcyBlbSBUSUMxFjAUBgNVBAsM
DU51dmEgU29sdWNvZXMxFDASBgNVBAMMC251dmEuY29tLmJyMB4XDTIxMDExNzE1
NDMxNVoXDTMxMDExNTE1NDMxNVowgYoxCzAJBgNVBAYTAkJSMRUwEwYDVQQIDAxN
aW5hcyBHZXJhaXMxFzAVBgNVBAcMDkJlbG8gSG9yaXpvbnRlMR0wGwYDVQQKDBRO
dXZhIFNvbHVjb2VzIGVtIFRJQzEWMBQGA1UECwwNTnV2YSBTb2x1Y29lczEUMBIG
A1UEAwwLbnV2YS5jb20uYnIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
AQDT9sARGoj09X5Na1LjERY+B2s2TAA+W2tIBwnJWc1h27tBSdzqDubEMngRIunc
jYuS3khHIEPCT3DzSAgbdHMj4iJ4XitNwjj1XLuO2GWI5ke2wOuCxoOLm/HhMlhW
inKxo6hC6JojyaSinAdx7mGJ93wrt716E6SVcxhJn9CHI81yz3JYqcfNt7SCtUn5
YVaGtM+UviyZcv9C3mEaG3IxUr1n7C91prCR7aPJOasbrV0Wcfv/4UuFa5GttR9c
vUh20nl2x+e7VMyjOswJvVV26T3KzPDu0oNxouMaXRgojkZvRinqIUoxvSCnxdwO
gzMnQbd24wLmGeYr4JD8ztTskzIhx8nimr5x4OscC1jiBdV3xBqrsMHID4INZPvy
cF7eErVc3gKBsStlllNKESdimxhyt3Ruu+UNJJDT8SyA79X2pRCgjVRtWb8ZivA/
UobMkjtWoj6HxQ0t1ewb9pP2bkCdMsPYcIKXcFIxM7vJ/UQdSd0dLsVXTCEuiy2A
qQPW+oukZ6LxBVdjvMc1WBj8C96R8mmserL5v+Q69pczmtBlsdHOAg6ru87iZu/q
wCMuAwtORatGCUFJbrADXwp+YfD6L1PNzeg4TCaHQYSFUAsuqOY76IANshLlSXk8
CkErkkVwD4SMOIYHWvksBw8iBRmzVvNPA5bR6vwE2fe7XQIDAQABo4H/MIH8MB0G
A1UdDgQWBBQC1z5arEKEpnH1btO/y4sr7tTIhjCBvwYDVR0jBIG3MIG0gBQC1z5a
rEKEpnH1btO/y4sr7tTIhqGBkKSBjTCBijELMAkGA1UEBhMCQlIxFTATBgNVBAgM
DE1pbmFzIEdlcmFpczEXMBUGA1UEBwwOQmVsbyBIb3Jpem9udGUxHTAbBgNVBAoM
FE51dmEgU29sdWNvZXMgZW0gVElDMRYwFAYDVQQLDA1OdXZhIFNvbHVjb2VzMRQw
EgYDVQQDDAtudXZhLmNvbS5icoIJAJ49DzwRMASdMAwGA1UdEwQFMAMBAf8wCwYD
VR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQA3hGjpd65lWLmg91HD3HabD47T
/XOhQ+e96qmKFBIkqXvUh80k5bANJ5tB1mh1yKd60RdNhvRK4t9DoDtNiLLILa2r
wXTgpoMrBPbyoCe1Twwb2LyXFk2ba3e6KewNswyD26YirbK0ElPYj9PFum7qkfiS
D5XuMyHnPY1Z00ed1hF+umRYNTMffGQbX5i8d0cSP3daeXNLy2TsAs1W1JWL4z4G
d1JIvilqe8TJzFfNNp5lRa8qH+kE/BoLkj0R1uczJiJ0JImPImRyYKZKSD+YQpPI
PHc677BuRFp6oAy8tLNJulMwm3NWbxR/LzWF6UBj4J40as8T8DwQ/GV3ONxn+fTO
0zS++mqwt1U6J7TMIaNptgR6LBdcEKbiObvjkVj1T0Ih9gsO5gBuTUQ4Q/d85lor
WaEFj6w8sdSzWjYGwt/IrJ/yzKCmH2jAOnUTWnKYsxRCCVCL1/dzvhVhsEUBJyN0
1+H3fozUUakO48cJPRb4l3WUXpq1gS9DtLIp4aCSuO58BTFOW27xrcQyDfKJYTQ4
mFDeWQPM41b9Lcv8L5uTFo3hEYoqB1VIVYdhQcW9KQp4qZHApwH261Lh1MHwv7zX
L4GkUo1vB3u2i6WTfU4g6+mBhAAUoPMP49QKnlx2b6eZ/SQ5HY+CMeXlshaTy+nJ
/HxYnKhpIab6ETfJ6A==
-----END CERTIFICATE-----
</ca>


<cert>
-----BEGIN CERTIFICATE-----
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
fsp9KmxjwlQQIHA=
-----END CERTIFICATE-----
</cert>


<key>
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----
</key>



6.4 - Cliente OpenVPN no Windows

Acesse o site https://openvpn.net/download-open-vpn/ e baixe o OpenVPN Connect para Windows.


Siga os passos:








Localize o ícone do OpenVPN Connect na sua área de trabalho ou no menu Iniciar e abra (clique duas vezes):


Ao abrir o OpenVPN Connect, clique no menu superior FILE e em seguida no botão BROWSE, localize o arquivo OVPN (vou usar do usuário suporte1 criado anteriormente no servidor da CA).


Clique no ADD.


Ao conectar a tela com o gráfico do tráfego na VPN será exibido. Conexão realizada com sucesso.




6.5 - Cliente OpenVPN no MacOS

Acesse o site https://openvpn.net/download-open-vpn/ e baixe o OpenVPN Connect para MAC OS.


Siga os passos:








Ao abrir o OpenVPN Connect, clique no menu superior FILE e em seguida no botão BROWSE, localize o arquivo OVPN (vou usar do usuário suporte2 criado anteriormente no servidor da CA).



Clique no ADD.


Ao conectar a tela com o gráfico do tráfego na VPN será exibido. Conexão realizada com sucesso.




6.6 - Cliente OpenVPN no Android

Com seu dispositivo Android em mãos, localize o aplicativo da Play Store e abra-o.


Usando a ferramenta de busca, digite openvpn.
Ao localizar o aplicativo OpenVPN Connect, acione o botão Instalar.


O aplicativo OpenVPN Connect será instalado.


Você pode abri-lo imediatamente pelo botão Abrir.


Para abri-lo nas próximas vezes, localize o ícone do OpenVPN Connect na sua lista de aplicativos.


Ao abrir o aplicativo OpenVPN Connect, acione o menu FILE (arquivo), conceda permissão ao aplicativo para ler seus arquivos.


Localize o arquivo OVPN desejado (aqui usaremos do usuário suporte3).


Com o arquivo selecionado, clique em ADD para importar e criar a conexão.


Clique em OK na pergunta Solicitação de Conexão para confiar no servidor adicionado.


Concluido, conexão registrada e realizada com sucesso!



Capítulo 7 - OpenVPN como servidor multiponto em camada 2

Semelhante ao capítulo anterior, iremos montar um servidor OpenVPN multi-ponto, porem usando transporte em camada 2.

O uso de camada 2 permite algumas capacidades: os participantes (usuários) da VPN estarão em uma rede local, permitindo a comunicação entre si usando o servidor OpenVPN como um switch virtual (bridge).

No servidor será possível envolver outras interfaces de rede na bridge para unir a rede da empresa com a rede virtual da VPN.

O efeito obtido é semelhante ao usuário estar fisicamente na empresa.


Um passo importante, e opcional, antes de rodar o servidor, tornar a interface TAP persistente antes mesmo da execução do OpenVPN, para que inclui-la na bridge.

A interface de rede criada no servidor se chamará ovpn02, a interface de rede local onde se encontra os servidores da empresa é a eth2, conforme diagrama acima.

Prepare com os comandos abaixo no servidor OpenVPN:

# - Modulo no kernel:
modprobe tap

# - Criar interface L2 permanente:
openvpn --mktun --dev ovpn02
ip link set up dev ovpn02


# - Criar bridge:
brctl addbr brt0
ip link set up dev brt0

#  - Desativar STP:
brctl stp brt0 off

# - Colocar interface TAP na bridge:
brctl addif brt0 ovpn02
ip link set up dev ovpn02

# - Colocar interface de rede local (exemplo: eth2) na bridge.
# - Voce pode colocar qualquer interface L2 na bridge (eth, veth, outras VPNs L2)
brctl addif brt0 eth2
ip link set up dev eth2



7.1 - Configuração do servidor

Vou usar a mesma configuração de servidor OpenVPN, alterando algumas linhas para mudar para modo L2, destacadas em fundo verde:

# Arquivo /etc/openvpn/openvpn-pmtp-srv-002.conf

proto udp
port  33002

dev-type  tap
dev       ovpns02
persist-key
persist-tun

topology              subnet
ifconfig              192.168.201.1 255.255.255.0
server-bridge         192.168.201.1 255.255.255.0 192.168.201.150 192.168.201.160
server-ipv6           2001:db8:F200::255/64
status                /var/log/openvpn-pmtp-srv-002.dat
ifconfig-pool-persist /var/lib/openvpn/pmtp-srv-002.dat

tls-server

cipher AES-256-CBC
auth   SHA512

dh       /etc/openvpn/dh2048.pem
ca       /etc/openvpn/srv-ovpn01/nuva-ca.crt
cert     /etc/openvpn/srv-ovpn01/ovpn01.crt
key      /etc/openvpn/srv-ovpn01/ovpn01.key
persist-key

keepalive 10 60
daemon

user  nobody
group nogroup

writepid   /var/run/openvpn-pmtp-srv-002.pid
log-append /var/log/openvpn-pmtp-srv-002.log
verb       3

explicit-exit-notify 1


7.2 - Configuração dos clientes

As alterações nos arquivos OVPN dos clientes é mais simples e sutil, coloquei abaixo apenas as linhas que foram alteradas:

# Arquivo *.ovpn

# ...

port  33002

dev-type  tap
dev       ovpns02

# ...

Simples assim, quando os clientes se conectarem à VPN em L2, poderão se comunicar na mesma sub-rede da empresa e entre si, usando o servidor como switch/bridge.



Capítulo 8 - Servidor OpenVPN provendo acesso à Internet

Parei aqui...


Capítulo 9 - OpenVPN implementado no VyOS

Falta fazer...


Capítulo 10 - OpenVPN implementado no Mikrotik RouterOS

Falta fazer...



Obrigado pela audiência!



























Anotacoes gerais / lixao / APAGAR DEPOIS DE PRONTO

# - xpto:
command arg1 arg2 arg3


 3.1.7 - Configurando Linux Servidor:
 Crie o arquivo de configuracao:
        touch /etc/openvpn/ssl-p2p-server.conf
        (

        ) > /etc/openvpn/ssl-p2p-server.conf
        
 Rodar servidor:
        openvpn --config /etc/openvpn/ssl-p2p-server.conf

 3.1.8 - Configurando Linux Cliente:
 Crie o arquivo de configuracao:
        touch /etc/openvpn/ssl-p2p-client.conf
        (
            echo 'port 9001'
            echo 'dev tun'
            echo ''
            echo 'tls-auth /etc/openvpn/ta.key 1'
            echo 'ca       /etc/ssl/nuva-ca/nuva-ca.crt'
            echo 'cert     /etc/openvpn/nuva-client-0001/cli0001.crt'
            echo 'key      /etc/openvpn/nuva-client-0001/cli0001.key'
            echo 'persist-key'
            echo 'persist-tun'
            echo 'keepalive 2 6'
            echo 'user  nobody'
            echo 'group nogroup'
            echo 'verb 3'
            echo 'daemon'
            echo 'log-append /var/log/ssl-p2p-client.log'
        ) > /etc/openvpn/ssl-p2p-client.conf

 Rodar cliente:
        openvpn --config /etc/openvpn/ssl-p2p-client.conf

 Testar funcionamento (lado cliente):
        fping -M -b 1472 10.200.0.1
        
 Obs.: a instrucao 'tls-auth' pode ser removida.



#------------------------------------------------------- a revisar:
       openvpn --show-digests
       openvpn --show-engines
       openvpn --show-tls


# Modo 2: via configuracao:



# - lado servidor:
#-----------------------------------------------------------------------------------
#   crie o arquivo /etc/openvpn/p2p-server.conf
   touch /etc/openvpn/p2p-server.conf
   mcedit /etc/openvpn/p2p-server.conf
#--------------------------------------------- conteudo ini:

dev tun
ifconfig 10.4.0.1 10.4.0.2
verb 3
keepalive 10 60
persist-tun
persist-key
persist-local-ip
comp-lzo
auth none
cipher none

#--------------------------------------------- conteudo fim.


# - lado cliente:
#-----------------------------------------------------------------------------------
#   crie o arquivo /etc/openvpn/p2p-client.conf
   touch /etc/openvpn/p2p-client.conf
   mcedit /etc/openvpn/p2p-client.conf
#--------------------------------------------- conteudo ini:

remote 170.247.23.180 1194
nobind
persist-tun
persist-key
comp-lzo adaptive
dev tun
dev-type tun
ifconfig 10.4.0.2 10.4.0.1
keepalive 10 60
resolv-retry infinite
verb 3

#--------------------------------------------- conteudo fim.

# Rodar no lado servidor:
   openvpn --config /etc/openvpn/p2p-server.conf --daemon server

# Rodar no lado cliente:
   openvpn --config /etc/openvpn/p2p-client.conf --daemon client





# Exemplo 2 - Site-to-Site (ptp) com senha fixa e sem criptografia tunnel L3 PtP Linux-VyOS-1.2
#=========================================================================================
#=========================================================================================

# ip linux: 192.168.200.253
# ip vyos.: 192.168.200.125

# Em ambos:
mkdir -p /config/auth
cat > /config/auth/ovpn0.key << EOF
-----BEGIN OpenVPN Static key V1-----
a0b8eaab531f19ce4e6913633088335e
0c0ce50454a176d74e9ba62694802d6e
1bf9ca53ce110ee6962387c2fa6c841b
f43f4450184a8ad314d9f2852245c09c
9c232fca7ceffb381b4cbd1f26586f63
b06249d3491e95552a1e8fbb3404bb8c
541f5c3144db5d707dbd04e0276a5f98
36b5baa720a3834f343de18440f4281f
5581e065ba6a77db492950dd633d7680
ce5dd3ece4ec029fd371630a123c99d2
25acfbf345ef0a2e4e150b5bf790b01b
93e883ce6742c22c93bbe1df460f6eff
98268404fef197d02325686e712d6917
bf7964681afefb28576ed5e0d7b8e593
b623e75269720a6898e0c428fe2d1ea8
40dcb6f3b2e4b53b5d2d1d616ef7d220
-----END OpenVPN Static key V1-----
EOF


# lado VyOS (servidor):
#-----------------------------------------------------------------------------------

configure
delete interfaces openvpn vtun0
set interfaces openvpn vtun0 local-address 10.99.0.1
set interfaces openvpn vtun0 mode 'site-to-site'
set interfaces openvpn vtun0 persistent-tunnel
set interfaces openvpn vtun0 protocol 'udp'
set interfaces openvpn vtun0 remote-address '10.99.0.2'
set interfaces openvpn vtun0 server subnet '10.99.0.0/24'
set interfaces openvpn vtun0 shared-secret-key-file '/config/auth/ovpn0.key'
commit
save
exit

# Processo:
# /usr/sbin/openvpn \
#    --daemon openvpn-vtun0 --verb 3 --writepid /var/run/openvpn-vtun0.pid \
#    --status /opt/vyatta/etc/openvpn/status/vtun0.status 30 \
#    --dev-type tun --dev vtun0 --ping 10 --ping-restart 60 \
#    --ifconfig 10.99.0.1 10.99.0.2 \
#    --secret /config/auth/ovpn0.key \
#    --persist-tun
#

# lado Linux (cliente):
#-----------------------------------------------------------------------------------

killall openvpn
killall openvpn
/usr/sbin/openvpn \
    --daemon client \
    --remote 192.168.200.125 1194 \
    --verb 3 --writepid /var/run/openvpn-vtun0.pid \
    --status /var/run/vtun0.status 30 \
    --dev-type tun --dev vtun0 --ping 10 --ping-restart 60 \
    --ifconfig 10.99.0.2 10.99.0.1 \
    --secret /config/auth/ovpn0.key \
    --persist-tun


# Teste:
#-----------------------------------------------------------------------------------

ping -s 1472 10.99.0.1
ping -s 1472 10.99.0.2




# Exemplo 3 - Site-to-Site (ptp) com senha fixa e sem criptografia tunnel L3 PtP Mikrotik-VyOS-1.2
#=========================================================================================
#=========================================================================================

# ip mikrotik.: 192.168.200.135
# ip vyos.....: 192.168.200.125

# lado Mikrotik (servidor):
#-----------------------------------------------------------------------------------

/interface ovpn-server
add name=ovpns1


# lado VyOS (client): < NAO FUNCIONOU, FALTA INVESTIGAR
#-----------------------------------------------------------------------------------

configure
delete interfaces openvpn vtun0
set interfaces openvpn vtun0 mode client
set interfaces openvpn vtun0 remote-host 192.168.200.135
set interfaces openvpn vtun0 remote-port 1194
set interfaces openvpn vtun0 protocol udp
set interfaces openvpn vtun0 persistent-tunnel
commit
save
exit

#=========================================================================================
# Servidor Linux com clientes - sem criptografia
#=========================================================================================


# Linux (Servidor):
#-----------------------------------------------------------------------------------

mkdir /etc/openvpn
modprobe tun
modprobe tap
cd /etc/openvpn




# Linux (Cliente - 01):
#-----------------------------------------------------------------------------------



#=========================================================================================
# VyOS como servidor OpenVPN para estacoes Windows (openvpn client)
#=========================================================================================

# Links:
    https://openvpn.net/community-resources/setting-up-your-own-certificate-authority-ca/
    https://docs.vyos.io/en/latest/vpn/openvpn.html


# VyOS (Servidor):
#-----------------------------------------------------------------------------------

sudo su
cp -r /usr/share/easy-rsa/ /config/my-easy-rsa-config
cd /config/my-easy-rsa-config
cp vars orig-vars 2>/dev/null

cat > vars << EOF
set_var EASYRSA_DN              "org"
set_var EASYRSA_REQ_COUNTRY     "BR"
set_var EASYRSA_REQ_PROVINCE    "Minas Gerais"
set_var EASYRSA_REQ_CITY        "Belo Horizonte"
set_var EASYRSA_REQ_ORG         "Nuva Solucoes"
set_var EASYRSA_REQ_EMAIL       "contato@nuva.com.br"
set_var EASYRSA_REQ_OU          "NuvaXR"
set_var EASYRSA_KEY_SIZE        2048
EOF



./easyrsa init-pki
./easyrsa build-ca
./easyrsa gen-req central nopass
./easyrsa sign-req server central
./easyrsa gen-dh
./easyrsa build-client-full branch1 nopass
./easyrsa gen-crl

mkdir /config/auth/ovpn
cp pki/ca.crt /config/auth/ovpn
cp pki/dh.pem  /config/auth/ovpn
cp pki/private/central.key /config/auth/ovpn
cp pki/issued/central.crt  /config/auth/ovpn
cp pki/crl.pem /config/auth/ovpn



configure
delete interfaces openvpn vtun1

set interfaces openvpn vtun1 mode server
set interfaces openvpn vtun1 local-port 1194
set interfaces openvpn vtun1 persistent-tunnel
set interfaces openvpn vtun1 protocol udp
set interfaces openvpn vtun1 topology 'subnet'
set interfaces openvpn vtun1 use-lzo-compression

set interfaces openvpn vtun1 tls ca-cert-file /config/auth/ovpn/ca.crt
set interfaces openvpn vtun1 tls cert-file /config/auth/ovpn/central.crt
set interfaces openvpn vtun1 tls key-file /config/auth/ovpn/central.key
set interfaces openvpn vtun1 tls crl-file /config/auth/ovpn/crl.pem
set interfaces openvpn vtun1 tls dh-file /config/auth/ovpn/dh.pem

set interfaces openvpn vtun1 server subnet 10.23.1.0/24
set interfaces openvpn vtun1 server domain-name nuva.com.br
set interfaces openvpn vtun1 server max-connections 1024
set interfaces openvpn vtun1 server name-server 8.8.8.8
set interfaces openvpn vtun1 server name-server 1.0.0.1

set interfaces openvpn vtun1 openvpn-option "--tun-mtu 1500 --fragment 1300 --mssfix"
set interfaces openvpn vtun1 openvpn-option "--push redirect-gateway"
set interfaces openvpn vtun1 openvpn-option "--duplicate-cn"
set interfaces openvpn vtun1 openvpn-option "--client-cert-not-required"
set interfaces openvpn vtun1 openvpn-option "--comp-lzo"
set interfaces openvpn vtun1 openvpn-option "--persist-key"
set interfaces openvpn vtun1 openvpn-option "--persist-tun"

commit
save

# Processo:
# /usr/sbin/openvpn \
#    --daemon openvpn-vtun1 \
#    --config vtun1.conf \
#    --status vtun1.status 30 \
#    --writepid vtun1.pid
#


# VyOS (Client):
#-----------------------------------------------------------------------------------

delete interfaces openvpn vtun10
set interfaces openvpn vtun10 encryption cipher 'aes256'
set interfaces openvpn vtun10 hash 'sha512'
set interfaces openvpn vtun10 mode 'client'
set interfaces openvpn vtun10 persistent-tunnel
set interfaces openvpn vtun10 protocol 'udp'
set interfaces openvpn vtun10 remote-host '172.18.201.10'
set interfaces openvpn vtun10 remote-port '1194'
set interfaces openvpn vtun10 tls ca-cert-file '/config/auth/ca.crt'
set interfaces openvpn vtun10 tls cert-file '/config/auth/client1.crt'
set interfaces openvpn vtun10 tls key-file '/config/auth/client1.key'
set interfaces openvpn vtun10 use-lzo-compression

# Comandos VyOS:
#-----------------------------------------------------------------------------------

show openvpn client
show openvpn server
show openvpn site-to-site

eset openvpn client CLIENTNAME
reset openvpn interface OVPNINTERFACE


# Windows (Client)
#-----------------------------------------------------------------------------------





#=========================================================================================
#=========================================================================================
#=========================================================================================
#========================================================================================= Ex Web 01

--client-cert-not-required

#------------- server

port 1194
proto udp
dev tun
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
dh /etc/openvpn/keys/dh2048.pem
server 198.18.200.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 192.168.10.234 255.255.255.0"
duplicate-cn
keepalive 10 120
cipher AES-256-GCM
persist-key
persist-tun
status openvpn-status.log
verb 4
explicit-exit-notify 1
plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so login


#------------- client

client
dev tun
proto udp-client
remote abc.efg.xyz
port 1194
nobind
persist-key
verb 4
mute 10
persist-tun
cipher AES-256-CBC
auth SHA1
auth-user-pass f_secret



#========================================================================================= Ex Web 02


# ------------------ server
# Ports & protocols
port 1194
proto udp
dev tun

# Server certs and keys
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key  # This file should be kept secret
dh /etc/openvpn/keys/dh2048.pem

# Server subnet
server 198.18.200.0 255.255.255.0

# Persist IP lease pool
ifconfig-pool-persist ipp.txt

# Pushing to a private subnet
push "route 192.168.10.234 255.255.255.0"

# Allowing duplicate common names for clients (no keys/certs)
duplicate-cn

# KeepAlive
keepalive 10 120

# Cryptographic cipher.
cipher AES-256-CBC

# privilege downgrade fix.
persist-key
persist-tun

# Output a short status log
status openvpn-status.log

# Verbosity level 4
verb 4

# Notify the client that when the server restarts
explicit-exit-notify 1

# Add PAM Auth plugin
plugin /usr/lib/openvpn/openvpn-plugin-auth-pam.so login

# No need for client cert
client-cert-not-required


#---------------------- client

client

dev tun

# protocol
proto udp-client

# Server
remote abc.efg.xyz

# Service port
port 1194

# Not binding to a specific port
nobind

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


# moderate verbosity
verb 4
mute 10

# Chosen yptographic cipher.
cipher AES-256-CBC

# cipher algorithm
auth SHA1

# Username and password are stored in this file
auth-user-pass f_secret

auth-nocache


#========================================================================================= Ex Web 03

client-cert-not-required
verify-client-cert none


#----------------------- server
port 1194
proto udp
dev tun
sndbuf 0
rcvbuf 0
ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh /etc/openvpn/dh.pem
auth SHA512
tls-auth /etc/openvpn/ta.key 0
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 94.237.127.99"
push "dhcp-option DNS 94.237.40.99"
keepalive 10 120
cipher AES-256-CBC
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
verb 4
crl-verify /etc/openvpn/crl.pem
--verify-client-cert none
log-append /var/log/openvpn.log
script-security 2
auth-user-pass-verify /etc/openvpn/example.sh via-file


#----------------------- client
client
dev tun
proto udp
sndbuf 0
rcvbuf 0
remote 94.237.88.154 1194
resolv-retry 5
nobind
persist-key
persist-tun
remote-cert-tls server
auth SHA512
cipher AES-256-CBC
setenv opt block-outside-dns
key-direction 1
verb 3
auth-user-pass
script-security 2


-----BEGIN CERTIFICATE-----
###
###
-----END CERTIFICATE-------


#=========================================================================================
#=========================================================================================
#=========================================================================================
#=========================================================================================
#=========================================================================================
#=========================================================================================
#=========================================================================================


CONTATO