Let's Encrypt your Nginx !

Let’s Encrypt est un projet d’autorité de certification gratuite, automatisé et libre.

Concrètement, cela nous permet notamment d’avoir des sites et applications web en https, reconnues comme dignes de confiance par les navigateurs internet. Et cela sans payer et surtout basé sur des logiciels open source !

La beta est ouverte au public depuis jeudi, j’en ai donc profité pour remplacer les certificats auto-signés de mon GitLab sous Nginx par de vrais certificats “made by” Let’s Encrypt.

Installation et génération des certificats

L’installation de Let’s Encrypt est simple, il suffit de cloner le repository et de lancer un script qui va installer la bonne version du logiciel selon l’OS.

git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto --help

La cible de Let’s Encrypt est de fournir un service permettant d’automatiser la génération des certificats et leur renouvellement. Cela marche bien pour un serveur Apache mais pas encore pour Nginx (ne pas oublier que c’est une beta).

On va donc lui demander de seulement générer les certifacts et de ne pas tout gérer. Pour cela, il suffit de stopper Nginx (la coupure ne sera pas très longue) et lancer la génération du certificat pour son domaine.

sudo nginx -s stop
./letsencrypt-auto certonly --standalone -d my-gitlab-domain.fr -d www.my-gitlab-domain.fr

Et voilà, les certifacts sont prềts dans /etc/letsencrypt/live/my-gitlab-domain.fr/

Redémarrer nginx et configurer le domaine

On redémarre le service Nginx.

sudo service nginx start

Et on modifie la configuration de notre serveur Nginx.

server {
listen 443;
listen [::]:443;
# Make site accessible from http://localhost/
server_name www.my-gitlab-domain.fr my-gitlab-domain.fr;
ssl on;
ssl_certificate /etc/letsencrypt/live/my-gitlab-domain.fr/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/my-gitlab-domain.fr/privkey.pem;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/my-gitlab-domain.fr/fullchain.pem;
location / {
...
}
}

On recharge la configuration pour qu’elle soit prise en compte par Nginx.

sudo ngnix -s reload

Le tour est joué !

Renouvellement

Le certificat est valide pour 60 jours et sans renouvellement automatique pour Nginx pour l’instant, il suffira de relancer la commande pour le renouveller.

./letsencrypt-auto certonly --standalone -d my-gitlab-domain.fr -d www.my-gitlab-domain.fr

Sources:

Commenter et partager

Dans le cadre d’un projet basé sur Hapi.js (je reviendrai dessus dans un prochain article), j’ai pris un peu de temps pour améliorer la façon de déployer mes applications Node.js.

Voici ce que j’ai mis en place pour mes petits projets.

Déployer à chaque “git push”

Quoi de plus sympa qu’une application qui se déploie en production sur un simple commit/push ? Rien, on est bien d’accord ?
Je me suis donc inspiré de cet article pour mettre en place, sur mon serveur Ubuntu, un bare repository vers lequel je push lorsque je veux déployer mon application.

Contenu d'un bare repository
branches config description HEAD hooks index info objects refs

Je définis une action sur l’événement post-receive, ce qui se fait simplement en créant un fichier du même nom dans le répertoire hooks.

hooks/post-receive
#!/bin/sh
GIT_WORK_TREE=/opt/my-app git checkout -f
cd /opt/my-app
npm install

Ainsi à chaque push, un checkout est fait dans le repertoire d’installation de mon application (un git clone ayant était fait manuellement la première fois) puis un npm install pour mettre à jour mon application.

Facile, non ?

Oui. Un peu trop facile peut-être…

Mettre à jour son application d’un simple push c’est cool, mais encore faut-il s’assurer que la qualité est toujours au rendez-vous. Mon projet étant hébergé sous GitHub, j’utilise Travis CI comme outil d’intégration continu, parfaitement intégré puisqu’il déclenchera un build à chaque push sur GitHub.
Il se configure assez simplement grâce au fichier .travis.yml à la racine du projet.

.travis.yml (début)
sudo: false
language: node_js
node_js:
- 4.0
services: mongodb
addons:
apt:
sources:
- mongodb-3.0-precise
packages:
- mongodb-org-server
...
...

