06 Dec 2019, 00:00

Serveur OpenVPN ponté sous Debian Buster

Share

Mentionné sans aucun password, en rajouter si désiré.
Prévu pour permettre un lien avec le réseau local distant, mais sans redirection de l’ensemble du trafic via VPN.

Préparation générale

apt install bridge-utils openvpn

Création de la PKI et des certificats/clés

cd /etc/openvpn
make-cadir easy-rsa/
cd easy-rsa
nano vars

Trouver les lignes qui définissent les noms de notre organisation et les modifier comme souhaité ;
Passer la taille de clés à 4096b ;
Changer le temps d’expiration par défaut du CA et des certificats en nombre de jours(ici, 10 ans)

set_var EASYRSA_REQ_COUNTRY    "FR"
set_var EASYRSA_REQ_PROVINCE   "IDF"
set_var EASYRSA_REQ_CITY       "Paris"
set_var EASYRSA_REQ_ORG        "Ma badass orga"
set_var EASYRSA_REQ_EMAIL      "me@example.net"
set_var EASYRSA_REQ_OU         "Mon OU qui déchire"

set_var EASYRSA_KEY_SIZE        4096

set_var EASYRSA_CA_EXPIRE       3650

set_var EASYRSA_CERT_EXPIRE     3650

# Le CRL a aussi une date d'expiration, on la passe à 10 ans
set_var EASYRSA_CRL_DAYS        3650

Puis on lance toute la procédure

# Initier la PKI ;
# Supprime la PKI si déjà existante
./easyrsa init-pki

# Créer les params Diffie-Hellman
./easyrsa gen-dh

# Créer les fichier de l'autorité de certif
./easyrsa build-ca nopass  # nopass pour absence de mot de passe
# Génération et signature de la CSR (signing request) du server, avec définition du Common Name
./easyrsa gen-req mon-server-vpn nopass
./easyrsa sign-req server mon-server-vpn # le "server" indique le type
# Vérification si souhaitée
openssl verify -CAfile pki/ca.crt pki/issued/mon-server-vpn.crt

# Génération et signature d'un kit de connexion pour un client
./easyrsa gen-req mon-pc-client nopass
./easyrsa sign-req client mon-pc-client

Les certificats sont dans issued, les clés dans private.

Génération TLS
Ce fichier devra être présent sur chacun des clients

openvpn --genkey --secret ta.key
mv ta.key /etc/openvpn/easy-rsa/pki/

Réseau

Activer forward IPv4

echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.d/10-network.conf

Fichier /etc/network/interfaces qui crée le bridge et l’adaptateur TAP au démarrage ;
vérifier la cohérence des noms d’interface

auto lo
iface lo inet loopback

auto br0
iface br0 inet static
    pre-up openvpn --mktun --dev tap0
    post-down openvpn --rmmtun --dev tap0
    bridge_hw 00:11:22:aa:bb:cc
    bridge_ports eth0 tap0
    address 192.168.1.2
    netmask 255.255.255.0
    gateway 192.168.1.1

Les interfaces impliquées dans le bridge (eth0, tap0) n’ont pas besoin d’être configurées dans ce fichier.
La directive bridge_hw permet de spécifier l’adresse MAC du bridge (qui sera constatée depuis le réseau, le routeur etc). Par souci de simplicité, je conseille de la fixer à la même valeur que la carte réseau physique (eth0 par exemple). Sinon, il me semble qu’elle prendra la première valeur “alphabétique” entre les différentes cartes réseau impliquées, et l’adresse de la carte tap0 peut varier d’un démarrage à l’autre.

Définition du fichier de conf du server

On peut récupérer le fichier d’exemple ainsi :

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

En voici une version minimaliste, à mettre dans /etc/openvpn/server/ :

port 1194
proto udp
dev tap0 # doit être en accord avec le fichier interfaces
ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/mon-serveur-vpn.crt
key /etc/openvpn/easy-rsa/pki/private/mon-server-vpn.key  # This file should be kept secret
dh /etc/openvpn/easy-rsa/pki/dh.pem
server-bridge
keepalive 10 120
cipher AES-256-CBC
compress lz4-v2
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
explicit-exit-notify 1

# Pour TLS
tls-auth /etc/openvpn/easy-rsa/pki/ta.key 0  #" 0 pour le server, 1 pour les clients
#auth SHA256  ## ???

On peut vérifier qu’il se lance bien via

openvpn /etc/openvpn/server/mon-server-vpn.conf

Si “Initialization Completed”, c’est gagné.

Rotation des logs

