Reverse-Proxy sous Apache
2020-03-24T17:37:53+01:00 | 4 minutes de lecture | Mise à jour le 2020-05-12T10:37:53+01:00
Procédure de mise en place d’une redirection d’un site en accès HTTP simple vers du HTTPS par l’intermédiaire d’un Reverse-Proxy.
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.
graph LR; A[Connexion entrante] -->|SSL:443| B{Reverse-Proxy} B -->|Non-SSL:4040| C[Docker]
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.
sudo a2enmod proxy proxy_http rewrite
sudo systemctl restart apache2
[!TIP]
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 :
<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
<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.
RewriteEngine on
RewriteCond %{SERVER_NAME} =pokedex.scrample.xyz
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
La section au complet :
<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 :
<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 :
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é :
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.