owntracks / quicksetup

A (mostly) automated installer for OwnTracks Recorder, Frontend with MQTT and Let's Encrypt
https://owntracks.org/booklet/guide/quicksetup/
15 stars 4 forks source link

Tailscale with MQTT? #68

Open amrul-jamrul opened 2 days ago

amrul-jamrul commented 2 days ago

On my previous http setup I was able to have an owntracks container running on my pi and access the its service by pinging its tailscale ip while my VPN was on.

I've gone through the quicksetup and set my tailscale ip as dns_domain and then run the boostrap script. From here I can access the service at [tailscaleip]/owntracks from both my phone and computer to download the configurations.

However, after this I am unable to push any updates to the MQTT broker as it will refuse the connection. Is there a way to get this approach working with MQTT or is it not possible?

jpmens commented 2 days ago

I cannot answer that question as I've no experience with Tailscale. If it is an HTTP-only proxy then it will not work. MQTT is a distinct protocol. You would please need to consult the Tailscale documentation.

amrul-jamrul commented 1 day ago

Looks like Tailscale supports MQTT, I've tried multiple configurations afore mentioned:

[tailscale-ip]/owntracks, with both MQTT mode and HTTP configuration for friends neither worked. So I tried just seeing if it would work on local network instead.

[pi-ip]/owntracks with MQTT mode or HTTP mode was also gave connection errors for both configurations as well. Error logs for HTTP mode

Caused by: java.net.ConnectException: failed to connect to /IP (port XXX) from /IP (port XXX) after 30000ms: isConnected failed: ECONNREFUSED (Connection refused)
    at libcore.io.IoBridge.isConnected(IoBridge.java:347)
    at libcore.io.IoBridge.connectErrno(IoBridge.java:237)
    at libcore.io.IoBridge.connect(IoBridge.java:179)
    at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:142)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
    at java.net.Socket.connect(Socket.java:646)
    at okhttp3.internal.platform.Platform.connectSocket(SourceFile:6)
    at okhttp3.internal.connection.RealConnection.connectSocket(SourceFile:71)
    ... 21 more
Caused by: android.system.ErrnoException: isConnected failed: ECONNREFUSED (Connection refused)
    at libcore.io.IoBridge.isConnected(IoBridge.java:334)
    ... 31 more

Error logs for MQTT mode

2024-11-23 TIME I [DefaultDispatcher-worker-3] MessageProcessor$resendDelayWait: Waiting for 2m before retrying send
2024-11-23 TIME I [DefaultDispatcher-worker-1] MQTTReconnectWorker: MQTT reconnect worker job started
2024-11-23 TIME I [DefaultDispatcher-worker-6] MQTTMessageProcessorEndpoint$connectToBroker: Connecting to ssl://IP?# timeout = 30s
2024-11-23 TIME E [DefaultDispatcher-worker-6] MQTTMessageProcessorEndpoint$connectToBroker: MQTT client unable to connect to endpoint: failed to connect to /IP (port XXXX) from /IP (port XXXX) after 30000ms: isConnected failed: ECONNREFUSED (Connection refused)

Are these issues due to using an IP as opposed to a full domain?

jpmens commented 1 day ago

I see an ECONNREFUSED which means there's nothing listening on that TCP port (or it's firewall blocked.)

Do yourself a favor while attempting to set up and configure the Tailscale connection:

  1. keep an eye on the Mosquitto logs (tail -f /var/log/mosquitto/mosquitto.log in order to detect connections, publishes and subscribes
  2. use the utilities mosquitto_pub / mosquitto_sub. They're not super easy to use, but it's worth learning how they work.

If I were you I would first ensure everything works seamlessly on my local network, and later add the Tailscale ontop of that.

On the other hand: do you really require the VPN? We configure the MQTT broker (and the Web interface) to use TLS by default if you configure an email address in configuration.yaml.

Is that not sufficient for your requirements?

amrul-jamrul commented 1 day ago

I'm using tailscale for 2 reasons

  1. I am behind a double NAT so I can't portforward so its the only way to reach my devices when I'm outside of my home network
  2. I don't own a domain currently so its the only way I can interact with my services. So generally I'll just have something on the pi and then just connect to its ip and it's port.
amrul-jamrul commented 1 day ago

I've also run through my ufw settings and all the ports that it was throwing errors for are open

jpmens commented 1 day ago

Are these issues due to using an IP as opposed to a full domain?

No, absolutely not.

You are obfuscating port numbers so it's difficult to know what you're actually attempting. (Obfuscating IP addresses is fine, obviously.)

In theory, (I repeat: theory as I've never used Tailscale), you have a VPN on your mobile, and instruct our app to connect to a specific port which will exit on the VPN endpoint (your home?) and there be connected to the MQTT broker (Mosquitto). I assume the ECONNREFUSED is being handed up by Tailscale to our app.

Note also, that MQTT uses TCP/1883 for unencrypted traffic (which is fine in your case as you're protecting with a VPN) and TCP/8883 for TLS traffic (default ports). Note also, that we configure Mosquitto (via bootstrap.sh) to listen to port 1883 only on the loopback interface; you'll see this in:

$ sudo grep 1883 /etc/mosquitto/conf.d/owntracks.conf
# -- 1883 ----- Plain (loopback only)
listener 1883 127.0.0.1

You can change this, obviously, and restart Mosquitto, but be aware the config will be reset whenever you rerun ./bootstrap.sh

Depending on which address/port Tailscale is attempting to hand the connection off to on the endpoint, this might be the issue.