Blog of :/blog/VPN_d'entreprise_avec_Debian_+_OpenVPN_+_BIND.html

VPN d'entreprise avec Debian + OpenVPN + BIND

Introduction

L'idée est de créer un LAN virtuel pour les salariés, avec un sous-domaine dédié, et des services qui écoutent uniquement sur cette interface.

Pour ce faire, on se repose sur les briques suivantes :

  • Debian Jessie
  • OpenVPN 2.3
  • BIND 9.8

Nous supposerons que le nom de domaine de l'entreprise est example.com, et que le sous-domaine associé aux services internes est lan.example.com.
Le sous-réseau dédié au VPN sera quant à lui 10.22.33.0/24.

Nous allons également faire rediriger tout le trafic de nos utilisateurs via le VPN, afin de sécuriser le réseau local où l'on peut facilement intercepter les paquets.

OpenVPN

Commençons par l'installation d'OpenVPN :

# apt-get install openvpn easy-rsa

PKI

Pour créer la PKI contenant les certificats qui seront dédiés au serveur VPN, on utilise la commande suivante :

# make-cadir /etc/openvpn/ssl

On peut se déplacer dans ce répertoire, et éditer les paramètres KEY_* du fichier vars pour configurer les valeurs par défaut des certificats :

# cd /etc/openvpn/ssl
# vi vars
[...]
export KEY_COUNTRY="FR"
export KEY_PROVINCE="Ile-de-France"
export KEY_CITY="Paris"
export KEY_ORG="Example Organization"
export KEY_EMAIL="admin@example.com"
export KEY_OU="Example LAN"
[...]

On peut maintenant procéder à l'initialisation de la PKI, à la création de la CA, ainsi que du certificat du serveur :

# source ./vars
# ./clean-all
# ./build-dh
# ./build-ca
[...]
# ./build-key-server vpn.example.com
[...]

Lors du prompt des créations de clefs, vous pouvez laisser les valeurs par défaut. Il n'est pas nécessaire de mettre de Challenge Password.

Pour chaque membre du VPN, il sera nécessaire de créer un certificat de cette manière :

# ./build-key employee_name.lan.example.com

Vous pouvez également demander à vos utilisateurs d'envoyer un CSR que vous pouvez vous contenter de signer.

Une fois les certificats générés, ils se retrouvent dans keys/. Il vous faudra transmettre ca.crt ainsi que la clef et le certificat généré à chacun de vos utilisateurs.

Configuration serveur

Créez le fichier /etc/openvpn/server.conf pour y mettre les lignes suivantes :

local 0.0.0.0
proto tcp
dev tun

ca /etc/openvpn/ssl/keys/ca.crt
cert /etc/openvpn/ssl/keys/vpn.example.com.crt
key /etc/openvpn/ssl/keys/vpn.example.com.key
dh /etc/openvpn/ssl/keys/dh1024.pem

server 10.22.33.0 255.255.255.0
ifconfig-pool-persist ipp.txt

keepalive 10 60

persist-key
persist-remote-ip
persist-local-ip
comp-lzo

# Autorise la communication entre les clients
client-to-client

# Indique aux clients d'utiliser ce serveur
# DNS par défaut
push "dhcp-option DNS 10.22.33.1"
push "dhcp-option DOMAIN lan.budget-insight.com"

Activez ip_forward pour rediriger le trafic :

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

Comme vos utilisateurs vont utiliser le VPN comme route par défaut pour sortir sur Internet, vous devez créer les règles iptables suivantes :

# iptables -t nat -I POSTROUTING -s 10.22.33.0/24 -j MASQUERADE
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Vous pouvez maintenant lancer le serveur VPN :

# /etc/init.d/openvpn start

Configuration client

Le client doit installer les paquets suivants :

# apt-get install openvpn resolvconf

Une fois que vos utilisateurs ont mis la CA, la clef et le certificat dans /etc/openvpn/ssl/, ils doivent écrire le fichier /etc/openvpn/client.conf suivant :

client

dev tun
proto tcp

remote vpn.example.com 1194

resolv-retry infinite

nobind

persist-key
persist-tun

ca certs/ca.crt
cert certs/employee_name.lan.example.com.crt
key certs/employee_name.lan.example.com.key

