Installation de Hitch : utiliser le HTTPS avec Varnish

Varnish HTTPS avec Hitch

Varnish ne supporte pas le TLS. Hitch est un proxy réseau qui gère les connexions TLS/SSL et transmet le traffic décrypté à Varnish, il fournit donc un support HTTPS. Hitch est donc votre meilleur ami, il est juste dédié à gérer les connexions TLS et rien d’autre.

J’ai au début géré mes connexions TLS avec nginx, mais j’ai voulu changer pour Hitch car il est beaucoup plus léger, et contrairement à Nginx il n’analyse pas les requêtes / réponses HTTP. Il se moque de ce qu’il « transporte ». Ce qui se traduit par moins d’analyse donc moins de ressources utilisées.

Edit : Mise à jour de la version de hitch (1.7.2)

Hitch apporte les fonctionnalités suivante :

  • Support de TLS1.0, TLS1.1, TLS1.2, TLS1.3, SSLv3
  • SNI, avec ou sans des certificats wildcard
  • OCSP stapling
  • Support du protocole HAProxy’s PROXY
  • Configuration souple
  • Rechargement des certificats à chaud
  • Performance garantie

Quand on active Varnish, on le met en écoute sur le 80. En mettant Hitch en amont de Varnish, il faut lui indiquer qu’il doit écouter sur un nouveau port le protocole PROXY. Il faut donc ajouter un nouveau paramètre et le laisser écouter. Voici une explication en image du fonctionnement.
Mise en place de Hitch
Comme expliqué Hitch transmet bytes à bytes les données, en d’autre mots il ne rajoute pas de X-Forwarded-Proto  or X-Forwarded-For sur la requête reçue.
Le support du protocole PROXY existe pour transmettre la vrai @IP du client au backend.

Avec nginx, on a l’habitude de faire des set pour transmettre l’ensemble de ces headers

proxy_set_header X-Real-IP  $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;

Installation de hitch sur Debian

Hitch est dans les paquets Debian, il s’agit de la version 1.4.3.
Dans ce tuto j’ai préféré compiler la dernière version 1.7.2 pour bénéficier des derniers correctifs

Installation des dépendances nécessaires à la compilation

sudo apt-get install libev-dev libssl-dev automake python-docutils flex bison pkg-config

Téléchargement et compilation

wget https://hitch-tls.org/source/hitch-1.7.2.tar.gz

tar -xzf hitch-1.7.2.tar.gz
cd hitch-1.7.2
 ./configure
make
sudo make install

Vérification de l’installation

# hitch -V
hitch 1.7.2

Pour éviter l’erreur suivante lors du lancement du service {ocsp} Warning: Unable to stat directory ‘/var/lib/hitch/’: No such file or directory’. OCSP stapling will be disabled. Nous allons créer ce dossier en amont :

sudo mkdir /var/lib/hitch/

Création de la configuration

Créer le dossier qui va contenir le fichier de conf
sudo mdkir /etc/hitch/
Créer le fichier
sudo vim /etc/hitch/hitch.conf

Y insérer le code suivant (découpé en plusieurs étapes pour vous détailler chaque option) :

  • Définition du port d’écoute et des ciphers
frontend = "[*]:443"
ciphers = "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"
  • Définition du backend ainsi que le port sur lequel transférer la requête
# Send traffic to the Varnish backend using the PROXY protocol
backend = "[127.0.0.1]:8443"
  • Transmet l’@IP du client au Backend en utilisant le protocole PROXY v2
