Com acceidr a una LAN des d'internet usant una VPN (OpenVPN HowTo)

  • warning: tempnam(): open_basedir restriction in effect. File() is not within the allowed path(s): (/srv/www/gilug.org/www/site.tree/) in /srv/www/gilug.org/www/site.tree/public/includes/file.inc on line 802.
  • warning: fopen(): Filename cannot be empty in /srv/www/gilug.org/www/site.tree/public/includes/file.inc on line 803.
  • El fitxer no s'ha pogut crear.

En aquest article explicaré les meves experiències per configurar un servidor OpenVPN per permetre accés a una LAN a múltiples clients connectats a Internet (road warriors).

En realitat reedito l'entrada al meu wiki personal, perquè crec que és un tema interessant i hi ha poca documentació en català de OpenVPN.

** Disclaimer **
Ja se sap, si intentes seguir els passos aquí descrits, i després veus que al teu ordinador no li caus bé i s'ha volgut espatllar, no serà culpa meva, tal com he dir, això només són les meves experiències! ;-D

Intro
Primer de tot cal saber que OpenVPN permet usar dos modes: bridge i routing. El mode bridge permet passar els paquets broadcast cap a la VPN, però això fa augmentar molt el trànsit i no s'aconsella el seu ús més info). Per tant s'ha escollit el mode routing. En aquest mode, la VPN té el seu propi rang IP, per això caldrà enrutar el trànsit. La sort és que OpenVPN ho posa molt fàcil tal com veurem. Explico això pequè jo al principi anava perdut amb tants rang's d'Ips diferents, jeje.

Un altre avantatge, en el meu cas és que el servidor OpenVPN fa de gateway de la LAN i per tant no s'ha de tocar cap configuració de cap màquina de la LAN per tal que puguin usar la VPN.

L'escenari és el següent:

  1. LAN (rang IPs 192.168.0.x), amb els workstations i els servidors privats (Samba, SQL)
  2. Servidor OpenVPN fent de gateway per la lan amb 2 targetes de xarxa:
    1. eth1: 192.168.0.100
    2. eth0: 10.0.0.2
  3. Es crearà una VPN (rang IPs 172.16.0.x) per tal que el client (Road Warrior) pugui entrar a la LAN i accedir al servidor Samba i SQL.

Esquemàticament tenim:

                                +------------------+
                                |                  |
                                |   PRIVATE LAN    |
                                |  WORKSTATIONS +  |
+--------------+                |   FILE SERVER    | 192.168.0.x
|              |                |                  |
|     ROAD     |                +------------------+ 
|    WARRIOR   |                         ^
|   (CLIENT)   |                         | 
|              |                         | 192.168.0.100
+--------------+                  +--------------+
       | VPN TUNNEL IP            |              |
       | (172.16.0.x)             |   OpenVPN    | VPN TUNNEL IP
       |                          |    SERVER    | (172.16.0.1)
+--------------+                  |              |
|              |                  +--------------+
|   INTERNET   |                         ^ 10.0.0.2
|              |                         | 
+--------------+                         | (DMZ)
       |                                 |
       |       SERVER PUBLIC IP  +--------------+
       +------------------------>|    ROUTER    |
                                 +--------------+

Instal·lació OpenVPN
Bé, ja se sap que Debian posa aquestes coses molt fàcils ;-D:

Proxy-Server:~# apt-get install openvpn

Ull! Cal mirar si tenim la interfície que necessitem (en el nostre cas tun) a /dev/net, si no la creem:

Proxy-Server:~# mkdir /dev/net
Proxy-Server:~# mknod /dev/net/tun c 10 200
Proxy-Server:~# depmod -a

NOTA: L'última ordre és per carregar el mòdul, debian ja té l'alias fet a /etc/modutils/aliases: alias char-major-10-200 tun)

