eclipse-paho / paho.mqtt-spy

mqtt-spy is an open source desktop & command line utility intended to help you with monitoring activity on MQTT topics
Other
619 stars 146 forks source link

Feature request: support for proxies #39

Open heckler opened 7 years ago

heckler commented 7 years ago

When I'm behind a corporate proxy, mqtt-spy cannot reach out and connect to the internet. There might be some way to specify proxy settings when one is behind an outbound firewall, but I haven't found any reference in the documentation.

I've tried starting it with the following options, to no avail:

java -jar mqtt-spy-1.0.0.jar -Dhttp.proxyHost=my-proxy-host -Dhttp.proxyPort=8080 -Dhttps.proxyHost=my-proxy-host -Dhttps.proxyPort=8080

And the result is that connection is not successful:

Unable to connect to server (32103) - java.net.ConnectException: Connection timed out: connect
        at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:79)
        at org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule.start(SSLNetworkModule.java:86)
        at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:650)
        at java.lang.Thread.run(Unknown Source)
Caused by: java.net.ConnectException: Connection timed out: connect
        at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
        at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
        at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
        at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
        at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
        at java.net.PlainSocketImpl.connect(Unknown Source)
        at java.net.SocksSocketImpl.connect(Unknown Source)
        at java.net.Socket.connect(Unknown Source)
        at sun.security.ssl.SSLSocketImpl.connect(Unknown Source)
        at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:70)
        ... 3 more
kamilfb commented 7 years ago

hi @heckler. any thoughts on how I could test that locally?

heckler commented 7 years ago

Hello @kamilfb,

If you don't have any proxied network, the easiest way to test this that I know off is using a local proxy interceptor on your machine. The one I use all the time for development work is Burp Suite:

https://portswigger.net/burp

https://support.portswigger.net/customer/portal/articles/1783038-launching-burp-suite-from-the-command-line

You can ignore all the claims for multimple options and capabilities, for just a simple proxy all you need is to download the JAR archive and run it:

java -jar burpsuite_free_v1.7.27.jar

This will open a graphical UI with the interceptor active by default on localhost:8080 (this may be different if 8080 is in use on your system)

Then you can run the following tests:

$curl www.google.com

In the above test, curl fetches the content directly, and the proxy is not involved. This is the case if you have a direct connection to the internet (the default)

If you have to go through a proxy (like on a corporate network), you can tell curl and most software to use a proxy to get out with a couple of environment variables:

$export http_proxy=http://localhost:8080
$export https_proxy=https://localhost:8080

$curl www.google.com

This time curl will appear to hung on your console. If you head over to the BURP window, you should see th "Intercept" tab lit up, indicating that there is a pending request. If you click "Forward", the request is sent on its way unchanged and the curl invocation will complete. (this is, incidentally, a good way to intercept, inspect and optionally modify requests from any sofware which supports proxies; you can set rules and intercept the responses before they are delivered to the original app too.)

How this relates to paho mqtt-spy:

If mqtt-spy were to support proxies, then setting these environment variables or passing -Dhttp.proxy=... on the cmdline should have the effect of proxying the calls through Burp (or through your corporate network's http proxy) and you should see the traffic intercepted. As it currently stands, mqtt-spy ignores proxy settigns and always tries to connect directly - which fails on proxied networks

heckler commented 7 years ago

Actually, looking at this thread, this might be much harder to handle than I initially thought.

kamilfb commented 7 years ago

Thank you for the explanation, that really helps. Just wondering.... if we need http proxy maybe we need to go via websockets (http) and not raw mqtt? Have you tried ticking the websocket option in connection settings? I will also explore how this might work and report back.

heckler commented 7 years ago

Good point about WebSockets!

I went poking around and that might be hard to implement against AWS IoT as it uses an authentication schema (SigV4) which is specific to AWS.

Here's the doc about accessing AWS IoT over WebSockets: http://docs.aws.amazon.com/iot/latest/developerguide/protocols.html

And here's the info on SigV4: http://docs.aws.amazon.com/general/latest/gr//sigv4_signing.html

(I don't think it is worth considering supporting SigV4 to unblock WebSockets to AWS IoT at this point; raw MQTT works fine - as long as one is not behind a firewall, that is)

olivm-fr commented 5 years ago

HTTP proxy support has been added to the code in the following fork : https://github.com/olivm-fr/paho.mqtt-spy/releases/tag/1.0.1-proxy1 :-)