Reverse Proxy with SSL termination

From Knowledge
Jump to: navigation, search

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).

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.