Y a-t-il un moyen de rediriger les demandes HTTPS vers HTTP en ajoutant une règle dans le fichier vhost du domaine?
Réponses
Trop de publicités?Pourquoi quelque chose comme ça est-il utile? Au premier regard, je n'étais pas sûr que cela puisse être fait. Mais cela posait une question intéressante.
Vous pourriez essayer de mettre une déclaration de redirection dans votre fichier de configuration et redémarrer votre serveur. Deux possibilités pourraient se produire:
- Le serveur émettra la redirection - ce que vous semblez vouloir.
- Le serveur effectuera d'abord l'échange https, puis émettra la redirection, dans ce cas, quel est l'intérêt?
J'ajouterai plus si je trouve quelque chose de plus concret.
MISE À JOUR: (quelques heures plus tard) Vous pourriez essayer ceci. Vous devez mettre ceci dans votre fichier nginx.conf -
server {
listen 443;
server_name _ *;
rewrite ^(.*) http://$host$1 permanent;
}
Envoie une redirection permanente au client. Je suppose que vous utilisez le port 443 (par défaut) pour le https.
server {
listen 80;
server_name _ *;
...
}
Ajoutez ceci pour que vos requêtes http normales sur le port 80 ne soient pas perturbées.
MISE À JOUR: 18 décembre 2016 - server_name _
devrait être utilisé au lieu de server_name _ *
dans les versions nginx > 0.6.25 (merci à @Luca Steeb)
rewrite
et if
devraient être évités avec Nginx. La célèbre phrase est : "Nginx n'est pas Apache" : en d'autres termes, Nginx a de meilleures façons de gérer les URL que la réécriture. return
fait toujours techniquement partie du module de réécriture, mais il ne comporte pas le surcoût de rewrite
, et n'est pas aussi sujet aux problèmes que if
.
Nginx a une page entière sur pourquoi if
est "maléfique". Il fournit également une page constructive expliquant pourquoi rewrite
et if
sont mauvais, et comment vous pouvez contourner cela. Voici ce que la page a à dire concernant rewrite
et if
:
C'est une façon incorrecte, fastidieuse et inefficace de le faire.
Vous pouvez résoudre ce problème de manière appropriée en utilisant return
:
server {
listen 443 ssl;
# Vous aurez besoin d'un certificat générique si vous souhaitez spécifier plusieurs
# noms de domaine ici.
server_name domain.example www.domain.example;
# Si vous avez un certificat partagé entre plusieurs serveurs,
# vous pouvez les déplacer en dehors du bloc `server`.
ssl_certificate /chemin/vers/cert.pem;
ssl_certificate_key /chemin/vers/cert.key;
# 301 indique une redirection permanente. Si votre redirection est
# temporaire, vous pouvez la changer en 302 ou omettre le numéro
# complètement.
# $http_host est le nom d'hôte et, le cas échéant, le port - contrairement à $host,
# qui ne fonctionnera pas sur des ports non standard
# $request_uri est l'URI brute demandée par le client, y compris éventuellement
# une chaîne de requête
return 301 http://$http_host$request_uri;
}
Si vous attendez beaucoup de robots n'envoyant pas d'en-tête Host
, vous pouvez utiliser $host
au lieu de $http_host
tant que vous restez sur les ports 80 et 443. Sinon, vous devrez dynamiquement remplir un substitut $http_host
. Ce code est efficace et sûr tant qu'il apparaît à la racine de server
(plutôt que dans un bloc location
), malgré l'utilisation de if
. Cependant, vous devriez utiliser un serveur par défaut pour que cela soit applicable, ce qui devrait être évité avec https.
set $request_host $server_name:$server_port;
if ($http_host) {
set $request_host $http_host;
}
Si vous souhaitez imposer SSL/TLS pour des chemins spécifiques, mais l'interdire autrement :
server {
listen 443 ssl;
server_name domain.example;
ssl_certificate /chemin/vers/cert.pem;
ssl_certificate_key /chemin/vers/cert.key;
location / {
return 301 http://$host$request_uri;
}
location /secure/ {
try_files $uri =404;
}
}
server {
listen 80;
server_name domain.example;
location / {
try_files $uri =404;
}
location /secure/ {
return 301 https://$http_host$request_uri;
}
}
Si votre serveur n'est pas en communication directe avec le client - par exemple, si vous utilisez CloudFlare - les choses se compliquent un peu. Vous devrez vous assurer que tout serveur en communication directe avec le client ajoute un en-tête X-Forwarded-Proto
approprié à la requête.
L'utilisation de ceci est une proposition compliquée ; pour une explication détaillée, consultez IfIsEvil. Pour que cela soit utile, le bloc if
ne peut pas être à l'intérieur d'un bloc location
, pour diverses raisons complexes. Cela force l'utilisation de rewrite
pour les tests d'URI. En bref, si vous devez utiliser ceci sur un serveur en production... ne le faites pas. Pensez-y de cette façon : si vous avez dépassé Apache, vous avez dépassé cette solution.
/secure, /secure/, et tout ce qui est dans /secure/ imposera https, tandis que toutes les autres URI imposeront http. La construction PCRE (?!
) est une assertion de recherche négative. (?:
) est un groupe non capturant.
server {
# Si vous utilisez https entre les serveurs, vous devrez modifier le bloc listen
# et vous assurer que les déclarations ssl_* appropriées sont présentes ou
# héritées.
listen 80;
server_name domain.example;
if ($http_x_forwarded_proto = https) {
rewrite ^(?!/secure)/ http://$http_host$request_uri? permanent;
}
if ($http_x_forwarded_proto != https) {
rewrite ^/secure(?:/|$) https://$http_host$request_uri? permanent;
}
}
Cette question aurait été mieux adaptée au site serverfault.com.
Une meilleure façon de rediriger vers http:
server {
listen 443;
return 301 http://$host$request_uri;
}
Cela évite à la fois la clause 'if' et l'expression régulière dans la réécriture qui sont des fonctionnalités des autres solutions à ce jour. Les deux ont des implications en termes de performance, bien que en pratique, il faudrait avoir beaucoup de trafic avant que cela ne soit important.
En fonction de votre configuration, vous voudrez probablement également spécifier une adresse IP dans la clause listen, et peut-être une clause servername ci-dessus. Tel qu'il est, cela s'appliquera à toutes les demandes de port 443 pour tous les noms de domaine. En général, vous voulez une adresse IP par domaine avec https, donc lier le ci-dessus à une IP est plus pertinent que de le lier à un nom de domaine, mais il existe des variations, par exemple lorsque tous les domaines sont des sous-domaines d'un domaine.
MODIFIER: La TLS est quasi universelle maintenant, et avec elle l'Identification du Nom du Serveur (SNI) qui permet des sites HTTPS sur plusieurs domaines partageant une seule IP. Il y a un bon article disponible ici
Ouvrez le fichier de configuration Nginx pour votre domaine. Ce fichier est généralement situé dans le répertoire /etc/nginx/sites-available/ sur les systèmes Linux. Ensuite, dans le bloc de serveur pour la configuration HTTPS (SSL), ajoutez les lignes suivantes pour effectuer la redirection :
server {
listen 443 ssl;
server_name votre-domaine.com;
ssl_certificate /chemin/vers/votre/certificat/ssl.crt;
ssl_certificate_key /chemin/vers/votre/cle/privee.key;
# Effectuer la redirection HTTPS vers HTTP
location / {
return 301 http://$host$request_uri;
}
# Les réglages de configuration SSL supplémentaires vont ici
}
Enregistrez et quittez l'éditeur de texte, puis testez votre configuration Nginx avec :
sudo nginx -t
Si le terminal affiche "ok" et "valide", vous pouvez recharger la configuration Nginx en utilisant :
sudo systemctl reload nginx
Cette configuration redirigera toutes les demandes HTTPS vers HTTP avec une redirection 301 (permanente).
- Réponses précédentes
- Plus de réponses