Assurer la stabilité de votre liaison VPN

Cette article fait suite à celui expliquant la mise en place d’un serveur VPN et de la configuration du client sous Ubuntu.

J’avais décris comment utiliser le network manager pour gérer la connexion au serveur openVPN mais malheureusement c’est loin d’être parfait:

  • Si le lien internet tombe, le client ne se reconnecte pas au serveur automatiquement.
  • Au demarrage malgré l’option connecter automatiquement cochée, le client ne se connecte pas automatiquement. C’est ballot.

Il en resulte quelques déconvenues si le VPN sert a « sortir » sur le net depuis une autre route que celle de notre FAI. On va se retrouver a surfer (voir pire…) sans passer par le VPN et donc en présentant l’IP attribuée par notre FA sans forcement s’en rendre compte. Ouille !!!

Je vais donc dans cet article vous expliquer comment éviter ce petit désagrément en utilisant un petit soft qui va surveiller le client openVPN et le réactiver dans le cas ou il aurait décidé d’abandonner son job. Le petit soft en question est deamontools de notre maitre a tous Daniel J Bernstein (aka DJB le créateur de qmail).
Continue reading

Partagez cet article

Serveur vpn (openvpn) sur Cloud OVH – Ubuntu server 10.04

Il vous arrive fréquemment d’utiliser des points d’accès pas forcement sécurisé ou/et limités (restriction de port) ?

Je vous propose dans cet article de mettre en place un serveur VPN qui va servir de point d’entré vers le net. Ainsi tout votre trafic entre votre client et le VPN sera crypté et comme on va utiliser des ports standards pour le serveur vous pourrez contacter n’importe quel service externe même si la politique de l’admin de votre point d’accès l’interdit. (histoire de soulager ma conscience: Vous devez respecter les règles mise en place par votre admin, si il ne veut pas que vous sortez vers les ports X ne le faite pas !).

Niveau hardware on va utiliser un « cloud’ OVH: https://www.ovh.com/fr/cloud/ qui se prête très bien a cette utilisation et qui à 1 cts de l’heure ne devrait pas nous ruiner.
A noter que vous pouvez « éteindre » votre VPS, l’image disque sera conservée et ça ne vous coutera rien. En d’autre terme si vous étes vraiement pres de vos euros, il vous suffit de le lancer uniquement quand vous en avez l’utilité. (attention l’IP va changer en cas de mise en pause/réveil).

Installation de base du serveur

Alors la c’est tout con grâce au cloud OVH: vous vous rendez sur le manager cloud, vous cliquez sur le premier bouton « Créez un cloud », vous sélectionnez « Ubuntu server 10.04″, vous renseignez le nom de votre machine virtuelle (personnellement j’utilise le nom d’hôte que je souhaite donnez à la machine)  et hop c’est fait.
Ne prenez pas plus des 256 Mo de RAM proposé, c’est largement suffisent.

Une fois le cloud démarré, ce qui devrait prendre quelques secondes, on se connecte et on met a jour la machine:

apt-get update
apt_get upgrade

Installation d’openvpn

Rien de bien compliqué de ce coté la:

apt-get install openvpn

Création de l’autorité de certification maitre

Les petits gars d’openvpn nous fournissent des scripts pour créer le nécessaire, elle n’est pas belle la vie  ;)
On se rend donc dans le repertoire qui contient les scripts:

cd /usr/share/doc/openvpn/examples/easy-rsa/2.0/

On edite le fichier « vars » qui contient les info d’identification pour créer les certificats et clés. Laissez toutes les options par défaut sauf la derniere partie:

nano vars

# These are the default values for fields

# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"

Il nous faut maintenant « initialiser » ces variables:

. ./vars

Par sécurité on va faire le ménage (théoriquement c’est inutile mais bon si vous devez refaire la procédure ça évitera les surprises):

./clean-all

On crée à présent l’autorité de certification maitre:

./build-ca

Durant cette étape, répondez par defaut a toutes les questions posées sauf pour le FQN:

''Common Name (eg, your name or your server's hostname) []:''

Création du certificat serveur et de sa clé

Pour cette partie (et le reste) on va avoir besoin d’un nom d’hôte pour la machine. Dans mon cas je vais faire preuve d’originalité puisque je vais utiliser vpn.toorop.fr.
Dans la mesure on l’on utilise un cloud, l’IP du serveur va changer a chaque fois que l’on va stopper et redémarrer le VPS  (l’IP ne change pas en cas de reboot par contre). Il faut donc veiller a mettre a jour l’enregistrement DNS si cette IP change (vous pouvez utiliser des services comme dyndns).

La aussi on utilise les scripts prévus pour générer le certificat et la clé correspondante:

./build-key-server vpn.toorop.fr

Il va vous etre proposé de signer le certificat, il faudra répondre « yes », si on vous demande le FQN indiquez le par contre ne mettez pas de mot de passe (A challenge password):

# ./build-key-server vpn.toorop.fr
Generating a 1024 bit RSA private key
.................................++++++
...............++++++
writing new private key to 'vpn.toorop.fr.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [FR]:
State or Province Name (full name) [Tarn]:
Locality Name (eg, city) [Albi]:
Organization Name (eg, company) [Toorop Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [vpn.toorop.fr]:
Name []:
Email Address [toorop@toorop.fr]:

 

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /usr/share/doc/openvpn/examples/easy-rsa/2.0/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :P RINTABLE:'FR'
stateOrProvinceName   :P RINTABLE:'Tarn'
localityName          :P RINTABLE:'Albi'
organizationName      :P RINTABLE:'Toorop Ltd'
commonName            :P RINTABLE:'vpn.toorop.fr'
emailAddress          :IA5STRING:'toorop @  toorop.   fr'
Certificate is to be certified until Jun  4 12:00:35 2020 GMT (3650 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Création de la clé pour le client

Je ne vais configurer qu’un client, si vous avez plusieurs client il suffit de reproduire cette procédure pour chacun d’entre eux.
La aussi il va nécessaire de donner un nom a chaque client, dans mon cas mon notebook se nomme mini, je vais donc utiliser ce fqn:

./build-key mini
# ./build-key mini
Generating a 1024 bit RSA private key
................++++++
.....................................................++++++
writing new private key to 'mini.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [FR]:
State or Province Name (full name) [Tarn]:
Locality Name (eg, city) [Albi]:
Organization Name (eg, company) [Toorop Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) [mini]:
Name []:
Email Address [toorop@toorop.fr]:

 

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /usr/share/doc/openvpn/examples/easy-rsa/2.0/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :P RINTABLE:'FR'
stateOrProvinceName   :P RINTABLE:'Tarn'
localityName          :P RINTABLE:'Albi'
organizationName      :P RINTABLE:'Toorop Ltd'
commonName            :P RINTABLE:'mini'
emailAddress          :IA5STRING:'toorop@toorop.fr'
Certificate is to be certified until Jun  4 12:05:50 2020 GMT (3650 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

Création des paramètres Diffie-Hellman

Pour ceux qui se demandent: mais qu’est ce que c’est que ce truc, je vous renvois a l’article de wikipedia. Pour faire simple, pour que le client et le serveur se causent ils doivent créer une clé qui sera connue que d’eux. Cette étape permet d’initialiser le nécessaire pour la création de ces clés.

./build-dh

Mise en place des certificats

Les certificats et les clés nécessaires sont créés, vous le trouverez dans le répertoire keys. Bon c’est bien beau tout ça mais pour que le serveur puisse les utiliser il faut les placer au bon endroit. En l’occurrence dans /etc/openvpn/ :

cp dh*.pem ca.crt vpn.toorop.fr.crt vpn.toorop.fr.key /etc/openvpn/

Configuration du serveur

Des fichiers de configuration d’exemple sont fournis, on va donc les utiliser comme base.

cd /usr/share/doc/openvpn/examples/sample-config-files
gunzip server.conf.gz
cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn/

On va éditer ce fichier de conf pour changer:

  • le port d’écoute du serveur
  • Le type d’interface (ici tap)
  • les noms des certificats
  • Les routes pour que le vpn serve de passerelle
  • le cache/resolver DNS à utiliser
nano /etc/openvpn/server.conf

 

# Which TCP/UDP port should OpenVPN listen on?
# If you want to run multiple OpenVPN instances
# on the same machine, use a different port
# number for each one.  You will need to
# open up this port on your firewall.
port 443
.
.
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
dev tap
;dev tun
.
.
#
# Any X509 key management system can be used.
# OpenVPN can also use a PKCS #12 formatted key file
# (see "pkcs12" directive in man page).
ca ca.crt
cert vpn.toorop.fr.crt
key vpn.toorop.fr.key  # This file should be kept secret
.
.
# network gateway through the VPN, causing
# all IP traffic such as web browsing and
# and DNS lookups to go through the VPN
# (The OpenVPN server machine may need to NAT
# or bridge the TUN/TAP interface to the internet
# in order for this to work properly).
;push "redirect-gateway def1 bypass-dhcp"
push "redirect-gateway def1"
.
.
push "dhcp-option DNS 213.186.33.99"

Quelques explications sur les DNS: Vos clients n’auront certainement pas de cache DNS, il faudra donc utiliser un cache externe, cette directive permet de forcer la config du client pour utiliser le resolver DNS indiqué. On pourrait/devrait utiliser le resolver du « serveur » vpn mais par défaut c’est bind et comme je ne suis pas fan, je prefere le squeezer dans la conf et utiliser un cache externe, en l’ocrurence celui d’OVH (accessible uniquement depuis les dediés/IP OVH) en attendant d’installer autre chose.

Voila on va vérifier que tout est OK du coté serveur avant de passer au coté client. Pour cela on commence par arreter openvpn (si il est lancé) et on le relance en debug:

/etc/init.d/openvpn stop
cd /etc/openvpn
openvpn server.conf
.
.openvpn server.conf
Mon Jun  7 14:38:24 2010 OpenVPN 2.1.0 i486-pc-linux-gnu [SSL] [LZO2] [EPOLL] [PKCS11] [MH] [PF_INET6] [eurephia] built on Jan 26 2010
Mon Jun  7 14:38:24 2010 NOTE: OpenVPN 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables
Mon Jun  7 14:38:24 2010 Diffie-Hellman initialized with 1024 bit key
Mon Jun  7 14:38:24 2010 /usr/bin/openssl-vulnkey -q -b 1024 -m <modulus omitted>
Mon Jun  7 14:38:25 2010 TLS-Auth MTU parms [ L:1542 D:138 EF:38 EB:0 ET:0 EL:0 ]
Mon Jun  7 14:38:25 2010 ROUTE default_gateway=192.168.253.126
Mon Jun  7 14:38:25 2010 TUN/TAP device tun0 opened
Mon Jun  7 14:38:25 2010 TUN/TAP TX queue length set to 100
Mon Jun  7 14:38:25 2010 /sbin/ifconfig tun0 10.8.0.1 pointopoint 10.8.0.2 mtu 1500
Mon Jun  7 14:38:25 2010 /sbin/route add -net 10.8.0.0 netmask 255.255.255.0 gw 10.8.0.2
Mon Jun  7 14:38:25 2010 Data Channel MTU parms [ L:1542 D:1450 EF:42 EB:135 ET:0 EL:0 AF:3/1 ]
Mon Jun  7 14:38:25 2010 Socket Buffers: R=[112640->131072] S=[112640->131072]
Mon Jun  7 14:38:25 2010 UDPv4 link local (bound): [undef]
Mon Jun  7 14:38:25 2010 UDPv4 link remote: [undef]
Mon Jun  7 14:38:25 2010 MULTI: multi_init called, r=256 v=256
Mon Jun  7 14:38:25 2010 IFCONFIG POOL: base=10.8.0.4 size=62
Mon Jun  7 14:38:25 2010 IFCONFIG POOL LIST
Mon Jun  7 14:38:25 2010 Initialization Sequence Completed

Configuration du routage sur le serveur

Le « serveur » vpn va servir de passerelle, il faut donc que le trafic qui entre par l’IP du VPN sorte vers internet en passant par l’IP publique du serveur.

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward

Parfait, il nous faut maintenant configurer le client.

Configuration du client

Mon poste client est sous Ubuntu, donc je ne vais decrire que la procedure pour cet OS. Pour les autres vous trouverez une foultitude de tuto sur le net.

Comme on dispose d’une interface graphique on ne va commencer par installer network-manager-openvpn qui va nous permettre de monter le VPN grace au network manager. Mais attention un des scripts est bugé et donc….. ça ne marche pas ! (merci a Pierre-Samuel pour le deblocage ;) )

Il faut éditer le fichier /etc/NetworkManager/dispatcher.d/01ifupdown, pour vous faciliter la tache je vous donne celui a utiliser:

cat /etc/NetworkManager/dispatcher.d/01ifupdown
#!/bin/sh -e
# Script to dispatch NetworkManager events
#
# Runs ifupdown scripts when NetworkManager fiddles with interfaces.

 

if [ -z "$1" ]; then
    echo "$0: called with no interface" 1>&2
    exit 1;
fi

# Fake ifupdown environment
export IFACE="$1"
export LOGICAL="$1"
export ADDRFAM="NetworkManager"
export METHOD="NetworkManager"
export VERBOSITY="0"

# Run the right scripts
case "$2" in
    up|vpn-up)
	export MODE="start"
	export PHASE="up"

if [ -d /var/run/network/ ] ; then
		tmpfile=`mktemp -t`
		if [ -e /var/run/network/ifstate ] ; then
			cat /var/run/network/ifstate | grep -v ^$IFACE= > $tmpfile || true
		fi
		echo $IFACE=$IFACE >> $tmpfile
		mv $tmpfile /var/run/network/ifstate
	fi

exec run-parts /etc/network/if-up.d
	;;
    down|vpn-down)
	export MODE="stop"
	export PHASE="down"

if [ -e /var/run/network/ifstate ] ; then
		tmpfile=`mktemp -t`
		cat /var/run/network/ifstate | grep -v ^$IFACE= > $tmpfile || true
		mv $tmpfile /var/run/network/ifstate
	fi

exec run-parts /etc/network/if-down.d
	;;
    pre-up)
	export MODE="start"
	export PHASE="pre-up"
	exec run-parts /etc/network/if-pre-up.d
	;;
    post-down)
	export MODE="stop"
	export PHASE="post-down"
	exec run-parts /etc/network/if-post-down.d
	;;
    *)
	echo "$0: called with unknown action \`$2'" 1>&2
	exit 1
	;;
