O proxy reverso Nginx WebSocket mantém o retorno 200 em vez de 101

6

Atualmente, estou tentando ter um hack.chat no meu servidor pessoal em funcionamento.

Longa história curta, consiste em dois servidores. O primeiro é um servidor httpd simples que serve javascript e CSS. O segundo, o sistema de bate-papo, é um servidor node.js ao qual o javascript se conecta usando o websocket. E aí vem os problemas.

Eu quero que tudo use a porta 80, com um nome de domínio diferente em um único IP, usando um bloco de servidor separado no Nginx.

Eu segui o documento do websocket do Nginx , mas isso não está funcionando. Quando o websocket tenta se conectar, ele sempre recebe um código de retorno 200, enquanto, se eu entendi bem, ele deve obter 101 (protocolo de comutação).

Minha versão do Nginx é 1.8.0 e meu servidor está rodando no gentoo com o linux 4.0.5

Aqui está um dump dos arquivos conf nginx relevantes:

nginx.conf:

user nginx nginx;
worker_processes 1;

error_log /var/log/nginx/error_log info;

events {
    worker_connections 1024;
    use epoll;
}

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

    log_format main
        '$remote_addr - $remote_user [$time_local] '
        '"$request" $status $bytes_sent '
        '"$http_referer" "$http_user_agent" '
        '"$gzip_ratio"';

    client_header_timeout 10m;
    client_body_timeout 10m;
    send_timeout 10m;

    connection_pool_size 256;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 2k;
    request_pool_size 4k;

    gzip on;
    gzip_min_length 1100;
    gzip_buffers 4 8k;
    gzip_types text/plain;

    output_buffers 1 32k;
    postpone_output 1460;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;

    keepalive_timeout 75 20;

    ignore_invalid_headers on;

    include /etc/nginx/sites-enabled/*;
}

sites habilitados / chat:

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

server{
    listen 0.0.0.0:80;
    server_name chat.axellink.fr;

    location / {
        proxy_pass http://127.0.0.1:6060;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    access_log /var/log/nginx/chat_access;
    error_log /var/log/nginx/chat_error debug;
}

Quando dou uma olhada no access_log, ele mostra efetivamente a resposta 200 e não há erro no error_log. Infelizmente, o servidor node.js não me fornece nenhum log (ou eu não sei como visualizá-lo).

Agradecemos antecipadamente por qualquer resposta.

EDITAR

Thx to mc0e, eu consegui fazer com que o servidor hack.chat respondesse 101. Ao comparar o que realmente acontece entre nginx e node.js com o que acontece em uma conexão direta, vi que em um cabeçalho direto Upgrade: websocket está definido mas nginx não. Por isso, corrigi meus bate-papos habilitados para sites para:

server{
    listen 0.0.0.0:80;
    server_name chat.axellink.fr;

    location / {
        proxy_pass http://127.0.0.1:6060;
        proxy_http_version 1.1;
        proxy_set_header Upgrade "websocket";
        proxy_set_header Connection "Upgrade";
    }

    access_log /var/log/nginx/chat_access;
    error_log /var/log/nginx/chat_error debug;
}

Eu também removi o bloco do mapa como ele costumava definir o cabeçalho da conexão para fechar em vez de atualizar.

Ainda não funciona. hack.chat devolve um 101 com Connection: Upgrade e Upgrade: websocket mas de alguma forma o nginx retorna um 101 com Connection: keep-alive (como o que eu vejo no firefox): /

EDITAR

Faz um ngrep em comunicações nginx, ele envia o pacote hack.chat devolve a ele e o firefox está reclamando sobre origem cruzada. Vou tentar evitar a origem cruzada.

ÚLTIMA EDIÇÃO

Ok, agora que estou em casa fiz um teste e funcionou como um encanto. Bastante surto que meu último problema foi por causa do meu proxy de trabalho, vamos esperar que seja o cache ou então tudo teria sido inútil.

Aqui está o último do meu conf que evita a origem cruzada:

server{
        listen 0.0.0.0:80;
        server_name chat.axellink.fr;

        location / {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_set_header X-NginX-Proxy true;
                proxy_pass http://127.0.0.1:8081;
        }

        location /chat/ {
                proxy_pass http://127.0.0.1:6060;
                proxy_http_version 1.1;
                proxy_set_header Upgrade "websocket";
                proxy_set_header Connection "Upgrade";
        }

        access_log /var/log/nginx/chat_access;
        error_log /var/log/nginx/chat_error debug;
}
    
por axellink 31.07.2015 / 14:41

1 resposta

2

A partir da minha leitura do dock nsx websocket, quando o seu proxy nginx vê os cabeçalhos Upgrade, passa-os para o hack.chat. O hack.chat precisa então responder com a resposta 101.

Primeiro, você quer poder depurar as transações HTTP e hack.chat, para saber se o problema está no aplicativo cliente, no servidor da Web ou nas comunicações hack.chat. Isso também permitirá que você obtenha a resposta HTTP exata, que você diz que atualmente não sabe como chegar. No entanto, se o problema for do lado do servidor, talvez você ainda esteja procurando melhorar os registros do que deu errado.

Você pode capturar o tráfego HTTP com o tcpdump ou ngrep. Eu iria para o ngrep. Fazê-lo assim lhe dará saída em seu terminal.

ngrep 'Host: chat.axellink.fr' port 80

Você provavelmente deseja executar isso em seu servidor da Web, mas, se tiver um ambiente de área de trabalho que possa executar o ngrep, poderá optar por executá-lo nesse local. Se você executá-lo no servidor, você também pode capturar a interação entre o nginx e seu servidor de bate-papo.

ngrep '.' port 6060

A saída do terminal é geralmente suficiente para ver o que você precisa, mas você também pode usar o sinalizador '-O' para o ngrep gravar os dados em um arquivo de despejo pcap como o tcpdump faz com '-w'. Você pode então trazer esse arquivo de volta para sua área de trabalho para vê-lo com um cliente gráfico como o wireshark.

Você pode identificar o problema, mas, se não, capture as várias interações e adicione-as à sua pergunta.

Existe um problema com o javascript pedindo a comunicação hack.chat em um domínio diferente daquele em que o javascript é exibido? Isso pode ser relevante: link

    
por 07.08.2015 / 11:04