fragen stichworte

Nginx WebSocket Reverse Proxy gibt 200 statt 101 zurück

Ich versuche gerade, einen hack.chat auf meinem Personal Server zu haben.

Kurz gesagt, es besteht aus zwei Servern. Der erste ist ein einfacher httpd-Server, der Javascript und CSS bereitstellt. Der zweite, das Chatsystem, ist ein node.js-Server, mit dem das Javascript über Websocket verbunden wird. Und hier kommen die Probleme.

Ich möchte, dass Port 80 mit einem anderen Domänennamen auf einer einzelnen IP verwendet wird und ein separater Serverblock in Nginx verwendet wird.

Ich habe dem Nginx-Websocket-Dokument gefolgt, aber das funktioniert nicht. Wenn der Websocket versucht, eine Verbindung herzustellen, erhält er immer einen Rückgabewert von 200, und wenn ich es gut verstanden habe, sollte er 101 (Schaltprotokoll) erhalten.

Meine Nginx-Version ist 1.8.0 und mein Server läuft auf gentoo mit Linux 4.0.5

Hier ist ein Speicherauszug der relevanten Nginx-Conf-Dateien:

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

Wenn ich mir das access_log anschaue, zeigt es effektiv die 200-Antwort und es ist kein Fehler im error_log vorhanden. Leider gibt mir der node.js-Server kein Protokoll (oder ich weiß nicht, wie ich es anzeigen soll).

Vielen Dank im Voraus für jede Antwort.

BEARBEITEN

Thx bis mc0e, ich habe es geschafft, dass der Server hack.chat 101 antwortet. Durch den Vergleich, was zwischen nginx und node.js tatsächlich passiert, mit dem, was bei einer direkten Verbindung passiert, habe ich gesehen, dass direkt beim Header ein Upgrade: websocket gesetzt ist aber nginx nicht. Also habe ich meine Sites-fähig/Chat korrigiert auf:

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

Ich habe auch den Map-Block entfernt, da der Connection-Header anstelle von Upgrade geschlossen wurde.

Immer noch nicht funktioniert. hack.chat gibt eine 101 mit Connection: Upgrade und Upgrade: websocket zurück, aber irgendwie gibt Nginx eine 101 mit Connection: keep-alive (wie ich es in Firefox sehe):/

BEARBEITEN

Hat eine Ngrep-Kommunikation mit Nginx durchgeführt, sendet er das Paket, das hack.chat zurückgibt, und Firefox beschwert sich über Herkunftsursprung. Ich werde versuchen, den Ursprung zu vermeiden.

LAST EDIT

Nun, da ich zu Hause bin, habe ich einen Test gemacht und es hat wie ein Zauber funktioniert. Ziemlich sicher, dass meine letzte Ausgabe wegen meines Arbeitsproxys war. Hoffen wir, dass es ein Cache ist, sonst wäre alles nutzlos gewesen.

Hier ist der letzte meiner Konfessionen, der eine Kreuzung verhindert:

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

antworten

Wenn ich beim Lesen des Nginx Websocket-Docks die Upgrade-Header von Ihrem Nginx-Proxy erkennt, gibt er sie an hack.chat weiter. hack.chat muss dann mit der 101-Antwort antworten.

Zunächst möchten Sie die tatsächlichen HTTP- und hack.chat-Transaktionen debuggen können, damit Sie wissen, ob das Problem in Ihrer Client-App oder auf dem Webserver oder bei der hack.chat-Kommunikation liegt. Auf diese Weise erhalten Sie auch die genaue HTTP-Antwort, die Sie derzeit nicht kennen. Wenn das Problem jedoch auf der Serverseite liegt, suchen Sie möglicherweise immer noch nach besseren Protokollen über das, was schiefgegangen ist.

Sie können den http-Verkehr mit tcpdump oder ngrep erfassen. Ich würde für Ngrep gehen. Wenn Sie dies tun, erhalten Sie eine Ausgabe in Ihrem Terminal.

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

Sie möchten dies wahrscheinlich auf Ihrem Webserver ausführen. Wenn Sie jedoch über eine Desktopumgebung verfügen, in der ngrep ausgeführt werden kann, können Sie es dort ausführen. Wenn Sie es auf dem Server ausführen, können Sie auch die Interaktion zwischen nginx und Ihrem Chatserver erfassen.

ngrep '.' port 6060

Die Terminalausgabe reicht oft aus, um zu sehen, was Sie benötigen. Sie können jedoch auch das Flag '-O' verwenden, um die Daten in eine pcap-Dump-Datei zu schreiben, wie dies bei tcpdump mit '-w' der Fall ist. Sie können diese Datei dann auf Ihren Desktop zurückbringen, um sie mit einem grafischen Client wie wireshark anzuzeigen.

Möglicherweise können Sie das Problem daraus erkennen. Wenn nicht, erfassen Sie die verschiedenen Interaktionen und fügen Sie sie Ihrer Frage hinzu.

Gibt es ein Problem mit Javascript, das nach der hack.chat-Kommunikation auf einer anderen Domain als der gefragt wird, von der das Javascript bedient wird? Dies kann relevant sein: https://stackoverflow.com/questions/20093070/unable-to-create-cross-domain-websocket-connection-to-node-js-socket-io-server