AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / server / Perguntas / 67316
Accepted
MikeN
MikeN
Asked: 2009-09-22 06:04:43 +0800 CST2009-09-22 06:04:43 +0800 CST 2009-09-22 06:04:43 +0800 CST

No Nginx, como posso reescrever todas as solicitações http para https mantendo o subdomínio?

  • 772

Eu quero reescrever todas as solicitações http no meu servidor web para serem solicitações https, comecei com o seguinte:

servidor {
    ouça 80;

    local / {
      reescrever ^(.*) https://mysite.com$1 permanente;
    }
...


Um problema é que isso elimina qualquer informação 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?

nginx
  • 11 11 respostas
  • 558786 Views

11 respostas

  • Voted
  1. Best Answer
    Saif Bechan
    2011-12-06T12:43:47+08:002011-12-06T12:43:47+08:00

    Maneira correta em novas versões do nginx

    Acontece que minha primeira resposta a esta pergunta estava correta em determinado momento, mas se transformou em outra armadilha - para se manter atualizado, verifique Armadilhas de reescrita de impostos

    Fui corrigido por muitos usuários do SE, então o crédito vai para eles, mas o mais importante, aqui está o código correto:

    server {
           listen         80;
           server_name    my.domain.com;
           return         301 https://$server_name$request_uri;
    }
    
    server {
           listen         443 ssl;
           server_name    my.domain.com;
           # add Strict-Transport-Security to prevent man in the middle attacks
           add_header Strict-Transport-Security "max-age=31536000" always; 
    
           [....]
    }
    
    • 792
  2. Michael Neale
    2010-08-17T19:07:22+08:002010-08-17T19:07:22+08:00

    NOTA: A melhor maneira de fazer isso foi fornecida por https://serverfault.com/a/401632/3641 - mas é repetida aqui:

    server {
        listen         80;
        return 301 https://$host$request_uri;
    }
    

    No caso mais simples, seu host será corrigido para ser o serviço para o qual você deseja enviá-los - isso fará um redirecionamento 301 para o navegador e a URL do navegador será atualizada de acordo.

    Abaixo está a resposta anterior, que é ineficiente devido ao regex, um simples 301 é ótimo, como mostrado por @kmindi

    Eu tenho usado o nginx 0.8.39 e superior e usei o seguinte:

     server {
           listen 80;
           rewrite ^(.*) https://$host$1 permanent;
     }
    

    Envia um redirecionamento permanente para o cliente.

    • 287
  3. kmindi
    2012-06-24T09:19:34+08:002012-06-24T09:19:34+08:00

    Eu acho que a melhor e única maneira deve ser usar um redirecionamento HTTP 301 movido permanentemente assim:

    server {
        listen         [::]:80;
        return 301 https://$host$request_uri;
    }
    

    O redirecionamento HTTP 301 movido permanentemente também é o mais eficiente, pois não há regex a ser avaliada, de acordo com os pitfails já mencionados .


    O novo HTTP 308 Moved Permanently preserva o método Request e é suportado pelos principais navegadores . Por exemplo, usar 308impede que os navegadores alterem o método de solicitação de POSTpara GETpara 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.phpe será redirecionado para exatamente https://192.168.0.100/index.php.

    Eu uso listen [::]:80no meu host porque eu bindv6onlyconfigurei para false, então ele também se liga ao soquete ipv4. mude para listen 80se você não quiser IPv6 ou quiser vincular em outro lugar.

    A solução de Saif Bechan usa o server_nameque no meu caso é localhost, mas que não é acessível por uma rede.

    A solução de Michael Neale é boa, mas de acordo com os pitfails, existe uma solução melhor com o redirecionamento 301 ;)

    • 129
  4. Oriol
    2015-08-01T11:50:48+08:002015-08-01T11:50:48+08:00

    Dentro do bloco do servidor, você também pode fazer o seguinte:

    # Force HTTPS connection. This rules is domain agnostic
    if ($scheme != "https") {
        rewrite ^ https://$host$uri permanent;
    }
    
    • 23
  5. Aleck Landgraf
    2012-06-25T20:29:06+08:002012-06-25T20:29:06+08:00

    O 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:

    server {
      listen 80;
      server_name _;
      rewrite ^ https://$host$request_uri? permanent;
    }
    server {
      listen  443;
      server_name example.com;
      ssl on;
      ssl_certificate /etc/ssl/certs/myssl.crt;
      ssl_certificate_key /etc/ssl/private/myssl.key;
      ssl_prefer_server_ciphers       on;
    # ...
    # rest of config here
    # ...
    }
    
    • 19
  6. Mahmoud Al-Qudsi
    2017-03-20T12:24:33+08:002017-03-20T12:24:33+08:00

    Postei um comentário sobre a resposta correta há muito, muito tempo com uma correção muito importante, mas sinto que é necessário destacar essa correção em sua própria resposta. Nenhuma das respostas anteriores é segura de usar se em algum momento você configurou um HTTP não seguro e espera conteúdo do usuário, tem formulários, hospeda uma API ou configurou qualquer site, ferramenta, aplicativo ou utilitário para falar com seu site.

    O problema ocorre quando uma POSTsolicitação é feita ao seu servidor. Se a resposta do servidor com um 30xredirecionamento simples, o conteúdo do POST será perdido. O que acontece é que o navegador/cliente atualizará a solicitação para SSL, mas fará o downgrade paraPOST uma GETsolicitação. Os POSTparâ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 307redirecionamento. Isso é detalhado na RFC 7231 S6.4.7:

      Note: This status code is similar to 302 (Found), except that it
      does not allow changing the request method from POST to GET.  This
      specification defines no equivalent counterpart for 301 (Moved
      Permanently) ([RFC7238], however, defines the status code 308
      (Permanent Redirect) for this purpose).
    

    A solução, adaptada da solução aceita, é usar 307em seu código de redirecionamento:

    server {
           listen         80;
           server_name    my.domain.com;
           return         307 https://$server_name$request_uri;
    }
    
    server {
           listen         443 ssl;
           server_name    my.domain.com;
           # add Strict-Transport-Security to prevent man in the middle attacks
           add_header Strict-Transport-Security "max-age=31536000"; 
    
           [....]
    }
    
    • 10
  7. stamster
    2016-04-22T10:27:43+08:002016-04-22T10:27:43+08:00

    Consegui fazer assim:

    server {
    listen 80;
    listen 443 ssl;
    
    server_name domain.tld www.domain.tld;
    
    # global HTTP handler
    if ($scheme = http) {
            return 301 https://www.domain.tld$request_uri;
    }
    
    # global non-WWW HTTPS handler
    if ($http_host = domain.tld){
            return 303 https://www.domain.tld$request_uri;
    }
    }
    

    https://stackoverflow.com/a/36777526/6076984

    • 4
  8. MANCHUCK
    2017-01-05T09:09:18+08:002017-01-05T09:09:18+08:00

    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 aos clientes, verifico o cabeçalho X-Forwarded-Proto e redireciono:

    if ($http_x_forwarded_proto != 'https') {
        return 301 "https://www.exampl.com";
    }
    
    • 4
  9. Paul A Jungwirth
    2018-03-25T21:58:53+08:002018-03-25T21:58:53+08:00

    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 outro lugar na Internet. Se seus logs estiverem cheios de mensagens como esta, você saberá que isso aconteceu com você:

    42.232.104.114 - - [25/Mar/2018:04:50:49 +0000] "GET http://www.ioffer.com/i/new-fashion-fine-gold-bracelet-versaec-bracelet-641175733 HTTP/1.1" 301 185 "http://www.ioffer.com/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Hotbar 4.1.8.0; RogueCleaner; Alexa Toolbar)"
    

    O problema é que $hostvai ecoar de volta o que o navegador enviar no Hostcabeçalho ou até mesmo o nome do host da linha de abertura do HTTP, como esta:

    GET http://www.ioffer.com/i/new-fashion-fine-gold-bracelet-versaec-bracelet-641175733 HTTP/1.1
    

    Por causa desse problema, algumas outras respostas aqui recomendam usar $server_nameem vez de $host. $server_namesempre avalia o que você coloca na server_namedeclaração. Mas se você tiver vários subdomínios ou usar um curinga, isso não funcionará, porque $server_nameusará apenas a primeira entrada após a server_namedeclaração e, mais importante, apenas ecoará um curinga (não o expandirá).

    Então, como oferecer suporte a vários domínios mantendo a segurança? Em meus próprios sistemas, lidei com esse dilema listando primeirodefault_server um bloco que não usa $host, e depois listando um bloco curinga que usa:

    server {
      listen 80 default_server;
      server_name example.com;
      return 301 https://example.com$request_uri;
    }
    server {
      listen 80;
      server_name *.example.com;
      return 301 https://$host$request_uri;
    }
    

    (Você também pode listar mais de um domínio no segundo bloco.)

    Com essa combinação, os domínios sem correspondência serão redirecionados para algum lugar codificado (sempre example.com), e os domínios que corresponderem ao seu irão para o lugar certo. Seu servidor não será útil como um proxy aberto, então você não atrairá problemas.

    Se você está se sentindo mal-humorado, suponho que você também pode fazer com que o default_serverbloco não corresponda a nenhum de seus domínios legítimos e sirva algo ofensivo. . . .

    [1] Tecnicamente "proxy" é a palavra errada, pois seu servidor não está saindo e atendendo as requisições dos 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 com ruído e consome sua CPU e largura de banda, então você pode parar com isso.

    • 4
  10. Julius
    2019-03-01T09:21:24+08:002019-03-01T09:21:24+08:00

    Parece que ninguém realmente acertou 100%. Para que as solicitações da porta 80 vão para seus equivalentes 443 para um servidor web inteiro, você precisa usar a diretiva listen , não a diretiva server_name para especificar o nome catch-all. Veja também https://nginx.org/en/docs/http/request_processing.html

    servidor {
        ouvir 80 padrão;
        ouvir [::]:80 padrão;
          return 307 https://$host$request_uri;
    }
    
    • $host captura nomes de subdomínios.
    • 307 e 308 incluem URIs de solicitação POST e GET.
    • 307 é Temporário, mude para o Permanente 308 após testes completos:

    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 retornava alguns vhosts existentes. Minha ordem de trabalho com problemas do nginx é sempre começar removendo o arquivo padrão, colocando-o de volta comentando linha por linha para ver onde está errado.

    • 2

