OpenVPN: tun y tap

Despues de haber usado VPNs IPSec, L2TP, PPTP y PPP/SSH… sin duda me quedo con OpenVPN.

Aqui pongo varios ejemplos de configuraciones (para un «TUN» -Routing IP- y un «TAP» -Bridge Ethernet-) (Edit [2017.04.25] la configuracion y las pruebas han sido sobre Ubuntu 16.04 en el server y Windows 7 en el cliente, el articulo inicial fue para Ubuntu 12.04 -cambian pocas cosas-), si no funciona el «redirect-gateway def1» (para que todo el trafico salga a traves de la vpn) o alguna otra opcion es posible que debas arrancar el openvpn-gui con privilegios administrativos:

# Primero generamos el Diffie-Hellman (en el server)
openssl gendh -out dh-2048.pem 2048
# Generamos Shared-Secret (en el Server)
# Este fichero es compartido en server y clientes
openvpn --genkey --secret secret.key

Aunque la parte de la creacion de los certificados X.509 no la explico aqui (server.{crt,key} & client.{crt,key}); a modo de resumen (usando solo certificados auto-firmados):

  • dh-2048.pem: es privado, estará solo en el servidor (owner{root:root} perm{600})
  • server.crt: es publico, compartido entre todos -servidor y clientes-
  • server.key: es privado, estará solo en el servidor (owner{root:root} perm{600})
  • client.crt: es publico, generado para cada cliente
  • client.key: es privado, estará solo en el cliente
  • ca.crt: es publico, estará solo en el servidor con permisos restringidos (owner{root:root} perm{644}), todos los client.crt se meten dentro de este fichero de modo concatenado, es la lista de clientes permitidos

Para poder dar soporte a clientes UDP/1194 (standard) y TCP/443 (firewall-friendly) hay que crear 2 ficheros diferentes en el server y asignar 2 rangos de IPs separados (para que no haya problemas con las las rutas).


 
Empezamos con la configuracion de una VPN de nivel 3 (TUN)

Fichero de configuracion del server TUN para clientes UDP/1194:

# --- /etc/openvpn/server-tun-udp.conf
proto udp
port 1194
# specific networking
# tuned version of: server 192.168.uuu.0 255.255.255.0
ifconfig 192.168.uuu.254 255.255.255.0
ifconfig-pool 192.168.uuu.1 192.168.uuu.253
push "route-gateway 192.168.uuu.254"
## NOTA: << incluir server-tun-common.conf >>

Fichero de configuracion del server TUN para clientes TCP/443

# --- /etc/openvpn/server-tun-tcp.conf
proto tcp-server
port 443
# Si el puerto es compartido con un servidor Web/HTTPS:
port-share internal.acme.com 8443
# specific networking
# tuned version of: server 192.168.ttt.0 255.255.255.0
ifconfig 192.168.ttt.254 255.255.255.0
ifconfig-pool 192.168.ttt.1 192.168.ttt.253
push "route-gateway 192.168.ttt.254"
## NOTA: << incluir server-tun-common.conf >>

Aqui esta la configuracion comun UDP/TCP del server TUN:

# --- /etc/openvpn/server-tun-common.conf
mode server
tls-server
max-clients 253
dev tun
script-security 2
up-restart
up "/etc/openvpn/tun-up.sh eth0"
#down "/etc/openvpn/tun-down.sh eth0"
plugin /usr/lib/openvpn/openvpn-plugin-down-root.so "/etc/openvpn/tun-down.sh eth0"
persist-key
persist-tun
ca ca.crt
cert server.crt
dh dh-2048.pem
key server.key       # This files should be kept secret
tls-auth secret.key
# optional user/password
#auth-user-pass-verify /etc/openvpn/auth.sh via-file
user nobody
group nogroup
keepalive 10 120
verb 3
mssfix
# common networking
topology subnet
push "topology subnet"
push "route 192.168.0.0 255.255.0.0 vpn_gateway" # Internal Network
push "dhcp-option DOMAIN ddddddd.ddd"
push "dhcp-option DNS 192.168.x.x"
push "dhcp-option DNS 192.168.x.x"
#
push "redirect-gateway def1"
push "register-dns"

Estos dos script configuran el interface tun cuando se arranca el OpenVPN:

# --- /etc/openvpn/tun-up.sh (server)
#!/bin/sh
LAN_DEV=$1
LNET="192.168.0.0/16"
/sbin/ip link set "$dev" up
/sbin/sysctl -q -w net.ipv4.conf.${LAN_DEV}.forwarding=1 net.ipv4.conf.${dev}.forwarding=1
# Si queremos que los clientes que vayan fuera de la red local salgan con un NAT:
/sbin/iptables -t nat -D POSTROUTING -s $ifconfig_local/$ifconfig_netmask ! -d $LNET -j MASQUERADE 1>/dev/null 2>&1
/sbin/iptables -t nat -A POSTROUTING -s $ifconfig_local/$ifconfig_netmask ! -d $LNET -j MASQUERADE
# --- /etc/openvpn/tun-down.sh (server)
#!/bin/sh
LAN_DEV=$1
LNET="192.168.0.0/16"
/sbin/sysctl -q -w net.ipv4.conf.${dev}.forwarding=1
/sbin/ip link set "$dev" down
/sbin/iptables -t nat -D POSTROUTING -s $ifconfig_local/$ifconfig_netmask ! -d $LNET -j MASQUERADE
# --- /etc/openvpn/auth.sh (server)
#!/bin/bash
# Script de ejemplo para auth-user-pass-verify (opcional)
authUserPass () {
  local lines username password
  readarray -t lines < "$1"
  username=${lines[0]}
  password=${lines[1]}
  # Replace your own authentication mechanism here
  if [[ "$username" = "hal9000" && "$password" = "changeit" ]]; then
    exit 0 # OK
  fi
}
authUserPass "$1"
exit 1 # NOT OK