ns-cert-type server
comp-lzo
verb 3

# Utilise le VPN comme route par défaut
redirect-gateway def1

# Active la redéfinition du serveur DNS à utiliser
script-security 3 execve
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

Il ne reste plus qu'à lancer le VPN :

# /etc/init.d/openvpn start

BIND

Maintenant le VPN en place, on veut pouvoir configurer BIND pour être à la fois un serveur DNS interne au réseau, un relai pour les utilisateurs, et un serveur d'autorité pour le nom de domaine sur Internet.

Éditons les fichiers de configuration de /etc/bind/ :

named.conf.options

options {
    directory "/var/cache/bind";

    forwarders {
        // Utilisation des serveurs DNS de Google pour
        // relayer les requêtes DNS faites depuis le LAN
        8.8.8.8;
        8.8.4.4;
    };

    auth-nxdomain no;    // conform to RFC1035
    listen-on { any; };
    listen-on-v6 { any; };
    allow-recursion {
        10.22.33.0/24;
        localhost;
        ::1;
        127.0.0.1;
    };

    // Serveur DNS secondaire du domaine example.com
    allow-transfer { 213.186.33.199; };
};

named.conf.local

view "internal" {
    match-clients {
        10.22.33.0/24;
        127.0.0.1;
    };
    recursion yes;

    zone "example.com" {
            type master;
            file "/etc/bind/zone/example.com.lan";
            allow-transfer { any; };
    };
};

view "external" {
    match-clients { any; };
    recursion no;

    include "/etc/bind/named.conf.default-zones";

    zone "example.com" {
            type master;
            file "/etc/bind/zone/example.com";
            notify yes;
            // Serveur DNS secondaire
            notify-source 213.186.33.199;
    };
};

Le système de vues de BIND permet de définir des typologies de clients. On a d'une part les clients internes qui, pour le domaine example.com, vont avoir une zone dédiée, et pour qui les requêtes sur les autres domaines vont être forwardées, et les clients externes qui ne peuvent requêter que sur les domaines de l'entreprise.

zone/example.com

$TTL 12H
@       IN   SOA   example.com.  admin.example.com. (
                           2014022101
                           8H
                           30M
                           4W
                           8H )

        IN   NS    ns.example.com.
             NS    ns.kimsufi.com.

        IN   MX    10 mail.example.com.
        IN   MX    20 mail.symlink.me.

@       IN   A     88.11.22.33
mail    IN   A     88.11.22.33
ns      IN   A     88.11.22.33
www     IN   A     88.11.22.33
vpn     IN   A     88.11.22.33

$ORIGIN example.com.

zone/example.com.lan

$TTL 12H
@       IN   SOA   example.com.  admin.example.com. (
                           2014022101
                           8H
                           30M
                           4W
                           8H )

        IN   NS    ns.example.com.
             NS    ns.kimsufi.com.

        IN   MX    10 mail.example.com.
        IN   MX    20 mail.symlink.me.

@       IN   A     10.22.33.1
mail    IN   A     10.22.33.1
ns      IN   A     10.22.33.1
www     IN   A     10.22.33.1
vpn     IN   A     10.22.33.1

git.lan         IN   A   10.22.33.1
projects.lan    IN   A   10.22.33.2

romain.lan      IN   A   10.22.33.6
simon.lan       IN   A   10.22.33.10
vincent.lan     IN   A   10.22.33.14

$ORIGIN example.com.

Il ne reste plus qu'à relancer bind…

# /etc/init.d/bind9 restart

Apache

Petit extra, si vous souhaitez configurer certains vhosts apache pour n'écouter que sur le VPN, vous devez d'une part définir le NameVirtualHost suivant 

NameVirtualHost 10.22.33.1:80

Ensuite, la déclaration du vhost se fait comme suit :

<VirtualHost 10.22.33.1:80>
    ServerName git.lan.example.com

    # ...
</VirtualHost>

Sachez que pour les vhosts que vous souhaitez voir écouter sur les deux interfaces, vous allez devoir faire quelque chose qui semble redondant :

<VirtualHost *:80 10.22.33.1:80>
    ServerName www.example.com

    # ...
</VirtualHost>