# L2TP Ipsec client



## Sindikat88 (Jul 12, 2017)

Hello!
Prompt the problem resolution.
It is necessary to adjust the client of L2TP/IPSEC on FreeBSD.
I perform tuning according to https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/ipsec.html.
But nothing is impossible.
Clients are connected by Windows without problems.
Local internal network: 192.168.190.0/24
Remote internal network: 192.168.10.0/24
VPN network: 192.168.196.0/24
VPN server - router Mikrotik.
The kernel is collected with parameters:

```
options IPSEC #IP security
options IPSEC_ESP #IP security (crypto; define w/IPSEC)
options IPSEC_FILTERTUNNEL
options IPSEC_NAT_T
options IPSEC_FILTERGIF #filter ipsec packets from a tunnel
device crypto
device enc
device gif
```

/etc/rc.conf:

```
gif_interfaces="gif0"
gifconfig_gif0="My_external_IP Server_External_IP"
ifconfig_gif0="inet 192.168.190.1 192.168.10.1 netmask 0xffffffff"
racoon_enable="YES"
ipsec_enable="YES"
ipsec_program="/usr/local/sbin/setkey"
ipsec_file="/etc/ipsec.conf"
mpd_enable="YES"
```
/usr/local/etc/racoon/racoon.conf:

```
# $KAME: racoon.conf.in,v 1.18 2001/08/16 06:33:40 itojun Exp $

# "path" affects "include" directives.  "path" must be specified before any
# "include" directive with relative file path.
# you can overwrite "path" directive afterwards, however, doing so may add
# more confusion.
path include "@sysconfdir_x@/racoon";
#include "remote.conf";

# the file should contain key ID/key pairs, for pre-shared key authentication.
path pre_shared_key "/usr/local/etc/racoon/psk.txt";

# racoon will look for certificate file in the directory,
# if the certificate/certificate request payload is received.
#path certificate "@sysconfdir_x@/cert";

# "log" specifies logging level.  It is followed by either "notify", "debug"
# or "debug2".
log debug2;

# "padding" defines some padding parameters.  You should not touch these.
padding
{
        maximum_length 20;      # maximum padding length.
        randomize off;          # enable randomize length.
        strict_check off;       # enable strict check.
        exclusive_tail off;     # extract last one octet.
}

# if no listen directive is specified, racoon will listen on all
# available interface addresses.
listen
{
        isakmp My_External_IP [7001];
        isakmp My_External_IP [500];
        #admin [7002];          # administrative port for racoonctl.
        #strict_address;        # requires that all addresses must be bound.
}

# Specify various default timers.
timer
{
        # These value can be changed per remote node.
        counter 5;              # maximum trying count to send.
        interval 20 sec;        # maximum interval to resend.
        persend 1;              # the number of packets per send.

        # maximum time to wait for completing each phase.
        phase1 30 sec;
        phase2 15 sec;
}

remote Server_External_IP
{
        exchange_mode           main,aggressive;
        doi                     ipsec_doi;
        lifetime time           24 hour;
        situation               identity_only;
        my_identifier           address;
        peers_identifier        address;
        proposal_check          obey;
        passive                 off;
        generate_policy         off;
        nat_traversal           on;

                                proposal {
        encryption_algorithm blowfish;
        hash_algorithm md5;
        authentication_method pre_shared_key;
        dh_group modp2048;
                                }
}

remote ::1 [8000]
{
        #exchange_mode main,aggressive;
        exchange_mode aggressive,main;
        doi ipsec_doi;
        situation identity_only;

        my_identifier user_fqdn "sakane@kame.net";
        peers_identifier user_fqdn "sakane@kame.net";
        #certificate_type x509 "mycert" "mypriv";

        nonce_size 16;
        lifetime time 1 min;    # sec,min,hour

        proposal {
                encryption_algorithm 3des;
                hash_algorithm sha1;
                authentication_method pre_shared_key;
                dh_group 2;
        }
}

sainfo subnet 192.168.190.0/24 any subnet 192.168.10.0/24 any
{
        pfs_group                       modp2048;
        encryption_algorithm            blowfish,3des;
        authentication_algorithm        hmac_md5,hmac_sha1;
        compression_algorithm           deflate;
}

sainfo anonymous {
        encryption_algorithm 3des;
        authentication_algorithm hmac_md5, hmac_sha1;
        lifetime time 1 hour ;
        compression_algorithm deflate;
}
```

