summaryrefslogtreecommitdiff
path: root/nat-traverse
diff options
context:
space:
mode:
Diffstat (limited to 'nat-traverse')
-rwxr-xr-xnat-traverse98
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