diff options
Diffstat (limited to 'nat-traverse')
-rwxr-xr-x | nat-traverse | 98 |
1 files changed, 76 insertions, 22 deletions
diff --git a/nat-traverse b/nat-traverse index ca7b54c..e887a8f 100755 --- a/nat-traverse +++ b/nat-traverse @@ -1,6 +1,6 @@ #!/usr/bin/perl # nat-traverse -- Use of UDP to traverse NAT gateways -# Copyright (C) 2005 Ingo Blechschmidt <iblech@web.de> +# Copyright (C) 2005, 2012 Ingo Blechschmidt <iblech@web.de> # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -14,7 +14,7 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. use warnings; @@ -27,7 +27,7 @@ use Getopt::Long; # More elegant use constant {...} not available in Perl 5.6.x. use constant GARBAGE_MAGIC => "nat-traverse-garbage"; -use constant ACK_MAGIC => "nat-traverse-ack"; +use constant ACK_MAGIC => "nat-traverse-ackacka"; use constant PACKET_SIZE => 8 * 1024; sub debug($); @@ -38,7 +38,7 @@ GetOptions( "timeout=i" => \(my $TIMEOUT = 10), "quit-after-connect" => \my $QUIT_AFTER_CONNECT, "cmd=s" => \my $CMD, - "version" => sub { print "nat-traverse 0.4\n" and exit }, + "version" => sub { print "nat-traverse 0.5\n"; exit }, "help" => \&usage, ) or usage(); usage() unless @ARGV == 1; @@ -60,7 +60,7 @@ sub sockgen { return $sock; } -# Helper sub to wait for a given char. +# Helper sub to wait for a given string. sub waitfor { my ($sock, $match) = @_; @@ -115,7 +115,7 @@ if(defined $CMD) { die "Couldn't fork: $!\n" unless defined $pid; if($pid) { - # Parent -- read chars from STDIN and send them to the socket. + # Parent -- read from STDIN and to the socket. my $buf; while(1) { my $ret = sysread STDIN, $buf, PACKET_SIZE; @@ -131,7 +131,7 @@ if(defined $CMD) { } else { # Child -- print what's "in the socket". - print $_ while + print($_) or die "Couldn't write to STDOUT: $!\n" while defined(sysread $sock, $_, PACKET_SIZE) or die "Couldn't read from socket: $!\n"; } @@ -155,7 +155,7 @@ if(defined $CMD) { # Display usage info. sub usage { print STDERR <<'USAGE'; exit } -nat-traverse v0.4 -- Use of UDP to traverse NAT gateways +nat-traverse v0.5 -- Use of UDP to traverse NAT gateways Usage: user@left $ nat-traverse [options] port1:natgw-of-right:port2 @@ -191,12 +191,17 @@ nat-traverse - Use of UDP to traverse NAT gateways =head1 SYNOPSIS +To create a simple text-only tunnel, use the commands + user@left $ nat-traverse 40000:natgw-of-right:40001 user@right $ nat-traverse 40001:natgw-of-left:40000 +where C<40000> is an unused UDP port on C<left> and C<40001> is an unused port on +C<right>. See L</EXAMPLES> for more. + =head1 VERSION -This document describes nat-traverse v0.4. +This document describes nat-traverse v0.5. =head1 DESCRIPTION @@ -209,6 +214,10 @@ either. I<nat-traverse works out-of-the-box.> See L</TECHNIQUE> for how this is achieved. +Limitation: nat-traverse does not work with gateways which change the port +numbers. This is a fundamental problem of nat-traverse's design, as the changed +port numbers are (in general) not predictable. + =head1 OPTIONS =over @@ -257,7 +266,7 @@ nat-traverse -- thus OpenVPN would be able to cross NAT gateways. =head1 TECHNIQUE -nat-traverse establishes connections between hosts behind NAT gateways, without need +nat-traverse establishes connections between hosts behind NAT gateways without need for reconfiguration of the involved NAT gateways. =over @@ -283,7 +292,7 @@ are replies to the packets sent in step 2. Finally, both hosts send an acknowledgement packet to signal readiness. When these packets are received, the connection is established and nat-traverse can -either relay STDIN to the socket or execute a program. +either relay STDIN/STDOUT to the socket or execute a program. =back @@ -309,7 +318,7 @@ establish reliable TCP connections over the tunnel, even though the tunnel uses UDP! Furthermore, you could even add IPv6 addresses to C<ppp0> by running C<ip -6 addr add...>! -Note though that although this VPN I<is> a private network, it is I<not> +Note though that although this VPN I<is> arguably a private network, it is I<not> secured in any way. You may want to use SSH to encrypt the connection. =head2 Port Forwarding with netcat @@ -331,17 +340,62 @@ C<22>): # Will connect to right's SSH daemon! But do note that you lose the reliability of TCP in this example, as the actual -data is transported via UDP. If you want reliable streams, use PPP on top of -nat-traverse, as described above. +data is transported via UDP; so this is only a toy example. If you want +reliable streams, use PPP on top of nat-traverse, as described above. + +=head2 Setup of a VPN with OpenVPN + +You can use L<OpenVPN|http://openvpn.net/> over nat-traverse if you want to +have a I<secure> VPN. + +Using OpenVPN over nat-traverse requires only one change to OpenVPN's +configuration file, presuming that you don't want to use OpenVPN's multi-client +mode: You have to adjust the C<code> and C<lport> options +accordingly, for example: + + # Options to add to left's and right's OpenVPN config: + port 60001 + lport 60001 + + # Command to execute on left resp. right: + root@left # until \ + nat-traverse --quit-after-connect 60001:right:60001 \ + do \ + sleep 5 \ + done; \ + openvpn [...] + root@right # until \ + nat-traverse --quit-after-connect 60001:left:60001 \ + do \ + sleep 5 \ + done; \ + openvpn [...]<!-- + +The C<until> loop ensures that OpenVPN will not be started before +nat-traverse was able to establish the connection. Michael Kugele +(C<michael (at) kugele.net>) also reported a way to still be able to +use OpenVPN's multi-client mode with nat-traverse: As all instances of +nat-traverse have to use unique ports (because a connection is identified by +the source/destination port combination), you've to use redirection rules to +redirect the ports used by nat-traverse to the port the OpenVPN daemon listens +on: + + iptables -t nat -A PREROUTING -p udp \ + --dport $LPORT -j DNAT --to $HOST:$PORT + iptables -t nat -A PREROUTING -p udp \ + --dport $PORT -j REDIRECT --to-port $LPORT + +C<$LPORT> specifies the source port nat-traverse uses on the server +side, and C<$HOST:$PORT> is the address of the OpenVPN server.) =head1 LIMITATIONS -Only IPv4 is supported, nat-traverse won't work with IPv6 addresses. Even -though it would be relatively trivial to add IPv6 support, I refrained from -doing that, as there's no need to use NAT with IPv6 (the address space IPv6 -provides is sufficient). +Only IPv4 is supported, nat-traverse won't work with IPv6 addresses. Drop me a +note if you do need IPv6 support. -If you do need IPv6 support, drop me a note and I'll patch nat-traverse. +nat-traverse does not work with gateways which change the port numbers. This +is a fundamental problem of nat-traverse's design, as the changed port numbers +are (in general) not predictable. =head1 SEE ALSO @@ -383,10 +437,10 @@ starten kann. Damit ist ein einfaches VPN schnell aufgebaut. =head1 AUTHOR -Copyright (C) 2005 Ingo Blechschmidt, E<lt>iblech@web.deE<gt>. +Copyright (C) 2005, 2012 Ingo Blechschmidt, E<lt>iblech@web.deE<gt>. -You may want to visit nat-traverse's Freshmeat project page, -L<http://freshmeat.net/projects/nat-traverse/>, for new releases. +You may want to visit nat-traverse's Freecode project page, +L<http://freecode.com/projects/nat-traverse/>. =head1 LICENSE |