Would this TCP splicing technique work?
Posted 19 Dec 2000 at 03:20 UTC by Omnifarious 
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:
- Side1 Binds their TCP socket to a particular port.
- Side1 Tries to connect to Broker on an agreed upon
port.
- Broker Replies with an RST when it recieves the expected SYN.
Records source IP and source port.
- Side2 Binds their TCP socket to a particular port.
- Side2 Tries to connect to Broker on an agreed upon
port.
- Broker Replies with an RST when it recieves the expected SYN.
Records source IP and source port.
- Broker Informs Side1 of Side2's source port
and source IP.
- Broker Informs Side2 of Side1's source port
and source IP.
- Source1 Uses same socket originally bound to connect to
Source2's IP and port.
- Source2 Uses same socket originally bound to connect to
Source1's IP and port.
- 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:
- 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.
- 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.
- 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).
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.
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