Voici un petit tutoriel que je souhaite faire depuis plusieurs mois concernant l’installation d’un serveur OpenVPN sur un serveur GNU/Linux Debian, finalement je profite de l’installation que je réalise dans le cadre de l’association Proxgroup ainsi que la migration de mon serveur chez OVH pour écrire ce petit tutoriel, j’espère qui vous sera utile.

Préparation

Installation des paquets Debian :

apt-get update
apt-get install openvpn

Installer ZIP si vous utilisez mes scripts à la fin du tutoriel :

apt-get install zip

Configuration du serveur

Pour le serveur, nous allons utiliser le port TCP 443, cela permet de passer outre la plupart des pares-feu puisqu’il utilise le même port que HTTPS.

Voici le fichier de configuration du serveur (Changez les lignes en surbrillance) :

# Serveur TCP/443
mode server
proto tcp-server
port 443
dev tun

# Clés certificats
crl-verify crl.pem
ca         keys/ca.crt
cert       keys/vpn.safranil.fr.crt # Remplacer par votre certificat
key        keys/vpn.safranil.fr.key # Remplacer par votre certificat
dh         keys/dh2048.pem # Remplacer le nombre par la taille de votre clé
tls-auth   keys/ta.key 0
key-direction 0
cipher AES-256-CBC

# Réseau
server 10.250.0.0 255.255.255.0 # IP à assigner aux clients
push "redirect-gateway def1" # Utiliser le VPN comme routeur par défaut
#push "route 10.0.0.0 255.255.255.0" # Utiliser le VPN pour ce connecter au réseau 10.0.0.0/24
push "dhcp-option DNS 8.8.8.8" # Serveurs DNS
push "dhcp-option DNS 8.8.4.4"
keepalive 10 120
ifconfig-pool-persist ipp.txt # Persistance des adresses IP
client-to-client # Autoriser la connexion entre machines du VPN
push "route 10.250.0.0 255.255.255.0" # Autoriser la connexion entre machines du VPN
duplicate-cn # Autorise de multiples connexions pour un certificat
max-clients 100 # Nombre maximum de clients VPN

# Sécurité
user nobody
group nogroup
chroot /etc/openvpn/jail
persist-key
persist-tun
comp-lzo # Compression de la connexion

# Log
verb 3
mute 20
status /var/log/openvpn-status.log
log-append /var/log/openvpn.log

On créer la cage pour le démon OpenVPN, voir l’option chroot ci-dessus :

mkdir /etc/openvpn/jail

Configuration du réseau

On active le forwarding sur le serveur :

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "1" > /proc/sys/net/ipv4/ip_forward

On ajoute les règles permettant aux utilisateurs du VPN de sortir sur Internet dans un fichier init. N’oubliez pas de changer a.dre.sse.ip par l’adresse IP de votre serveur VPN et 10.0.0.0/24 par votre plage d’adresse IP :

#! /bin/sh
### BEGIN INIT INFO
# Provides:          vpnpostrouting
# Required-Start:    
# Required-Stop:     
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Network Postrouting
# Description:       Network Postrouting for internal/VPN IP addresses
### END INIT INFO

SCRIPTNAME=/etc/init.d/vpnpostrouting

do_start()
{
        /sbin/iptables -t nat -I POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
        /sbin/iptables -t nat -I POSTROUTING -s 10.0.0.0/24 -o eth0 -j SNAT --to a.dre.sse.ip
}

do_stop()
{
        /sbin/iptables -t nat -D POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
        /sbin/iptables -t nat -D POSTROUTING -s 10.0.0.0/24 -o eth0 -j SNAT --to a.dre.sse.ip
}

case "$1" in
  start)
        echo "Starting Network Postrouting"
        do_start
        ;;
  stop)
        echo "Stopping Network Postrouting"
        do_stop
        ;;
  restart|force-reload)
        echo "Restarting Network Postrouting"
        do_stop
        do_start
        ;;
  *)
        echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
        exit 3
        ;;
esac

On ajoute les droits d’exécution au script ainsi que le lancement automatique lors du démarrage de la machine :

chmod ugo+x /etc/init.d/vpnpostrouting
update-rc.d vpnpostrouting defaults

Création des certificats serveur

Information : La génération de certificats et clés privés peu prendre du temps, beaucoup de temps, si votre /dev/random ne génère pas suffisamment de données aléatoires, je vous invite à installer le démon Haveged permettant de remplir le /dev/random à partir de la latence du processeur, pour plus d’informations à ce sujet, je vous invite à lire l’excellent article de Digital Ocean : https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged

