[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

17 posts / 0 new
Last post
extofme
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

UPDATE 1/10/11 New patch http://www.vyatta.org/node/4744#comment-18244
UPDATE 1/11/11 DNS patch http://www.vyatta.org/node/4744#comment-18248

vyatta team,

this is my first post here, so i'd like to say that i really appreciate the work you guys have/are doing. we use vyatta in our small company's network; the configuration format is superb, enabling us to track changes with ease. i have learned incredible amounts from your documentation. thank you so much; keep up the great work!

i decided to also use vyatta for my home network. after reading and battling the IPsec + L2TP configs and documents for the past week+, i started looking at the config files themselves to understand why i could only ever get my setup partially working. in short:

) i have a dynamic IP assigned by my ISP
) i want to connect to this IP from mobile devices (android/etc.)
) i wish to use IPsec/L2TP for this

i'm not an expert by any means, but extensive reading + trial/error has identified this problem:

) in vyatta 6.1, setting "outside-address" to 0.0.0.0 in L2TP remote-access config does not result in the same outputs as setting "local-ip" to 0.0.0.0 in IPsec site-to-site config

specifically, 6.1 generates this output:

# cat /etc/ipsec.secrets | grep PSK
0.0.0.0 %any : PSK "test"

# cat /etc/ipsec.d/tunnels/remote-access | grep 'left='
  left=0.0.0.0

instead of (like site-to-site):

# cat /etc/ipsec.secrets | grep PSK
: PSK "test"

# cat /etc/ipsec.d/tunnels/remote-access | grep 'left='
  left=%defaultroute

if i make the above changes manually, i am able to successfully connect from a Nexus S android phone with IPsec/L2TP from an arbitrary IP, and it also handles the fact that my local IP address is not static.

this patch to L2TPConfig.pm corrects the problem permanently:

[code]--- /opt/vyatta/share/perl5/Vyatta/L2TPConfig.pm.orig 2011-01-08 21:49:40.000000000 +0000
+++ /opt/vyatta/share/perl5/Vyatta/L2TPConfig.pm 2011-01-08 22:04:39.000000000 +0000
@@ -313,9 +313,14 @@
my $oaddr = $self->{_out_addr};
return (undef, "IPsec pre-shared secret not defined") if (!defined($key));
return (undef, "Outside address not defined") if (!defined($oaddr));
+ my $peers = "$oaddr %any ";
+ # when outside-address is dynamic then only the generic form works
+ if ($oaddr eq '0.0.0.0') {
+ $peers = '';
+ }
my $str =<

extofme
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

:-(

i'm having a couple problems that only surfaced once i rebooted for the first time in awhile:

) my 10.10.1.1 eth1 interface is static, and beats out [slower] DHCP-based eth0 (the real gateway)... pluto chooses wrong IP at boot to use for SA? simple `restart vpn` once after boot corrects this

) xl2tpd will not start at boot time if the IP in the config is 0.0.0.0 for some reason? simple `sudo /etc/init.d/xl2tpd start` once after boot corrects this... `restart vpn` doesn't work here

any idea on how to correct the above? seems i have some race conditions; i can work around it easy enough, but i like to find a proper solution :-)

thoughts?

C Anthony

extofme
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

i figured out the problem.

there wasn't a race condition; %defaultroute was chosen correctly (shown by /var/run/ipsec.info). it didn't work because the IPsec config wasn't reloaded (`ipsec rereadall` and `ipsec update`) after the L2TP config was appended, nor was the xl2tpd daemon even started ...

... because the clustering code thought 0.0.0.0 might be a cluster IP :-)

AFAICS, the clustering code checks to see if the the L2TP IP exactly matches any defined IPsec local interface; if it does, it assumes it's not clustered (cluster = "virtual" interface?). I followed in the path of the IPsec code and special cased 0.0.0.0.

following is updated patches. i'm not 100% i'm doing this right; i will open a bug if need be i'm just looking for some feedback. i haven't got internet access thru the VPN yet, but i do have local access (same subnet as VPN clients)... i just haven't figured it out yet; networking isn't my strongest skill, i think it's NAT and route problems :-(

C Anthony

ps ... vyatta-update-l2tp.pl patch might be slightly off (line number wise), i did a fair amount of editing when tracking down the issue and forgot to backup the original.

--------------------------------------------------------------