Ahora hay que activar el autostart de los tuneles del OpenVPN:

# --- /etc/default/openvpn
AUTOSTART="server-tun-tcp server-tun-udp"

Aqui tenemos la configuracion del cliente TUN, tiene un failover, primero intentará conectar usando UDP/1194 y si falla, lo intentará por TCP/443:

# --- client-tun.conf
client
dev tun

allow-pull-fqdn
server-poll-timeout 10
resolv-retry infinite
persist-key
persist-tun
mssfix
ca server.crt
cert client.crt
key client.key       # This files should be kept secret
tls-auth secret.key
# optional user/password
#auth-user-pass
verb 3

<connection>
remote remote-host-or-ip 1194 udp
explicit-exit-notify
</connection>

<connection>
remote remote-host-or-ip 443 tcp
</connection>

Con esto ya tenemos una VPN de nivel 3.

Vamos a por el TAP? solo cambia la configuración, la mecanica es la misma:
 

Empezamos con la configuracion de una VPN de nivel 2 (TAP)

Fichero de configuracion del server TAP para clientes UDP/1194:

# --- /etc/openvpn/server-tap-udp.conf
proto udp
port 1194
## NOTA: << incluir server-tap-common.conf >>

Fichero de configuracion del server TAP para clientes TCP/443:

# --- /etc/openvpn/server-tap-tcp.conf
proto tcp-server
port 443
# Si el puerto es compartido con un servidor Web/HTTPS:
port-share internal.acme.com 8443
## NOTA: << incluir server-tap-common.conf >>

Aqui esta la configuracion comun UDP/TCP del server TAP:

# --- /etc/openvpn/server-tap-common.conf
server-bridge
dev tap
script-security 2
up-restart
up "/etc/openvpn/tap-up.sh br0"
#down "/etc/openvpn/tap-down.sh br0"
plugin /usr/lib/openvpn/openvpn-plugin-down-root.so "/etc/openvpn/tun-down.sh br0"
persist-key
persist-tun
ca ca.crt
cert server.crt
dh dh-2048.pem
key server.key       # This files should be kept secret
tls-auth secret.key
# optional user/password
#auth-user-pass-verify /etc/openvpn/auth.sh via-file
user nobody
group nogroup
keepalive 10 120
verb 3

Estos dos script configuran el interface tap cuando se arranca el OpenVPN y lo añaden al Bridge (br0) que haya en la maquina:

# --- /etc/openvpn/tap-up.sh (server)
#!/bin/sh
BR=$1
/sbin/ip link set "$dev" up promisc on mtu "$tun_mtu"
/sbin/brctl addif $BR $dev
# --- /etc/openvpn/tap-down.sh (server)
#!/bin/sh
BR=$1
/sbin/brctl delif $BR $dev
/sbin/ip link set "$dev" down

Ahora hay que activar el autostart de los tuneles del OpenVPN:

# --- /etc/default/openvpn
AUTOSTART="server-tap-tcp server-tap-udp"

Por si no tienes ya habilitado el Bridge en la maquina (apt-get install bridge-utils), aqui hay un ejemplo de configuración:

# --- /etc/network/interfaces
auto eth0
iface eth0 inet static

# bridge-utils-interfaces(5)
auto br0
iface br0 inet static
        address 192.168.x.xxx
        network 192.168.x.0
        netmask 255.255.255.0
        broadcast 192.168.x.255
        gateway 192.168.x.x
        # dns-* options are implemented by the resolvconf package, if installed
        dns-nameservers 192.168.x.x
        dns-search dddddd.ddd
        #
        bridge_ports eth0
        bridge_stp off
        bridge_fd 0
        bridge_maxwait 0
        post-up ip link set br0 address $(cat /sys/class/net/eth0/address)

Aqui tenemos la configuracion del cliente TAP, solo cambia el tipo de device, tambien tiene un failover, primero intentará conectar usando UDP/1194 y si falla, lo intentará por TCP/443:

# --- client-tap.conf
client
dev tap

allow-pull-fqdn
server-poll-timeout 10
resolv-retry infinite
persist-key
persist-tun
mssfix
ca server.crt
cert client.crt
key client.key       # This files should be kept secret
tls-auth secret.key
# optional user/password
#auth-user-pass
verb 3

<connection>
remote remote-host-or-ip 1194 udp
explicit-exit-notify
</connection>

<connection>
remote remote-host-or-ip 443 tcp
</connection>

Con esto ya tenemos una VPN de nivel 2.

Edit [2015.04.04] Recomendacion de Ciphers (server/client):

auth SHA256
cipher AES-256-CBC
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384

Referencias:
OpenVPN 2.3 Manpage
New features of OpenVPN 2.1 / 2.2

Deja un comentario