On copie le répertoire contenant tous les executables pour la génération des certificats clients et serveur :

cp /usr/share/doc/openvpn/examples/easy-rsa/2.0 ./easy-rsa -Rf

On prépare l’environement pour générer les certificats, cela doit être fait à chaque séance de génération de certificats, vous pouvez modifier le fichier vars afin de placer vos paramêtres personnels :

source ./vars

On efface tous les certificats précédément générés (utile uniquement si vous avez déjà généré des certificats et que vous générez de nouvelles clé pour le serveur) :

./clean-all

Création du certificat racine, il servira à signer tous les certificats par la suite :

./build-ca

On génére le certificat pour le serveur :

./build-key-server $KEY_CN

On génére la clé Diffie-Hellman afin de sécuriser les échanges de clé entre le client et le serveur VPN :

./build-dh

On génére la clé secrète afin de sécuriser les échanges de clé entre le client et le serveur VPN :

openvpn --genkey --secret keys/ta.key

Création de la liste de révocation des certificats :

openssl ca -gencrl -out keys/crl.pem -config "$KEY_CONFIG"

Voilà pour la parti configuration du serveur, il ne reste plus qu’à copier le dossier keys dans /etc/openvpn et de copier le fichier keys/crl.pem dans /etc/openvpn/jail.

Création des certificats clients

Passont maintenant à la création du / des certificats pour les clients.

Si ce n’est pas déjà fait, on prépare l’environement pour générer les certificats, vous pourvez modifier le fichier vars afin de placer vos paramêtres personnels :

source ./vars

On génére le certificat du client (remplacez <NOM> par le nom de votre client) :

./build-key >NOM<

Il ne reste plus qu’à copier le dossier keys dans /etc/openvpn afin que le serveur OpenVPN reconnaisse notre nouveau client (n’oubliez de recharger le serveur pour que les nouveaux certificats soit correctement lus par OpenVPN).

Il faut ensuite installer sur le client les fichiers suivants (remplacez <NOM> par le nom de votre client) :

  • <NOM>.key
  • <NOM>.crt
  • ca.crt
  • ta.crt

Ainsi que le fichier de configuration du client dont voici un exemple :

client
dev tun
proto tcp-client
remote <ADRESSE_SERVEUR> 443
resolv-retry infinite
cipher AES-256-CBC
ca ca.crt
cert <NOM>.crt
key <NOM>.key
tls-auth ta.key 1
remote-cert-tls server
key-direction 1
nobind
persist-key
persist-tun
comp-lzo
verb 3

Ce fichier doit être enregistré en .conf pour Linux et en .ovpn pour Windows.

Révocation des certificats

Pour révoquer un certificat, rien de plus simple (remplacez <NOM> par le nom de votre client) :

./revoke-full <NOM>

Les scripts qui font tout tout seuls ^^

Je vous propose en bonus 4 petits scripts qui vous feront toute la besogne, comme ça, plus besoin de chercher les commandes à exécuter 😛 .

Télécharger les scripts au format ZIP (3 Ko) ou au format TAR (7 Ko)

Si vous avez des questions, commentaires, suggestions, laissez un commentaire ou envoyez moi un tweet à @Safranil.

Il y a peu de temps, j’ai eu un souci d’espace disque sur un serveur et j’ai effacé les fichiers incriminés. Jusque là, tout va bien, la commande du m’affiche un répertoire avec quelques gigaoctet en moins sauf que la commande df m’indique toujours que l’espace est occupé. Après quelques recherches sur Internet, il s’avère que si un fichier ouvert par un processus est effacé, le fichier est encore compté dans l’espace disque utilisé, voici la commande qui permet de voir les processus qui ont des pointeurs de fichiers effacés encore ouvert :

lsof | grep "(deleted)"

Ou celle-ci pour voir les processus par rapport à un répertoire :

lsof | grep "(deleted)" | grep "/tmp"

Un petit coup de kill -15 pour arrêter proprement le processus ou kill -9 s’il ne veut pas abandonner son exécution.

Voilà, problème assez surprenant lorsque on le découvre pour la première fois ;-).

Source photographique : https://www.flickr.com/photos/104908187@N06/10185681264 Licence CC-BY 2.0

Voici un petit tutoriel (mon premier d’ailleurs) sur la mise en place de notification Zabbix via l’application Telegram.

Compilation de Telegram

Il existe une version de Telegram pour linux en ligne de commande, le projet hébergé sur GitHub se nomme Telegram messenger CLI, pour cette partie, il suffit de suivre simplement le tutoriel pour la compilation, pour ma part, je vais détailler les étapes pour une GNU/Debian car mon serveur Zabbix est dessus.

