Eu queria saber se o nginx é capaz de lidar com solicitações http e https na mesma porta . [*]
É isso que estou tentando fazer. Estou executando um servidor web (lighttpd) que manipula solicitações http e um programa C que serve uma seção específica da árvore de documentos por https. Esses dois processos são executados no mesmo servidor.
No nível do firewall, eu posso ter apenas uma porta encaminhando tráfego para este servidor . Então, o que eu gostaria de fazer é configurar o nginx neste servidor para que ele escute solicitações em uma única porta e, em seguida:
A) redireciona todas as solicitações http://myhost.com/ * para que elas acessem o localhost: 8080 (onde o lighttpd está escutando)
B) se um usuário solicitar uma URL iniciando com, por exemplo, https: // myhost.com/app, enviará essa solicitação para localhost: 8008 (programa C). Observe que, nesse caso, o tráfego entre o navegador remoto e o nginx deve ser criptografado.
Você acha que isso seria possível? Se for, como pode ser feito?
Eu sei como fazer isso usando duas portas diferentes. O desafio que enfrento é fazer isso com apenas uma única porta (infelizmente, não tenho controle sobre a configuração do firewall nesse ambiente específico, portanto, essa é uma restrição que não posso evitar). O uso de técnicas como a porta reversa em relação ao ssh para ignorar o firewall também não funcionará, porque isso deve funcionar para usuários remotos com nada mais que um navegador da web e um link da Internet.
Se isso estiver além dos recursos do nginx, você conhece algum outro produto que atenda a esses requisitos? (até agora não consegui configurar isso com lighttpd e pound). Eu também preferiria evitar o Apache (embora eu esteja disposto a usá-lo se for a única opção possível).
Agradecemos antecipadamente, Alex
[*] Só para esclarecer, estou falando sobre como lidar com conexões HTTP criptografadas e não criptografadas pela mesma porta. Não importa se a criptografia é feita através de SSL ou TLS.
Respostas:
Para aqueles que possam estar pesquisando:
Adicione
ssl on;
eerror_page 497 $request_uri;
à sua definição de servidor.fonte
ssl on;
eerror_page 497 =200 $request_uri;
à sua definição de servidor. Isso irá alterar o código de status para 200.De acordo com o artigo da wikipedia sobre códigos de status, o Nginx possui um código de erro personalizado quando o tráfego http é enviado para a porta https (código de erro 497)
E de acordo com os documentos do nginx em error_page , você pode definir um URI que será mostrado para um erro específico.
Assim, podemos criar uma uri para a qual os clientes serão enviados quando o código de erro 497 for gerado.
nginx.conf
No entanto, se um cliente fizer uma solicitação por qualquer outro método, exceto um GET, esse pedido será transformado em um GET. Assim, para preservar o método de solicitação pelo qual o cliente entrou; usamos redirecionamentos de processamento de erros, conforme mostrado nos documentos nginx em error_page
E é por isso que usamos o
301 =307
redirecionamento.Usando o arquivo nginx.conf mostrado aqui, podemos ter http e https escutando na mesma porta
fonte
Se você quiser ser realmente esperto, poderá usar um proxy de conexão para detectar os primeiros bytes do fluxo de dados recebidos e enviar a conexão com base no conteúdo do byte 0: se for 0x16 (o SSL / TLS ' handshake 'byte), passe a conexão para o lado SSL; se for um caractere alfabético, faça HTTP normal. Meu comentário sobre a numeração de portas se aplica .
fonte
Sim, é possível, mas precisa corrigir o código-fonte nginx (o HoverHell possui solução sem o patch). O Nginx trata isso como configuração incorreta e não como configuração válida.
A variável $ ssl_session_id pode ser usada para diferir entre conexão simples e ssl.
Patch contra o nginx-0.7.65:
Configuração do servidor:
fonte
Eu não acho que exista algo que possa lidar com dois protocolos diferentes em uma única porta ...
Estou curioso para saber por que você pode encaminhar apenas uma porta, mas isso de lado ... não é o ideal, mas se eu estivesse no seu lugar, eu serviria tudo por https.
fonte
Você não pode suportar HTTP e HTTPS na mesma porta, porque as duas extremidades da conexão esperam falar um determinado idioma e não são inteligentes o suficiente para resolver se a outra extremidade está falando outra coisa.
Como sugeriu seu comentário à resposta de Wil, você pode usar a atualização TLS (acredito que as versões mais recentes do nginx o suportam, embora ainda não tenha tentado), mas isso não está executando HTTP e HTTPS, está executando HTTP com atualização TLS. O problema ainda é o suporte ao navegador - a maioria dos navegadores (ainda) não o suporta. Se você tem um pool limitado de clientes, essa é uma possibilidade, no entanto.
fonte
Não tenho certeza de como isso ocorre, mas o CUPSD responde aos http e https na porta 631. Se o nginx não puder fazer isso agora, talvez eles possam aprender como a equipe do CUPS consegue, mas o CUPS está sob a GPL, portanto, o nginx pode precisar alterar sua licença se quiser implementar esse recurso e não conseguir encontrar o código para fazê-lo em outro lugar.
fonte
Em teoria, você poderia ter uma página da web acessível via HTTP, capaz de abrir um WebSocket em https: 443 para qualquer lugar que ele quiser. O handshake inicial do WebSocket é HTTP. Portanto, sim, é possível criar uma página com aparência insegura, realmente capaz de comunicação segura. Você poderia fazer isso com a Netty Library .
fonte
Finalmente, é possível fazer isso corretamente desde 1.15.2. Veja as informações aqui .
No seu nginx.conf, adicione um bloco como este (fora do bloco http):
Em seguida, você pode criar seu bloco de servidor normal, mas ouvindo estas portas diferentes:
Dessa forma, o bloco de fluxo pode ler e detectar se é TLS ou não (na porta 8080 neste exemplo) e, em seguida, o proxy passa localmente para a porta correta do servidor.
fonte