Transformer un site http Apache en site https sécurisé via le proxy inverse Nginx
Je dois prendre en charge un ancien site WordPress fonctionnant sur un serveur Web Apache. Pour rendre les choses plus sûres, ce serveur Apache est dans un conteneur Docker, et il est accessible au monde via la configuration du proxy inverse Nginx. Ce site est actuellement diffusé via http et je souhaite le déplacer vers https.
Je pense que j'ai deux options:
Le certificat SSL est installé pour le site Nginx, et il le fait
proxy_passpour le site http ordinaire sur le conteneur Apache:server { listen 443 ssl; server_name www.example.com; ssl_certificate /etc/nginx/ssl/letsencrypt/live/www.example.com/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/letsencrypt/live/www.example.com/privkey.pem; access_log /var/log/nginx/example.com.access.log; location / { proxy_pass http://Apache2-PHP5.6:80; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }Dans ce scénario du point de vue du serveur Apache, il sert toujours le site via http
C'est plus laborieux: le certificat SSL est installé à la fois sur le serveur de passerelle Nginx et sur le site Apache mandaté. Ensuite, il serait nécessaire de passer
httpàhttpslaproxy_passvaleur de configuration.
J'aurais aimé que tout se passe bien avec le premier scénario. Mais le fait qu'Apache ait l'impression de servir des trucs sur http pose quelques problèmes: il y a des redirections d'URL cachées que j'aimerais vraiment ne pas reconfigurer / déboguer. Et ces redirections d'URL font quelque chose comme ceci: si l'URL demandée est http://www.example.com, elle est réécrite (état http 301) comme http://www.example.com/main. Cette redirection est reçue par le navigateur, et donc, même si la première requête était sur https, maintenant l'URL redirigée est http. Le html du site contient également des hrefs de chemin complet vers ses propres ressources (fichiers JavaScript et CSS) qui incluent également la référence de protocole. Il n'est pas clair à ce stade si ces hrefs adoptent le protocole à partir de la façon dont la demande a été faite, ou s'il est codé en dur. Quoi qu'il en soit, malheureusement, cela ne fonctionne pas sans creuser sérieusement.
Donc, je me retrouve avec l'option 2. J'ai essayé, cela fonctionne, je peux configurer le même certificat SSL sur Nginx et sur Apache conteneurisé. Mais j'aimerais savoir si c'est vraiment ainsi qu'il faut le laisser fonctionner. Parce que bien que le serveur Apache sache maintenant que le contenu est servi via https, il y a maintenant un double SSL-ing pour chaque demande. Ça ne va pas.
Réponses
Vous devriez être en mesure d'indiquer à Apache que la requête entrante est envoyée par proxy à partir d'une requête HTTPS avec la proxy_set_header X-Forwarded-Proto "https";déclaration dans la première configuration
Vous pouvez résoudre le problème dans votre option n ° 1 (qui, comme vous l'avez dit, est une bien meilleure approche) en définissant HTTP_X_FORWARDED_PROTO dans votre configuration nginx avec
proxy_set_header X-Forwarded-Proto $scheme;
et en configurant WordPress pour le reconnaître en ajoutant cette ligne à wp-config.php
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { $_SERVER['HTTPS'] = 'on';
}
Voir également l' article de support Wordpress pour une variante de cette solution.
Normalement, je préférerais faire tout le gros du travail sur le proxy inverse et garder le site backend qui est exposé aussi original que possible.
Votre problème semble être essentiellement le fait que le backend (WordPress) génère et utilise des URI (absolus) qui diffèrent de ce que vous voulez que les visiteurs utilisent.
Vous pouvez remédier à cela en réécrivant le contenu (HTML) que WordPress génère dans nginx avec le ngx_http_sub_module . Cela vous permettra également de réécrire les URL absolues avec quelque chose de similaire à:
location / {
sub_filter 'http://example.com/' 'https://www.example.com/' ;
sub_filter 'http://www.example.com/' 'https://www.example.com/' ;
sub_filter_once off;
proxy_pass http://Apache2-PHP5.6:80;
proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}