/usr/local/etc/racoon/psk.txt:


```
# IPv4/v6 addresses
Server_External_IP  password
```

/etc/ipsec.conf

```
flush;
spdflush;
spdadd 192.168.190.1/24 192.168.196.1/24 ipencap -P out ipsec esp/tunnel/My_External_IP-Server_External_IP/require;
spdadd 192.168.196.1/24 192.168.190.1/24 ipencap -P in ipsec esp/tunnel/Server_External_IP-My_External_IP/require;
```
racoon.log

```
/usr/local/sbin/racoon -F -f /usr/local/etc/racoon/racoon.conf -l /var/log/racoon.log
Foreground mode.
2017-07-12 15:49:15: INFO: @(#)ipsec-tools 0.8.2 (http://ipsec-tools.sourceforge.net)
2017-07-12 15:49:15: INFO: @(#)This product linked OpenSSL 1.0.1s-freebsd  1 Mar 2016 (http://www.openssl.org/)
2017-07-12 15:49:15: INFO: Reading configuration from "/usr/local/etc/racoon/racoon.conf"
2017-07-12 15:49:15: DEBUG2: lifetime = 86400
2017-07-12 15:49:15: DEBUG2: lifebyte = 0
2017-07-12 15:49:15: DEBUG2: encklen=128
2017-07-12 15:49:15: DEBUG2: p:1 t:1
2017-07-12 15:49:15: DEBUG2: Blowfish-CBC(3)
2017-07-12 15:49:15: DEBUG2: MD5(1)
2017-07-12 15:49:15: DEBUG2: 2048-bit MODP group(14)
2017-07-12 15:49:15: DEBUG2: pre-shared key(1)
2017-07-12 15:49:15: DEBUG2:
2017-07-12 15:49:15: DEBUG2: Etype mismatch: got 2, expected 4.
2017-07-12 15:49:15: DEBUG: hmac(modp2048)
2017-07-12 15:49:15: DEBUG2: lifetime = 60
2017-07-12 15:49:15: DEBUG2: lifebyte = 0
2017-07-12 15:49:15: DEBUG2: encklen=0
2017-07-12 15:49:15: DEBUG2: p:1 t:1
2017-07-12 15:49:15: DEBUG2: 3DES-CBC(5)
2017-07-12 15:49:15: DEBUG2: SHA(2)
2017-07-12 15:49:15: DEBUG2: 1024-bit MODP group(2)
2017-07-12 15:49:15: DEBUG2: pre-shared key(1)
2017-07-12 15:49:15: DEBUG2:
2017-07-12 15:49:15: DEBUG: hmac(modp1024)
2017-07-12 15:49:15: DEBUG: no check of compression algorithm; not supported in sadb message.
2017-07-12 15:49:15: DEBUG: getsainfo params: loc='192.168.190.0/24' rmt='192.168.10.0/24' peer='NULL' client='NULL' id=0
2017-07-12 15:49:15: DEBUG: no check of compression algorithm; not supported in sadb message.
2017-07-12 15:49:15: DEBUG: getsainfo params: loc='ANONYMOUS' rmt='ANONYMOUS' peer='NULL' client='NULL' id=0
2017-07-12 15:49:15: DEBUG: evaluating sainfo: loc='192.168.190.0/24', rmt='192.168.10.0/24', peer='ANY', id=0
2017-07-12 15:49:15: DEBUG: check and compare ids : values matched (ANONYMOUS)
2017-07-12 15:49:15: DEBUG: check and compare ids : values matched (ANONYMOUS)
2017-07-12 15:49:15: DEBUG2: parse successed.
2017-07-12 15:49:15: INFO: My_External_IP[500] used as isakmp port (fd=4)
2017-07-12 15:49:15: INFO: My_External_IP[7001] used as isakmp port (fd=5)
2017-07-12 15:49:15: DEBUG: pk_recv: retry[0] recv()
2017-07-12 15:49:15: DEBUG: got pfkey X_SPDDUMP message
2017-07-12 15:49:15: DEBUG2:
02120000 0b000100 01000000 5b0c0000 03000500 11200000 10020000 1fad3aed
00000000 00000000 03000600 11200000 100206a5 5becb16f 00000000 00000000
03001200 02000100 01000000 00000000 08003200 01020000
2017-07-12 15:49:15: DEBUG: pk_recv: retry[0] recv()
2017-07-12 15:49:15: DEBUG: got pfkey X_SPDDUMP message
2017-07-12 15:49:15: DEBUG2:
02120000 0b000100 00000000 5b0c0000 03000500 11200000 100206a5 5becb16f
00000000 00000000 03000600 11200000 10020000 1fad3aed 00000000 00000000
03001200 02000200 02000000 00000000 08003200 01020000
2017-07-12 15:49:15: DEBUG: sub:0x7fffffffe278: Server_External_IP/32[1701] My_External_IP/32[0] proto=udp dir=out
2017-07-12 15:49:15: DEBUG: db :0x80205d610: My_External_IP/32[0] Server_External_IP/32[1701] proto=udp dir=in
```