Configuració Inicial (client-servidor amb clau estàtica)
En la primera configuració provarem de fer una connexió punt a punt entre el servidor i el client (al final d'aquest apartat podrem connectar-nos a qualsevol PC de la xarxa del servidor). Per fer-ho he seguit el mini-HowTo oficial.

Servidor
Editem /etc/openvpn/server.conf (el primer cop no hi és, l'hem de crear):

dev tun
ifconfig 172.16.0.1 172.16.0.2
secret static.key

Hem d'assegurar-nos que els paquets poden arribar a la interfície que els correspon. Hem d'obrir el port 1194 del router cap al servidor, i assegurar-nos que no el tenim "firewallejat". En el meu cas tinc l'iptables molt restrictiu: he hagut de donar permís als paquets udp al port 1194 i a l'ínterfície tun0

Proxy-Server:~# iptables -A INPUT -i eth0 -p udp --dport 1194 -j ACCEPT
Proxy-Server:~# iptables -A INPUT -i tun+ -j ACCEPT
Proxy-Server:~# iptables -A FORWARD -i tun+ -j ACCEPT
Proxy-Server:~# iptables -A FORWARD -o tun+ -j ACCEPT

Client
La màquina client serà un WindowsXP. Per fer-ho primer de tot descarreguem i instal·lem la versió windows de openvpn. Un cop fet, anem a C:\Archivos de programa\openvpn\config i editem el fitxer client.opvn (l'extensió és important!):

remote IP_REMOTA (la visible, externa. Si tenim ip dinàmica millor posar-hi el domini)
dev tun
ifconfig 172.16.0.2 172.16.0.1
secret static.key

Ara cal crear la clau amb la què es comunicaran el client i el servidor. En aquest primer exemple, la cosa és simple. Es tracta d'una clau simètrica compartida per ambdós extrems. Creem la clau al servidor:

Proxy-Server:/etc/openvpn# openvpn --genkey --secret static.key

Ara copiem la clau al client (a C:\Archivos de programa\openvpn\config) d'una manera segura (amb un pen drive, després cal esborrar-la!, mitjançant sftp, ...). Llavors obrim el servidor (de moment des de la línia d'ordres, estem fent proves, després ja l'obrirem com un servei):

Proxy-Server:/etc/openvpn# openvpn --config server.conf
Mon Jun 26 11:38:49 2006 OpenVPN 2.0 i386-pc-linux [SSL] [LZO] [EPOLL] built on Apr 6 2006
Mon Jun 26 11:38:49 2006 IMPORTANT: OpenVPN's default port number is now 1194, based on an official port number assignment by IANA. OpenVPN 2.0-beta16 and earlier used 5000 as the default port.
Mon Jun 26 11:38:49 2006 Static Encrypt: Cipher 'BF-CBC' initialized with 128 bit key
Mon Jun 26 11:38:49 2006 Static Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Mon Jun 26 11:38:49 2006 Static Decrypt: Cipher 'BF-CBC' initialized with 128 bit key
Mon Jun 26 11:38:49 2006 Static Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication
Mon Jun 26 11:38:49 2006 TUN/TAP device tun0 opened
Mon Jun 26 11:38:49 2006 /sbin/ifconfig tun0 172.16.0.1 pointopoint 172.16.0.2 mtu 1500
Mon Jun 26 11:38:49 2006 Data Channel MTU parms [ L:1544 D:1450 EF:44 EB:4 ET:0 EL:0 ]
Mon Jun 26 11:38:49 2006 Local Options hash (VER=V4): 'e3a9d6ca'
Mon Jun 26 11:38:49 2006 Expected Remote Options hash (VER=V4): 'cf0e726a'
Mon Jun 26 11:38:49 2006 UDPv4 link local (bound): [undef]:1194
Mon Jun 26 11:38:49 2006 UDPv4 link remote: [undef]

Ara des del client, fem clic amb el botó dret a sobre el fitxer client.opvn i li diem Start OpenVPN on this config file(de moment, ho fem manualment, es pot configurar pequè s'iniciï com un servei). Al cap de pocs segons veurem un missatge que diu:

connection initialized with IP_VISIBLE_REMOTA[1194]

En aquests moments podem (o hauríem de poder) fer ping d'una màquina a l'altre utilitzant les ip's del túnnel que (172.16.0.X). Si no es pot fer el ping, cal revisar la configuració (sobretot repassar el firewall)

Optimitzant
Ara "tunegem" una mica els fitxers de configuació. La intenció és fer la connexió més segura a caigudes i poder accedir a tota la xarxa del servidor des del road warrior:

Servidor:

#Minimal configuration
dev tun
verb 3
ifconfig 172.16.0.1 172.16.0.2
secret /etc/openvpn/static.key

#Connection
comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key

#Misc
log-append /var/log/openvpn/openvpn.log
status /var/log/openvpn/status.log

Client:

#Minimal configuration
remote IP_REMOTA (la visible, externa. Si tenim ip dinàmica millor posar-hi el domini)
dev tun
ifconfig 172.16.0.2 172.16.0.1
secret static.key

# Per tal que el client pugui veure totes les màquines de la subxarxa del servidor
route 192.168.0.0 255.255.255.0

#Connection
comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key

Tornem a mirar que efectivament connecta (el client pot accedir a qualsevol màquina de la xarxa del servidor) i ja podem anar pel següent pas: Enlloc de fer servir una clau estàtica farem certificats individuals per a cada client.

NOTA: Si no et funciona, revisa el firewall. Amb la meva configuració d'iptables (FORWARD a DROP), he hagut de deixar pas als paquets sortints per la interficie tap0 (primer només deixava pas als entrants, però no als que sortien, vaig tenir problemes amb això!)

Autenticació PKI
Una mica de teoria barata (i ràpida) sobre PKI ( teoria real: L'autenticació PKI (Public Key Infrastructure) es basa en una parella de claus (una de privada i una de pública) per al servidor i una parella pera a cada client. Cadascuna d'aquestes claus està signada digitalment utilitant la clau privada d'una tercera entitat (la CA, Certificate Authority). Tant el client com el servidor saben la clau pública de la CA i així poden validar la clau de l'altre part. D'aquesta manera el client s'identifica contra el servidor i el servidor també ho fa amb el client. Un cop explicada la mini-teoria sobre PKI anem a veure com ho fem (seguint el HowTo oficial):

Proxy-Server:# cd /usr/share/doc/openvpn/examples/easy-rsa/
Proxy-Server:/usr/share/doc/openvpn/examples# cp -R easy-rsa /etc/openvpn
Proxy-Server:/usr/share/doc/openvpn/examples# cd /etc/openvpn/easy-rsa
Proxy-Server:/etc/openvpn/easy-rsa# joe vars

Toquem els paràmetres:

export KEY_COUNTRY=ES
export KEY_PROVINCE=GI
export KEY_CITY=GIRONA
export KEY_ORG="My-Org"
export KEY_EMAIL="my@mail"

NOTA: Si som paranoics podem augmentar la mida de la clau a 2048, però això fa baixar una mica la velocitat

Ara toca crear les claus:

Proxy-Server:/etc/openvpn/easy-rsa# ./vars
Proxy-Server:/etc/openvpn/easy-rsa# ./clean-all
Proxy-Server:/etc/openvpn/easy-rsa# ./build-ca

NOTA: He tingut problemes amb el ./vars, ja que no m'exporta les variables i ho he acabat fent a mà.

Ara a /etc/openvpn/easy-rsa/keys hi tenim la clau privada (ca.key, guardar-la molt bé!!!) i la clau pública (ca.crt) del CA (aquesta última l'hauran de tenir tots els clients i el servidor). Sí, el CA és el servidor, podria ser qualsevol altre màquina (i si paguem un CA oficial)

Ara cal generar les claus pel servidor i pel client (jo de moment només en tinc un):

Proxy-Server:/etc/openvpn/easy-rsa# ./build-key-server server (quan ho demani, dir-li que signi el certificat)
Proxy-Server:/etc/openvpn/easy-rsa# ./build-key client1 (quan ho demani, dir-li que signi el certificat)

En aquest punt ja tenim les claus generades. Per poder completar l'operació cal generar els paràmetres de Diffie Hellman (ens serveix perquè el client i el servidor s'intercanviïn les claus, més info):

Proxy-Server:/etc/openvpn/easy-rsa# ./build-dh

Resumint, tenim (extret de la web oficial):

Fitxer	       Necessitat Per	      @@s     	 Secret?
ca.crt	     server + all clients  Root CA cert    NO
ca.key 	     Màquina CA            Root CA key 	   YES
dh{n}.pem    server only 	   DH param        NO
server.crt   server only 	   Server Cert 	   NO
server.key   server only 	   Server Key	   YES
client1.crt  client1 only 	   Client1 Cert    NO
client1.key  client1 only 	   Client1 Key 	   YES

Un cop arribat aquí, només cal que cada màquina tingui les claus necessàries i modificar els fitxers de configuració (perquè quedi més lògic - almenys segons el meu criteri :-D - he posat el directori de les claus a /etc/openvpn/keys) :

Servidor:

dev tun

# If connections fails, this file will keep track the connections to restblish them
ifconfig-pool-persist ipp.txt

# IP Range clients (VPN Subnet, by default server will take 172.16.0.1)
server 172.16.0.0 255.255.255.0

# Key settings
ca keys/ca.crt
cert keys/server.crt
key keys/server.key # This file should be kept secret
tls-auth keys/ta.key 0 # This file is secret

# Diffie hellman
dh keys/dh1024.pem

# Connection
comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key

#Misc
verb 3
log-append /var/log/openvpn/openvpn.log
status /var/log/openvpn/status.log
user nobody
group nogroup

Client:

#Minimal configuration
client
remote IP_REMOTE
dev tun

# Key settings
ca keys/ca.crt
cert keys/client1.crt
key keys/client1.key # This file is secret
dh keys/dh1024.pem
tls-auth keys/ta.key 1 # This file is secret

ns-cert-type server

# Per tal que el client pugui veure totes les màquines a la xarxa del servidor
route 192.168.0.0 255.255.255.0

#Connection
comp-lzo
keepalive 10 60
ping-timer-rem
persist-tun
persist-key

Amb aquesta configuració, hauríem de ser capaços d'accedir a qualsevol màquina de la LAN (servidor SQL, recursos compartits als workstations, ssh al servidor de fitxers, etc.). Tot i així, cal dir que no es pot accedir a una carpeta compartida del Samba. Caldrà revisar-ne la configuració:

smb.conf:

[global]
hosts allow = 192.168.0. 172.16.0.

Si a més volem accedir usant noms NetBIOS enlloc de IPs, caldrà activar el servidor WINS (més info):

smb.conf:

[global]
wins support = yes
name resolve order = wins lmhosts hosts bcast

Bé, això és tot. Si has arribat fins aquí (vaia tostón, jeje) espero que t'hagi sigut útil, si menys no interessant.

----------------
Enllaços externs

  1. Web Oficial
  2. WINS en Samba
  3. PKI
  4. Diffie Hellman