[OpenVPN](https://openvpn.net/) permet de monter des tunnels [VPN](https://fr.wikipedia.org/wiki/Réseau_privé_virtuel) (Virtual Private Network) en utilisant [SSL/TLS](HowtoSSL) pour le chiffrement. Pour l'authentification, OpenVPN peut utiliser une simple clé partagée (PSK — Pre-Shared Key) ou des couples *utilisateur*/*mot de passe*, mais nous préférons utiliser des certificats avec une [PKI](https://fr.wikipedia.org/wiki/Infrastructure_%C3%A0_cl%C3%A9s_publiques) (Public Key Infrastructure).
On met en place une PKI sur le serveur via [shellpki](https://gitea.evolix.org/evolix/shellpki). Voir le [README](https://gitea.evolix.org/evolix/shellpki/src/branch/master/README.md) du projet.
On peut utiliser le check NRPE OpenVPN suivant pour monitorer le service OpenVPN [pour Debian](https://gitea.evolix.org/evolix/ansible-roles/raw/branch/unstable/openvpn/files/check_openvpn_debian.pl) ou [pour OpenBSD](https://gitea.evolix.org/evolix/ansible-roles/raw/branch/unstable/openvpn/files/check_openvpn_openbsd.pl), à ajouter dans la configuration NRPE :
On peut également utiliser le [check NRPE suivant](https://gitea.evolix.org/evolix/ansible-roles/raw/branch/unstable/openvpn/files/check_openvpn_certificates.sh) pour monitorer les dates d'expirations de la CA et du certificat serveur:
permit nopass _nrpe as root cmd /usr/local/libexec/nagios/plugins/check_openvpn_certificates.sh
# doas /usr/local/libexec/nagios/plugins/check_openvpn_certificates.sh
~~~
Un script [cert-expirations.sh](https://gitea.evolix.org/evolix/shellpki/raw/branch/dev/cert-expirations.sh) peut être mis en cron pour avertir régulièrement des prochaines expirations des certificats clients et serveur :
Il ne faut pas oublier les changements suivants à ajouter dans `/etc/default/minifirewall` (en remplaçant `192.0.2.0/24` par le réseau utilisé dans le paramètre `server`) :
Le fichier `/etc/newsyslog.conf` ne permet pas de faire une rotation propre des logs OpenVPN, car OpenVPN continue à écrire dans le file descriptor du fichier précédent. Cela peut mener à une saturation de la partition d'écriture, sans pouvoir supprimer le fichier qui n'existe plus, et où seul un restart d'OpenVPN peut régler le problème.
* Sans utiliser newsyslog si on ne veut pas avoir à redémarrer OpenVPN, on peut utiliser un cron qui va copier le fichier de log, compresser la copie, et vider l'actuel (équivalent d'un copytruncate du logrotate). De cette manière, le file descriptor n'est pas changé :
Une fois installé, copier les fichiers `.ovpn` et le certificat de la CA dans le répertoire de configuration d'OpenVPN, par exemple `C:\Program Files\OpenVPN\config`.
Les systèmes iOS d'Apple disposent nativement du support de plusieurs types de VPN (IKEv2, IPsec ou L2TP), mais pas pour OpenVPN. On utilise alors l'application «OpenVPN Connect» (éditée par «OpenVPN Technologies») qui va exploiter les API bas niveau de l'OS pour un support d'OpenVPN dans les interfaces du système.
Pour activer la connexion VPN il faut alors se rendre dans l'application «Réglages», puis «VPN» où sont listés les profils disponibles. On peut choisir celui à utiliser et activer la connexion. Si tout se passe bien, le symbole «VPN» apparaît dans la barre d'icônes tout en haut de l'écran.
En cas d'erreur `ROUTE: route addition failed using createipforwardentry`, l'utilisateur n'a pas les droits suffisants pour ajouter une nouvelle route.
Il faut essayer d'exécuter les logiciels (`openvpn.exe` et `openvpngui.exe`) dans un mode de compatibilité _lancer en Administrateur_. Pour plus de détails, voir <http://www.bolehvpn.net/forum/index.php?topic=1746.0>.
L'erreur `Authentificate/Decrypt packet error: cipher final failed` signifie que l'algorithme de chiffrement n'est pas synchronisé entre le client et le serveur.
L'erreur `Bad LZO decompression header byte` signifie que la compression LZOn'est pas activée sur le serveur, il faut donc désactiver la compression au niveau du client.
Les IPs que l'on peut mettre doivent être prises selon des paires spécifiques, que l'on peut voir sur [la documentation OpenPVN](https://openvpn.net/community-resources/how-to/#configuring-client-specific-rules-and-access-policies) :
Pour avoir une authentification qui se base à la fois sur les certificats **et** sur un utilisateur UNIX, il faut utiliser le module PAM, en rajoutant à la configuration du serveur :
Si en plus de ça, on veut qu'un certificat ne puisse être utilisé que par un seul utilisateur UNIX, il faut utiliser un script vérifiant que le common_name du certificat équivaut à l'username UNIX, en rajoutant dans la configuration du serveur :
~~~
script-security 2
client-connect /etc/openvpn/cn-validation.sh
~~~
Le script cn-validation.sh est disponible sur [notre dépôt shellpki sur Gitea](https://gitea.evolix.org/evolix/shellpki/raw/branch/dev/cn-validation.sh)
À partir d'OpenVPN 2.4, _comp-lzo_ est déprécié et doit être remplacé par l'option _compress_ pour activer la compression (tant au niveau serveur que client).
Ne préciser que _compress_ n'active cependant aucun algorithme de compression. Il faut préciser l'algorithme, soit _lz4_, soit _lzo_. _compress lz4_ est plus performant, mais _compress lzo_ est rétro-compatible avec l'option _comp-lzo_ et est donc préférable dans le cas où des clients ont une version inférieure à 2.4.
### MTU
Si vous rencontrez des problèmes de connexion au travers d'un VPN, par exemple un transfert de fichiers qui s'interrompt, ou une connexion SSH qui échoue, alors qu'un simple `ping` fonctionne, il est possible que cela soit un problème de [MTU](https://fr.wikipedia.org/wiki/Maximum_transmission_unit).
Une manière de contourner le problème est de forcer le MTU côté client avec le paramètre
Bien sûr vous pouvez ajuster la valeur, mais tester avec une valeur assez basse comme 1300 afin de voir rapidement si cela résoud votre problème avant d'ajuster plus finement votre valeur avec `ping -s <packetsize> <IP>`.
L'option `--mtu-test` d'OpenVPN permet également de mesurer de façon empirique la meilleure valeur OpenVPN à utiliser. Pour cela, OpenVPN envoie des pings de différentes tailles en mesurant le plus gros paquet ayant été reçus avec succès.
### Déconnecter les utilisateurs inactifs après X minutes
Pour déconnecter les utilisateurs après par exemple 15 minutes d'inactivité, on peut configurer ces paramètres sur le serveur :
Étant donné qu'on configure l'option `keepalive` par défaut, il faut la désactiver pour que la déconnexion fonctionne. Configuré sur le serveur, l'option `keepalive` configure les paramètres `ping`, `ping-restart`, `push "ping"`, et `push "ping-restart"`. L'option `ping-restart` écrase l'option `ping-exit`, empêchant la bonne déconnexion.
Côté clients, les paramètres suivants peuvent également être configurés, mais de façon facultative car ils sont poussés par le serveur à l'aide de `push "paramètre"` :
~~~
ping 10
ping-exit 15
~~~
Explication :
*`ping 10` côté serveur et clients : Un ping est envoyé par le serveur et le client toutes les 10s.
*`inactive 900` côté serveur : En parallèle, s'il n'y a aucune activité sur le VPN (en dehors du ping qui n'est pas considérée comme une activité utilisateur) pendant 15min, le serveur déconnecte le client. À ce moment-là, le client ne sait pas qu'il a été déconnecté.
*`ping-exit 15` côté clients : Le client termine sa connexion après 15s sans réception de ping de la part du serveur. En réalité, ça va être 5s si le dernier ping a été envoyé par le serveur 10s avant la déconnexion d'inactivité, ou 15s si le dernier ping a été envoyé par le serveur au même moment que la déconnexion d'inactivité.
Nous n'utilisons pas le paramètre `inactive` côté clients car il ne réagit pas de la même manière que côté serveur. La déconnexion du client pourrait avoir lieu côté serveur avant d'arriver côté client, pouvant perturber l'utilisateur.