----------



## obsigna (Jul 12, 2017)

I don't have experience with setting-up L2TP/IPsec clients on FreeBSD, however, I am operating several L2TP/IPsec dial-in services on various FreeBSD server machines. While I am not able to give you a complete solution, at least here come some hints:

A L2TP/IPsec VPN does consist of two different protocols, both of which must be configured on each side of the VPN.


IPsec may be covered by installing security/ipsec-tools and configuration of racoon.conf(5) and the security policies, although, I prefer security/strongswan.


Note, that IPsec in the L2TP/IPsec stack must operate in Transport mode, while you set up the security policies for Tunnel mode.


L2TP must be installed and configured separately. I use net/mpd5 for this.


A client which wants to connect to a L2TP/IPsec server would first initiate an IPsec connection in transport mode, using a pre-shared key or certificates for authentication.


The security policies on both sides of the IPsec line shall direct any UDP traffic on port 1701 (the L2TP port) via the established IPsec connection.


Now the L2TP client comes into play and tries to connect via UDP 1701 to the server by using separate credentials (usually username and password), and because of the SPD's which must have been set up correctly by the IPsec connection, the traffic should go over the IPsec line.


Special care must be taken if one or both of the endpoints are behind NAT. In this case, the FreeBSD kernel does not handle well the UDP checksums of the encapsulated L2TP packets, and while the IPsec connection can be established successfully, the L2TP line cannot, because all L2TP packets are dropped because of checksum mismatches – if you experience this behaviour once your L2TP/IPsec client setup is almost working, you need to patch the kernel, and re-compile it. For this, change line 486 of file /usr/src/sys/netinet/udp_usrreq.c from:

```
if (uh->uh_sum) {
```
to:
	
	



```
if (uh->uh_sum && uh->uh_dport != htons(1701) && uh->uh_dport != htons(4500)) {
```


----------



## Sindikat88 (Jul 13, 2017)

I apologize. I have forgotten to tell, mpd5 is used.
There is his config  /usr/local/etc/mpd5/mpd.conf:

```
startup:
      # Set web self 127.0.0.1 5008
      # Set user vpntest vpntest admin
      # Set web open

default:
      load my

my:
      create bundle static L2TP
      set bundle disable compression
      set bundle disable round-robin
      set bundle disable encryption
      set bundle disable crypt-reqd
      set bundle disable bw-manage
      set bundle disable ipv6cp
      set bundle enable ipcp
      set ipcp no vjcomp
      set iface mtu 1460
      set iface idle 0
      set iface enable tcpmssfix
      set iface route 192.168.196.0/24
      create link static L2 l2tp
      set link action bundle L2TP
      set link latency 0
      set link max-redial 1
      set link disable incoming acfcomp protocomp magicnum check-magic shortseq
      set link deny chap-msv2 chap-msv1 eap acfcomp protocomp shortseq
      set link accept pap
      set link keep-alive 10 75
      set l2tp peer Server_External_IP
      set auth authname "user"
      set auth password "password"
      open
```


----------



## Sindikat88 (Jul 18, 2017)

at whom be to eat the ideas how to launch L2TP/IPSEC the client under FreeBSD?
Or what users for NAT could use L2TP/IPSEC connection


----------



## Sindikat88 (Jul 21, 2017)

Colleagues, hello!
I at last adjusted L2TP/IPSEC connection to the Mikrotik server pre-shared key.
For this purpose we need racoon and mpd5. 
I give the configuration which works:
rc.conf

```
racoon_enable="YES"
ipsec_enable="YES"
ipsec_program="/usr/local/sbin/setkey"
ipsec_file="/etc/ipsec.conf"
mpd_enable="YES"
```
racoon.conf

```
# $KAME: racoon.conf.in,v 1.18 2001/08/16 06:33:40 itojun Exp $

# "path" affects "include" directives.  "path" must be specified before any
# "include" directive with relative file path.
# you can overwrite "path" directive afterwards, however, doing so may add
# more confusion.
path include "@sysconfdir_x@/racoon";
#include "remote.conf";

# the file should contain key ID/key pairs, for pre-shared key authentication.
path pre_shared_key "/usr/local/etc/racoon/psk.txt";

# racoon will look for certificate file in the directory,
# if the certificate/certificate request payload is received.
#path certificate "@sysconfdir_x@/cert";

# "log" specifies logging level.  It is followed by either "notify", "debug"
# or "debug2".
log debug;

# "padding" defines some padding parameters.  You should not touch these.
padding
{
        maximum_length 20;      # maximum padding length.
        randomize off;          # enable randomize length.
        strict_check off;       # enable strict check.
        exclusive_tail off;     # extract last one octet.
}

# if no listen directive is specified, racoon will listen on all
# available interface addresses.
listen
{
        isakmp                  My_External_IP [7001];
        isakmp                  My_External_IP [500];
        isakmp_natt             My_External_IP [4500];
        #admin [7002];          # administrative port for racoonctl.
        #strict_address;        # requires that all addresses must be bound.
}

# Specify various default timers.
timer
{
        # These value can be changed per remote node.
        counter 5;              # maximum trying count to send.
        interval 20 sec;        # maximum interval to resend.
        persend 1;              # the number of packets per send.
#       natt_keepalive  15 sec;
        # maximum time to wait for completing each phase.
        phase1 30 sec;
        phase2 15 sec;
}

remote Server_External_IP
{
        exchange_mode           main,aggressive;
        doi                     ipsec_doi;
        lifetime                time 24 hour;
        situation               identity_only;
        my_identifier           address My_External_IP;
        peers_identifier        address Server_External_IP;
        proposal_check          obey;
        passive                 off;
        generate_policy         off;
#       nat_traversal           off;

                                proposal {
        encryption_algorithm aes;
        hash_algorithm sha1;
        authentication_method pre_shared_key;
        dh_group modp2048;
                                }
}


sainfo anonymous
{
        pfs_group modp2048;
        encryption_algorithm            3des;
        authentication_algorithm        hmac_sha1;
        compression_algorithm           deflate;
}
```
psk.txt