1. Commençons par installer les paquets nécessaire à la compilation :

sudo apt-get install git libreadline-dev libconfig-dev libssl-dev lua5.2 liblua5.2-dev libevent-dev make

2. Puis créer le répertoire utilisateur de Zabbix s’il n’est pas créé par défaut :

mkdir /var/lib/zabbix
chown zabbix:zabbix /var/lib/zabbix

3. On prend ensuite l’identité de Zabbix pour la suite des événements :

sudo su zabbix
cd ~

4. On récupère les sources de Telegram CLI et on compile :

git clone --recursive https://github.com/vysheng/tg.git
cd tg
./configure
make

5. On copie les certificats dans le /etc/ (en Root)

mkdir /etc/telegram-cli
cp *.pub /etc/telegram-cli/
chmod 755 /etc/telegram-cli
chmod 644 /etc/telegram-cli/*

À ce point, nous avons compilé Telegram et il ne reste plus qu’a le configurer correctement.

Configuration

Tout d’abord, nous allons créer un compte Telegram dédié à Zabbix pour qu’il puisse envoyer des messages aux groupes et autres utilisateurs, pour cela, je vous invite à utiliser l’interface Web de Telegram, cela va nous permettre de choisir un nom à afficher ainsi que son avatar.

1. On commence par prendre l’identité de Zabbix :

sudo su zabbix
cd ~/tg

2. On lance Telegram pour la première fois :

bin/telegram-cli -k /etc/telegram-cli/tg-server.pub -D

On attends quelques secondes et l’application nous demande un numéro de téléphone et le code de sécurité, entrez ces informations et saisissez la commande safe_quit

Voila, Telegram est prêt pour l’envoi de nos alertes, passons à la configuration de Zabbix.

Configuration de Zabbix

Voici le script permettant l’envoi de message stocké dans le fichier /usr/lib/zabbix/alertscripts/telegram.sh

#!/bin/bash
# Send Zabbix notification through Telegram
# Copyright (C) 2015 David Cachau
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

export to=$1;
export subject=$2;
export body=$3;

cd /var/lib/zabbix/tg;
nohup bin/telegram-cli -p /var/lib/zabbix/.telegram-cli -c /var/lib/zabbix/.telegram-cli/config -k /etc/telegram-cli/tg-server.pub -vv -REDNW -e "msg $to \"$subject \n $body\"" >> /dev/null 2>&1 &

N’oublions pas de donner le droit d’exécution sur ce fichier :

chmod 755 /usr/lib/zabbix/alertscripts/telegram.sh
chown zabbix:zabbix /usr/lib/zabbix/alertscripts/telegram.sh

Une petite explication sur la commande s’impose : J’ai dû tricher un peu avec la commande nohup car Zabbix envoyai un SIGTERM/SIGINT à mon script, cela empêchai l’envoi correct des messages.

Enfin, créons le Media Type :

Ajouter un Media Type

Et l’action associée :

Ajouté une actions > Action

Voici le contenu des champs :
❌ {HOST.NAME}
✅ {HOST.NAME}
{TRIGGER.NAME}

Ajouté une action > Conditions

Ajouté une actions > Opérations

 Ajouté une actions > Opérations > Ajouter une opération

Il ne reste plus qu’à tester le fonctionnement et le tour est joué.

N’hésitez pas à apporter vos modifications à ce script, n’hésitez pas à commenter ou apporter des suggestions.

Petit post-it pour générer les clés SSH.

ssh-keygen -t dsa -C 'Safranil' -f fichier

Note : le -C permet de choisir le commentaire associé à la clé SSH, par défaut c’est utilisateur@machine, ici j’ai choisi mon pseudonyme.

Pour ce connecter avec la clé privée à un serveur :

ssh -i sshkey utilisateur@machine.domaine.tld

J’ai développé un petit script en Bash afin de migrer les adresses IP dans les fichiers de configuration donnés, il est utile lors d’une migration de serveur / VM où il n’est pas possible de préserver l’ip.

Le script offre aussi la possibilité de sauvegarder les fichiers dans une archive Tar avant de faire les modifications et peut ajouter automatiquement les fichiers de configurations de Apache et Bind ou de n’importe quel répertoire donné.

Le script est disponible sous licence GPL à cette adresse https://git.safranil.fr/safranil/script/blob/master/migrateip.bash.

Si vous avez des soucis ou des améliorations à proposer, vous pouvez laisser un commentaire.

Source photographique : https://www.flickr.com/photos/camknows/4712191684