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