Skip to content

SRV registration proxy

Mo McRoberts edited this page Aug 16, 2010 · 4 revisions

The situation is that it’s basically impossible to do XMPP s2s from inside NAT without some kind of external infrastructure support. This might a fairly simple proxy, or could be a full-blown ejabberd. Alternatively, you can persuade all of the XMPP servers out their to support some new kind of extension. Or, you can breach one of the initial constraints and have people supply login details to their (possibly shared) TVs so that it can just log in to an external server itself.

I’m far from a fan of the ‘login details’ approach. It’s a kludge, and it’s a UX nightmare, so I’m not really going to entertain that while there are other viable options.

The most lightweight of all approaches is to get around the dialback problem: that is, remote XMPP servers don’t know how to find your NAT’d server instance. They’re expecting to be able to find SRV records including a host and port to talk to you on. As a fan of minimal infrastructure approaches, it strikes me that the cleanest approach is to find an easy way of making those SRV records available somehow.

Now, this isn’t a magic infrastructureless approach – it does require that people (and by ‘people’ I generally mean device manufacturers, but it could just as easily be individuals rolling their own setups) run a server or two. Nothing complicated: a DNS server and an HTTPS server.

The process is essentially this:

  • Out-of-box, the device contacts a predefined server run by the device manufacturer, over HTTPS. It supplies a client certificate issued by the manufacturer, and requests a key and domain name.
  • The web server responds with some key data and a per-device FQDN, and the device stores both in some persistent fashion. This is a bootstrap process, and only needs to happen again if the manufacturer’s server gets wiped or if the device does.
  • Periodically, or after certain state changes have been identified, the device sends a request to the server, signed with the key it was previously supplied, asking it to register records on its behalf – these records live under the FQDN previously supplied, using the parameters the device gives it. So, in our scenario, the device would ask the server to register xmpp-server.tcp within its FQDN and pass in the TCP port number the local router had told it was mapped to its local s2s port. This (external) port number could be 5269, or it could be 16392 — it essentially doesn’t matter.
  • The server adds the entry to DNS, making sure the target of the SRV record points to an A record with the IP the device’s request came from. It then sends a success response back to the device.
  • When talking to remote XMPP servers, the device uses the FQDN it had been supplied as the domain name in its JID.

Now, the splendid news is that I’ve tested this, running with the following scenario:

  • Created a dummy domain name: 2247eae3630b46565dc68ad351991292.devices.ilaven.net
  • Altered my (static, in this case) firewall rules to pass inbound traffic on port 15269 to the s2s port (5269) of a copy of ejabberd running on a machine on the internal side of the LAN
  • Added a DNS entry for my external IP
  • Added a DNS entry for xmpp-server.tcp:
$ host -t any _xmpp-server._tcp.2247eae3630b46565dc68ad351991292.devices.ilaven.net

_xmpp-server._tcp.2247eae3630b46565dc68ad351991292.devices.ilaven.net has SRV record 0 0 15269 portcullis.dnsalias.net.
  • Registered an account on the ejabberd instance from inside the network, using (in this case) mo@2247eae3630b46565dc68ad351991292.devices.ilaven.net as the JID
  • Added a few accounts from external XMPP providers to my roster. Said hello, etc.
  • And, er, that’s it.

So in other words, so long as there’s a SRV record there underneath whatever domain name you happen to use when you talk to the remote XMPP server, everything will work swimmingly, irrespective of port.

I don’t know how much hackery the common XMPP servers would need to support alias domains (i.e., tv.local is the same as whatever.devices.ilaven.net, and all JIDs in one domain are equivalent to JIDs in the other), but it’s probably less than some of the other aspects of this whole idea in any case – and, depending on how this is implemented, might not actually be necessary anyway.

There’s loads of stuff to thrash out and prototype still, but there’s nothing which can’t feasibly be done – and nothing which requires massive infrastructure commitments nor convincing large-scale providers to support new stuff. This is a Good Thing.