Sommaire
Pour sécuriser votre Constellation vous devez utilise le protocole HTTPS afin de chiffrer toutes les communications en SSL.
Si vous avez un serveur Windows, vous pouvez également utiliser IIS pour configurer un reverse proxy vers Constellation.
Dans cet article nous allons découvrir comment exposer le serveur Constellation derrière un serveur Nginx protégé avec un certificat SSL Let’s Encrypt.
Prérequis : avoir une Constellation exposée publiquement avec un nom DNS
Avant de démarrer vous devez avoir un serveur Constellation opérationel.
Si vous installez Constellation sur un Linux, cela se résume à lancer la commande ci-dessous et à suivre l’assistant :
1 |
wget -O install.sh https://developer.myconstellation.io/download/installers/install-linux.sh && chmod +x install.sh && ./install.sh |
Pour plus d’information, veuillez suivre le guide : Installer Constellation sur Linux.
On considéra à ce stade que votre serveur Constellation est démarré et opérationnel. Vous pouvez lancer la commande suivante pour vérifier le statut des services Constellation :
1 |
sudo supervisorctl status |
Vous devriez voir le “constellation-server” avec le statut “RUNNING” (et la sentinelle si déployée) :
1 2 3 |
sebastien@ubuntu:~$ sudo supervisorctl status constellation-sentinel RUNNING pid 1194, uptime 1 day, 17:36:48 constellation-server RUNNING pid 2888, uptime 1 day, 15:06:41 |
Vous pouvez également installer Constellation sur un système Windows (voir le guide).
En effet, le reverse proxy (ici Ngnix) qui sera installé sur un système Linux peut exposer un service tel que Constellation quelque soit le serveur sur lequel il est déployé. Le reverse proxy n’est pas nécessairement sur la même machine sur le ou les services à exposer.
Il est donc possible d’installer un serveur Linux avec Nginx pour exposer en SSL un serveur Constellation sur un système Windows de la même manière que nous pouvons installer un serveur Windows avec IIS pour exposer en SSL un serveur Constellation sur un système Linux !
Dans ce guide nous avons installer le serveur Constellation et le reverse proxy Nginx sur le même serveur, sous Linux Ubuntu 16.
Si vous souhaitez activer le HTTPS et donc ajouter un certificat SSL, vous devez nécessairement avoir un nom DNS qui pointe vers l’adresse IP (public) de votre serveur de reverse proxy.
Plusieurs options s’offre à vous :
- Si vous avez un nom de domaine, modifiez votre zone DNS pour ajouter un “host” (enregistrement A ou AAAA) vers l’adresse IP (public) de votre Constellation.
- SI vous n’avez pas de nom de domaine :
- Achetez-en un ! Comptez environ 15€/an pour les extensions standards (.fr, .net, .com), 2,99€ HT par an pour un .ovh
- Utilisez un service de “Dynamic DNS” comme dyndns.fr, dyn.com ou autre
- Certains FAI comme Free proposent d’attacher un nom DNS type xxxx.hd.free.fr à votre IP de connexion
- Certains NAS comme Synology permettent aussi de créer un DDNS type xxx.synology.me vers votre IP de connexion
Dans le cas présent, j’ai crée l’entrée DNS “demo.internal.myconstellation.io” qui pointe vers l’adresse IP public du serveur Constellation installé sur un Ubuntu (le DNS doit pointer votre le serveur où sera installé le reverse proxy dans la mesure où tout passera par lui. Etant donné que le reverse proxy sera sur le même serveur que le service Constellation on peut dire que le DNS pointe vers le serveur Constellation).
Bien évidement, si votre serveur est installé dernière un routeur avec du NAT (typiquement sur un réseau local derrière une box Internet) vous devez configurer la redirection de port sur votre routeur/box internet.
Encore une fois, on part du principe que le serveur de R.P et Constellation sont sur le même serveur, donc la même IP interne.
Dans un premier temps redirigez seulement le port 8088 en tcp sur l’IP interne de votre serveur Constellation. A noter que nous supprimerons cette redirection une fois le reverse proxy installé.
Donc pour résumer et avant de démarrer, vous devez avoir votre serveur Constellation démarré répondant sur l’URL : http://<mon_nom_dns>:8088
Dans mon cas : http://demo.internal.myconstellation.io:8088 :
Voilà vous êtes prêt, votre Constellation est démarrée et elle répond bien sur un nom DNS public depuis l’internet.
Exposer Constellation derrière Nginx
Avant de démarrer il est recommandé de mettre à jour le référentiel du gestionnaire de package par la commande suivante :
1 |
sudo apt-get update |
Ensuite installez le serveur Web Nginx avec la commande :
1 |
sudo apt-get install nginx |
Les fichiers de configuration sont situés dans le répertoire “/etc/nginx/sites-available/” et pour les activer on crée un lien symbolique vers ces fichiers dans le répertoire “/etc/nginx/sites-enabled”.
Pour commencer désactivez la configuration par défaut par la commande ci-dessous :
1 |
sudo rm /etc/nginx/sites-enabled/default |
Comme vous l’aurez compris le contenu de cette configuration par défaut est toujours présente dans le répertoire “/etc/nginx/sites-available/” mais non activée car on a supprimé le lien symbolique vers ce fichier dans le répertoire “site-enabled”.
Maintenant nous allons créer une configuration pour notre reverse proxy avec la commande :
1 |
sudo nano /etc/nginx/sites-available/constellation |
Dans ce fichier, copiez le contenu suivant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
server { listen 80; listen [::]:80; server_name demo.internal.myconstellation.io; location / { proxy_pass http://localhost:8088; set $content_length_safe $http_content_length; if ($content_length_safe = "") { set $content_length_safe 0; } proxy_set_header Content-Length $content_length_safe; proxy_set_header Host $host; proxy_set_header Connection ""; proxy_http_version 1.1; proxy_buffering off; proxy_cache off; proxy_connect_timeout 30; proxy_send_timeout 30; proxy_read_timeout 150; } } |
Vous devez modifier le paramètre “server_name” avec le nom DNS de votre serveur Constellation, dans le cas présent “demo.internal.myconstellation.io”.
Il est important de bien reprendre les mêmes options, notamment le “proxy_buffering” pour permettre les “server-Sent events” vers le serveur Constellation.
Dans le cas présent Nginx va « proxifer » les requêtes vers http://localhost:8088, c’est à dire au service Constellation (port 8088) installé sur le même serveur (localhost).
Tapez ensuite sur la combinaison de touches “Ctrl+X” pour quitter en prenant suivant d’enregistrer le fichier. Puis, pour activer cette configuration, créez le lien symbolique suivant :
1 |
sudo ln -s /etc/nginx/sites-available/constellation /etc/nginx/sites-enabled/constellation |
Avant de redémarrer Nginx, éditez le fichier de configuration global pour augmenter la taille maximale des requêtes entrantes afin de pouvoir uploader des packages Constellation sur le serveur (par défaut cette taille est fixée à 1Mo, autrement dit vous obtiendrez une erreur 413 « Request Entity Too Large » si vous tentez d’uploader un package de plus de 1Mo).
1 |
sudo nano /etc/nginx/nginx.conf |
Sous la section « http », ajoutez l’option « client_max_body_size » (ou si l’option existe déjà, modifiez sa valeur) que nous fixerons à 100 Méga :
1 |
client_max_body_size 100M; |
Pour finir, rechargez Nginx afin prendre en compte notre nouvelle configuration :
1 |
sudo systemctl reload nginx |
Votre Constellation est maintenant accessible derrière Nginx sur le port 80.
Rendez-vous donc sur l’adresse http://<votre_nom_dns> (sans spécifier le port, car 80 par défaut) pour vérifier que le reverse proxy est opérationnel. Dans le cas présent http://demo.internal.myconstellation.io
Ce n’est donc plus Constellation qui répond mais notre serveur Nginx qui lui même communique avec le serveur Constellation local.
Donc pour résumer, sur le port 80 c’est le serveur Nginx qui répond en transférant au serveur Constellation sur le port 8088.
Note : si vous êtes dernière un routeur avec du NAT, n’oubliez pas d’ajouter la redirection du port 80 vers votre serveur Constellation interne. Par la même occasion vous pouvez supprimer la redirection du port 8088, ainsi tout passera nécessairement par Nginx.
Activer le HTTPS avec des certificats SSL Let’s Encrypt
Maintenant que votre service Constellation est exposé dernière le serveur Nginx vous allez pouvoir configurer différentes choses sur Nginx comme par exemple des restrictions d’accès , l’authentification, des limites (throttling) et bien d’autre chose. Dans le cas présent on va s’intéresser au support du SSL.
Pour activer le HTTPS, il vous faut un certificat SSL. Pour simplifier la démarche, Let’s Encrypt est une autorité de certification lancée en 2015 qui permet d’automatiser la génération de certificat. De plus le service est gratuit ! Les certificats sont valides trois mois, il faudra donc régulièrement les renouveler mais vous allez voir que cette action est entièrement automatisable.
Ici nous allons utiliser Certbot, un agent installé sur le serveur qui permet de générer et renouveler automatiquement les certificats SSL Let’s Encrypt.
Commencez par ajouter le repository suivant :
1 2 |
sudo add-apt-repository ppa:certbot/certbot sudo apt-get update |
Ensuite installez Certbot pour Nginx :
1 |
sudo apt-get install python-certbot-nginx |
Une fois installé, lancez la commande “certbot –nginx” en spécifiant le nom DNS vers votre serveur. Dans le cas présent :
1 |
sudo certbot --nginx -d demo.internal.myconstellation.io |
L’assistant vous demandera tout d’abord votre adresse mail :
Après avoir accepté les conditions du service, l’assistant va automatiquement valider un challenge en interrogeant votre site Web (d’où la nécessité d’avoir exposé correctement votre serveur sur Internet avec le nom DNS spécifié), créer le certificat SSL et l’ajouter dans votre configuration Nginx.
Pour finir l’assistant vous proposera de modifier automatiquement la configuration de votre Nginx pour rediriger tous les appels HTTP (port 80) vers HTTPS (port 443).
Choisissiez l’option 2 pour activer cette redirection.
Et voilà, votre serveur Nginx est configuré avec le certificat SSL généré par Let’s Encrypt et toutes les requêtes seront redirigés en HTTPS et donc chiffrés !
Votre Constellation est maintenant protégée !
Rechargez la page dans votre navigateur (F5) sur l’URL http://<mon_nom_dns> vous constaterez la redirection automatique en https:// et le cadenas vert vous informant du chiffrement SSL :
(Note : pour les personnes derrières un NAT, n’oubliez pas non plus d’ajouter la redirection du port 443 vers votre serveur Nginx interne)
Pour vérifier le bon renouvellement du certificat vous pouvez utiliser la commande suivante :
1 |
sudo certbot renew --dry-run |
Certbot a automatiquement installé un trigger dans systemd (ou crontab selon le système) pour réaliser le renouvellement et déploiement automatique de vos certificats avant leurs expirations.
Pour les plus curieux, vous pouvez jeter un œil dans le fichier “/etc/nginx/sites-available/constellation” pour voir les modifications apportées par Certbot.
Pour aller plus loin
Sécuriser le serveur avec un firewall UFW et fail2ban
Installer fail2ban
Fail2ban est un script tournant en tâche de fond qui va vérifier si les tentatives d’authentification SSH et Nginx; et en cas d’attaque, bannir l’IP grâce à iptables
.
1 |
sudo apt-get install fail2ban |
Pour plus d’info: https://www.digitalocean.com/community/tutorials/how-to-protect-an-nginx-server-with-fail2ban-on-ubuntu-14-04
Installer UFW
UFW est un firewall applicatif. Pour l’installer :
1 |
sudo apt-get install ufw |
Autorisez ensuite les services HTTP (nécessaire pour le challenge Let’s Encrypt), HTTPS (notre reverse proxy Nginx vers Constellation) et SSH :
1 2 3 |
sudo ufw allow http sudo ufw allow https sudo ufw allow ssh |
Pour l’activer :
1 |
sudo ufw enable |
Votre serveur Linux ne répondra plus que sur les ports 22 (ssh), 80 (http), 443 (https) en IPv4 et IPv6.
1 2 3 4 5 6 7 8 9 10 11 |
sebastien@ubuntu:~$ sudo ufw status Status: active To Action From -- ------ ---- 80 ALLOW Anywhere 443 ALLOW Anywhere 22 ALLOW Anywhere 80 (v6) ALLOW Anywhere (v6) 443 (v6) ALLOW Anywhere (v6) 22 (v6) ALLOW Anywhere (v6) |
Vous noterez que le port 8088 n’est maintenant plus accessible car bloqué par le firewall UFW. Il faudra forcement se connecter à Constellation via Nginx en HTTPS. N’oubliez pas alors de modifier l’URI de votre Constellation sur vos sentinelles existantes pour prendre en compte ce changement.
Ajouter d’autre application Web dernière votre reverse proxy SSL
Jusqu’au présent vous avez configuré un nom DNS type “demo.internal.myconstellation.io” qui pointe vers votre serveur Linux sur lequel le service Nginx répond en HTTP (80) et HTTPS (443) avec un certificat Let’s Encrypt pour “proxifier” les requêtes vers le service Constellation accessible localement sur le port 8088.
Vos utilisateurs se connectent donc forcement en HTTPS sur le reverse proxy pour accéder à Constellation !
La règle configurée dans Ngnix “proxifie” toutes les requêtes à partir de la racine « / » vers Constellation :
1 2 3 4 |
location / { proxy_pass http://localhost:8088; .... } |
Mais il est également possible d’adapter cette règle pour que votre reverse proxy ne soit plus exclusivement un passe-plat pour Constellation mais aussi pour vos autres services internes (une box domotique, un serveur Web, un objet connecté, une camera IP, etc…).
Vous aurez ainsi la possibilité d’exposer différents services Web internes dernière votre reverse proxy profitant d’un même port TCP (le 443) et donc d’un même canal de communication sécurisé (par le cryptage SSL).
Parmi les différentes options pour ce type de configuration :
- Reverse proxy en fonction du “server_name”
- Reverse proxy en fonction de la “location”
Reverse Proxy en fonction du server_name
Le principe est de rejouer ce tutoriel depuis le début pour chacune de vos applications à exposer.
Vous devrez ainsi créer une adresse DNS vers votre IP public pour chaque site, créer une configuration Nginx en changeant le « server_name » et « proxy_pass » vers la ressource interne à exposer et créer un certificat SSL avec Certbot pour tous vos sites créés.
Vous aurez ainsi une multitude de nom DNS qui pointerons tous vers votre serveur Nginx qui lui redirigera vers les ressources internes en fonction du « server_name ». Par exemple “constellation.mondomaine.fr”, “macamera.mondomaine.fr”, “jeedom.mondomaine.fr”, etc.. etc..
La configuration est simple car il s’agit de répéter ce tutoriel pour chaque service, par contre l’administration est un peu lourde et vous aurez autant de sous domaine et donc de certificat que de service à exposer.
Reverse Proxy en fonction de la “location”
Dans ce mode, nous gardons un seul site Nginx (celui configuré dans le fichier /etc/nginx/sites-available/constellation) et donc un seul nom de domaine (ici demo.internal.myconstellation.io) avec son certificat associé.
Cependant au lieu de “rediriger” les requêtes depuis la racine « / » vers Constellation nous allons créer plusieurs “location”.
Prenons un exemple pour bien comprendre. Ici le serveur Ngnix est installé sur la même que le serveur Constellation, donc localhost. Imaginons que dans ce même réseau LAN, j’ai par exemple un serveur ZoneMinder qui répond sur 192.168.0.10 et une box Jeedom sur 192.168.0.11.
Je pourrais éditer la configuration Nginx de cette façon :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
location /constellation/ { proxy_pass http://localhost:8088/constellation/; proxy_set_header Host $host; proxy_set_header Connection ""; proxy_http_version 1.1; proxy_buffering off; proxy_cache off; proxy_connect_timeout 30; proxy_send_timeout 30; } location /zm/ { proxy_pass <a href="http://192.168.0.10/zm/;">http://192.168.0.10/zm/; </a> proxy_set_header Host $host; proxy_set_header Connection ""; proxy_http_version 1.1; } location /jeedom/ { proxy_pass http://192.168.0.11; proxy_set_header Host $host; proxy_set_header Connection ""; proxy_http_version 1.1; } |
Ainsi, en fonction du “path” demandé, un service différent me répondra :
- https://<mon_nom_DNS>/constellation : réponse du serveur Constellation
- https://<mon_nom_DNS>/zm : réponse du serveur ZoneMinder
- https://<mon_nom_DNS>/jeedom : réponse du serveur Jeedom
Attention : si le serveur Constellation répond sur un “sous path”, comme ici “/constellation” il faut également modifier la configuration du serveur Constellation pour l’informer.
Pour cela modifiez le ficher “/opt/constellation-server/Constellation.Server.exe.config” :
1 |
sudo nano /opt/constellation-server/Constellation.Server.exe.config |
Et modifier le listenUri pour reprendre la même structure d’URI, ici en ajoutant “/constellation” :
1 2 3 |
<listenUris> <uri listenUri="http://+:8088/constellation" /> </listenUris> |
Pour finir, il faudra relancer le service Constellation pour prendre en compte ce changement :
1 |
sudo supervisorctl restart constellation-server |
Voilà votre Constellation répond maintenant sur le /constellation, dans notre cas https://demo.internal.myconstellation.io/constellation :
Si maintenant on change le path pour “/zm” soit ici https://demo.internal.myconstellation.io/zm, c’est notre serveur ZoneMinder qui répondra :
On a donc un seul serveur en frontal, Ngnix qui écoute en HTTPS avec le certificat Let’s Encrypt pour sécuriser TOUS les échanges et qui, selon le “path” demandé, transféra les requêtes vers les différents services internes de votre réseau.
A noter que vous pouvez également utiliser des expressions régulières (regex) pour définir vos “locations”. Pour plus d’information : https://www.scalescale.com/tips/nginx/nginx-location-directive/
Démarrez la discussion sur le forum Constellation