relate perguntas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Ping uma porta específica

    • 18 respostas
  • Marko Smith

    Qual porta o SFTP usa?

    • 6 respostas
  • Marko Smith

    Resolver o nome do host do endereço IP

    • 8 respostas
  • Marko Smith

    Como posso classificar a saída du -h por tamanho

    • 30 respostas
  • Marko Smith

    Linha de comando para listar usuários em um grupo do Windows Active Directory?

    • 9 respostas
  • Marko Smith

    Qual é o utilitário de linha de comando no Windows para fazer uma pesquisa reversa de DNS?

    • 14 respostas
  • Marko Smith

    Como verificar se uma porta está bloqueada em uma máquina Windows?

    • 4 respostas
  • Marko Smith

    Qual porta devo abrir para permitir a área de trabalho remota?

    • 9 respostas
  • Marko Smith

    O que é um arquivo Pem e como ele difere de outros formatos de arquivo de chave gerada pelo OpenSSL?

    • 3 respostas
  • Marko Smith

    Como determinar se uma variável bash está vazia?

    • 15 respostas
  • Martin Hope
    Davie Ping uma porta específica 2009-10-09 01:57:50 +0800 CST
  • Martin Hope
    MikeN No Nginx, como posso reescrever todas as solicitações http para https mantendo o subdomínio? 2009-09-22 06:04:43 +0800 CST
  • Martin Hope
    Tom Feiner Como posso classificar a saída du -h por tamanho 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    0x89 Qual é a diferença entre colchetes duplos e simples no bash? 2009-08-10 13:11:51 +0800 CST
  • Martin Hope
    kch Como altero a senha da minha chave privada? 2009-08-06 21:37:57 +0800 CST
  • Martin Hope
    Kyle Brandt Como funciona a sub-rede IPv4? 2009-08-05 06:05:31 +0800 CST
  • Martin Hope
    Noah Goodrich O que é um arquivo Pem e como ele difere de outros formatos de arquivo de chave gerada pelo OpenSSL? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent Como determinar se uma variável bash está vazia? 2009-05-13 09:54:48 +0800 CST

Hot tag

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve