ELB redirecciona 443/80 a un solo puerto en el contenedor docker nginx

0

Tenemos un AWS ELB público que redirige el tráfico de esta manera:

HTTP    80  HTTP    9001
TCP     443 TCP     9001

La instancia de destino es una instancia de AWS ECS que ejecuta Docker con un contenedor nginx.

Docker está reenviando 9001 -> 8080, y nginx está escuchando en 8080. Aquí hay un recorte de la configuración de nginx:

server {
    ssl on;
    ssl_certificate /etc/nginx/mydomain.crt;
    ssl_certificate_key /etc/nginx/mydomain.key;

    listen 8080;
    server_name %{ROUTER_CLEARCARE_SERVER_NAME};

    access_log  /var/log/nginx/access.log  logstash_json;


    if ($http_x_forwarded_proto != 'https') {
        return 301 https://$host$request_uri;
    }

    set $target_web "web.mydomain.com:80";
    location / {
        proxy_read_timeout 180;
        proxy_connect_timeout 2;
        proxy_send_timeout 180;
        keepalive_timeout  180;
        resolver 10.10.0.2 valid=30s;
        proxy_set_header Host $host;
        proxy_pass http://$target_web;
        proxy_set_header X-Unique-ID $request_id;
    }
}

Necesito hacer la terminación SSL en el contenedor nginx porque tenemos varios certificados para varios dominios, y estamos usando enrutamiento basado en rutas con diferentes tiempos de espera (los ELB solo admiten un solo certificado, y ALB no admite el enrutamiento basado en rutas con diferentes tiempos de espera y certificados ).

Aquí está el truco: nginx solo puede escuchar en un puerto (estamos usando una herramienta llamada Empire para implementar el contenedor nginx en AWS ECS y actualmente solo admiten esta configuración).

¿Puede nginx admitir http y https en un solo puerto?

En este momento, con esa configuración, aparece este error cuando intento presionar http://example.com :

The plain HTTP request was sent to HTTPS port

Y obtengo este error cuando intento presionar https://example.com , obtengo este error:

mydomain.com redirected you too many times.
1

Encontré una declaración de que escuchar HTTP y HTTPS debería ser posible para NginX en esta página predeterminada del servidor (consulte la segunda respuesta de Komu) . Lo repito a continuación, para que lo encuentres más fácilmente. ¿Puedes probarlo? Si no está vinculado a NginX, es posible que también le interese este complemento de node.js , que también permite escuchar HTTP y HTTPS en el mismo puerto.


quoted from here:

According to wikipedia article on status codes, Nginx has a custom error code when http traffic is sent to https port (error code 497)

And according to nginx docs on error_page, you can define a URI that will be shown for a specific error. Thus we can create a uri that clients will be sent to when error code 497 is raised.

#lets assume your IP address is 89.89.89.89 and also that you want nginx to listen on port 7000 and your app is running on port 3000

server {
    listen 7000 ssl;

    ssl_certificate /path/to/ssl_certificate.cer;
    ssl_certificate_key /path/to/ssl_certificate_key.key;
    ssl_client_certificate /path/to/ssl_client_certificate.cer;

    error_page 497 301 =307 https://89.89.89.89:7000$request_uri;

    location / {
        proxy_pass http://89.89.89.89:3000/;

        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Protocol $scheme;
    }
}

However if a client makes a request via any other method except a GET, that request will be turned into a GET. Thus to preserve the request method that the client came in via; we use error processing redirects as shown in nginx docs on error_page

And thats why we use the 301 =307 redirect.

Using the nginx.conf file shown here, we are able to have http and https listen in on the same port

0