strongswan mpd5 to meraki mx100 client vpn

I am attempting to connect to my corporate network from my freebsd laptop. I have successfully connected the ipsec component via stronswan.

Code:
initiating Main Mode IKE_SA ivpn[3] to 1.1.1.1
generating ID_PROT request 0 [ SA V V V V V ]
sending packet: from 172.31.0.5[500] to 1.1.1.1[500] (212 bytes)
received packet: from 1.1.1.1[500] to 172.31.0.5[500] (156 bytes)
parsed ID_PROT response 0 [ SA V V V V ]
received XAuth vendor ID
received NAT-T (RFC 3947) vendor ID
received DPD vendor ID
received FRAGMENTATION vendor ID
generating ID_PROT request 0 [ KE No NAT-D NAT-D ]
sending packet: from 172.31.0.5[500] to 1.1.1.1[500] (244 bytes)
received packet: from 1.1.1.1[500] to 172.31.0.5[500] (228 bytes)
parsed ID_PROT response 0 [ KE No NAT-D NAT-D ]
local host is behind NAT, sending keep alives
generating ID_PROT request 0 [ ID HASH N(INITIAL_CONTACT) ]
sending packet: from 172.31.0.5[4500] to 1.1.1.1[4500] (100 bytes)
received packet: from 1.1.1.1[4500] to 172.31.0.5[4500] (92 bytes)
parsed ID_PROT response 0 [ ID HASH V ]
received DPD vendor ID
IKE_SA ivpn[3] established between 172.31.0.5[172.31.0.5]...1.1.1.1[1.1.1.1]
scheduling reauthentication in 3307s
maximum IKE_SA lifetime 3487s
generating QUICK_MODE request 1009082280 [ HASH SA No KE ID ID NAT-OA NAT-OA ]
sending packet: from 172.31.0.5[4500] to 1.1.1.1[4500] (356 bytes)
received packet: from 1.1.1.1[4500] to 172.31.0.5[4500] (316 bytes)
parsed QUICK_MODE response 1009082280 [ HASH SA No KE ID ID NAT-OA NAT-OA ]
CHILD_SA ivpn{5} established with SPIs c93788a4_i 0f3161bf_o and TS 172.31.0.5/32[udp/l2f] === 1.1.1.1/32[udp/l2f]
generating QUICK_MODE request 1009082280 [ HASH ]
connection 'ivpn' established successfully

After getting this working, my next step is to get the l2tp portion of my l2tp/ipsec connection working. Using an example I found in the forums, I setup mpd5 like so.

Code:
#################################################################
#
#       MPD configuration file
#
# This file defines the configuration for mpd: what the
# bundles are, what the links are in those bundles, how
# the interface should be configured, various PPP parameters,
# etc. It contains commands just as you would type them
# in at the console. Lines without padding are labels. Lines
# starting with a "#" are comments.
#
# $Id: mpd.conf.sample,v 1.49 2015/06/02 08:30:35 dmitryluhtionov Exp $
#
#################################################################

startup:
        # configure mpd users
        # set user foo bar admin
        # set user foo1 bar1
        # configure the console
        # set console self 127.0.0.1 5005
        # set console open
        # configure the web server
        # set web self 0.0.0.0 5006
        # set web open

#
# Default configuration is "dialup"

default:
        #load dialup
        load ivpn_L2TP

ivpn_L2TP:
        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 172.31.0.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 1.1.1.1
        set auth authname "fakeuser"
        set auth password "fakepassword"
        open

When I run mpd5 manually as root, these are the results I get. Below are my interfaces and output.

Code:
re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
        ether 40:61:86:e3:d5:bc
        hwaddr 40:61:86:e3:d5:bc
        inet 172.31.0.5 netmask 0xffffff00 broadcast 172.31.0.255 
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
        inet6 ::1 prefixlen 128 
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 
        inet 127.0.0.1 netmask 0xff000000 
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
        groups: lo 
ng0: flags=8890<POINTOPOINT,NOARP,SIMPLEX,MULTICAST> metric 0 mtu 1500
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>

Code:
Multi-link PPP daemon for FreeBSD
 
process 28251 started, version 5.8 (root@111amd64-quarterly-job-04 07:26  3-Jul-2018)
[L2TP] Bundle: Interface ng0 created
[L2] [L2] Link: OPEN event
[L2] LCP: Open event
[L2] LCP: state change Initial --> Starting
[L2] LCP: LayerStart
L2TP: Initiating control connection 0x80325e310 0.0.0.0 0 <-> 1.1.1.1 1701
L2TP: Control connection 0x80325e310 terminated: 6 (expecting reply; none received)
[L2] Link: DOWN event
[L2] LCP: Down event
[L2] Link: reconnection attempt 1 in 1 seconds
[L2] Link: reconnection attempt 1
L2TP: Initiating control connection 0x80325e610 0.0.0.0 0 <-> 1.1.1.1 1701
L2TP: Control connection 0x80325e310 destroyed
L2TP: Control connection 0x80325e610 terminated: 6 (expecting reply; none received)
[L2] Link: DOWN event
[L2] Link: giving up after 1 reconnection attempts
[L2] LCP: Close event
[L2] LCP: state change Starting --> Initial
[L2] LCP: LayerFinish
[L2] LCP: Down event
L2TP: Control connection 0x80325e610 destroyed

