nginx comme proxy inverse avec SSL en amont

18

Je construis un proxy pour une API interne pour permettre aux clients de se connecter sans avoir à installer les certificats auto-signés.

Les clients (construits, possédés et utilisés uniquement en interne) se connecteront via SSL à la boîte nginx, où j'utilise XSendfile pour valider les informations d'identification au niveau de l'application (une application rails). Si les informations d'identification sont valides, la connexion est retransmise à nginx où il utilise proxy_pass pour envoyer la connexion sur le serveur en amont.

Maintenant, cela fonctionne très bien pour les connexions http standard, mais j'essaie de comprendre comment ajouter nos certificats dans le mélange.

Cette question est presque identique à celle-ci , mais avec des exigences de certificat maladroites.

Est-ce même possible avec nginx? Y a-t-il une meilleure solution?

Je me contenterais également de http du client -> nginx, et d'un certificat auto-signé de nginx à l'API.

simonmaddox
la source

Réponses:

19

Pour toute personne tombant sur cette question qui souhaite utiliser nginx, vous pouvez le configurer comme n'importe quel proxy normal, et pour accepter un certificat auto-signé du backend, vous devez fournir le certificat pem exporté (et peut-être une clé) et définir la vérification SSL de. Par exemple:

...

server {
    listen       10.1.2.3:80;
    server_name  10.1.2.3 myproxy.mycompany.com;

    location / {
         proxy_pass                    https://backend.server.ip/;
         proxy_ssl_trusted_certificate /etc/nginx/sslcerts/backend.server.pem;
         proxy_ssl_verify              off;

         ... other proxy settings
    }

Si votre serveur principal sécurisé utilise SNI d'identification de nom de serveur avec plusieurs hôtes servis par paire IP / port, vous devrez peut-être également l'inclure proxy_ssl_server_name on;dans la configuration. Cela fonctionne sur nginx 1.7.0 et versions ultérieures.

utilisateur shonky linux
la source
1
proxy_ssl_server_name on;était tout ce dont j'avais besoin pour que cela fonctionne lorsque le proxy est acheminé vers un hôte sur Google App Engine à l'aide de son SSL intégré géré par Google! (Ce n'est pas un certificat auto-signé ou quoi que ce soit, donc il fallait juste cette ligne). Merci pour le bon conseil.
XP84
J'obtiens 'aucun "ssl_certificate" n'est défini pour la directive "listen ... ssl"' si je n'utilise pas ssl_certificate. Est-il possible de proxy SSL sans fournir le certificat en amont?
Damien
Le commentaire est hors sujet car il s'agit de la connexion proxy à HTTP en amont https. Si vous souhaitez proxyer https, il est probablement préférable de le traiter comme une question distincte. La réponse rapide et courte est que No Nginx ne peut pas "écouter" un port https sans certificat ni clé privée.
shonky linux user
5

Je pense que vous voulez probablement quelque chose comme ça (évidemment simplifié pour cet exemple):

worker_processes  1;
events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    upstream backend {
        server mybackendserver:443;
    }

    server {
        server_name localhost;
        listen 443 ssl;
        ssl_certificate /etc/nginx/server.crt;
        ssl_certificate_key /etc/nginx/server.key;
        ssl_verify_client off;
        location / {
            proxy_pass  https://backend;
            proxy_set_header Host $http_host;
            proxy_set_header X_FORWARDED_PROTO https;
        }
    }
}

La seule chose que vous pourriez avoir à changer serait de rendre l '"hôte" explicite - si, par exemple, votre nom d'hôte mandaté n'était pas le même que le nom d'hôte utilisé sur le serveur proxy nginx.

Confiture
la source
D'après ma compréhension, les paramètres ssl_certificate et ssl_certificate_key font référence à la connexion client , pas à la connexion en amont. Est-ce le cas?
simonmaddox
1
D'après ce que je comprends, oui. Dans cet exemple, le certificat que le client voit est celui fourni par nginx. nginx voit (et vérifie? Je ne suis pas sûr ...) celui fourni par le serveur, mais ne le transmet pas au client.
Jam
3

Pour tous ceux qui rencontreront cela à l'avenir, j'ai fini par ne pas utiliser nginx pour cela.

Au lieu de cela, j'ai fini par utiliser stunnel en "mode client". Très facile à installer et fait exactement ce dont j'ai besoin.

simonmaddox
la source