Quero reescrever todas as solicitações http no meu servidor da Web para serem https, comecei com o seguinte:
servidor { ouça 80; local / { reescrever ^ (. *) https: //mysite.com$1 permanente; } ...
Um problema é que isso remove todas as informações de subdomínio (por exemplo, node1.mysite.com/folder), como eu poderia reescrever o acima para redirecionar tudo para https e manter o subdomínio?
Respostas:
Maneira correta em novas versões do nginx
Minha primeira resposta a esta pergunta estava correta em um determinado momento, mas ela se transformou em outra armadilha - para manter-se atualizado, verifique Taxing reescrever armadilhas
Fui corrigido por muitos usuários do SE, então o crédito é para eles, mas mais importante, aqui está o código correto:
fonte
$host
vez de$server_name
se estiver usando subdomínios.NOTA: A melhor maneira de fazer isso foi fornecida por https://serverfault.com/a/401632/3641 - mas é repetida aqui:
No caso mais simples, seu host será corrigido como o seu serviço para o qual você deseja enviá-lo - isso fará um redirecionamento 301 para o navegador e o URL do navegador será atualizado de acordo.
Abaixo está a resposta anterior, que é ineficiente devido ao regex, um simples 301 é ótimo, como mostrado por @kmindi
Estou usando o nginx 0.8.39 e superior e usei o seguinte:
Envia um redirecionamento permanente para o cliente.
fonte
Eu acho que a melhor e única maneira deve estar usando um redirecionamento HTTP 301 movido permanentemente como este:
O redirecionamento HTTP 301 movido permanentemente também é o mais eficiente, pois não há regex a ser avaliado, de acordo com os pitfails já mencionados .
O novo HTTP 308 movido permanentemente preserva o método Request e é suportado pelos principais navegadores . Por exemplo, o uso
308
impede que os navegadores alterem o método de solicitação dePOST
paraGET
para a solicitação de redirecionamento.Se você deseja preservar o nome do host e o subdomínio, este é o caminho.
Isso ainda funciona se você não tiver DNS , pois também o estou usando localmente. Estou solicitando, por exemplo, com
http://192.168.0.100/index.php
e será redirecionado para exatamentehttps://192.168.0.100/index.php
.Eu uso
listen [::]:80
no meu host porquebindv6only
defini comofalse
, portanto, ele também se liga ao soquete ipv4. altere paralisten 80
se você não deseja IPv6 ou deseja vincular em outro lugar.A solução da Saif Bechan usa o
server_name
que, no meu caso, é localhost, mas que não é acessível através de uma rede.A solução de Michael Neale é boa, mas de acordo com as pitfails, há uma solução melhor com o redirecionamento 301;)
fonte
Dentro do bloco do servidor, você também pode fazer o seguinte:
fonte
O exemplo acima não funcionou com novos subdomínios sendo criados o tempo todo. por exemplo, AAA.example.com BBB.example.com para cerca de 30 subdomínios.
Finalmente consegui uma configuração trabalhando com o seguinte:
fonte
301 https://*/
ou cancelaria a solicitação prematuramente nas outras respostas aqui.server_name _;
com$host
foi a resposta que fez o truque. +1_
pelo domínio real, por exemplo,.domain.com
eu tinha dois servidores e o nginx estava acidentalmente direcionando um dos meus servidores para o servidor padrão.Publiquei um comentário sobre a resposta correta há muito, muito tempo atrás, com uma correção muito importante, mas considero necessário destacar essa correção em sua própria resposta. Nenhuma das respostas anteriores é segura de usar se, em algum momento, você tiver configurado HTTP inseguro e esperar conteúdo do usuário, tiver formulários, hospedar uma API ou tiver configurado qualquer site, ferramenta, aplicativo ou utilitário para falar com seu site.
O problema ocorre quando uma
POST
solicitação é feita ao seu servidor. Se a resposta do servidor com um30x
redirecionamento simples, o conteúdo do POST será perdido. O que acontece é que o navegador / cliente irá atualizar o pedido para SSL, mas degradar oPOST
a umGET
pedido. OsPOST
parâmetros serão perdidos e uma solicitação incorreta será feita ao seu servidor.A solução é simples. Você precisa usar um
HTTP 1.1 307
redirecionamento. Isso está detalhado no RFC 7231 S6.4.7:A solução, adaptada da solução aceita, é usar
307
no seu código de redirecionamento:fonte
Eu consegui fazer assim:
https://stackoverflow.com/a/36777526/6076984
fonte
Estou executando o ngnix atrás de um AWS ELB. O ELB está conversando com o ngnix por http. Como o ELB não tem como enviar redirecionamentos para clientes, verifico o cabeçalho X-Forwarded-Proto e redireciono:
fonte
Se você
return 301 https://$host$request_uri;
for a resposta padrão na porta 80, seu servidor poderá, mais cedo ou mais tarde, entrar em uma lista de proxies abertos [1] e começar a ser abusado para enviar tráfego para outros lugares na Internet. Se seus logs forem preenchidos com mensagens como esta, você saberá que isso aconteceu com você:O problema é que
$host
ele retornará o que o navegador enviar noHost
cabeçalho ou até o nome do host da linha de abertura do HTTP, como esta:Devido a esse problema, algumas outras respostas aqui recomendam o uso em
$server_name
vez de$host
.$server_name
sempre avalia o que você coloca naserver_name
declaração. Mas se você tiver vários subdomínios lá ou usar um curinga, isso não funcionará, porque$server_name
só usa a primeira entrada após aserver_name
declaração e, o mais importante, apenas fará eco de um curinga (não o expanda).Então, como oferecer suporte a vários domínios enquanto mantém a segurança? Em meus próprios sistemas, lidei com esse dilema listando primeiro um
default_server
bloco que não usa$host
e, em seguida, listando um bloco curinga que:(Você também pode listar mais de um domínio no segundo bloco.)
Com essa combinação, os domínios não correspondentes serão redirecionados para algum lugar codificado (sempre
example.com
) e os domínios que correspondem ao seu irão para o lugar certo. Seu servidor não será útil como um proxy aberto, portanto você não estará atraindo problemas.Se você estiver com raiva, suponho que você também possa fazer com que o
default_server
bloco não corresponda a nenhum dos seus domínios legítimos e sirva algo ofensivo. . . .[1] Tecnicamente "proxy" é a palavra errada, porque seu servidor não está saindo e atendendo solicitações para os clientes, apenas enviando um redirecionamento, mas não tenho certeza qual seria a palavra certa. Também não tenho certeza de qual é o objetivo, mas ele enche seus logs de ruído e consome sua CPU e largura de banda; portanto, é melhor parar com isso.
fonte
Parece que ninguém realmente acertou 100%. Para que as solicitações da porta 80 atinjam seus equivalentes 443 para um servidor da Web inteiro, é necessário usar a diretiva listen , não a diretiva server_name para especificar o nome geral . Veja também https://nginx.org/en/docs/http/request_processing.html
E certifique-se de verificar o que já está em /etc/nginx/conf.d/, porque na maioria das vezes eu tive problemas em que o default.conf retornou algum vhost existente. Minha ordem de trabalhar com os problemas do nginx está sempre começando movendo o arquivo padrão, colocando-o de volta comentando linha por linha para ver onde ele dá errado.
fonte
fonte