Reputation: 13041
I am trying to establish an MQTT connection via Websockets over a reverse proxy. Is it possible to configure the Angular CLI proxy to forward requests to ws://localhost:4200/mqtt
to wss://mqtt.example.com/mqtt
?
I have been trying multiple configurations and can't seem to get it to work. Here is what I have in my proxy.conf.json
:
"/mqtt/*": {
"target": "wss://mqtt.example.com/",
"secure": false,
"ws": true,
"changeOrigin": true,
"logLevel": "debug"
}
I have tried various combinations, using secure
and/or changeOrigin
to either true or false and I am never able to connect.
Using "secure": false, "ws": true, "changeOrigin": true,
or "secure": true, "ws": true, "changeOrigin": true,
I always get:
Error during WebSocket handshake: Unexpected response code: 502
Update
I changed the proxy definition to omit the changeOrigin
option and append /mqtt
to the target:
"/mqtt": {
"target": "wss://mqtt.example.com/mqtt",
"secure": false,
"ws": true,
"logLevel": "debug"
},
Now get a different error message:
Error during WebSocket handshake: Unexpected response code: 404
My problem is that I cannot see the exact request that the Angular CLI is sending to the remote server, I have already set the logLevel
to debug
but that does not give any useful output to diagnose the problem. It would be very helpful to debug this if I could see the exact request that the proxy makes to the remote server.
Update 2
Its definitely not necessary to include /mqtt
in the target, because then I end up with /mqtt/mqtt
in the final request that the proxy makes.
Debugging this further I have discovered the following error message in my Kubernetes Ingress controller:
upstream prematurely closed connection while reading response header from upstream,
However, when I connect directly to the secure websocket using a local MQTT client (MqttBox) then the connection works, so I still think that its not a problem with the upstream configuration but something introduced in to the proxy connection.
Update 3
When I look at the mosquitto broker logs I keep seeing the following output:
1581786178: Socket error on client , disconnecting.
Also I am wondering if my problem might be caused because part of the connection goes via TLS, so the connection chain looks like this:
Browser/Client
-- WS/HTTP --> Angular CLI Proxy (localhost:4200)
-- WSS/HTTPS --> Ingress Controller (mqtt.example.com:443)
-- WS/HTTP --> MQTT Broker (port 9001)
Inspecting traffic via tcpdump -vvvs 1500 - -i any port 9001
I was able to extract the following header:
GET /mqtt HTTP/1.1
Host: mqtt.example.com
Upgrade: websocket
Connection: upgrade
X-Request-ID: [...]
X-Real-IP: [...]
X-Forwarded-For: [...]
X-Forwarded-Host: [...]
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Original-URI: /mqtt
X-Scheme: https
sec-websocket-protocol: mqtt
sec-websocket-extensions: permessage-deflate; client_max_window_bits
sec-websocket-key: [...]
accept-language: en-US,en;q=0.9
accept-encoding: gzip, deflate, br
sec-websocket-version: 13
origin: chrome-extension://[...]
user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36
cache-control: no-cache
pragma: no-cache
Update 4
I have investigated this further. When I disable TLS on the Kubernetes Ingress controller and the whole chain is communicating unsecured, then I have no problems and I can proxy the Websocket connection via the Angular CLI. However, as soon as I enable TLS then I run into the errors that I described above. So to sum up, the following three constellations work fine:
# whole chain unsecured (WORKS OK):
Browser/Client
-- WS/HTTP --> Angular CLI Proxy (localhost:4200)
-- WS/HTTP --> Ingress Controller (mqtt.example.com:443)
-- WS/HTTP --> MQTT Broker (port 9001)
# wss to public eclipse mqtt broker (WORKS OK):
Browser/Client
-- WS/HTTP --> Angular CLI Proxy (localhost:4200)
-- WSS/HTTPS --> MQTT Broker (mqtt.eclipse.org:443)
# secured connection directly from browser/client to broker (WORKS OK):
Browser/Client
-- WSS/HTTPS --> Ingress Controller (mqtt.example.com:443)
-- WS/HTTP --> MQTT Broker (port 9001)
Upvotes: 2
Views: 4165
Reputation: 18245
This is possible; the following config works with the eclipse test server:
"/wss": {
"target": "https://mqtt.eclipse.org:443/mqtt",
"secure": false,
"ws": true
},
note: Both https://mqtt.eclipse.org:443/mqtt
and wss://mqtt.eclipse.org:443/mqtt
work ok.
With that configuration I am able to connect (and subscribe/publish etc) using the Paho JS MQTT Client:
I'm not sure what is wrong with your config but suspect that "target": "wss://mqtt.example.com/"
should be "target": "wss://mqtt.example.com/mqtt"
(but that might just be due to how you anonymised the data?). Hopefully trying it with the test server will point you in the right direction (I assume you have checked that the proxy works with a standard http
page).
Upvotes: 2