esac

Maintenant il nous reste a configurer la connexion en elle meme, via le networkmanager.
On va avoir besoin de la clé, du certificat et de l’autorité de certification que l’on a créé a l’etape precedente. On telecharge donc tout ça dans ~/vpn/:

$ cd ~
$ mkdir vpn
$ cd vpn
$ scp root@IP_DU_SERVEUR:/usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/ca.crt vpn/
$ scp root@IP_DU_SERVEUR:/usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/mini.crt vpn/
$ scp root@IP_DU_SERVEUR:/usr/share/doc/openvpn/examples/easy-rsa/2.0/keys/mini.key vpn/

On lance le networkmanager: connection VPN=> nouvelle connexion.

Vous devez renseigner :

  • Passerelle: Nom d’hote du cloud, attention pesnez a la configurer sinon utilisez l’IP
  • Certificat de l’utilisateur: dans mon cas mini.crt
  • Certificat du CA: ca.crt
  • Clé privée: mini.key

Dans l’onglet « avancé »:

  • Changez le port pour y mettre 443
  • Activez la compression LZO
  • Sélectionnez « Utilisez un peripherique TAP »

Voila, on valide et on a plus qu’a cliquer sur « connexion VPN » -> Le nom que l’on a donné a la connexion et NORMALEMENT ça fonctionne. (si ça fonctionne du premier coup dites le moi, j’aime les choses improbables)

# If enabled, this directive will configure
# all clients to redirect their default
# network gateway through the VPN, causing
# all IP traffic such as web browsing and
# and DNS lookups to go through the VPN
# (The OpenVPN server machine may need to NAT
# or bridge the TUN/TAP interface to the internet
# in order for this to work properly).
;push « redirect-gateway def1 bypass-dhcp »
push « redirect-gateway def1″

 

 

Partagez cet article