Howto OpenVPN
- Installation
- Configuration serveur
- Configuration client
- Erreurs
fréquentes
- Erreur « –crl-verify fails » (serveur OpenVPN – OpenBSD)
- Erreur « CRL has expired » (serveur OpenVPN – OpenBSD)
- Erreur « createipforwardentry » (client OpenVPN – Windows)
- Erreur « no more TUN/TAP adapter » (client OpenVPN – Windows)
- Erreur « cipher final failed » (client OpenVPN – Android)
- Erreur « Bad LZO decompression header byte » (client OpenVPN – Android)
- Erreur « Temporary directory (–tmp-dir) fails with ‘/var/empty//tmp’: No such file or directory (errno=2) »
- Je ne passe pas par le VPN pour joindre cette IP alors que je devrais : réseaux mobiles et NAT64/DNS64
- FAQ
- Documentation : https://openvpn.net/index.php/open-source/documentation.html
- Rôle Ansible : https://gitea.evolix.org/evolix/ansible-roles/src/branch/stable/openvpn
OpenVPN permet de monter des tunnels VPN (Virtual Private Network) en utilisant SSL/TLS 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 (Public Key Infrastructure).
Installation
Debian
# apt install openvpn
$ /usr/sbin/openvpn --version
OpenVPN 2.5.1 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] built on May 14 2021
library versions: OpenSSL 1.1.1k 25 Mar 2021, LZO 2.10
# systemctl status openvpn
● openvpn.service - OpenVPN service
Loaded: loaded (/lib/systemd/system/openvpn.service; enabled; vendor preset: enabled)
Active: active (exited) since Tue 2022-01-04 15:11:48 CET; 27s ago
Process: 74469 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 74469 (code=exited, status=0/SUCCESS)
CPU: 819us
OpenBSD
# pkg_add openvpn
$ openvpn --version
OpenVPN 2.5.1 x86_64-unknown-openbsd6.9 [SSL (OpenSSL)] [LZO] [LZ4] [MH/RECVDA] [AEAD] built on Apr 19 2021
library versions: LibreSSL 3.3.2, LZO 2.10
Configuration serveur
On met en place une PKI sur le serveur via shellpki. Voir le README du projet.
Une fois fait, on génère le dhparam :
# openssl dhparam -out /etc/shellpki/dh2048.pem 2048
La configuration se fait via le fichier
/etc/openvpn/server.conf
avec les paramètres suivants à
adapter :
local
: adresse IP du serveur, sur laquelle les clients se connecteront (adresse IP publique généralement)cert
: certificat du serveur VPN (créé précédemment)key
: clé du serveur VPN (créée précédemment)server
: réseau privé sur lequel le serveur VPN et les clients communiquerontpush
: route vers le réseau que les clients pourront joindre à travers OpenVPN ; ce paramètre peut être indiqué plusieurs foisifconfig-pool-persist
: permet aux clients de conserver la même IP en cas de redémarrage
user _openvpn
group _openvpn
local 198.51.100.1
port 1194
proto udp
dev tun
mode server
topology subnet
keepalive 10 120
tls-exit
cipher AES-256-GCM # AES
persist-key
persist-tun
ifconfig-pool-persist /etc/openvpn/ipp.txt
status /var/log/openvpn-status.log
log-append /var/log/openvpn.log
ca /etc/shellpki/cacert.pem
cert /etc/shellpki/certs/fw.vpn.example.com.crt
key /etc/shellpki/private/fw.vpn.example.com-1621504035.key
dh /etc/shellpki/dh2048.pem
crl-verify /etc/shellpki/crl.pem
server 192.0.2.0 255.255.255.0
#push "route 192.0.3.0 255.255.255.0"
# Management interface (used by check_openvpn for Nagios)
management 127.0.0.1 1195 /etc/openvpn/management-pwd
Générer un mot de passe pour l’accès à l’interface de management (nécessaire au check Nagios) :
# apg -n1 -m 12 > /etc/openvpn/management-pwd
On peut utiliser le check NRPE OpenVPN suivant pour monitorer le service OpenVPN pour Debian ou pour OpenBSD, à ajouter dans la configuration NRPE :
## Debian
# wget https://gitea.evolix.org/evolix/ansible-roles/raw/branch/unstable/openvpn/files/check_openvpn_debian.pl -O /usr/local/lib/nagios/plugins/check_openvpn
# chmod 755 /usr/local/lib/nagios/plugins/check_openvpn
# chown root:nagios /usr/local/lib/nagios/plugins/check_openvpn
# apt install libnet-telnet-perl
# /usr/local/lib/nagios/plugins/check_openvpn -H 127.0.0.1 -p 1195 -P $MANAGEMENT_PWD
## OpenBSD
# wget https://gitea.evolix.org/evolix/ansible-roles/raw/branch/unstable/openvpn/files/check_openvpn_openbsd.pl -O /usr/local/libexec/nagios/plugins/check_openvpn.pl
# chmod 755 /usr/local/libexec/nagios/plugins/check_openvpn.pl
# chown root:wheel /usr/local/libexec/nagios/plugins/check_openvpn.pl
# pkg_add p5-Net-Telnet
# /usr/local/libexec/nagios/plugins/check_openvpn.pl -H 127.0.0.1 -p 1195 -P $MANAGEMENT_PWD
On peut également utiliser le check NRPE suivant pour monitorer les dates d’expirations de la CA et du certificat serveur:
## Debian
# wget https://gitea.evolix.org/evolix/ansible-roles/raw/branch/unstable/openvpn/files/check_openvpn_certificates.sh -O /usr/local/lib/nagios/plugins/check_openvpn_certificates.sh
# chmod 755 /usr/local/lib/nagios/plugins/check_openvpn
# chown root:nagios /usr/local/lib/nagios/plugins/check_openvpn
# visudo -f /etc/sudoers.d/openvpn
nagios ALL=NOPASSWD: /usr/local/lib/nagios/plugins/check_openvpn_certificates.sh
# sudo /usr/local/lib/nagios/plugins/check_openvpn_certificates.sh
## OpenBSD
# wget https://gitea.evolix.org/evolix/ansible-roles/raw/branch/unstable/openvpn/files/check_openvpn_certificates.sh -O /usr/local/libexec/nagios/plugins/check_openvpn_certificates.sh
# chmod 755 /usr/local/libexec/nagios/plugins/check_openvpn_certificates.sh
# chown root:wheel /usr/local/libexec/nagios/plugins/check_openvpn_certificates.sh
# vim /etc/doas.conf
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 peut être mis en cron pour avertir régulièrement des prochaines expirations des certificats clients et serveur :
# wget https://gitea.evolix.org/evolix/shellpki/raw/branch/dev/cert-expirations.sh -O /usr/share/scripts/cert-expirations.sh
# chmod +x /usr/share/scripts/cert-expirations.sh
# crontab -e
@monthly /usr/share/scripts/cert-expirations.sh | mail -E -s "PKI OpenVPN XXX : recapitulatif expirations" mail@example.com
Penser à remplacer :
- L’horaire d’exécution du cron, si voulu ;
- L’emplacement des certificats dans le script (/etc/shellpki/certs/), ceux-ci peuvent se trouver dans “/etc/openvpn/ssl/certs/” ou ailleurs encore ;
- Le nom du serveur XXX dans le sujet “PKI OpenVPN XXX” ;
- L’adresse mail de contact.
Serveur sous Debian
On crée un utilisateur _openvpn
sous lequel OpenVPN
tournera :
# useradd _openvpn --system -M --home-dir /nonexistent --shell /usr/sbin/nologin
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
) :
# Public services (IPv4/IPv6)
[…]
SERVICESUDP1='1194'
[…]
# OpenVPN
/sbin/iptables -t nat -A POSTROUTING -s 192.0.2.0/24 -o $INT -j MASQUERADE
Ainsi qu’autoriser le routage via sysctl :
# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.d/openvpn.conf
# sysctl -p /etc/sysctl.d/openvpn.conf
Rotation des logs, en créant un fichier
/etc/logrotate.d/openvpn
:
/var/log/openvpn.log
{
weekly
rotate 52
missingok
notifempty
delaycompress
compress
copytruncate
}
Le service s’active et se démarre ensuite via :
# systemctl enable --now openvpn@server.service
Serveur sous OpenBSD
On autorise la connexion au serveur VPN en modifiant
/etc/pf.conf
:
# OpenVPN
pass in quick on $ext_if proto udp from any to self port 1194
Puis on recharge PacketFilter :
# pfctl -nf /etc/pf.conf && pfctl -f /etc/pf.conf
Rotation des logs :
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.
- Pour tout de même utiliser newsyslog, il faut rajouter la ligne
suivante dans le fichier
/etc/newsyslog.conf
:
/var/log/openvpn.log 600 52 * $W6D4 Z
Ainsi que plannifier en crontab un restart d’OpenVPN juste après cette rotation, pour qu’il puisse récupérer le nouveau file descriptor :
05 4 * * 6 /etc/rc.d/openvpn restart
- 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é :
0 4 * * 6 cp /var/log/openvpn.log /var/log/openvpn.log.$(date +\%F) && echo "$(date +\%F' '\%R) - logfile turned over via cron" > /var/log/openvpn.log && gzip /var/log/openvpn.log.$(date +\%F) && find /var/log/ -type f -name "openvpn.log.*" -mtime +365 -exec rm {} \+
Pour activer OpenVPN au démarrage :
# rcctl enable openvpn
# rcctl set openvpn flags "--daemon --config /etc/openvpn/server.conf"
Pour lancer OpenVPN :
# rcctl start openvpn
IPv6
Pour configurer l’IPv6, il suffit d’ajouter le paramètre
server-ipv6
en plus du paramètre server
. Il
faut, pour l’IPv6, soit utiliser un réseau publique que l’on possède et
que l’on dédie à cette utilisation (et pour lequel on fait le routage
nécessaire dans notre infrastructure), soit utiliser le préfixe local
fd00::/64
sur lequel on peut faire du NAT :
server 192.0.2.0 255.255.255.0
server-ip6 2001:db8:10::/64
On peut ensuite pousser les routes IPv6 aux clients :
push "route-ipv6 2001:db8:20::/64"
push "route-ipv6 2001:db8:30::/64"
Si l’on veut faire écouter le serveur OpenVPN en IPv6 et en IPv4 à la
fois, il faut remplacer proto udp
par
proto udp6
ou proto tcp
par
proto tcp6
. Attention cependant : sur certains OS, dont
OpenBSD, udp6
et tcp6
n’impliquent pas
udp
et tcp
, donc seul l’IPv6 écoutera. Il
faudra alors choisir entre l’IPv4 et l’IPv6.
Configuration client
La configuration client se trouve généralement dans un fichier
<nom_certificat>.ovpn
. Cette extension permet
l’exécution d’OpenVPN sous Windows, et est donc généralement utilisée
sous n’importe quel système pour l’uniformité. Néammoins, c’est parfois
l’extension .conf
qui est utilisée, puisque sous Linux,
OpenBSD, ou d’autres systèmes encore, l’extension n’a pas vraiment
d’importance.
Pour simplifier la configuration pour les utilisateurs finaux on peut générer un fichier de configuration embarquant les certificats :
client
dev tun
tls-client
proto udp
remote vpn.example.com 1194
nobind
user nobody
group nogroup
persist-key
persist-tun
cipher AES-256-GCM
<ca>
-----BEGIN CERTIFICATE-----
[…]
-----END CERTIFICATE-----
</ca>
<cert>
Certificate:
Data:
[…]
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN RSA PRIVATE KEY-----
[…]
-----END RSA PRIVATE KEY-----
</key>
Nouveau certificat avec shellpki
Pour une nouvelle connexion VPN, il faudra créer un nouveau certificat :
# shellpki create <commonName>
Choisir un Common Name unique pour la machine (ex :
client1.vpn.example.com
)Récupérer la configuration client dans
/etc/shellpki/openvpn/
Renouveller un certificat avec shellpki
Il faut utiliser l’option --replace-existing
:
# shellpki create --replace-existing <commonName>
Si c’est le certificat du serveur OpenVPN, il faut en plus modifier
la configuration /etc/openvpn/server.conf
pour indiquer la
nouvelle key puis relancer le démon.
Révoquer un certificat avec shellpki
# shellpki revoke <commonName>
Vérifier les certificats révoqués
# openssl crl -inform PEM -text -noout -in /etc/shellpki/crl.pem
L’association entre le numéro de série indiqué et le CN du certificat
correspondant peut être faite à l’aide du fichier
/etc/shellpki/index.txt
Client sous Linux
Pour démarrer le client OpenVPN, il existe un template systemd, pour le démarrer et l’activer au démarrage :
# systemctl enable --now openvpn@client
Attention, si l’option chroot
est configurée, il faudra
au moins y créer un dossier tmp
, sans lequel OpenVPN ne
démarrera pas. Par exemple, avec chroot /var/empty
:
mkdir /var/empty/tmp/
chown $OPENVPN_USER:$OPENVPN_GROUP /var/empty/tmp/
chmod 700 /var/empty/tmp/
En remplaçant $OPENVPN_USER et $OPENVPN_GROUP selon les paramètres
configurés pour user
et group
(souvent
nobody
).
Client sous Windows
On peut télécharger un client 32 bits ou 64 bits sur https://openvpn.net/community-downloads/.
Une fois installé, copier le fichier .ovpn
et le
certificat de la CA dans le répertoire de configuration d’OpenVPN, par
exemple C:\Program Files\OpenVPN\config
.
Attention, il faut exécuter OpenVPN en tant qu’administrateur, cela
peut se faire via un clic droit :
Exécuter en tant qu'administrateur
.
OpenVPN est alors disponible dans la barre des tâches. Pour lancer
une session, effectuez un clic-droit et sélectionnez
Connecter
.
Client sous macOS
Télécharger la dernière version stable de Tunnelblick sur https://tunnelblick.net/downloads.html
On suit les instructions d’installation (en anglais), puis :
- on choisit de générer la configuration (indiquer qu’on n’a pas de fichiers de configuration) ;
- cela génère une configuration standard, notamment un dossier sur le
bureau avec un fichier
config.ovpn
; - on édite le fichier
config.ovpn
en ajustant les optionsremote
,ca
,cert
etkey
; - on copie également la clé et les certificats (ca et cart) dans ce dossier ;
- on doit ensuite renommer ce dossier avec un nom se terminant par
.tblk
; - on « double-clic » ensuite dessus, et cela installe configuration ;
- on peut ensuite lancer le VPN via l’icone présente, puis choisir diverses options (connexion automatique, etc.).
Si on souhaite faire passer tout le trafic par le VPN, on peut cocher la case « Rediriger tout le trafic IPv4 au travers du VPN »
Client sous Android
On utilise l’application libre « OpenVPN for Android » disponible sur Google Play et F-Droid qui ne nécessite pas de droits « root » avec Android 4 ou supérieur.
La configuration d’un VPN nécessite les informations suivantes :
- le certificat CA peut être importé sous format PEM ;
- le certificat client doit être au format PKCS#12 (fichier .p12 ou .pfx), on pourra ainsi le créer à partir de la clé/certificat :
$ openssl pkcs12 -export -in goyk3OkjeuPread8Sluld.privacy.example.com.crt -inkey goyk3OkjeuPread8Sluld.privacy.example.com.key -out goyk3OkjeuPread8Sluld.privacy.example.com.p12
- décocher « Compression LZO » si ce n’est pas supporté par votre serveur ;
- décocher « Vérification du certificat de l’hôte » (sinon cela ne fonctionne pas a priori…) ;
- forcer « Algorithme de chiffrement » à AES-256-GCM (à ajuster selon votre serveur).
Si erreur ca md too weak
cela signifie que le certificat
utilise du MD5. Pour forcer quand même, il faut mettre dans les options
personnalisées :
tls-cipher "DEFAULT:@SECLEVEL=0"
Client sous Apple iOS
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 ajouter une configuration cliente, il suffit d’ouvrir le fichier
.ovpn
. Il est possible d’avoir plusieurs configurations
disponibles.
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.
Erreurs fréquentes
Erreur « –crl-verify fails » (serveur OpenVPN – OpenBSD)
Options error: --crl-verify fails with 'crl.pem': No such file or directory
Options error: Please correct these errors.
Il faut parfois regénérer un fichier CRL.
Si l’on utilise une version ancienne de shellpki :
# cd /tmp
# shellpki.sh crl
# cp crl.pem /var/empty
Sur les versions récentes, la CRL est re-générée à chaque révocation d’un certificat, ou peut être re-générée ainsi :
# openssl ca -gencrl -keyfile /etc/shellpki/cakey.key -cert /etc/shellpki/cacert.pem -out /etc/shellpki/crl.pem -config /etc/shellpki/openssl.cnf
Erreur « CRL has expired » (serveur OpenVPN – OpenBSD)
VERIFY ERROR: depth=0, error=CRL has expired: C=FR, ST=FR, L=Versailles, O=foo.bar, CN=SoX, emailAddress=hostmaster@foo.bar
Il est possible que la CRL ne soit plus valide, et qu’il faille la regénérer comme ci-dessus. Dans le cas de firewalls redondés, si une bascule sur le backup a récemment eu lieu, le fichier n’est sans doute pas synchronisé et expiré.
Erreur « createipforwardentry » (client OpenVPN – Windows)
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.
Erreur « no more TUN/TAP adapter » (client OpenVPN – Windows)
En cas d’erreur no more TUN/TAP adapter
, aller dans
« Menu démarrer » → « OpenVPN » → « Add new TUN/TAP Adapter ».
Erreur « cipher final failed » (client OpenVPN – Android)
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. Il faut donc ajuster la directive « cipher » sur
le client.
Erreur « Bad LZO decompression header byte » (client OpenVPN – Android)
L’erreur Bad LZO decompression header byte
signifie que
la compression LZO n’est pas activée sur le serveur, il faut donc
désactiver la compression au niveau du client.
Erreur « Temporary directory (–tmp-dir) fails with ‘/var/empty//tmp’: No such file or directory (errno=2) »
Un chroot est configuré dans /var/empty
mais le dossier
est vide. Il faut créer un répertoire tmp
dedans :
# mkdir /var/empty/tmp/
# chown _openvpn:_openvpn /var/empty/tmp/
# chmod 700 /var/empty/tmp/
Je ne passe pas par le VPN pour joindre cette IP alors que je devrais : réseaux mobiles et NAT64/DNS64
Dans le cas d’utilisation d’un partage de connexion depuis un réseau mobile (en particulier Bouygues, mais ça concerne aussi les autres opérateurs), un tunnel IPv6 est effectué par l’opérateur pour forcer l’utilisation d’IPv6, via du NAT64.
Si un site que je veux joindre, disons example.com
, a un
enregistrement DNS A sur 192.0.2.15
mais pas
d’enregistrement DNS AAAA IPv6, alors le résolveur DNS du réseau mobile
renverra à la fois l’enregistrement DNS A 192.0.2.15
et son
enregistrement DNS AAAA équivalent en NAT64, par exemple
64:ff9b::c000:20f
si la RFC6052
est appliquée. Étant donné que les OS ont généralement une préférence
pour l’IPv6, c’est cette adresse IPv6 que le système va essayer de
joindre.
Vu que le préfixe NAT64 utilisé n’est pas routé par le VPN, alors je joindrais ce site sans passer par le VPN. Pour résoudre le problème, il faut forcer l’utilisation d’un résolveur DNS dans la configuration du serveur OpenVPN :
push "dhcp-option DNS 198.51.100.53"
Avec 198.51.100.53
étant l’IP du serveur DNS à
adapter.
FAQ
Permettre aux clients de conserver la même IP au fil de connexions
ipp.txt
Le fichier ipp.txt
contient une liste des clients et de
leur adresse IP afin qu’en cas de redémarrage du serveur, ils conservent
la même adresse.
Dans le server.conf
ou server.ovpn
:
ifconfig-pool-persist /etc/openvpn/ipp.txt 0
Cela rend le fichier ipp.txt
en lecture seule pour
OpenVPN. Il faudra donc ajouter une nouvelle ligne de la forme
CN,IP
à chaque ajout d’un nouveau client.
Attention : cette configuration n’est qu’une
suggestion pour OpenVPN, il n’y a aucune garantie qu’OpenVPN attribue
réellement les IPs indiquées dans ce fichier aux clients. Pour que cela
soit garantie, il faut utiliser l’option client-config-dir
,
voir ce-dessous.
/etc/openvpn/ccd
Doc complète : https://community.openvpn.net/openvpn/wiki/Concepts-Addressing
Pour attribuer une IP de manière statique de façon garantie sur le temps, en se basant sur la configuration serveur classique, il faut :
- Supprimer la ligne de configuration
server 192.0.2.0 255.255.255.0
- Ajouter les paramètres de configuration suivants :
tls-server
push "topology subnet"
ifconfig 192.0.2.1 255.255.255.0
push "route-gateway 192.0.2.1"
ifconfig-pool 192.0.2.2 192.0.2.199 255.255.255.0
client-config-dir /etc/openvpn/ccd
- Créer le dossier
/etc/openvpn/ccd/
avec les bons droits :
# cd /etc/openvpn/
# mkdir ccd
# chmod 700 ccd
# chown _openvpn:_openvpn ccd
- Créer le fichier
/etc/openvpn/ccd/client1
(client1
étant le CN du client auquel attribuer l’IP statique) avec les bons droits, et mettre la configuration suivante :
# cd /etc/openvpn/ccd/
# echo "ifconfig-push 192.0.2.200 255.255.255.0" > client1
# chmod 600 client1
# chown _openvpn:_openvpn client1
- Répéter la configuration dans
/etc/openvpn/ccd/
pour chaque CN auquel attribuer une IP statique
Ainsi, le serveur est configuré sur l’IP 192.0.2.1, la plage IP 192.0.2.2 jusqu’à .199 sera dynamique, et la plage .200 jusqu’à .254 ne sera jamais attribuée dynamiquement mais ne pourra qu’être statique.
On peut aussi supprimer la ligne
ifconfig-pool 192.0.2.2 192.0.2.199 255.255.255.0
pour ne
pas avoir de plage dynamique du tout, et ne forcer que des attributions
statiques. Dans ce cas, il faut aussi supprimer la configuration
ifconfig-pool-persist /etc/openvpn/ipp.txt
. Un client qui
se connecte alors que son IP statique n’a pas été configurée n’aura pas
d’IP, et ne pourra donc pas utiliser OpenVPN malgré sa bonne
connexion.
De cette façon, on peut également utiliser des plages d’IPs avec des autorisations spécifiques sur le firewall : par exemple la page dynamique .2 à .199 avec des autorisations limitées, une plage statique .200 à .220 avec certaines autorisations, puis une plage statique .221 à .254 avec d’autres autorisations.
Router tout le trafic des clients par le VPN
Si l’on veut router tout le trafic des clients OpenVPN par le serveur OpenVPN, il faut ajouter cette configuration sur le serveur :
push "redirect-gateway def1"
Le mot-clé def1
permet à OpenVPN de ne pas remplacer et
donc supprimer la route par défaut déjà en place, mais de seulement
ajouter 2 routes en utilisant 0.0.0.0/1 et 128.0.0.0/1, qui seront plus
précises que la route par défaut (0.0.0.0/0) et seront donc utilisées à
la place de celle-ci.
Si l’on ne veut pas que tous les clients aient cette configuration, alors on peut l’ajouter du côté du client qui la souhaite uniquement :
redirect-gateway def1
À l’inverse, si le serveur est configuré pour que tous les clients aient tout leur trafic routé par le VPN, mais qu’un client en particulier ne souhaite pas cette option, il peut la refuser dans sa configuration client (source) :
pull-filter ignore "redirect-gateway"
On peut utiliser cette option directement depuis la ligne de commande :
# openvpn --pull-filter ignore redirect-gateway --config …
Authentification via Radius
Il faut installer le plugin :
# apt install openvpn-auth-radius
# cp /usr/share/doc/openvpn-auth-radius/examples/radiusplugin.cnf /etc/openvpn/
# openvpn --genkey secret /etc/openvpn/ta.key
On ajoute dans la configuration du serveur :
verify-client-cert none
username-as-common-name
tls-auth ta.key 0
topology subnet
plugin /usr/lib/openvpn/radiusplugin.so /etc/openvpn/radiusplugin.cnf
status /var/log/openvpn/status.log 1
et on modifie le paramètre sharedsecret du fichier
/etc/openvpn/radiusplugin.cnf
pour se connecter au serveur
Radius.
Puis dans la configuration du client :
auth-user-pass
#auth-user-pass /etc/openvpn/passwd
auth-nocache
Authentification via PAM et certificat
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 :
plugin /usr/lib/x86_64-linux-gnu/openvpn/plugins/openvpn-plugin-auth-pam.so login
Et dans la configuration du client :
auth-user-pass
auth-nocache
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
comp-lzo ou compress ?
https://community.openvpn.net/openvpn/wiki/DeprecatedOptions#a--comp-lzo
À 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.
Une manière de contourner le problème est de forcer le MTU côté client avec le paramètre
link-mtu 1300
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 :
#keepalive 10 120
inactive 900
ping 10
push "ping 10"
push "ping-exit 15"
É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.