I am certain it is my lack of understanding of mpd5 and wanted to see if someone spotted something I missed potentially.
 
From the strongSwan log I notice, that both peers are behind NAT. Starting with FreeBSD 11.1, IPSEC_NAT_T(raversal) is compiled into the kernel. With older FreeBSD versions, you would need to compile a custom kernel with IPSEC and IPSEC_NAT_T(raversal) enabled.

In case you are runnung an older FreeBSD, this would explain why L2TP does not receive a response to its initial packet. The packet goes into the tunnel, but is not NAT_T'ed correctly and the peer does discard the faulty thing and does not respond, of course. This is related to the failure of generating correct UDP checksums for inner UDP packets wich are enveloped by the NAT-T outer UDP packets. The problem has been resolved starting with FreeBSD 11.1.

If you are not on FreeBSD 11.1, 11.2 or 12-CURRENT, then I suggest to upgrade your system before anything else. Older systems with IPSEC_NAT_T compiled in, still didn't work reliably for example with Windows and Linux peers in cases where NAT is involved. FreeBSD 11.2-RELEASE works perfectly though.

If you are already running the latest FreeBSD, then I cannot be of help here.

PS: You need also to enable passthrough of UDP fragments in the firewalls. UDP fragment packets do not carry a port number, and therefore it is not sufficient to simply allow UDP traffic on ports 500 and 4500.
 
From the strongSwan log I notice, that both peers are behind NAT. Starting with FreeBSD 11.1, IPSEC_NAT_T(raversal) is compiled into the kernel. With older FreeBSD versions, you would need to compile a custom kernel with IPSEC and IPSEC_NAT_T(raversal) enabled.

In case you are runnung an older FreeBSD, this would explain why L2TP does not receive a response to its initial packet. The packet goes into the tunnel, but is not NAT_T'ed correctly and the peer does discard the faulty thing and does not respond, of course. This is related to the failure of generating correct UDP checksums for inner UDP packets wich are enveloped by the NAT-T outer UDP packets. The problem has been resolved starting with FreeBSD 11.1.

If you are not on FreeBSD 11.1, 11.2 or 12-CURRENT, then I suggest to upgrade your system before anything else. Older systems with IPSEC_NAT_T compiled in, still didn't work reliably for example with Windows and Linux peers in cases where NAT is involved. FreeBSD 11.2-RELEASE works perfectly though.

If you are already running the latest FreeBSD, then I cannot be of help here.

PS: You need also to enbale passthroug of UDP fragments in the firewalls. UDP fragment packets do not carry a port number, and therefore it is not sufficient to simply allow UDP traffic on ports 500 and 4500.


Thank you obsigna. I am running 11.1 on the freebsd box I am running strongswan on. Would the firewall be aware of what type of packetss are being transported through the tunnel? I would think it wouldn't be aware?
 
I was talking about the firewalls facing the internet. Both sides would see UDP 500 and UDP 4500 traffic. You configured an MTU of 1460 for the L2TP UDP 1701 traffic. This will be enveloped into IPsec UDP 4500 packet. As a matter of fact, the overhead of L2TP and IPsec does not leave space for 1460 bytes to be transferred in one packet, therefore 1 L2TP 1701 packet would actually be split into 2 IPsec UDP packets, one which carries the port number 4500 and another one which is the fragment of the first and does not carry a port number, but is supposed to be reassembled with the first packet.

Now a firewall which blocks all packets which don't belong to known ports would block the fragment, and IPsec traffic which consists of fragmented packets cannot be reassembled.

For this reason I got in the rule set of my ipfw(8) firewall the following:
Code:
...
# Rules for incomming traffic - deny everything that is not explicitely allowed.
...
/sbin/ipfw -q add 5010 allow udp from any to me 500,4500 in recv $WAN keep-state
/sbin/ipfw -q add 5020 allow udp from any to me in recv $WAN frag
...

The MTU of L2TP/IPsec with NAT-T without fragmenting is 1230 – see: https://forums.freebsd.org/threads/howto-set-up-a-l2tp-ipsec-vpn-dial-in-server-part-i-to-iii.26755/page-5#post-240781. FreeBSD complains about this value because it is too small for IPv6 traffic, but we may ignore this as long IPv6 is not a concern.
 
