je me demandais si nginx est capable de gérer les requêtes http et https sur le même port . [*]
C'est ce que j'essaie de faire. J'exécute un serveur Web (lighttpd) gérant les requêtes http et un programme C qui dessert une section particulière de l'arborescence de documents via https. Ces deux processus s'exécutent sur le même serveur.
Au niveau du pare-feu, je ne peux avoir qu'un seul port redirigeant le trafic vers ce serveur . Donc, ce que je voudrais faire, c'est configurer nginx sur ce serveur pour qu'il écoute les requêtes sur un seul port, puis:
A) redirige toutes les requêtes http://myhost.com/ * afin qu'elles se dirigent vers localhost: 8080 (où lighttpd écoute)
B) si un utilisateur demande une URL commençant par, par exemple, https: // myhost.com/app, il envoie cette demande à localhost: 8008 (programme C). Notez que dans ce cas, le trafic entre le navigateur distant et nginx doit être chiffré.
Pensez-vous que cela pourrait être possible? Si tel est le cas, comment le faire?
Je sais comment faire cela en utilisant deux ports différents. Le défi auquel je suis confronté consiste à le faire avec un seul port (malheureusement, je n'ai pas de contrôle sur la configuration du pare-feu dans cet environnement particulier, c'est donc une restriction que je ne peux pas éviter). L'utilisation de techniques telles que la redirection de port inverse via ssh pour contourner le pare-feu ne fonctionnera pas non plus, car cela devrait fonctionner pour les utilisateurs distants n'ayant rien de plus qu'un navigateur Web et un lien Internet.
Si cela dépasse les capacités de nginx, connaissez-vous un autre produit qui pourrait répondre à ces exigences? (jusqu'à présent, je n'ai pas réussi à configurer cela avec lighttpd et pound). Je préfère également éviter Apache (même si je suis prêt à l'utiliser si c'est le seul choix possible).
Merci d'avance, Alex
[*] Juste pour être clair, je parle de la gestion des connexions HTTP chiffrées et non chiffrées via le même port. Peu importe que le cryptage soit effectué via SSL ou TLS.
Réponses:
Selon un article de wikipedia sur les codes d'état, Nginx a un code d'erreur personnalisé lorsque le trafic http est envoyé au port https (code d'erreur 497)
Et selon les documents nginx sur error_page , vous pouvez définir un URI qui sera affiché pour une erreur spécifique.
Ainsi, nous pouvons créer un uri auquel les clients seront envoyés lorsque le code d'erreur 497 sera généré.
nginx.conf
Cependant, si un client fait une demande via une autre méthode que GET, cette demande sera transformée en GET. Ainsi, pour conserver la méthode de demande par laquelle le client est entré; nous utilisons des redirections de traitement d'erreur comme indiqué dans les documents nginx sur error_page
Et c'est pourquoi nous utilisons la
301 =307
redirection.En utilisant le fichier nginx.conf montré ici, nous pouvons écouter http et https sur le même port
la source
Pour ceux qui pourraient chercher:
Ajoutez
ssl on;
eterror_page 497 $request_uri;
à votre définition de serveur.la source
ssl on;
eterror_page 497 =200 $request_uri;
à la définition de votre serveur. Cela changera le code de statut en 200.Si vous vouliez être vraiment intelligent, vous pouvez utiliser un proxy de connexion pour renifler les deux premiers octets du flux de données entrant et transmettre la connexion en fonction du contenu de l'octet 0: si c'est 0x16 (le SSL / TLS ' handshake 'byte), passez la connexion au côté SSL, si c'est un caractère alphabétique, faites HTTP normal. Mon commentaire sur la numérotation des ports s'applique .
la source
Oui, c'est possible, mais il faut patcher le code source nginx (HoverHell a une solution sans patcher). Nginx traite cela comme une mauvaise configuration plutôt qu'une configuration valide.
La variable $ ssl_session_id peut être utilisée pour faire la différence entre une connexion simple et une connexion ssl.
Patch contre nginx-0.7.65:
Configuration du serveur:
la source
Je ne pense pas qu'il y ait quoi que ce soit qui puisse gérer deux protocoles différents sur un seul port ...
Je suis curieux de savoir pourquoi vous ne pouvez transférer qu'un seul port, mais cela mis à part ... ce n'est pas idéal mais si j'étais à votre place, je servirais tout sur https.
la source
Vous ne pouvez pas prendre en charge HTTP et HTTPS sur le même port, car les deux extrémités de la connexion s'attendent à parler une certaine langue et ne sont pas assez intelligentes pour déterminer si l'autre extrémité parle autre chose.
Comme le suggère votre commentaire sur la réponse de Wil, vous pouvez utiliser la mise à niveau TLS (je pense que les versions plus récentes de nginx le prennent en charge, bien que je n'aie pas essayé), mais cela n'exécute pas HTTP et HTTPS, il exécute simplement HTTP avec la mise à niveau TLS. Le problème est toujours la prise en charge du navigateur - la plupart des navigateurs (toujours) ne la prennent pas en charge. Si vous avez un bassin limité de clients, c'est une possibilité, cependant.
la source
Je ne sais pas comment il le retire, mais CUPSD répond à la fois à http et https sur le port 631. Si nginx ne peut pas le faire maintenant, ils peuvent peut-être apprendre de la façon dont l'équipe CUPS le retire, mais CUPS est sous le GPL, donc nginx devra peut-être envisager de modifier sa licence s'il souhaite implémenter une telle capacité et ne peut pas trouver le code pour le faire ailleurs.
la source
En théorie, vous pourriez avoir une page Web accessible via HTTP, qui est capable d'ouvrir un WebSocket sur https: 443 à l'endroit où il le souhaite. La poignée de main initiale de WebSocket est HTTP. Donc, oui, il est possible de créer une page d'apparence non sécurisée réellement capable de sécuriser la communication. Vous pouvez le faire avec la bibliothèque Netty .
la source
C'est enfin possible de faire correctement depuis la 1.15.2. Voir les informations ici .
Dans votre nginx.conf, ajoutez un bloc comme celui-ci (en dehors du bloc http):
Ensuite, vous pouvez créer votre bloc serveur normal, mais en écoutant sur ces différents ports:
De cette façon, le bloc de flux peut lire et détecter s'il s'agit de TLS ou non (sur le port 8080 dans cet exemple), puis le proxy le transmet localement au port de serveur correct.
la source