home page (more sweet code) ||
follow my twitter ||
blog ||
email me || samy kamkar
chownat
DESCRIPTION
chownat, pronounced "chone nat", allows two peers behind
two separate NATs with NO port forwarding and NO DMZ setup
on their routers to directly communicate with each other.
There is NO middle man, NO proxy, NO 3rd party, and the
application runs as an unprivileged user on both ends.
More importantly, it opens up a tunnel between the two
machines so one peer can access a service, such as a web
server, on the other machine which is also behind a NAT.
A new version, pwnat, is available which allows the server
to run WITHOUT ever knowing any client IP addresses.
Learn more here!
DOWNLOAD
chownat will work on any operating system (*NIX, Win32, OS X, etc) with perl.
A Windows executable is available as well.
v0.08b-beta, released 05/19/2005
download perl source here
v0.07, released 08/27/2004
download perl source here
download Windows executable here
download Windows zip file here
Changelog
available here
SYNOPSIS
chownat.pl [-d] <-c|-s> <local port> <dest host> [communication port]
CHANGES
Fixed a bug encountered during UTF-8 character transmission dependant
on the default language set on the machine.
Added lazy buffering / simple sequencing in the case that packets get
dropped. Lost packets will now get retransmitted and the connection
won't continue until the dropped packets are resent.
Added a verbose debug argument.
OPTIONS
chownat may be invoked with the following command-line
options:
-d
(optional) Debug mode to debug what chownat is doing.
A second -d specifies verbose debug mode.
-c
Client mode: use this to open a tunnel on localhost:local_port
and allows you to connect to localhost:local_port and your
connection to be opened to the destination server.
-s
Server mode: whoever connects to your chownat server will
end up connecting to whatever service that is already running
on localhost:local_port.
local port
Local port to listen on or connect to, depending on whether
-c or -s is used.
dest host
Destination host to connect to or to allow connections from.
comm port
(optional) UDP port for the two chownat machines to communicate
on. Defaults to 2222.
FAQ
Does the server have to specify the client host?
chownat DOES require the server to know the client host, however,
a new version, pwnat, is available which allows the server
to run WITHOUT ever knowing any client IP addresses.
Learn more here!
Ok, so does this really work?
Yes. Try it!
I'm confused. This can't work.
You should be, and it does work.
But it can't. My NAT blocks incoming packets and so will the other.
I know. It is non-obvious and non-trivial how my method overcomes the
widely-held belief that P2P penetration of NATs is impossible. My
program gets around that with a simple solution. New version forthcoming
will include a server that does not require the client's IP, as well.
But how?!
Great question! I thought you'd never ask.
Look below at HOW'S IT WORK?
Do I need to be root or a privileged user on either end to run this?
No.
Does this use DNS for anything?
No.
Do I need to setup port forwarding or a DMZ on either end?
No.
Is there some sort of proxy or 3rd party that tunnels information between
the two NATs?
No. The connection is direct, peer to peer.
Will this work behind my corporate NAT and firewall?
This will work behind almost any NAT and firewall.
What uses does this have?
This will allow you to tunnel any service that you want to run (http,
ssh, quake server, IRC, ftp, etc.) through your NAT. Then other users
behind their NATs can connect to you, even though you are in fact
behind a NAT that blocks incoming requests.
Are there any NATs or firewalls that this won't work with?
This will not work yet with OpenBSD+pf. There is no theoretical
reason that I can see that would stop a version getting through
just fine, so I am working on a version that will work with OpenBSD+pf.
What NATs specifically will this work on?
This will work on all NATs, including a Full Cone, Restricted Cone, Port
Restricted Cone, and Symmetric NAT. Only a strict firewall or UDP port
munging will stop chownat from working successfully. See RFC 3489 for
more information.
What if one or both ends aren't behind a NAT?
Everything will work just as well. You can use chownat to tunnel TCP
payload over UDP if you wish; no NATs are necessary.
HOW'S IT WORK?
Example of a client behind a NAT talking to a machine NOT behind a NAT:
Machine A -> NAT A -> net -> quake server
Machine A sends a UDP packet to quake server, opening a "session".
NAT A sees this and says:
"If any UDP packets come back soon with the same host and port info,
I'm routing it to machine A."
Quake server sends UDP packets back, hits NAT A, and NAT A seeing the right
hosts and ports, sends it to machine A. Machine A and quake server are now
able to communicate without any problem.
Now here is how chownat works. Goal is:
Machine A (ssh client) -> NAT A -> net -> NAT B -> Machine B (ssh server)
When you start up the chownat server on machine B, it slowly fires off
UDP packets to machine A. Of course, NAT A is not expecting these so it
drops every one of them. Machine B does not stop.
Once you begin the chownat client on machine A, it begins sending UDP
packets to machine B. Note: chownat defaults source and destination
ports to 2222. Any unprivileged user can set UDP source and dest ports.
Normally the UDP packets that machine A is sending to NAT B would get dropped.
However, since machine B is sending similar packets OUT, NAT B assumes
these are responses and lets them back in. Once machine B sees these packets,
it sends handshake packets back to machine A. These packets will not get
dropped by NAT A because of the same reason: NAT A sees packets going out, and
the packets coming back to the NAT look like responses to the ones going out.
Finally, both sides are fully communicating over UDP, allowing protocols that
run over TCP to tunnel through.
Note: There is a keep-alive process on the chownat server and client that
always keeps the UDP "session" active. The packets it sends have a 0 byte
payload and are only sent when the client is not sending data out. Otherwise,
the fastest it will possibly send the keep-alive packets is one packet every 5
seconds. If any other type of data is traveling through the tunnel, no
keep-alive packets will be transmitted.
The next big version update will be a true client/server model,
where the server does not need to know any client IP addresses to
allow them to connect. The client will only need to know the server.
I am not telling how it will work, just yet :)
EXAMPLE USAGE
Two machines exist across the Internet.
Machine nat1 is behind a NAT.
Machine nat2 is behind another NAT.
Machine nat1 is running a web server on port 80,
however it cannot be accessed because it is behind a NAT.
Machine nat1 wants to let nat2 connect to its web server.
In this case, nat1 runs:
./chownat.pl -d -s 80 nat2.com
And nat2 runs:
./chownat.pl -d -c 8000 nat1.com
nat2 connects to http://localhost:8000 in their local browser
and will access the http server nat1 has running on port 80
Similar scenario with ssh:
ssh server side:
./chownat.pl -d -s 22 nat2.com
client side:
./chownat.pl -d -c 1234 nat1.com
ssh -p 1234 user@localhost
SEE ALSO
perl(1)
BUGS
See CONTACT.
CONTACT
PLEASE e-mail bug reports, comments, questions or fanmail to samy@samy.pl.
Be sure to include the word ``chownat'' somewhere in the ``Subject:'' field.
Visit https://samy.pl for more awesome stuff.
I look forward to hearing from you!
chownat, by Samy Kamkar, 08/16/2004