Thank you again obsigna. I was a bit skeptical that the l2tp packets were actually being tunneled through the ipsec tunnel, so I jumped on the firewall that the packets would go through on it's way to the ivpn connection and did a tcpdump on the internal interface for port 1701 and sure enough, the packets were trying to go straight to the destination without using the tunnel, so, clearly I am not successfully making my l2tp attempts enter the tunnel....hmmm

Code:
[root@fw ~]# tcpdump -i dc0 port 1701
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on dc0, link-type EN10MB (Ethernet), capture size 65535 bytes
10:59:30.143454 IP baba.nixlike.com.54271 > ivpn.somedomain.com.l2f:  l2tp:[TLS](0/0)Ns=0,Nr=0 *MSGTYPE(SCCRQ) *HOST_NAME(baba) VENDOR_NAME(FreeBSD MPD) *BEARER_CAP(AD) *RECV_WIN_SIZE(8) *PROTO_VER(1.0) *FRAMING_CAP(AS) *ASSND_TUN_ID(49735)
10:59:31.150222 IP baba.nixlike.com.54271 > ivpn.somedomain.com.l2f:  l2tp:[TLS](0/0)Ns=0,Nr=0 *MSGTYPE(SCCRQ) *HOST_NAME(baba) VENDOR_NAME(FreeBSD MPD) *BEARER_CAP(AD) *RECV_WIN_SIZE(8) *PROTO_VER(1.0) *FRAMING_CAP(AS) *ASSND_TUN_ID(49735)
10:59:33.151776 IP baba.nixlike.com.54271 > ivpn.somedomain.com.l2f:  l2tp:[TLS](0/0)Ns=0,Nr=0 *MSGTYPE(SCCRQ) *HOST_NAME(baba) VENDOR_NAME(FreeBSD MPD) *BEARER_CAP(AD) *RECV_WIN_SIZE(8) *PROTO_VER(1.0) *FRAMING_CAP(AS) *ASSND_TUN_ID(49735)
10:59:37.152248 IP baba.nixlike.com.54271 > ivpn.somedomain.com.l2f:  l2tp:[TLS](0/0)Ns=0,Nr=0 *MSGTYPE(SCCRQ) *HOST_NAME(baba) VENDOR_NAME(FreeBSD MPD) *BEARER_CAP(AD) *RECV_WIN_SIZE(8) *PROTO_VER(1.0) *FRAMING_CAP(AS) *ASSND_TUN_ID(49735)
10:59:45.151665 IP baba.nixlike.com.54271 > ivpn.somedomain.com.l2f:  l2tp:[TLS](0/0)Ns=0,Nr=0 *MSGTYPE(SCCRQ) *HOST_NAME(baba) VENDOR_NAME(FreeBSD MPD) *BEARER_CAP(AD) *RECV_WIN_SIZE(8) *PROTO_VER(1.0) *FRAMING_CAP(AS) *ASSND_TUN_ID(49735)
 
Ok, so that seems to have been my issue. I changed one line in my ipsec.conf for strongswan and the packets were forced through the tunnel and I was able to successfully connect.

Code:
config setup
        # strictcrlpolicy=yes
        # uniqueids = no
conn %default
      ikelifetime=60m
      keylife=20m
      rekeymargin=3m
      keyingtries=1
      keyexchange=ikev1
      authby=secret
      ike=aes128-sha1-modp1024,3des-sha1-modp1024!
      esp=aes128-sha1-modp1024,3des-sha1-modp1024!

conn ivpn
      keyexchange=ikev1
      left=%defaultroute
      auto=add
      authby=secret
      type=transport
      leftprotoport=17/%any
      rightprotoport=17/1701
      right=1.1.1.1

The leftprotoport value previously was 17/1701.

Thanks for the nudges.
 
This is a little diagram that gives a little clearer picture, I changed the IPs to protect and save the innocent.

ivpn.png


I wrote a little script so that I could just type one thing as root when I needed to connect to the vpn.

Code:
#!/bin/sh

### Need an "up" or "down" as the $1 string
if [ "${1}x" = "x" ];then
        echo "No string provided, expexting up or down"
        exit 1
fi

case "$1" in
([uU][pP])
        cat > /var/tmp/resolv.conf.ivpn << EOF
search somedomain.com
nameserver 172.31.0.2
nameserver 172.31.0.3
EOF
        /usr/local/sbin/ipsec up ivpn
        /usr/sbin/service mpd5 onestart
        /sbin/resolvconf -a ng0 < /var/tmp/resolv.conf.ivpn
        ;;
([dD][oO][wW][nN])
        /usr/sbin/service mpd5 stop
        /usr/local/sbin/ipsec down ivpn
        /sbin/resolvconf -d ng0
        rm /var/tmp/resolv.conf.ivpn
        ;;
esac
 
Back
Top