web-dev-qa-db-fra.com

Permet de chiffrer avec un proxy inverse nginx

Introduction

J'ai un serveur de développement (exécutant actuellement Ubuntu 14.04 LTS), que j'utilise depuis un certain temps maintenant pour héberger divers outils de développement sur différents ports. Parce que les ports peuvent être difficiles à retenir, j'ai décidé d'utiliser le port 80 pour tous mes services et de faire la redirection de port en interne, en fonction du nom d'hôte.

Au lieu d'écrire domain.com:5432, je peux simplement y accéder via sub.domain.com

Par exemple, l'application X, qui utilise le port 7547 et s'exécute sur sub.domain.com a la configuration nginx suivante:

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 "";
    }
}

La question

Compte tenu de la structure de configuration actuelle, que j'ai choisie, est-il possible d'utiliser letsencrypt et d'exécuter les différents services sous https?

46
0x450

Oui, vous pouvez avoir des requêtes proxy nginx vers des serveurs HTTP, puis répondre lui-même aux clients via HTTPS. En faisant cela, vous voudrez être sûr que la connexion proxy nginx <-> est peu susceptible d'être reniflée par celui qui est votre attaquant attendu. Les approches suffisamment sûres peuvent inclure:

  • procuration au même hôte (comme vous le faites)
  • procuration à d'autres hôtes derrière votre pare-feu

Il est peu probable que la procuration à un autre hôte sur Internet public soit suffisamment sûre.

Voici les instructions pour obtenir un certificat Let's Encrypt en utilisant le même serveur Web que vous utilisez en tant que proxy.

Demander votre certificat initial à Let's Encrypt

Modifiez votre clause server pour autoriser le sous-répertoire .well-known à servir à partir d'un répertoire local, par exemple:

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 est l'endroit où les serveurs Let's Encrypt chercheront les réponses aux défis qu'il pose.

Vous pouvez ensuite utiliser le client certbot pour demander un certificat à Let's Encrypt en utilisant le plugin webroot (en tant que root):

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

Votre clé, votre certificat et votre chaîne de certificats seront désormais installés dans /etc/letsencrypt/live/sub.domain.com/

Configuration de nginx pour utiliser votre certificat

Créez d'abord une nouvelle clause de serveur comme celle-ci:

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
        […]
    }
}

Recharger nginx:

service nginx reload

Vérifiez que HTTPS fonctionne désormais en visitant https://sub.domain.com et https://www.sub.domain.com dans votre navigateur (et tout autre navigateur que vous souhaitez spécifiquement prendre en charge) et en vérifiant qu'ils ne signalent pas les erreurs de certificat.

Recommandé: consultez également raymii.org: Sécurité SSL renforcée sur nginx et testez votre configuration sur SSL Labs .

(Recommandé) Redirige les requêtes HTTP vers HTTPS

Une fois que vous avez confirmé que votre site fonctionne avec le https:// version de l'URL, plutôt que certains utilisateurs ont diffusé du contenu non sécurisé car ils sont allés à http://sub.domain.com, redirigez-les vers la version HTTPS du site.

Remplacez la totalité de votre clause de port 80 server par:

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

Vous devriez également maintenant décommenter cette ligne dans la configuration du port 443, afin que les navigateurs se souviennent de ne même pas essayer la version HTTP du site:

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

Renouveler automatiquement votre certificat

Vous pouvez utiliser cette commande (en tant que root) pour renouveler tous les certificats connus de certbot et recharger nginx en utilisant le nouveau certificat (qui aura le même chemin que votre certificat existant):

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

certbot tentera uniquement de renouveler les certificats qui datent de plus de 60 jours, il est donc sûr (et recommandé!) d'exécuter cette commande très régulièrement , et automatiquement si possible. Par exemple, vous pouvez mettre la commande suivante dans /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"

Vous pouvez tester les renouvellements avec une exécution à sec, qui contactera les serveurs de mise en attente de Let's Encrypt pour faire un véritable test de contact avec votre domaine, mais ne le fera pas stocker les certificats résultants:

certbot --dry-run renew

Ou vous pouvez forcer un renouvellement anticipé avec:

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

Remarque: vous pouvez effectuer un essai à sec autant de fois que vous le souhaitez, mais les renouvellements réels sont soumis à Let's Encrypt rate limits .

82
puzzlement

Oui, vous pouvez utiliser nginx comme point de terminaison de https et coopérer avec les backends via http. Par exemple ma config:

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/;
        }
...
}

Mais comme je le sais, avec Let's Encrypt, vous devez pointer tous les sous-domaines lorsque vous obtenez un certificat, et si cela pose problème, vous choisissez url https://Host/service au lieu de https://service.Host

2
fghj