{"id":115,"date":"2016-02-29T11:28:24","date_gmt":"2016-02-29T10:28:24","guid":{"rendered":"http:\/\/blog.vincentcharles.ovh\/?p=115"},"modified":"2018-03-15T11:09:57","modified_gmt":"2018-03-15T10:09:57","slug":"installer-un-serveur-openvpn","status":"publish","type":"post","link":"https:\/\/blog.vincentcharles.ovh\/index.php\/2016\/02\/29\/installer-un-serveur-openvpn\/","title":{"rendered":"Installer un serveur OpenVPN"},"content":{"rendered":"<p>Avoir un serveur bien s\u00e9curis\u00e9 c&rsquo;est bien mais communiquer avec lui en passant par un VPN c&rsquo;est encore mieux. Autre cas de figure : dans un lieu publique les connexions peuvent \u00eatre \u00e9cout\u00e9s&#8230; utiliser un VPN pour ensuite acc\u00e9der \u00e0 internet est la fa\u00e7on la plus propre pour prot\u00e9ger ses donn\u00e9es.<\/p>\n<p><!--more--><\/p>\n<p>Nous allons voir ici l&rsquo;installation du serveur OpenVPN (il existe d&rsquo;autres protocoles VPN, comme PPTP ou L2P) que je trouve extr\u00eamement performant et s\u00e9curis\u00e9.<\/p>\n<h2>L&rsquo;installation des paquets de base<\/h2>\n<p>L&rsquo;installation de base est assez simple. En fait, nous avons besoin de trois petites choses :<\/p>\n<ul>\n<li>Le serveur OpenVPN<\/li>\n<li>Le syst\u00e8me OpenSSL pour la g\u00e9n\u00e9ration des cl\u00e9s et certificats<\/li>\n<li>L&rsquo;ensemble de scripts Easy-RSA pour faciliter le d\u00e9ploiement des cl\u00e9s<\/li>\n<\/ul>\n<p>Pour cela, on proc\u00e8de (sous Debian par exemple) de la fa\u00e7on suivante :<\/p>\n<figure class=\"pc-legacy\"><pre><code class=\"language-bash\">apt-get install openssl openvpn easy-rsa<\/code><\/pre><\/figure>\n<p>Ensuite, nous allons cr\u00e9er nos dossiers de configuration dans \u00ab\u00a0<em>\/etc\/openvpn<\/em>\u00a0\u00bb puis copier l&rsquo;ensemble des scripts \u00ab\u00a0Easy-RSA\u00a0\u00bb \u00e0 l&#8217;emplacement voulu.<\/p>\n<figure class=\"pc-legacy\"><pre><code class=\"language-bash\">mkdir \/etc\/openvpn\/clientsconfig\nmkdir \/etc\/openvpn\/easy-rsa\nmkdir \/etc\/openvpn\/easy-rsa\/keys\ncp \/usr\/share\/easy-rsa\/* \/etc\/openvpn\/easy-rsa\/\ncd \/etc\/openvpn\/easy-rsa<\/code><\/pre><\/figure>\n<p>A cette \u00e9tape, nous avons pr\u00e9parer l&rsquo;arborescence du dossier de configuration d&rsquo;OpenVPN.<\/p>\n<h2>G\u00e9n\u00e9ration des certificats<\/h2>\n<p>Avant de lancer la g\u00e9n\u00e9ration des certificats, il faut configurer le fichier \u00ab\u00a0vars\u00a0\u00bb :<\/p>\n<figure class=\"pc-legacy\"><pre><code class=\"language-bash\">nano -w vars<\/code><\/pre><\/figure>\n<p>Dans ce fichier, personnaliser les entr\u00e9es \u00ab\u00a0KEY_{COUNTRY,PROVINCE,CITY,ORG,EMAIL,OU}\u00a0\u00bb comme bon vous semble. Ensuite, choisissez la taille des cl\u00e9s que vous souhaitez \u00ab\u00a0KEY_SIZE\u00a0\u00bb. Pour les gens normaux, 1024 bits, c&rsquo;est tr\u00e8s bien (mettre KEY_SIZE=1024). Pour les paranos, passer en 2048 bits (consid\u00e9r\u00e9 par la NSA comme inviolable). Attention toutefois, plus les cl\u00e9s sont grandes, plus la g\u00e9n\u00e9ration des certificats est longue et plus vous consommerez de CPU lors de l&rsquo;utilisation de votre tunnel (cl\u00e9 plus grande, plus de calcul pour d\u00e9coder les donn\u00e9es).<\/p>\n<p>Maintenant, on passe \u00e0 la g\u00e9n\u00e9ration des cl\u00e9s serveurs. On va en faire 3 principales :<\/p>\n<ul>\n<li>Certificat et cl\u00e9 permettant la g\u00e9n\u00e9ration des autres certificats (ca.crt)<\/li>\n<li>Certificat et cl\u00e9 du serveur (server.crt et server.key)<\/li>\n<li>Certificat Diffie-Hellman (dh1024.dem ou dh2048.dem). Perso je suis parano, alors 2048 bits.<\/li>\n<\/ul>\n<figure class=\"pc-legacy\"><pre><code class=\"language-bash\">source .\/vars\n.\/clean-all\n.\/build-dh\n.\/build-ca\n.\/build-key-server server<\/code><\/pre><\/figure>\n<p><em>PS : ne mettez pas de \u00ab\u00a0challange password\u00a0\u00bb pour les cl\u00e9s serveurs, sinon vous ne pourrez pas d\u00e9marrer ce dernier automatiquement puisqu&rsquo;il vous demandera la cl\u00e9 \u00e0 chaque lancement (attention donc en cas de reboot de la machine surtout si votre OpenVPN est la seul porte d&rsquo;entr\u00e9e de votre r\u00e9seau comme chez moi \ud83d\ude00 ).<\/em><\/p>\n<p>On r\u00e9alise ensuite une cl\u00e9 particuli\u00e8re pour initier les \u00e9changes entre client et serveur (s\u00e9curit\u00e9 suppl\u00e9mentaire) :<\/p>\n<figure class=\"pc-legacy\"><pre><code class=\"language-bash\">openvpn --genkey --secret keys\/ta.key<\/code><\/pre><\/figure>\n<p>On g\u00e9n\u00e8re nos cl\u00e9s clients (une cl\u00e9 par client) :<\/p>\n<figure class=\"pc-legacy\"><pre><code class=\"language-bash\">.\/build-key client\n# Vous pouvez changer le nom du client, mais cela modifiera \u00e9galement le nom du certificat et de la cl\u00e9.<\/code><\/pre><\/figure>\n<p>Voil\u00e0 \u00e0 ce stade, nous avons tout ce qu&rsquo;il nous faut pour faire fonctionner notre serveur de fa\u00e7on s\u00e9curis\u00e9. On passe \u00e0 la configuration du serveur lui m\u00eame et du client.<\/p>\n<h2>Configuration du serveur (server.conf)<\/h2>\n<p>Pour la configuration du serveur, on va commencer par rapatrier les cl\u00e9s et certificats utiles dans le dossier \/etc\/openvpn :<\/p>\n<figure class=\"pc-legacy\"><pre><code class=\"language-bash\">cd \/etc\/openvpn\/easy-rsa\/key\ncp ca.crt server.crt server.key ta.key dh2048.dem \/etc\/openvpn\n# On va en profiter aussi pour r\u00e9cup\u00e9rer les fichiers pour le client :\ncp ca.crt client.crt client.key ta.key dh2048.dem \/etc\/openvpn\/clientsconf<\/code><\/pre><\/figure>\n<p>Maintenant, on passe a la configuration du serveur, en cr\u00e9ant (ou \u00e9ditant) le fichier \u00ab\u00a0<em>server.conf<\/em>\u00a0\u00bb :<\/p>\n<figure class=\"pc-legacy\"><pre><code class=\"language-bash\">local 192.168.1.150\nport 443\nproto tcp\ndev tun\nca \/etc\/openvpn\/ca.crt\ncert \/etc\/openvpn\/server.crt\nkey \/etc\/openvpn\/server.key\ndh \/etc\/openvpn\/dh2048.pem\nserver 10.8.0.0 255.255.255.0\npush &quot;route 10.8.0.0 255.255.255.0&quot;\npush &quot;redirect-gateway def1 bypass-dhcp&quot;\npush &quot;dhcp-option DNS 8.8.8.8&quot;\npush &quot;dhcp-option DNS 8.8.4.4&quot;\nclient-to-client\nkeepalive 10 120\ncipher AES-256-CBC\nauth SHA512\ntls-cipher TLS-DHE-RSA-WITH-AES-256-CBC-SHA\ncomp-lzo\nmax-clients 10\nuser nobody\ngroup nogroup\npersist-key\npersist-tun\nstatus \/etc\/openvpn\/openvpn-status.log\nverb 3\nchroot \/etc\/openvpn\/jail<\/code><\/pre><\/figure>\n<p>Si on regarde de pr\u00e8s, on utilise toutes les s\u00e9curit\u00e9s disponibles sur OpenVPN. On va m\u00eame jusqu&rsquo;\u00e0 forcer le hachage des cl\u00e9s et les ciphers de cryptage (SHA512, AES-256-CBC&#8230;). Bref vous pourriez (ne le faite pas on est bien d&rsquo;accord) mettre tous vos num\u00e9ros de carte bleue, ya pas de probl\u00e8me avec le VPN.<\/p>\n<p>Pour lancer le serveur enfin :<\/p>\n<figure class=\"pc-legacy\"><pre><code class=\"language-bash\">openvpn --config \/etc\/openvpn\/server.conf\n# Pour un lancement automatique \nudpate-rc.d openvpn defaults\n# Et v\u00e9rifier que la configuration sera bien charg\u00e9 dans \/etc\/default\/openvpn\n# Ligne AUTOSTART=&quot;all&quot; decomment\u00e9e ou plus strict, une ligne AUTOSTART=&quot;server&quot; n&#039;autorisant QUE le fichier server.conf (ignorant les autres fichiers config s&#039;il y en a).<\/code><\/pre><\/figure>\n<p>Erratum : Je me rend compte que j&rsquo;ai inclus dans le fichier de configuration une \u00ab\u00a0jail\/prison\u00a0\u00bb pour bloquer l&rsquo;acc\u00e8s au syst\u00e8me depuis le VPN (encore une protection suppl\u00e9mentaire me direz-vous). Pour que cela fonctionne, il faut simplement faire ceci :<\/p>\n<figure class=\"pc-legacy\"><pre><code class=\"language-bash\">mkdir \/etc\/openvpn\/jail\nmkdir \/etc\/openvpn\/jail\/tmp\nmkdir \/etc\/openvpn\/jail\/dev\nchmod 755 \/etc\/openvpn\/jail -R<\/code><\/pre><\/figure>\n<h2>\u00c9changes de certificats avec les clients<\/h2>\n<p style=\"text-align: justify;\">Paragraphe tr\u00e8s important puisqu&rsquo;il r\u00e9capitule l&rsquo;ensemble des fichiers g\u00e9n\u00e9r\u00e9s (certificats et cl\u00e9s) et vous indique leur importance :<\/p>\n<ul style=\"text-align: justify;\">\n<li>Le certificat ca.crt doit \u00eatre pr\u00e9sent sur toutes les machines (serveur et clients)<\/li>\n<li>La cl\u00e9 associ\u00e9e ca.key doit rester secr\u00e8te. C&rsquo;est elle qui permet de crypter tous les autres certificats donc elle est capitale. Dans la mesure du possible, si vous ne souhaitez plus g\u00e9n\u00e9rer de cl\u00e9s apr\u00e8s l&rsquo;installation, d\u00e9placer la dans un lieu sur (hors du serveur).<\/li>\n<li>Le certificat dh2048.dem et le fichier cl\u00e9 ta.key doivent \u00eatre pr\u00e9sents sur toutes les machines.<\/li>\n<li>Le certificat du serveur (server.crt) est essentiel pour le serveur et doit \u00eatre accompagn\u00e9 de sa cl\u00e9 (server.key). Gardez au chaud les deux fichiers sur le serveur et particuli\u00e8rement la cl\u00e9 (server.key) qui est \u00e9galement secr\u00e8te.<\/li>\n<li>Le certificat du client et sa cl\u00e9 (client.crt \/ client.key) a mettre \u00e0 disposition du client.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Pour r\u00e9capituler, <strong>les fichiers secrets sont : ca.key \/ server.key \/ client.key<\/strong><br \/>\n<span style=\"text-decoration: underline;\">Les fichiers a garder sur le serveur : ca.crt \/ server.crt \/ server.key \/ ta.key \/ dh2048.dem<\/span><br \/>\n<span style=\"text-decoration: underline;\">Les fichiers a envoyer sur le client : ca.crt \/ client.crt \/ client.key \/ ta.key \/dh2048.dem<\/span><\/p>\n<h2>Configuration des clients<\/h2>\n<p>La configuration est aussi simple que pour le serveur :<\/p>\n<figure class=\"pc-legacy\"><pre><code class=\"language-bash\">client\nremote &lt;votre_IP_internet_serveur&gt; 443\nproto tcp\ndev tun\nresolv-retry infinite\nnobind\npersist-key\npersist-tun\nmute-replay-warnings\nns-cert-type server\nkey-direction 1\nca ca.crt\ncert client.crt\nkey client.key\ntls-auth ta.key 1\ncipher AES-256-CBC\nauth SHA512\ntls-cipher TLS-DHE-RSA-WITH-AES-256-CBC-SHA\ncomp-lzo\nverb 1\nmute 20<\/code><\/pre><\/figure>\n<h2>Autre : routage depuis le VPN vers Internet<\/h2>\n<p style=\"text-align: justify;\">La partie routage. La plus int\u00e9ressante non. En fait, pour faire communiquer l&rsquo;interface virtuelle (tun0 du tunnel) et l&rsquo;interface physique (eth0 dans mon cas), il faut utiliser quelques r\u00e8gles iptables. Je prends l&rsquo;exemple dans mon cas d&rsquo;une interface OpenVPN portant le nom <em>tun0<\/em>, ip\/masque : <em>10.8.0.0\/24<\/em> et d&rsquo;une interface physique (boucle locale chez moi) portant le nom <em>eth0<\/em>, ip\/masque : <em>192.168.1.0\/24.<\/em><\/p>\n<p>La r\u00e8gle est la suivante :<\/p>\n<figure class=\"pc-legacy\"><pre><code class=\"language-bash\">iptables -t nat -A POSTROUTING -s 10.8.0.0\/24 -o eth0 -j ACCEPT<\/code><\/pre><\/figure>\n<p>Il faut \u00e9galement activer l&rsquo;IP4.Forwarding :<\/p>\n<figure class=\"pc-legacy\"><pre><code class=\"language-bash\">nano -w \/etc\/sysctl.conf\n# Ajouter \u00e0 la fin :\nnet.ip4.ip_forward = 1\n# Sauvegarder et quitter le fichier\nsysctl -p\n# Normalement, cela vous r\u00e9-affiche la ligne ajouter au fichier.<\/code><\/pre><\/figure>\n<p style=\"text-align: justify;\">Si vous avez suivi \u00e0 la lettre mes instructions concernant le firewall (r\u00e8gles sur DROP pour l&rsquo;INPUT et l&rsquo;OUPUT), vous devez bien \u00e9videment ouvrir le port d&rsquo;\u00e9coute d&rsquo;OpenVPN (dans l&rsquo;exemple le TCP443 car c&rsquo;est le plus simple d&rsquo;acc\u00e8s depuis tous les hotspots [port HTTPS standard]) mais \u00e9galement permettre le forward des interfaces <em>tun0<\/em> vers <em>eth0<\/em> et inversement (car on peut consid\u00e9rer notre connexion OpenVPN comme fiable si vous ne partagez pas \u00e0 n\u2019importe qui vos certificats et cl\u00e9s) :<\/p>\n<figure class=\"pc-legacy\"><pre><code class=\"language-bash\">iptables -A INPUT -i tun+ -j ACCEPT\niptables -A OUTPUT -o tun+ -j ACCEPT\niptables -A FORWARD -i tun+ -j ACCEPT\niptables -A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT\niptables -A FORWAR -i eth0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT<\/code><\/pre><\/figure>\n<p>Voil\u00e0 c&rsquo;est pr\u00eat !<\/p>\n<p style=\"text-align: justify;\"><em>Remarque pour les plus <strong>hardcore<\/strong> d&rsquo;entre vous : maintenant que l&rsquo;on a un acc\u00e8s s\u00e9curis\u00e9 avec un VPN et des cl\u00e9s 2048 bits, on peut supprimer notre acc\u00e8s SSH depuis l&rsquo;ext\u00e9rieur et restreindre son acc\u00e8s que depuis la boucle locale (chez vous par exemple) ou depuis le VPN (c&rsquo;est \u00e0 dire dans notre cas, l&rsquo;interface tun0). Pour cela, on \u00e9dite simplement le fichier <strong>\/etc\/hosts.allow<\/strong> (on aurait pu modifier le fichier \/etc\/ssh\/sshd_config avec l&#8217;emplacement ListenAddress, mais c&rsquo;est compliqu\u00e9 \u00e0 faire alors ne tentez \u00e7a que si vous avez un acc\u00e8s physique \u00e0 la machine et un clavier\/\u00e9cran \u00e0 port\u00e9 de mains) :<\/em><\/p>\n<figure class=\"pc-legacy\"><pre><code class=\"language-bash\">sshd : 192.168.1. : allow\nsshd : 10.8.0. : allow\nsshd : ALL : deny<\/code><\/pre><\/figure>\n<p>Dans ce cas l\u00e0, vous autorisez toutes les IP de la plage 192.168.1.1 \u00e0 192.168.1.254 et toutes les IP de la plage 10.8.0.1 \u00e0 10.8.0.254 et vous refusez tout le reste.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Avoir un serveur bien s\u00e9curis\u00e9 c&rsquo;est bien mais communiquer avec lui en passant par un VPN c&rsquo;est encore mieux. Autre cas de figure : dans un lieu publique les connexions peuvent \u00eatre \u00e9cout\u00e9s&#8230; utiliser un VPN pour ensuite acc\u00e9der \u00e0 internet est la fa\u00e7on la plus propre pour prot\u00e9ger ses donn\u00e9es.<\/p>\n","protected":false},"author":1,"featured_media":306,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,10,25,2,11],"tags":[17],"class_list":["post-115","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorial_android","category-tutorial_linux","category-tutorial_server","category-tutorial","category-tutorial_windows","tag-niveau_moyen"],"_links":{"self":[{"href":"https:\/\/blog.vincentcharles.ovh\/index.php\/wp-json\/wp\/v2\/posts\/115","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.vincentcharles.ovh\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.vincentcharles.ovh\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.vincentcharles.ovh\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.vincentcharles.ovh\/index.php\/wp-json\/wp\/v2\/comments?post=115"}],"version-history":[{"count":8,"href":"https:\/\/blog.vincentcharles.ovh\/index.php\/wp-json\/wp\/v2\/posts\/115\/revisions"}],"predecessor-version":[{"id":206,"href":"https:\/\/blog.vincentcharles.ovh\/index.php\/wp-json\/wp\/v2\/posts\/115\/revisions\/206"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.vincentcharles.ovh\/index.php\/wp-json\/wp\/v2\/media\/306"}],"wp:attachment":[{"href":"https:\/\/blog.vincentcharles.ovh\/index.php\/wp-json\/wp\/v2\/media?parent=115"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.vincentcharles.ovh\/index.php\/wp-json\/wp\/v2\/categories?post=115"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.vincentcharles.ovh\/index.php\/wp-json\/wp\/v2\/tags?post=115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}