fragen stichworte

Websocket-Reverse-Proxy mit nginx: Fehler bei der Anforderung im Serverprotokoll, funktioniert jedoch im Browser

Die Situation

Ich führe Etherpad aus, das über nginx weitergeleitet wird. Etherpad verwendet Websockets mit Socket.io.

Meine Nginx-Konfiguration ist mehr oder weniger dieses. Der Standortblock für socket.io lautet:

rewrite/CustomSubDir/socket.io/(.*)/socket.io/$1 break;
proxy_pass http://localhost:CustomPort/;
proxy_redirect  //CustomSubDir/;
proxy_cookie_path//CustomSubDir/;

# usual proxy header
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;

# websocket
proxy_set_header Accept-Encoding "";
proxy_http_version 1.1;
# http://nginx.org/en/docs/http/websocket.html
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;

proxy_buffers 8 32k;
proxy_buffer_size 64k;

proxy_buffering off;

Was ist verwirrend?

Die gute Nachricht lautet also: Alles funktioniert! Ich frage daher nicht, wie man etwas zum Laufen bringt.
Die Basis ist: Obwohl alles funktioniert, zeigt mir nginx immer Fehlermeldungen.

Was ist los?

nginx zeigt mir diese Fehler in error.log:

2016/05/24 xx:yy:zz [error] 22197#0: *12059 connect() failed (111: Connection refused) while connecting to upstream, client: SOM.IPA.DDR.EES, server: somedomain.example.com, request: "GET/CustomSubDir/socket.io/?EIO=3&transport=polling&t=1464121868147-3&sid=H2GhIY24t2a40etpAACd HTTP/2.0", upstream: "http://[::1]:CustomPort/socket.io/?EIO=3&transport=polling&t=1464121868147-3&sid=H2GhIY24t2a40etpAACd", host: "somedomain.example.com"
2016/05/24 xx:yy:zz [error] 22197#0: *12070 connect() failed (111: Connection refused) while connecting to upstream, client: SOM.IPA.DDR.EES, server: somedomain.example.com, request: "POST/CustomSubDir/socket.io/?EIO=3&transport=polling&t=1464122037998-5&sid=T-pthraR669TF2cKAACe HTTP/2.0", upstream: "http://[::1]:CustomPort/socket.io/?EIO=3&transport=polling&t=1464122037998-5&sid=T-pthraR669TF2cKAACe", host: "somedomain.example.com"

Ich konnte diese Anfragen also aufspüren. Hier ist warum: 1. Dies sind offensichtlich Websocket-Anfragen. 2. Und das sind - und das ist etwas Besonderes - POST-Anfragen.

Beim Laden eines Etherpad oder Wiederherstellen einer Verbindung nach einem Verbindungsabbruch wird nur eine Anforderung gestellt, die diese Anforderungen erfüllt. Ich kann es eindeutig im Browser sehen und kann es in Echtzeit im nginx-Fehlerprotokoll sehen. Dies ist die Anforderung in meinem Browser:

200 POST https://somedomain.example.com/CustomSubDir/socket.io/?EIO=3&transport=polling&t=1464121868143-2&sid=H2GhIY24t2a40etpAACd

Und es enthält (z. B.) diese Nutzdaten:

164:42["message",{"component":"pad","type":"CLIENT_READY","padId":"CENSORED","sessionID":"null","password":null,"token":"t.qbszmj[...]","protocolVersion":2}]

Die Antwort des Servers lautet:

HTTP/2.0 200 OK
Server: nginx
Date: Tue, 24 May 2016 xx:yy:zz GMT
Content-Type: text/html
Content-Length: 2
access-control-allow-origin: *
Set-Cookie: io=H2GhIY24t[...]
X-Firefox-Spdy: h2

ok

Warum kann ich sicher sein, dass dies der Täter ist

?

Ich bin sehr sicher, dass dies durch die POST-Anfrage verursacht wird. Nicht nur, weil es die einzige POST-Anforderung mit dieser URL beim Zugriff auf das Pad ist, kann ich auch das Verhalten vergleichen. Denn auf demselben Server führe ich auch Etherdraw aus, was sehr ähnlich funktioniert, aber es hat einen wichtigen Unterschied: Es scheint keine POST-Websocket-Anfragen zu verwenden.
Und rate was? Das error.log ist leer.

Meine Fragen

Was sind meine Fragen:

  1. Wie kann ich sehen, dass die Anforderung in meinem Browser erfolgreich ist (mit einer korrekten Serverantwort!), während Nginx mich im Protokoll als fehlgeschlagen meldet?
  2. Wie kann ich diese Fehlermeldungen beseitigen? AFAIK die Anfragen schlagen nicht fehl ...

antworten

Ich konnte mein Problem dank @ webzwo0i lösen, der mir auf GitHub mitgeteilt hat, dass es sich um einen IPv4/IPv6-Konflikt handeln könnte.

Also habe ich nochmal in die Fehlerprotokolle geschaut und mir dabei besonders aufgefallen:

"[...] connect() failed (111: Connection refused) while connecting to upstream[...]", upstream: "http://[::1]:CustomPort/socket.io/[...]"

Dies ist die IPv6-localhost-Adresse, aber Etherpad/NodeJS scheint nur eine Verbindung mit der IPv4-Adresse herzustellen.

Das Ändern aller localhost s in der nginx-Konfiguration zu 127.0.0.1 hat mein Problem gelöst. Die Fehler im Protokoll sind weg. Ich habe auch bemerkt, dass einige andere Anfragen auch die gleichen Fehler im Protokoll verursacht haben, also ist es nicht spezifisch für die Anforderungen, die ich beschrieben habe.