De nos jours le https devient incontournable pour n'importe quel site.
Sur un serveur managé, la plupart des hébergeurs propose des solutions très simple et gratuit grâce à Let's encrypt. En quelques clicks ainsi qu'une petite configuration dans un fichier .htaccess, le tour est joué!
Pour nodejs, c'est plus compliqué, car rare sont encore les hébergeurs proposant nvm. Du coup, s'il faut installer un certificat https, il n'y a pas d'admin pour le faire. Et avant même d'attaquer le http, comment lier un simple nom de domaine à nodejs, puisque nodejs fonctionne par "port".
Afin de faciliter ceci, nous allons installer NGINX qui fera office de reverse proxy pour rediriger les appels du nom de domaine vers le port souhaité.
Commençons par nos pré-requis:
- En tout premier lieu, il faut s'assurer que l'on dispose d'un nom de domaine (ex. example.com) qui est redirigé vers l'IP du serveur.
- Ensuite, si ce n'est pas déjà fait, suivez ce tuto pour installer NGINX: https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-debian-9
- Pour finir, on partira du principe que nodejs est déjà installé sur le serveur. Si ce n'est pas le cas, il existe plusieurs façon d'installer nodejs, mais mes préférences se portent sur NVM: https://github.com/creationix/nvm, permettant d'installer facilement différente version de NodeJS en tapant simplement
nvm i [numero_version_nodejs]
Etape 1. Configurer le reverse proxy
Une fois ces 3 pré-requis validé, créons un petit projet Hello World en NodeJS, installons pm2 pour faire tourner notre appli de manière permanente et configurons NGINX pour qu'il fasse son travail de reverse proxy en suivant le tutoriel suivant: https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-debian-9#step-2-%E2%80%94-creating-a-node-js-application
Au final, en tapant le nom de domaine dans notre navigateur (http://example.com) dans cette exemple, NGINX redirigera vers le port 3000 sur laquelle l'appli NodeJS tourne et affichera "Hello World".
Etape 2. Installer Let's encrypt
Installer certbot:
sudo apt-get install certbot
Pour commander le certificat, tapez:
sudo certbot certonly -d example.com --webroot -w /etc/letsencrypt/webrootauth
(changer example.com par votre nom de domaine)
Etant donné que Let's Encrypt doit être parfois rénouveler, créez un cron qui lancera chaque jour le renouvellement du certificat, soit :
crontab -e
0 0 * * * /usr/bin/certbot --noninteractive --agree-tos -- post-hook 'systemct1 reload nginx' renew
(Voir https://www.taniarascia.com/setting-up-a-basic-cron-job-in-linux pour comprendre la base du cron)
Etape 3. Configurer NGINX pour le https
Merci à Alex Kaworu qui nous propose ce script. Ajoutons donc le contenu de https://gist.github.com/kAworu/24b77c6a7443f11888e2bef3f60c252f dans le nouveau fichier suivant: /etc/nginx/letsencrypt.location
Créer ensuite le dossier suivant:
sudo mkdir -p /etc/letsencrypt/webrootauth/.well-known/acme-challenge
Nous avons besoin également de l'IP du serveur DNS que nous utilisons pour la config ci-dessous:
nslookup google.ch | awk '/^Server:/ {print $2}'
Si la commande nslookup n'existe pas, lancez préalablement:
sudo apt-get install dnsutils
Générons les paramètres pour les échanges Diffie-Hellman (voir config ci-dessous):
sudo /usr/bin/openssl dhparam -out /etc/ssl/dh2048.pem 2048
Puis, éditons enfin le fichier de configuration NGINX créé à l'étape 1:
sudo nano /etc/nginx/sites-available/example.com
(si ce n'est pas déjà fait, remplaçons example.com par votre nom de domaine, sans oublier de mettre à jour le lien symbolique dans /etc/nginx/sites-enabled)
Et basons nous sur le lien suivant pour réaliser la configuration: https://wiki.mozilla.org/Security/Server_Side_TLS
On devrait avoir quelque chose du genre:
server {
listen 80;
listen [::]:80;# Remplacer example.com par votre nom de domaine
server_name example.com;# Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response.
return 301 https://$host$request_uri;
}server {
listen 443 ssl http2;
listen [::]:443 ssl http2;server_name fl-project.site;
# see Mozilla recommandations https://wiki.mozilla.org/Security/Server_Side_TLS
ssl on;# certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
ssl_certificate /etc/letsencrypt/live/fl-project.site/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/fl-project.site/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
ssl_dhparam /etc/ssl/dh2048.pem;# intermediate configuration. tweak to your needs.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on;# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;## verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /etc/letsencrypt/live/fl-project.site/chain.pem;# Remplacez <IP DNS resolver> par l'IP préalablement trouvé à l'aide de nslookup
resolver <IP DNS resolver>;location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}# Ajouter cette ligne pour charger le script d'Alex Kaworu (voir plus haut)
include letsencrypt.location;
}
Redémarrons le serveur NGINX:
sudo service nginx restart
Si tout fonctionne correctement, https://example.com (dans cette exemple) devrait afficher "Hello world" !