Would this TCP splicing technique work?

Posted 19 Dec 2000 at 03:20 UTC by Omnifarious Share This

In response to a Slashdot article about the problems of making TCP/IP connections between two hosts behind different NATs, I posted this scheme. Nobody replied to my post, though I got a couple of responses via e-mail telling me they thought it was a neat idea.

Anyway, this is a technique for using the simultaneous SYN exchange method of bringing up a TCP/IP connection to make connections between two hosts behind different NATs using a broker. I'm curious what you all think of its chances of working.

TCP allows a connection to be established if both sides simultaneously send eachother a SYN packet. This method requires a little NAT cooperation, but only a little. Here's how it could work:

  1. Side1 Binds their TCP socket to a particular port.
  2. Side1 Tries to connect to Broker on an agreed upon port.
  3. Broker Replies with an RST when it recieves the expected SYN. Records source IP and source port.
  4. Side2 Binds their TCP socket to a particular port.
  5. Side2 Tries to connect to Broker on an agreed upon port.
  6. Broker Replies with an RST when it recieves the expected SYN. Records source IP and source port.
  7. Broker Informs Side1 of Side2's source port and source IP.
  8. Broker Informs Side2 of Side1's source port and source IP.
  9. Source1 Uses same socket originally bound to connect to Source2's IP and port.
  10. Source2 Uses same socket originally bound to connect to Source1's IP and port.
  11. Voila! They connect via exchange of simultaneous SYNs.

This requires cooperation between the sources and their NATs. Specifically, it requires these three things from a NAT:

  1. The NAT should keep the same outgoing port for the same TCP port on a client for a period of time. This is very similar to how a NAT handles UDP.
  2. A NAT must not reply to SYNs it recieves on a bound TCP port that don't originate from the connected to IP. Normally it would reply with an RST.
  3. A NAT must change the IP it's expecting TCP packets from if the client sends out a new SYN to a different IP and port combo.

There is one non-problem I expect people to bring up. There seems to be an apparent race condition in step 11. This isn't really a race condition because of requirement 2 for NATs. Basically, the two sources can SYN eachother all day, and it won't matter until both NATs have performed the step required by requirement 3, at which point it will appear to both sources as if the SYNs were simultaneous.

It's a hack, but I think it'd work.


Interesting..., posted 19 Dec 2000 at 14:45 UTC by jbowman » (Journeyer)

I think if you can get the level of cooperation between the two NATs and the broker, it would work, but I think there's a security hole in here:

In steps 9 and 10 (and requirement 3), you require that the Source machine allow the 'far' end of the tcp connection to change based on the arrival of a syn packet from another machine, without any apparent means for authenticating the two. Using the 'broker' machine to pass data back and forth transparently would work, but I'm not sure that's what you want.

All in and all, it's a neat idea, but I think that given the level of access/cooperation you' d have to have with your NAT arrangement in the first place that you might be better served setting up a port-forward from the NAT device's live ip to your internal ip for a specific, prearranged port (on both sides).

Re: Security hole, posted 19 Dec 2000 at 15:54 UTC by Omnifarious » (Journeyer)

No, steps 9 and 10 and requirement 3 cause the NATs destination IP to change on the basis of a SYN packet coming from inside the NAT. Basically, the call sequence of the non-broker program looks like this:

s = socket(PF_INET, SOCK_STREAM, PF_UNSPEC);
bind(s, 0.0.0.0, port);
ret = connect(s, broker_ip, size);
assert(ret != 0);
other_ip = getOtherIPFromBroker(brokerfd);
ret = connect(s, other_ip, size);
assert(ret == 0);

The second connect causes a different SYN to be sent out to other_ip from the same IP and port as the SYN to broker_ip was originally sent from. The requirements require that the NAT hold open the same outgoing port for the same source IP and port, like they do now for UDP, and change the destination IP based on where the SYN packets are being sent to.

The intenet is to allow peer-to-peer services to connect even if they're behind NATs. A cooperating broker is not inconcievable in these cases.

Argh, I'm blind..., posted 19 Dec 2000 at 16:15 UTC by jbowman » (Journeyer)

Blech, it's morning and I somehow glossed over the contents of steps 7 and 8. Whoops. So, yes, you're fine authentication-wise there. :)

The pseudo-code for the call sequence helps, and it makes sense for what you're trying to accomplish. I'm trying to think of a better way to go about it, but it looks like my initial thoughts are that this is a fairly sensible way to do it.

problems, posted 21 Dec 2000 at 16:02 UTC by ajv » (Master)

The amount of to and fro traffic is going to make connections between distant nodes very expensive. It's better if you can mark the initial packet as NAT-preferred, and the reply to optionally contain the necessary information. This way latency is not much impinged by your changes.

Why is latency an issue? HTTP 1.0 connections from where I live (Australia) to the less well connected portions of Europe can cause grief. ping times of over 700 ms or more are typical. For future space- based IP sessions, any thought of 8 light minutes per AU for each one of these steps is not going to work. Think about how you can remove the steps to the barest minimum, whilst still achieving your goal.

The problem really needs sorting out in the IPv6 world with AH packet authentication.

There are security reasons for forcing the use of a single IP address or a pool of addresses to appear for any number of internal hosts. This doesn't change by going to IPv6, and in fact, due to AH, IPv6 is actually a retrograde step for sites relying on information hiding.

You also need to deal with load balancing devices that work by ever so slightly breaking IP to redistribute load. They are unfortunately with us now, for the largest sites in the world cannot cope without them.

Re: problems, posted 27 Dec 2000 at 21:22 UTC by jochen » (Journeyer)

> The problem really needs sorting out in the IPv6 world with AH packet > authentication.

NAT is in fact violating the RFCs, even in the current IPv4 world.

> There are security reasons for forcing the use of a single IP address > or a pool of addresses to appear for any number of internal hosts. > This doesn't change by going to IPv6, and in fact, due to AH, IPv6 is > actually a retrograde step for sites relying on information hiding.

There are better ways for this than using NAT. Remember, in an IPv6 world, you will have more IP adresses for one local net than the complete Internet has today. One possible way to hide your internal information would be to add and delete IP aliases for each connection. This way you could still use authenticated P2P connection with AH and still don't provide any valuable information to the outside (the IP adress won't work after the connection has been shut down).

--jochen

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!

X
Share this page