write-proxy-v2 = on
  • Définition des protocoles supportés par le backend. Édit : avec l’ancienne configuration des ALPN, j’avais dans mon syslog ce genre d’erreur : {backend} Socket error: Connection reset by peer  et certains utilisateurs ne pouvaient pas accéder au site puisque leur navigateur affichait ce message d’erreur ERR_SPDY_PROTOCOL_ERROR. J’ai corrigé en supprimant le HTTPS/2.
    • Application-Layer Protocol Negotiation (ALPN).  Avec la version 4.1 de Varnish il n’est pas possible d’activer le HTTPS/2, car celui ci ne le supporte pas encore. Il faut attendre la version 5. Il faut également savoir que pour que le HTTP/2 fonctionne avec les navigateurs récents, la négociation ALPN est nécessaire et il faut donc que Openssl le supporte également ce qui n’est pas le cas de la version 1.0.1t 3 May 2016 sur Debian Jessie
    • Active la vérification des réponses OCSP par rapport au certificat
    • Protocole SSL/TLS a utilisé
alpn-protos = "http/1.1"
ocsp-verify-staple = on
tls-protos = TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3 SSLv3
  • Liste des certificats SSL x590. Les certificats sont utilisés dans l’ordre dans lesquels ils sont listés.
    Pour que le fichier soit accepté, il doit être la concaténation de la clé privé et et du certificat correspondant. Il est également possible de concaténer une clé Diffie-Hellman qui se génère de cette façon :

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

L’échange de clés Diffie-Hellman est une méthode par laquelle « deux personnes » peuvent échanger de manière sécurisée.

Pour effectuer la concaténation il faut procéder de cette façon :

cat /etc/letsencrypt/live/example.org/privkey.pem \
/etc/letsencrypt/live/example.org/fullchain.pem \
/etc/ssl/certs/dhparam.pem \ > /etc/hitch/example.org.pem 
chmod 0600 /etc/hitch/example.org.pem
# List of PEM files, each with key, certificates and dhparams 
pem-file = "/etc/hitch/example.org.pem" 
pem-file = "/etc/hitch/site2.pem"
  • 3 autres options non primordiales, concernant l’activation du daemon, et la choix du user et group après avoir bindé les sockets. Personnellement j’ai repris ces 3 options qui sont présents dans le fichier d’exemple, même si je doute de leur intérêt.
daemon = on 
user = "nobody" 
group = "nogroup"

Création du daemon

Pour que Hitch se lance au démarrage il faut créer le service.
Si vous utilisez systemd sur votre serveur alors il vous faut récupérer la configuration ici et l’insérer dans le fichier /lib/systemd/system/hitch.service puis d’activer le service via un  sudo systemctl enable hitch.service 

Si vous utilisez init System V  alors vous devez récupérer le fichier ici

Conf Varnish

Il faut ensuite apporter des modifs dans Varnish. Commençons par modifier la ligne de commande de Varnish pour lui indiquer qu’il doit également écouter sur le port 8443, après le a -80 rajouter -a 127.0.0.1:8443,PROXY Il faut soit modifier le fichier /etc/init.d/varnish (pour init System V), soit /lib/systemd/system/varnish.service (pour systemd ).

Ensuite les modifs suivantes ont pour but d’informer Apache et le backend que nous sommes en HTTPS.

Créer le fichier suivant /etc/varnish/https.vcl

sub https_vcl_recv {
   if (std.port( server.ip ) == 443) {
      set req.http.X-Forwarded-Proto = "https";
      set req.http.https = "on";
   }
}

sub https_vcl_hash {
   if ( req.http.X-Forwarded-Proto ) {
      hash_data( req.http.X-Forwarded-Proto );
   }
}

Et dans votre fichier de configuration de Varnish fait un include du fichier que nous venons de créer include « /etc/varnish/https.vcl »;

Il vous faut ensuite appeler les deux méthodes créées https_vcl_recv et https_vcl_hash  respectivement dans vcl_recv et dans vcl_hash

Conf Apache

Et pour finir dans Apache il nous reste plus qu’à ajouter cette ligne dans votre vhost. Ainsi votre application détectera que vous utilisez de l’HTTPS et pourra générer correctement l’ensemble des liens.

SetEnvIf X-Forwarded-Proto https HTTPS=on

Il ne vous reste plus qu’à relancer l’ensemble des services

sudo service  hitch restart
sudo service apache2 restart
sudo service varnish restart