On déclare le langage et runtime qu’on utilise (ici Node.js v4) et les services dont on a besoin (ici MongoDB en l’installant à chaque build).

.travis.yml (fin)
...
...
ssh_known_hosts:
- my.server.fr
after_success:
- eval "$(ssh-agent -s)"
- mkdir ~/.ssh
- mv .travis-config ~/.ssh/config
- mv .deploy.pem ~/.ssh/deploy.pem
- chmod 600 ~/.ssh/deploy.pem
- git remote add deploy ssh://user@my.server.fr/opt/my-app-bare
- git push deploy master
before_install:
- openssl aes-256-cbc -K $encrypted_d3a1e9dbde14_key -iv $encrypted_d3a1e9dbde14_iv
-in .deploy.pem.enc -out .deploy.pem -d

Et vient la partie un peu plus velue.

Tout d’abord, on met en place la tuyauterie pour ssh en rajoutant notre serveur comme hôte de confiance (ssh_known_hosts) puis en décodant notre clé privée ssh (before_install) qui sera utilisé par Travis pour faire le push et qui avait été commit encryptée sur le repository.
La partie intéressante se trouve dans le after_success, juste après la tambouille pour initialiser la connexion ssh, on ajoute notre bare repository sous le nom deploy et on pousse notre branche master vers ce deploy.

Voilà, on a automatisé notre push vers notre serveur de production lorsqu’on push sur GitHub.

Bon, c’est bien joli tout ça mais en apparence on ne fait que dire à Travis de faire un push une fois le build terminé, ce qu’on savait déjà faire manuellement…

En apparence seulement, car ce qui est bien avec Travis c’est que si une cible test est présente dans notre package.json, il va l’exécuter automatiquement et la prendre en compte dans son résultat de build !
Ainsi si nos tests ne passent pas, le build est en échec et notre application n’est pas redéployée.
On peut même aller encore plus loin en fixant un seuil minimal de couverture de code de nos tests en dessous duquel ils sont considérés en échec. C’est ce que je fais avec Lab, l’outil de test de Hapi.js, avec la commande suivante qui fixe le seuil de couverture à 95% :

Lancement de tests
lab -c -t 95 -L

Sympa non ?

Oui. Mais c’est pas suffisant…

C’est pas suffisant parce que même si notre application est installée à la volée, il faut que notre serveur Node.js redémarre pour prendre en compte toutes les modifications. Pour ça, j’utilise PM2 en mode watch qui est un utilitaire qui va monitorer nos serveurs Node.js.

Ainsi lorsque des fichiers vont être mis à jour par notre push, PM2 va automatiquement redémarrer le serveur Node.js qu’on lui avait spécifié avec la commande :

pm2 start
pm2 start my-app.js

Cool !

PM2 est un outil vraiment sympa qui possède plein de fonctionnalités. Je vous recommande d’y jeter un oeil si vous ne connaissez pas.

Bonus

Bien, notre application est redéployée à chacun de nos push à condition que la qualité soit là et les modifications sont prises en compte sans qu’on ait à intervenir grâce à PM2.

Ce qui serait sympa, c’est d’avoir toutes les infos de build, de couverture de tests, versions de nos dépendances, etc, centralisées dans un seul endroit. Et les badges du README.md sont parfaits pour ça.

Les versions de dépendances npm (prod et dev) sont fournis par david-dm.org, le status de build par Travis et la couverture de code par Coverall.io qui se plugge lui-aussi sur GitHub.

Pour transmettre les informations à Coverralls, j’ai rajouté un script coverage dans package.json qui lance coveralls en sortie de rapport de Lab :

Lab et Coveralls
lab -c -L -r lcov | ./node_modules/.bin/coveralls

Je rajoute l’appel à ce script (npm run-script coverage) dans la cible after_success du fichier .travis.yml et le tour est joué.

Tous les outils utilisés ici sont gratuits pour des projets open-source.

Enjoy !

Commenter et partager

  • page sur

Pierre PIRONIN

J’ai créé ce blog pour parler de ce qui se passe autour de moi dans le domaine du génie logiciel.
J’exposerai mes devs, mes idées, mes lectures, les faits qui m’intéressent et les événements auxquels je participe.

Bonne lecture !


Artisan développeur


Auvergne, France