nginx como proxy inverso con SSL ascendente

18

Estoy creando un proxy para una API interna para permitir que los clientes se conecten sin tener que tener instalados los certificados autofirmados.

Los clientes (creados, propios y utilizados solo internamente) se conectarán a través de SSL al cuadro nginx, donde estoy usando XSendfile para validar las credenciales a nivel de aplicación (una aplicación de rails). Si las credenciales son válidas, la conexión se pasa de nuevo a nginx, donde utiliza proxy_pass para enviar la conexión al servidor ascendente.

Ahora esto funciona muy bien para las conexiones http estándar, pero estoy tratando de descubrir cómo agregar nuestros certificados a la mezcla.

Esta pregunta es casi idéntica a esta , pero con requisitos de certificado extraños.

¿Es esto posible con nginx? ¿Hay una mejor solución?

También me conformaría con http del cliente -> nginx, y certificado autofirmado de nginx a la API.

simonmaddox
fuente

Respuestas:

19

Para cualquiera que se encuentre con esta pregunta que quiera usar nginx, puede configurarlo como cualquier proxy normal, y para aceptar un certificado autofirmado desde el backend, debe proporcionar el certificado pem exportado (y tal vez una clave) y configurar la verificación SSL apagado. Por ejemplo:

...

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 su back-end seguro utiliza SNI de identificación de nombre de servidor con varios hosts atendidos por par IP / puerto, es posible que también deba incluirlos proxy_ssl_server_name on;en la configuración. Esto funciona en nginx 1.7.0 y versiones posteriores.

usuario shonky de linux
fuente
1
proxy_ssl_server_name on;¡era todo lo que necesitaba para que esto funcionara cuando enviaba el tráfico a un host en Google App Engine usando su SSL incorporado administrado por Google! (Esto no es un certificado autofirmado ni nada, así que solo necesitaba esa línea). Gracias por el gran consejo.
XP84
Obtengo 'no "ssl_certificate" está definido para la directiva "listen ... ssl" si no uso ssl_certificate. ¿Es posible proxy SSL sin proporcionar el certificado ascendente?
Damien el
El comentario no está relacionado con el tema, ya que se trata de enviar proxy http conectando a https ascendente Si desea proxy https, entonces probablemente se aborde mejor como una pregunta separada. La respuesta rápida y breve es No Nginx no puede "escuchar" un puerto https sin un certificado y una clave privada.
Usuario de Linux shonky
5

Creo que probablemente quieras algo como esto (obviamente simplificado para este ejemplo):

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

Lo único que podría tener que cambiar sería hacer explícito el "Host", si, por ejemplo, su nombre de host proxy no es el mismo que el nombre de host utilizado en el servidor proxy nginx.

Mermelada
fuente
Según tengo entendido, los parámetros ssl_certificate y ssl_certificate_key se refieren a la conexión del cliente , no a la conexión ascendente. ¿Es ese el caso?
simonmaddox
1
Por lo que entiendo, sí. En este ejemplo, el certificado que ve el cliente es el proporcionado por nginx. nginx ve (y verifica? No estoy seguro ...) el proporcionado por el servidor, pero no lo pasa al cliente.
Jam
3

Para cualquiera que se encuentre con esto en el futuro, terminé sin usar nginx para esto.

En cambio, terminé usando stunnel en "modo cliente". Muy fácil de configurar, y hace exactamente lo que necesito.

simonmaddox
fuente