Sommaire

Reverse-Proxy sous Apache

Principe

Suite à mon dernier tutoriel sur Docker Compose, j’étais resté avec Firefly III en HTTP simple car son service Web ne supporte pas le chiffrement SSL.

Le principe, comme illustré ci-dessous, est d’assurer le chiffrement de la communication entre le serveur et l’extérieur. Le reverse-proxy transmet les données en normal vers le service.

De ce fait, un site fonctionnant avec un lien comme http://pokedex.scrample.xyz:4040 sera accessible via https://pokedex.scrample.xyz On fera aussi le nécessaire pour rediriger automatiquement le trafic HTTP vers HTTPS.

Ce principe peut s’appliquer sur tous les services qui ne supportent pas le chiffrement (où que vous n’arrivez pas à faire fonctionner).
La communication non chiffrée n’est pas réellement un problème vu qu’elle s’effectue au sein même de la machine.

Configuration

Ayant déjà un serveur Apache2 sur mon serveur, j’ai utilisé ce dernier en tant que proxy inverse. J’ai déjà obtenu les certificats via Let’s Encrypt.

Nous allons effectuer ce traitement en 3 étapes :

  • Accès en HTTP (via le port 80)
  • Accès en HTTPS (via le port 443)
  • Redirection automatique de HTTP vers HTTPS

Activations des modules

Pour simplifier la procédure, on va d’abord activer tous les modules nécessaires à ce tutoriel. On redémarre ensuite Apache2.

1
2
sudo a2enmod proxy proxy_http rewrite
sudo systemctl restart apache2
Astuces
sudo apachectl -M

Accès en HTTP

On créer donc un fichier de conf (ex: pokedex.scrample.xyz.conf) dans le dossier /etc/apache2/sites-available/. On l’édite en reprenant l’exemple suivant :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<VirtualHost *:80>
    ServerName pokedex.scrample.xyz
    ServerAdmin webmaster@scrample.xyz

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:4040/
    ProxyPassReverse / http://127.0.0.1:4040/
</VirtualHost>

Un coup de sudo a2ensite pokedex.scrample.xyz.conf et un sudo systemctl reload apache2 devrait rendre le site accessible sous l’URL : http://pokedex.scrample.xyz.

Accès en HTTPS

De la même manière que dans la partie précédente, on créer un fichier de configuration pour la partie SSL. On peut aussi simplement ajouter ce contenu à la suite de l’autre fichier.
J’ai pour ma part créer un autre fichier pokedex.scrample.xyz-le-ssl.conf que j’ai ensuite activé avec un sudo a2ensite pokedex.scrample.xyz-le-ssl.conf

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<VirtualHost *:443>
    ServerName pokedex.scrample.xyz
    ServerAdmin webmaster@localhost
    
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    
    SSLEngine On
    SSLCertificateFile /etc/letsencrypt/live/pokedex.scrample.xyz/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/pokedex.scrample.xyz/privkey.pem
    
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:4040/
    ProxyPassReverse / http://127.0.0.1:4040/
    RedirectMatch ^/$ https://127.0.0.1:4040/

</VirtualHost>

Après une recharge de la configuration (sudo systemctl reload apache2), le site devrait être accessible sous l’URL : https://pokedex.scrample.xyz.

Redirection HTTP vers HTTPS

Pour cette partie, on ajoute simplement les 3 lignes suivantes dans la configuration du VirtualHost écoutant sur le port 80.

1
2
3
   RewriteEngine on
   RewriteCond %{SERVER_NAME} =pokedex.scrample.xyz
   RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

La section au complet :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<VirtualHost *:80>
   ServerName pokedex.scrample.xyz
   ServerAdmin webmaster@scrample.xyz

   ErrorLog ${APACHE_LOG_DIR}/error.log
   CustomLog ${APACHE_LOG_DIR}/access.log combined

   RewriteEngine on
   RewriteCond %{SERVER_NAME} =pokedex.scrample.xyz
   RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

Après une ultime recharge de la configuration (sudo systemctl reload apache2), en tapant simplement pokedex.scrample.xyz dans la barre d’adresse devrait vous amener vers le site en HTTPS.

Ports non conventionnels

Si votre nom domaine dessert déjà un autre service sur les ports 80 et 443, vous pouvez en utiliser d’autres.
Dans ce cas-là, il serait même utile de faire seulement la partie HTTPS en remplaçant le port 443 par un autre (ex: 4343).

Il vous faudra alors ajouté ce port dans la liste des ports d’écoutes dans le fichier /etc/apache2/ports.conf selon la directive suivante :

1
2
3
<IfModule ssl_module>
    Listen 4343
</IfModule>

Vous n’êtes pas obligé de le mettre dans le bloc IfModule.

Conteneurs Docker

Il est possible que, dans votre configuration, votre service soit aussi accessible en HTTP sur le port d’origine exposé par la configuration du conteneur (ici cela serait le port 4040).

Je suppose que votre définition du mapping des ports et pour l’exemple d’un Docker Compose comme ceci :

1
2
    ports:
      - 4040:80

Écrit comme cela, le port spécifié (4040) se trouve lié à toutes les interfaces sur la machine hôte. L’idéal est de faire en sorte que ce port soit accessible que sur l’interface lo (localhost).

Pour faire cela, il suffit de préciser l’adresse IP avant le port exposé :

1
2
    ports:
      - 127.0.0.1:4040:80

Vous pouvez voir la configuration spécifique de vos ports sur un conteneur avec la commande docker port <CONTENEUR>.

Pour voir plus de possibilités de configuration des ports, je vous renvoie sur la section correspondante de la documentation officielle.