Port Tunneling to SyncThing

Hi all,

I’d like to use ngrok to tunnel port 22000 to a public port on ngrok.com. Doing so in ngrok is trivial after signup: ngrok -proto=tcp -authtoken=fooobaaaarr 22000 - but I’m not sure where to go from there so that Syncthing:

  1. Listens on the local port, to receive incoming data through the tunnel
  2. Broadcasts from local port, but tells directory server and others to use the public port.

Right now, I see only one relevant setting, which is “Sync Protocol Listen Addresses”.

How would one set up Syncthing so that it does the above, and makes use of a port tunnel?

Thanks! Cathal PS: Please don’t suggest uPnP: It works, but in Ireland our ISPs layer NAT on NAT, so unless you arrange a dedicated IP specially with your ISP (not always possible) you’ll need hole-punching or a tunnel. Any thoughts on letting the directory server and other visible nodes hole-punch for Syncthing nodes behind layered NATs?

What I’ve tried so far:

  1. (Stupidly) set listening address to the outside port on ngrok.com, but that didn’t work.
  2. Set two listening addresses, one localhost at the local port, one distant at ngrok.com. It can’t listen at ngrok.com, of course, but I was hoping this would get sent to remote nodes who would attempt both and successfully connect through ngrok.com.

When I set two addresses, it bugs out, saying it doesn’t seem to be online and it keeps retrying/resetting. Probably because one of the “listen” addresses isn’t listenable, as it’s remote.

The missing option here is probably proxy settings, so that I could have a two-way proxy to a remote IP, but Syncthing doesn’t seem to support proxying?

Would I be right in assuming that if I can get this right just once, and have one publicly visible server running Syncthing, that it can introduce other devices? But that, even in this case, it can only introduce devices sharing a common repository?

If devices share more than one repository, is Syncthing clever enough to re-use a connection won through an intermediary via one repository to connect the other? So if I have Nodes 1,2,3 and they all share a repository publicly visible on Node 1, will 2 and 3 be able to connect through that repo and subsequently share a repo that Node 1 does not share?

This NATtification problem is pretty commonplace, so I can’t believe I’m the first person to ask about it; uPnP doesn’t magically resolve this for me, I need some kind of tunnel.

For this, just set the listening port to whatever ngrok wants to connect to.

You can’t tell it to announce the ngrok public port, because it doesn’t know about that port. For this to work, you’ll have to set up the other side to connect to whatever ngrok listens on, manually.

I think the common practice here is to set up a port forward manually and use the same listening port on the inside (what you configure syncthing for) as on the outside (the port forward). In this case, when syncthing is behind the NAT device, the announcement will be correct. Of course, in your case (ngrok) you’re not behind that NAT device so this practice fails. This I think is not commonplace.

You can’t tell it to announce the ngrok public port, because it doesn’t know about that port. For this to work, you’ll have to set up the other side to connect to whatever ngrok listens on, manually.

Right; so that’s a missing feature, then. My problem case here is that I need to announce a listening IP:Port other than the one I’m making requests to other users from. I could OpenVPN the whole system and expose a port that way, but what if I’m comfortable behind the NAT (security, speed vs. VPN, low setup/maintenance) for everything except Syncthing? Using one of the many port tunnellers out there to listen somewhere public for Syncthing incoming data would be very valuable, even if that incoming data were a prelude to NAT hole-punching.

Hole-punching in general would be a feature I’d consider critical for Syncthing to be useful to me and others in Ireland; we should be able to connect through some means, punch ports, and communicate through NATs with minimal setup. There are directory servers that could provide this service initially, and once connected to some other known users those users could act as hole-punching relays.

Right now, Syncthing is a really helpful tool for synchronising over the LAN between my phone and laptop, and my laptop and my wife’s, etc… but it’s not very useful for anything outside of that in the same way as server:client stuff like Owncloud or DHT-based hole-punching stuff like BTSync (yay spyware!). I’d love to see that change.

What are you trying to gain by the ngrok setup? What’s the use case that regular NAT port forwards don’t cover?

Would have to second this request. Would be great to be able to publish a list of ip:port to the global announce server. Then ngrok or other port tunneling systems would work. I have been having a hard time connecting from inside my NAT (looking at you Time Capsule), but was trivial to create an open port on ngrok.

Having a look through the code… The announce server is only given a port, and it pairs the IP of the incoming request with the listening port set on the local Syncthing. There is no way to tell the announce server to use a 3rd party.

Current work around is to start ngrok locally, then set the ip:port combo (ngrok.com:12345) on the other remote systems. Works fine until you drop the ngrok connection and are reassigned another port.

So I would second this as a feature request. The config file does contain a place for an address, but it is not sent to the global announce server.

No matter though, I’m migrating my (extensive) BTSync setup to Syncthing soon.

On the contrary, the discovery server can be told an address in addition to a port (even multiple such sets) and will trust what it’s told. It’s just that syncthing doesn’t send an address because it generally doesn’t know it’s external address, and a null address is replaced with the source address by the discovery server.

I’m not really clear on why it would be OK to configure your local syncthing instance with a static address:port to announce, but you can’t configure the other instance with that same static address:port to connect to instead?