Permite criptografar com um proxy reverso nginx

35

Introdução

Eu tenho um servidor dev (atualmente rodando o Ubuntu 14.04 LTS), que eu tenho usado há algum tempo para hospedar várias ferramentas de desenvolvimento em diferentes portas. Como as portas podem ser difíceis de lembrar, decidi usar a porta 80 para todos os meus serviços e fazer o encaminhamento de porta internamente, com base no nome do host.

Em vez de escrever domain.com:5432, posso acessá-lo simplesmente por sub.domain.com

Por exemplo, o aplicativo X, que está usando a porta 7547 e está em execução em sub.domain.com, tem a seguinte configuração nginx:

upstream sub {
    server 127.0.0.1:7547;
}

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com;
    access_log /var/log/nginx/sub.log combined;
    location / {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:7547;
            proxy_set_header Authorization "";
    }
}

A questão

Dada a estrutura de configuração atual, que escolhi, é possível usar o letsencrypt e executar os diferentes serviços em https?

    
por 0x450 06.04.2016 / 13:23

2 respostas

71

Sim, você pode ter solicitações de proxy nginx em servidores HTTP e depois responder a clientes por HTTPS. Ao fazer isso, você deve ter certeza de que o nginx < - > proxy connect é improvável de ser detectado por quem quer que seja seu atacante esperado. Abordagens suficientemente seguras podem incluir:

  • fazendo proxy para o mesmo host (como você)
  • fazendo proxy para outros hosts por trás do seu firewall

Proxying para outro host na Internet pública é improvável que seja seguro o suficiente.

Aqui estão as instruções para obter um certificado Let's Encrypt usando o mesmo servidor da Web que você está usando como proxy.

Solicitando seu certificado inicial de Let's Encrypt

Modifique sua cláusula server para permitir que o subdiretório .well-known seja servido a partir de um diretório local, por exemplo:

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com;
    […]
    location /.well-known {
            alias /var/www/sub.domain.com/.well-known;
    }

    location / {
        # proxy commands go here
        […]
    }
}

http://sub.domain.com/.well-known é onde os servidores Vamos criptografar procurarão as respostas para os desafios que ele apresenta.

Você pode então usar o cliente certbot para solicitar um certificado de Let's Encrypt usando o webroot (como root):

certbot certonly --webroot -w /var/www/sub.domain.com/ -d sub.domain.com -d www.sub.domain.com

Sua chave, certificado e cadeia de certificados serão instalados em /etc/letsencrypt/live/sub.domain.com/

Configurando o nginx para usar seu certificado

Primeiro, crie uma nova cláusula do servidor como esta:

server {
    listen 443 ssl;

    # if you wish, you can use the below line for listen instead
    # which enables HTTP/2
    # requires nginx version >= 1.9.5
    # listen 443 ssl http2;

    server_name sub.domain.com www.sub.domain.com;

    ssl_certificate /etc/letsencrypt/live/sub.domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sub.domain.com/privkey.pem;

    # Turn on OCSP stapling as recommended at 
    # https://community.letsencrypt.org/t/integration-guide/13123 
    # requires nginx version >= 1.3.7
    ssl_stapling on;
    ssl_stapling_verify on;

    # Uncomment this line only after testing in browsers,
    # as it commits you to continuing to serve your site over HTTPS
    # in future
    # add_header Strict-Transport-Security "max-age=31536000";

    access_log /var/log/nginx/sub.log combined;

    # maintain the .well-known directory alias for renewals
    location /.well-known {
        alias /var/www/sub.domain.com/.well-known;
    }

    location / {
        # proxy commands go here as in your port 80 configuration
        […]
    }
}

Recarregar nginx:

service nginx reload

Verifique se o HTTPS agora funciona visitando https://sub.domain.com e https://www.sub.domain.com no seu navegador (e em outros navegadores que você deseja especificamente oferecer suporte) e verificando se eles não reportam erros de certificado.

Recomendado: veja também raymii.org: Segurança SSL strong no nginx e teste sua configuração nos Laboratórios SSL .

(Recomendado) Redirecionar solicitações HTTP para HTTPS

Depois de confirmar que seu site funciona com a versão https:// do URL, em vez de alguns usuários terem exibido conteúdo inseguro porque eles acessaram http://sub.domain.com , redirecione-os para a versão HTTPS do site.

Substitua toda a sua porta 80 server cláusula por:

server {
    listen 80;
    server_name sub.domain.com www.sub.domain.com;
    rewrite     ^   https://$host$request_uri? permanent;
}

Você também deve remover o comentário desta linha na configuração da porta 443, para que os navegadores lembrem-se de nem tentar a versão HTTP do site:

add_header Strict-Transport-Security "max-age=31536000";

Renovar automaticamente seu certificado

Você pode usar este comando (como root) para renovar todos os certificados conhecidos do certbot e recarregar o nginx usando o novo certificado (que terá o mesmo caminho que o seu certificado existente):

certbot renew --renew-hook "service nginx reload"

certbot só tentará renovar certificados com mais de 60 dias, por isso é seguro (e recomendado!) executar este comando muito regularmente e automaticamente, se for possível. Por exemplo, você poderia colocar o seguinte comando em /etc/crontab :

# at 4:47am/pm, renew all Let's Encrypt certificates over 60 days old
47 4,16   * * *   root   certbot renew --quiet --renew-hook "service nginx reload"

Você pode testar renovações com uma execução a seco, que entrará em contato com os servidores de simulação Vamos criptografar para fazer um teste real de contato com seu domínio, mas não armazenará os certificados resultantes:

certbot --dry-run renew

Ou você pode forçar uma renovação antecipada com:

certbot renew --force-renew --renew-hook "service nginx reload"

Observação: você pode executar o dry quantas vezes quiser, mas as renovações reais estão sujeitas a Vamos criptografar limites de taxa .

    
por 20.06.2016 / 02:44
2

Sim, você pode usar nginx como ponto final de https e cooperar com os back-ends via http. Por exemplo minha configuração:

server {
        server_name host;
        listen 443 ssl;
...
 location /svn/ {
            auth_ldap off;

            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;

            proxy_pass http://localhost:1080/svn/;
            proxy_redirect http://localhost:1080/ https://host/;
        }
...
}

Mas, como eu sei, com o comando para criptografar, você precisa apontar todos os subdomínios ao obter o certificado. Se isso for um problema, escolha url https://host/service em vez de https://service.host

    
por 06.04.2016 / 14:24