Reverse Proxy with SSL termination
From Knowledge
Ce tutoriel explique l'installation et la configuration d'un service Apache avec terminaison SSL agissant comme Reverse-Proxy sur un serveur GNU/Linux Debian (mode CLI).
Contents
Conditions requises
- Ce tutoriel présuppose que le serveur d'application (ou tout autre serveur HTTP faisant tourner des applications web) est déjà installé sur la machine
- En outre, le certificat de l'autorité de certification et un couple certificat+clef privée pour le proxy inverse est nécessaire
Installation des composants nécessaires
- Installer le serveur Apache
apt-get update
apt-get install apache2
- Activer les modules proxy, proxy_http, ssl et headers de Apache2
a2enmod proxy proxy_http ssl headers
Préparation de la couche SSL du serveur Apache
- Activer le site SSL
ln -s /etc/apache2/sites-available/default-ssl /etc/apache2/sites-enabled/default-ssl
- Si le serveur ne doit être accédé qu'en HTTPS, editer le fichier /etc/apache2/apache2.conf comme suit:
<Location />
SSLRequireSSL
</Location>
- Editer le fichier /etc/apache2/ports.conf et ajouter le cas échéant le port 443
Listen 80 443
- Editer le fichier /etc/apache2/mods-enabled/ssl.conf comme suit:
SSLCipherSuite EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCMEECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+AESGCM:EECDH:EDH+AESGCM:EDH+aRSA:HIGH:!MEDIUM:!LOW:!aNULL:!eNULL:!LOW:!RC4:!MD5:!EXP:!PSK:!SRP:!DSS
SSLHonorCipherOrder On
SSLProtocol All -SSLv2 -SSLv3
SSLCompression Off
- Editer le fichier /etc/apache2/sites-enabled/default-ssl comme suit:
ServerName [url]:443
SSLEngine on #Activer SSL
SSLCertificateFile <cheminVersClefPublique>
SSLCertificateKeyFile <cheminVersClefPrivee>
SSLCertificateChainFile <clefPubliqueCaServeur>
SSLCACertificateFile <clefPubliqueCaClients>
#Par défaut, on exige pas une authentification du client par certificat.
#A changer si l'authentification du client par certificat est également
#utilisée dans d'autres circonstances.
SSLVerifyClient none
- Redémarrer le serveur apache2
/etc/init.d/apache2 restart
Préparation de la fonction proxy du serveur Apache
- Editer le fichier /etc/apache2/mods-enabled/proxy.conf comme suit:
ProxyVia Full
- Si les connexions HTTP sont souhaitées, éditer le fichier /etc/apache2/sites-enabled/000-default et insérer le bloc suivant juste avant la balise </VirtualHost>:
<Location /appserver>
#On initie les champs dans l'entête HTTP à... vide
RequestHeader set SSL_CLIENT_S_DN ""
RequestHeader set SSL_CLIENT_I_DN ""
RequestHeader set SSL_SERVER_S_DN_OU ""
RequestHeader set SSL_CLIENT_VERIFY ""
RequestHeader set SSL_CLIENT_CERT ""
#Active la fonctionnalité de proxy pour le context "/appserver" et
#redirige la requête au serveur d'application, sur le port 8080
ProxyPass http://localhost:8080/ #HTTP OK vu qu'on reste sur la même machine
ProxyPassReverse http://localhost:8080/ #HTTP OK vu qu'on reste sur la même machine
</Location>
- Editer le fichier /etc/apache2/sites-enabled/default-ssl et insérer le bloc suivant juste avant la balise </VirtualHost>:
<Location /appserver>
#On initie les champs dans l'entête HTTP à... vide
RequestHeader set SSL_CLIENT_S_DN ""
RequestHeader set SSL_CLIENT_I_DN ""
RequestHeader set SSL_SERVER_S_DN_OU ""
RequestHeader set SSL_CLIENT_VERIFY ""
RequestHeader set SSL_CLIENT_CERT ""
#Force le client à fournir un certificat pour l'authentification
#et à vérifier la chaine de confiance sur 10 niveaux.
SSLVerifyClient require
SSLVerifyDepth 10
#Désactive la transmission des informations via les variables d'environnement
SSLOptions -StdEnvVars -ExportCertData
#Ajoute différentes informations au sujet de la connexion SSL
#dans l'entête HTTP de façon à permettre au serveur d'application
#d'utiliser ces informations. Liste exhaustive des variables à l'adresse:
#http://httpd.apache.org/docs/current/mod/mod_ssl.html#envvars
RequestHeader set SSL_CLIENT_S_DN "%{SSL_CLIENT_S_DN}s"
RequestHeader set SSL_CLIENT_I_DN "%{SSL_CLIENT_I_DN}s"
RequestHeader set SSL_SERVER_S_DN_OU "%{SSL_SERVER_S_DN_OU}s"
RequestHeader set SSL_CLIENT_VERIFY "%{SSL_CLIENT_VERIFY}s"
RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}s"
#Active la fonctionnalité de proxy pour le context "/appserver" et
#redirige la requête au serveur d'application, sur le port 8080
ProxyPass http://localhost:8080/ #HTTP OK vu qu'on reste sur la même machine
ProxyPassReverse http://localhost:8080/ #HTTP OK vu qu'on reste sur la même machine
</Location>
- Redémarrer le serveur apache2
/etc/init.d/apache2 restart
Tester
- Créer le fichier headers.php à l'endroit approprié du serveur d'application (Attention, nous ne sommes plus sur le Reverse Proxy) pour tester le bon fonctionnement de la transmission des informations.
<!DOCTYPE html>
<html>
<head>
<title>HTTP Headers</title>
</head>
<body>
<?php
echo '<!DOCTYPE html>';
echo '<table style="border-collapse: collapse; border-width: 1px; border-color: black; border-style: solid; width: 100%;">';
foreach (getallheaders() as $name => $value)
{
echo '<tr style="border-collapse: collapse;">';
echo '<td style="padding: 5px; border-collapse: collapse; border-width: 1px; border-color: black; border-style: solid; font-family: arial, helvetica; font-weight: bold;">'.$name.'</td>';
echo '<td style="padding: 5px; border-collapse: collapse; border-width: 1px; border-color: black; border-style: solid; font-family: arial, helvetica;">'.$value.'</td>';
echo '</tr>';
}
echo '</table>';
?>
</body>
</html>
- Appeler l'URL https://localhost/appserver/headers.php. Le résultat devrait être un tableau HTML affichant l'entête HTTP. Il devrait notamment y avoir les champs SSL_CLIENT_S_DN, SSL_CLIENT_I_DN et SSL_CLIENT_CERT.