--- /opt/vyatta/sbin/vyatta-update-l2tp.pl.orig	2011-01-10 08:54:58.000000000 +0000
+++ /opt/vyatta/sbin/vyatta-update-l2tp.pl	2011-01-10 07:21:42.000000000 +0000
@@ -135,7 +135,7 @@
   exit 0;
 }
 
-if (!($config->maybeClustering($gconfig, @ipsec_ifs))
+if (($config->hasLocalWildcard() || !($config->maybeClustering($gconfig, @ipsec_ifs)))
     && $config->needsRestart($oconfig)) {
   # kill existing PPP sessions
   system("kill -TERM `pgrep -f 'name VyattaL2TPServer'` >&/dev/null");

[code]--- /opt/vyatta/share/perl5/Vyatta/L2TPConfig.pm.orig 2011-01-08 21:49:40.000000000 +0000
+++ /opt/vyatta/share/perl5/Vyatta/L2TPConfig.pm 2011-01-10 08:57:22.000000000 +0000
@@ -260,6 +260,11 @@
return $self->{_is_empty};
}

+sub hasLocalWildcard {
+ my ($self) = @_;
+ return ($self->{_out_addr} eq '0.0.0.0');
+}
+
sub setupX509IfNecessary {
my ($self) = @_;
return (undef, "IPsec authentication mode not defined")
@@ -313,9 +318,10 @@
my $oaddr = $self->{_out_addr};
return (undef, "IPsec pre-shared secret not defined") if (!defined($key));
return (undef, "Outside address not defined") if (!defined($oaddr));
+ my $peers = (($oaddr ne '0.0.0.0') ? "$oaddr %any " : '');
my $str =<{_out_addr};
return (undef, "Outside address not defined") if (!defined($oaddr));
my $onh = $self->{_out_nexthop};
- return (undef, "Outside nexthop not defined") if (!defined($onh));
+ my $nhop_str = (defined($onh) ? " leftnexthop=$onh\n" : '');
my $auth_str = " authby=secret\n";
return (undef, "IPsec authentication mode not defined")
if (!defined($self->{_mode}));
@@ -357,6 +363,9 @@
leftcert=$server_cert
EOS
}
+ if ($oaddr eq '0.0.0.0') {
+ $oaddr = '%defaultroute';
+ }
my $str =<

john.southworth
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

Hi, I am working on a VPN enhancement project for a future release. I'll file a bug for this and investigate this today. I'll let you know what I find. Thanks for investigating this. It looks like you are on the right track

extofme
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

ok cool. i forgot to metion i dropped the requirement for 'outside-nexthop' in the patches become is seems superfluous, and the man page for ipsec/strongswan says:

Quote:
this parameter is usually not needed any more because the NETKEY IPsec stack does not require explicit routing entries for the traffic to be tunneled. If leftsourceip is used with IKEv1 then leftnexthop must still be set in order for the source routes to work properly.

might be needed for some, but not in my use case apparently.

C Anthony

john.southworth
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends
extofme
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

shazam!

i finally have a fully functional VPN; my last issue was a DNS problem, not routing/NAT.

when trying to point my VPN users at the local vyatta DNS forwarding agent (dnsmasq), i neglected the fact that the config forces me to choose an interface to listen on. i chose my internal bridge, which works perfectly, except for that fact that none of the VPN users are actually on that bridge ...

i could assign static DNS addresses easy enough, but i want everything to be inherited ... sooo, my quick and [maybe not so?] dirty solution was this:

--- /opt/vyatta/share/vyatta-cfg/templates/service/dns/forwarding/node.def.orig	2011-01-11 07:52:05.000000000 +0000
+++ /opt/vyatta/share/vyatta-cfg/templates/service/dns/forwarding/node.def	2011-01-11 07:52:41.000000000 +0000
@@ -1,6 +1,5 @@
 priority: 918
 help: DNS forwarding
-commit:expression: $VAR(./listen-on) != ""; "At least one interface must be configured for DNS forwarding parameter 'listen-on'"
 delete:expression: "touch /tmp/dnsmasq.$PPID"
 end:expression: "if [ -f \"/tmp/dnsmasq.$PPID\" ]; then \
         sudo /opt/vyatta/sbin/vyatta-dns-forwarding.pl --stop-dnsforwarding \

i simply dropped the requirement to have an interface, which lets dnsmasq respond to everyone.

a more useful patch would probably be to allow users to define a listen-address and/or an interface (or none for that matter :-).

thanks,

C Anthony

extofme
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

EDIT: this doesn't work at all; while you can specify multiple interfaces, there is no way to match "wildcard" interfaces (ppp+) like you can with firewall rules... this is a dnsmasq config limitation. introducing the ability to bind dnsmasq to an address or address-group would be much more useful IMO.

-----------------------------------------------------------------------

the DNS patch is not needed... i didn't realize i could specify multiple interfaces for DNS forwarding :-) seems obvious now...

however, i also need 'ppp+' which matches any ppp interface... where is this in the docs? i have been thru almost every doc front to back and i dont remember this.

are there any other special characters?

and it's not always obvious (from CLI anyway) which properties can be repeated, though the docs might specify this; then again maybe i just missed it :-)

C Anthony

john.southworth
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

To tell if a configuration node is a multi-value node, look at the command in the documentation and under parameters it will say: 'Multi-Node'.

I'm looking into your l2tp patches, I need to make sure that it doesn't conflict with the way other tunnels are connecting. I'll be posting to bugzilla with the findings.

john.southworth
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

You can try to add what you need to /opt/vyatta/sbin/vyatta-dns-forwarding.pl for the dnsmasq config. I know that you can specify a listen address and a listen-on interface at the same time, so you may just be able to add the options that you need. You'll have to create a node for the new option but if you take a look at some of the node files under /opt/vyatta/share/vyatta-cfg/templates/services/dns/forwarding, they should give you an idea as to the format the node.def needs to be in.

extofme
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

ok, thanks for the pointers; i'll take a look at adding listen address and post the changes... do you want me to post them to the bug? am i even able to?

i have also noticed that sometimes the tunnels are not cleaned up properly, but i haven't identified why/when. i don't think it's related to my patches though, as i've read about it in other threads, but it seems to happen when the two ends are de-synced somehow (phone sleeps?) but the client end doesn't "realize" it? basically when i disco and try to reconnect, the logs complain the `eroute` already exists, and denies the client. it might time out, but issuing `restart vpn` fixes it... at the expense associated with a restart of course.

i'm not at home ATM, so i don't have the logs on-hand.

C Anthony

john.southworth
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

The Dnsmasq patch would actually be considered a different issue. You can register for a bugzilla account and file bug reports if you like.

The connections not being cleaned up properly is a known problem, I am adding a parameter to help with this as part of the enhancement project I am working on. If you adjust the ike-lifetime of the tunnels it will help the connections time out faster.

fogozito
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

where is the code for IPsec?

digipengi
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

Your code helped me get my configuration working. So far everything seems to be working but I will test it from the office tomorrow. Thanks again!

john.southworth
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

This code will work until the interface changes, then your %defaultroute will not get refreshed in the ipsec config and your tunnels will stop working. I have integrated the notion of a dhcp-interface into the l2tp configuration for an upcoming release. This will allow you to set an interface instead of an outside-address, it will also set a hook into dhclient that will update the configuration when the address of the configured interface changes.

digipengi
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

john.southworth wrote:
This code will work until the interface changes, then your %defaultroute will not get refreshed in the ipsec config and your tunnels will stop working. I have integrated the notion of a dhcp-interface into the l2tp configuration for an upcoming release. This will allow you to set an interface instead of an outside-address, it will also set a hook into dhclient that will update the configuration when the address of the configured interface changes.

Funny that you posted that cause just yesterday I connected to my VPN and ran an update for my dynamic DNS then disconnected and I got a phone call from home right away saying that they could not get online. If I power cycled my modem they were able to get online though. So I am not 100% as to what caused it yet but it seems to happen sporadically. Hopefully the new version will be out soon :)

extofme
[PATCH] IPsec/L2TP remote-access with dynamic IP; both ends

john.southworth wrote:
I have integrated the notion of a dhcp-interface into the l2tp configuration for an upcoming release. This will allow you to set an interface instead of an outside-address, it will also set a hook into dhclient that will update the configuration when the address of the configured interface changes.

ah nice, that will do it. i got ahead of myself and installed 6.2 thinking i could drop a few of my custom patches :-)

will she be in 6.2+1? many of these dynamic problems can be solved this way i think ... some places force interface, when i really need an address; others force address (this one) when i need an interface -- maybe some kind of generic mechanism here would be beneficial.

anyways good stuff, thanks for the update; looking forward to release.

C Anthony

Log in or register to post comments