```
# IPv4/v6 addresses
Server_External_IP  password
```
ipsec.conf:

```
flush;
spdflush;
spdadd 0.0.0.0/0 0.0.0.0/0[1701] any -P out ipsec esp/transport//require;
spdadd 0.0.0.0/0[1701] 0.0.0.0/0 any -P in ipsec esp/transport//require;
```
mpd5.conf

```
startup:
      # Set web self 127.0.0.1 5008
      # Set user vpntest vpntest admin
      # Set web open
log +ALL +EVENTS -FRAME -ECHO
default:
      load L2TP_client

L2TP_client:
        create bundle static B1
        create link static L1 l2tp
        set link action bundle B1
        set auth authname "user"
        set auth password "password"
        set link max-redial 0
        set link mtu 1460
        set link keep-alive 20 75

        set l2tp peer Server_External_IP
        open
```
It is a little explanations.
In Handbook recommend to create gif the adapter. To us to create it there is no need.
MPD5 will create the virtual adapter which will receive necessary settings from the server.


----------



## topcat (Sep 20, 2017)

Thanks for posting your setup! I am also trying to connect to a L2TP vpn running on Windows Server from my FreeBSD machine. In your final setup, did you need to recompile the kernel?


----------



## VVD (Jan 16, 2018)

Thanks for information in this thread!

Tried all your configs and can't see any gif interfaces automatically created after start ipsec, racoon and mpd5.
My network configuration is:
"VPN Server (L2TP over IPsec wendoze server) with white IP" - "(internet)" - "My gateway on FreeBSD 10.3 with white IP and ipf nat" - "(local network 10.0.0.0/16)" - "VPN client (workstation on FreeBSD 11.1)".
I have next information:
1. VPN Server IP;
2. My gateway external and internal IPs;
3. Workstation internal IP;
4. VPN Login;
5. VPN Password;
6. VPN PSK key.
I don't know tunnel's IP network - win clients can connect from local network without it.

What changes I have to do in examples in top of this thread? What logs I have to show for diagnostics?

Thanks for any help!


P.S. Sorry for my poor english.

P.P.S.
> gif_interfaces="gif0"
> gifconfig_gif0="My_external_IP Server_External_IP"
What version of FreeBSD do you use in 2017, if gif_interfaces is deprecated in 10.3 already?…


----------



## SirDice (Jan 17, 2018)

VVD said:


> What version of FreeBSD do you use in 2017, if gif_interfaces is deprecated in 10.3 already?…


It was already deprecated in 10.0 but was accepted during a transition period. You should use cloned_interfaces instead.


----------



## VVD (Jan 17, 2018)

SirDice said:


> You should use cloned_interfaces instead.


I know, but what is current name of "gifconfig_gif0" option?
And I can't understand what IPs I have to write here:
> ifconfig_gif0="inet 192.168.190.1 192.168.10.1 netmask 0xffffffff"

> In Handbook recommend to create gif the adapter. To us to create it there is no need.
> MPD5 will create the virtual adapter which will receive necessary settings from the server.
*Sindikat88*, don't see gif interfaces after start mpd5.


----------



## SirDice (Jan 18, 2018)

VVD said:


> I know, but what is current name of "gifconfig_gif0" option?



More or less complete example for a IPv6 over IPv4 tunnel:

```
cloned_interfaces="gif0"
create_args_gif0="tunnel 1.1.1.1 2.2.2.2"
ifconfig_gif0_ipv6="inet6 2001::xx 2001::yy prefixlen 64"
```



VVD said:


> And I can't understand what IPs I have to write here:
> > ifconfig_gif0="inet 192.168.190.1 192.168.10.1 netmask 0xffffffff"


Those are the two tunnel end-points. Each end of the tunnel has an IP address and it's those addresses you use.


----------