Dans la section précédente, on a défini /var/log/openvpn/openvpn.log comme chemin pour les journaux de connexion.
On peut le logrotater avec le fichier /etc/logrotate.d/openvpn qui contiendra ceci :

/var/log/openvpn/openvpn.log {
    missingok
    weekly
    compress
    rotate 8
}

Source

Activation du service (donc démarrage automatique) via systemd

systemctl enable openvpn-server@mon-server-vpn.service

Le nom entre @ et .service doit correspondre au nom du fichier de configuration.

Ajout du timestamp dans les logs

nano /etc/systemd/system/multi-user.target.wants/openvpn-server@mon-server-vpn.service
et supprimer --suppress-timestamps de la ligne ExecStart=

(même remarque que ci-dessus concernant le nom du fichier)

Client

Installer le client VPN souhaité selon la plateforme.
Le fichier de conf doit être en conformité avec le serveur.
Sous Windows, avec OpenVPN GUI, si on met les chemins complets, syntaxe de type :

"C:\\Users\\myuser\\OpenVPN\\ca.crt"

Si les fichiers sont dans le même dossier que la conf, on peut mettre simplement les noms de fichier.
Un fichier de conf client compatible avec le fichier de conf serveur ci-dessus :

client

# Adapter les noms de fichier
ca ca.crt
cert mon-pc-client.crt
key mon-pc-client.key

# Adapter l'IP/domaine et le port
remote example.com 1194

dev tap
proto udp
resolv-retry infinite
nobind
persist-key
persist-tun
cipher AES-256-CBC
compress lz4-v2
verb 3
tls-auth ta.key 1

Pour lancement auto via systemd :

systemctl enable openvpn-client@mon-pc-client.service

Révocation de certificat

cd /etc/openvpn/easy-rsa/
./easyrsa revoke mon-pc-client
./easyrsa gen-crl   ## Crée/update pki/crl.pem

## Ajouter le fichier dans la conf server
echo "crl-verify /etc/openvpn/easy-rsa/pki/crl.pem" >> /etc/openvpn/server/mon-server-vpn.conf

Puis restart le server ; la clé de mon-pc-client ne sera désormais plus acceptée.
Il faut relancer la commande ./easy-rsa gen-crl à chaque fois qu’un certificat est révoqué, pour mettre à jour le fichier crl.pem.

Attention : le CRL a aussi une durée d’expiration ! Elle peut être paramétrée dans le fichier vars. Pour la visualiser :
openssl crl -in pki/crl.pem -text | grep "Next Update"

Réactivation d’un certificat révoqué

Je n’ai pas trouvé de commande intégrée pour ce faire. Voici comment le faire à la main, bien que ça semble un peu hacky.

D’abord on trouve le serial correspondant au client à réactiver (ici, “monClientRevoque”) :
cd /etc/openvpn/easy-rsa && cat pki/index.txt | grep monClientRevoque qui donne un résultat de ce genre :
R 300956789123Z 200356789123Z 40FDF33486D24371D96668D056CBF883 unknown /CN=monClientRevoque

Il faut éditer ce fichier pour remplacer le R initial par un V, et supprimer le 3e champ (ici 200356789123Z) ; on a donc une ligne de ce genre :
V 300956789123Z 40FDF33486D24371D96668D056CBF883 unknown /CN=monClientRevoque
ATTENTION, il faut que le nombre de tabulations aligne correctement la ligne avec les autres lignes valides, sinon on aura des erreurs plus tard.

Puis on regénère le CRL avec la commande suivante :
./easy-rsa gen-crl

Le client devrait à nouveau avoir le droit de se connecter. Si on besoin de récupérer les fichiers du kit de connexion, ils sont disponibles dans ./pki/revoked/certs_by_serial, ./pki/revoked/private_by_serial et ./pki/revoked/reqs_by_serial et nommés en fonction du numéro de série (ici 40FDF33486D24371D96668D056CBF883).

Il est conseillé de replacer ces 3 fichiers à leurs emplacements initiaux (pki/issued/, pki/private/ et pki/reqs/), et avec le nom initial (monClientRevoque), pour éviter des erreurs si l’on souhaite révoquer à nouveau ce client.
Il y’aura toutefois un message d’impossibilité de supprimer le fichier dans pki/certs_by_serial/, mais ce message n’est pas bloquant.

Lister les clients connectés

cat /var/log/openvpn/openvpn-status.log | sed '/CLIENT_LIST/!d' | cut -d"," -f2 | sed '/CLIENT_LIST/d' | sort -d