es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Socket.io + Node.js detrás del AWS ALB no funciona correctamente.

Necesitaba un servicio proxy en el que pudiera pasar como encabezado la dirección IP del aguas arriba. Lo que tengo es:
– un servidor node js + socket.io que funciona localmente
– Nginx detrás de un AWS ALB (el ALB funciona con HTTPS y el Nginx funciona con HTTP para que el ALB se use como terminador SSL).

Tengo la siguiente configuración para Nginx:

server {
    listen       80;
    error_log stderr;
    access_log /dev/stdout;
    underscores_in_headers on;

    location / {
        proxy_pass_request_headers on;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_read_timeout 86400;
        if ($http_X_Pass_To = "") {
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Headers 'X-Pass-To,User-Agent,Content-Type';
            return 200;
        }
        proxy_pass http://$http_X_Pass_To$request_uri;
    }

    location /health {
        return 200 "healthy\n";
    }
}

map $http_upgrade $connection_upgrade {
    default upgrade;
        ''      close;
}

Lee el encabezado X-Pass-To y reenvía la solicitud al destino especificado.

El problema es que cuando ejecuto el cliente, funciona pero obtengo este error extraño que no se muestra en el desarrollo local:
WebSocket connection to ‘wss:///socket.io/?EIO=4&transport=websocket&sid=XggNamuD4_kpe2-JAABE’ failed:

Además, cuando uso el cliente, obtengo muchas solicitudes xhr en lugar de una, como funciona localmente. Y en la pestaña de red tengo una conexión ws finalizada que muestra mensajes N/A.

No tengo absolutamente ninguna idea de cuál podría ser el problema. Estaría bastante contento si algunos de ustedes saben mejor cuál puede ser la razón de este comportamiento extraño.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Solución para pasar la dirección IP como encabezado en el proxy Nginx

    Para resolver el problema dado, puede intentar los siguientes pasos:

    1. En el archivo de configuración de Nginx, establezca el parámetro real_ip_header en X-Forwarded-For. Este encabezado contendrá la dirección IP original de la solicitud, que se enviará al servidor ascendente.
      http {
          ...
          set_real_ip_from  0.0.0.0/0; # Establezca su rango de red o IPs permitidas para llamar a su AWS ALB
          real_ip_header    X-Forwarded-For;
          ...
      }
      
    2. En el servidor Node.js, modifique el código de inicialización de socket.io para usar el encabezado X-Forwarded-For para obtener la dirección IP del cliente.
      const io = require('socket.io')(server, {
          path: '/socket.io',
          serveClient: false,
          cookie: false,
          transports: ['websocket'],
          allowUpgrades: true,
          perMessageDeflate: false,
          httpCompression: true,
          wsEngine: 'ws',
          // Agregue la siguiente línea
          // Obtenga la dirección IP del cliente del encabezado X-Forwarded-For
          // Establézcala en el objeto de socket para futuras referencias
          // También puede usar otros encabezados que contengan la dirección IP
          // Por ejemplo, 'X-Real-IP', 'CF-Connecting-IP', etc.
          // Ver: https://socket.io/docs/v3/handling-cors/
          beforeConnect: (socket, { headers }) => {
              console.log(`Client IP: ${headers['x-forwarded-for']}`);
              socket.clientIp = headers['x-forwarded-for'];
          }
      });
      
    3. En el archivo de configuración de Nginx, agregue el encabezado X-Forwarded-For a los encabezados de solicitud enviados al servidor ascendente.
      server {
          listen       80;
      
          error_log stderr;
          access_log /dev/stdout;
          underscores_in_headers on;
      
          location / {
              proxy_pass_request_headers on;
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection $connection_upgrade;
              # Agregue la siguiente línea para pasar la dirección IP original al servidor ascendente
              proxy_set_header X-Forwarded-For $remote_addr;
              proxy_set_header Host $host;
              proxy_read_timeout 86400;
              if ($http_X_Pass_To = "") {
                  add_header Access-Control-Allow-Origin *;
                  add_header Access-Control-Allow-Headers 'X-Pass-To,User-Agent,Content-Type';
                  return 200;
              }
              proxy_pass http://$http_X_Pass_To$request_uri;
          }
      
          location /health {
              return 200 "healthy\n";
          }
      }
      
      map $http_upgrade $connection_upgrade {
          default upgrade;
          ''      close;
      }
      

    Con estos cambios, el proxy Nginx pasará la dirección IP original de la solicitud al servidor ascendente como el encabezado X-Forwarded-For. El servidor Node.js usará este encabezado para obtener la dirección IP del cliente y establecerla en el objeto de socket para futuras referencias. Esto debería solucionar el problema de la falla en la conexión websocket y las múltiples solicitudes xhr.

Comments are closed.