You need NetBSD-current later than 2013-07-01 with a kernel with options IPSEC. Install the pkgsrc package net/xl2tpd.

Network Topology

                          -------------
      192.168.2.4/24  ---| NetBSD Host |--- 1.2.3.4
   [internal interface]   -------------   [external interface]

We are going to use 192.168.2.80 as the local endpoint of each ppp interface and 192.168.2.81-89 for up to 9 simultaneous tunnels. We will provide DNS from 192.168.2.4.

Configuration files

All the configuration files except the firewall rules are provided as part of the xl2tp package, copy them in the right places. in ipsec.conf change @LOCAL_ADDRESS@ to your external address 1.2.3.4. Set the key in /etc/racoon/psk.txt (this will be your secret). Set the username and passwd in /etc/ppp/chap-secrets. Enable ipsec, racoon and xl2tpd in rc.conf. You'll need to include all the ppp interfaces in your firewall config file to allow traffic to and from them. I use npf, and I've automated this using /etc/ppp/ip-up file to generate my npf.conf file dynamically from the list of active interfaces and use npfctl reload /tmp/npf.conf to reload the rules. The npf file I am using is in /usr/share/examples/npf/l2tp_gw-npf.conf.

To debug problems you can use tcpdump on the external, internal, ppp interfaces, and npflog device.

Sample messages output.

This is aggressive mode (OS/X); the iPhone (iOS) uses main mode.

 racoon: INFO: respond new phase 1 negotiation: 1.2.3.4[500]<=>5.6.7.8[500]
 racoon: INFO: begin Aggressive mode.
 racoon: INFO: received broken Microsoft ID: FRAGMENTATION
 racoon: INFO: received Vendor ID: RFC 3947
 racoon: INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-07 
 racoon: INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-06 
 racoon: INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-05 
 racoon: INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-04 
 racoon: INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-03 
 racoon: INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-02 
 racoon: INFO: received Vendor ID: draft-ietf-ipsec-nat-t-ike-02  
 racoon: INFO: received Vendor ID: DPD 
 racoon: [5.6.7.8] INFO: Selected NAT-T version: RFC 3947 
 racoon: INFO: Adding remote and local NAT-D payloads. 
 racoon: [5.6.7.8] INFO: Hashing 5.6.7.8[500] with algo #2  
 racoon: [1.2.3.4] INFO: Hashing 1.2.3.4[500] with algo #2  
 racoon: INFO: NAT-T: ports changed to: 5.6.7.8[4500]<->1.2.3.4[4500] 
 racoon: [1.2.3.4] INFO: Hashing 1.2.3.4[4500] with algo #2  
 racoon: INFO: NAT-D payload #0 verified 
 racoon: [5.6.7.8] INFO: Hashing 5.6.7.8[4500] with algo #2  
 racoon: INFO: NAT-D payload #1 doesn't match 
 racoon: INFO: NAT detected: PEER 
 racoon: INFO: ISAKMP-SA established 1.2.3.4[4500]-5.6.7.8[4500] spi:4f47a16084102305:a47415e957a56da4 
 racoon: [5.6.7.8] INFO: received INITIAL-CONTACT 
 racoon: INFO: purging spi=249311193. 
 racoon: INFO: respond new phase 2 negotiation: 1.2.3.4[4500]<=>5.6.7.8[4500] 
 racoon: INFO: Update the generated policy : 192.168.1.103/32[55576] 1.2.3.4/32[1701] proto=udp dir=in 
 racoon: INFO: Adjusting my encmode UDP-Transport->Transport 
 racoon: INFO: Adjusting peer's encmode UDP-Transport(4)->Transport(2) 
 racoon: INFO: IPsec-SA established: ESP/Transport 1.2.3.4[500]->5.6.7.8[500] spi=258257246(0xf64b15e) 
 racoon: INFO: IPsec-SA established: ESP/Transport 1.2.3.4[500]->5.6.7.8[500] spi=236082834(0xe125692) 
 xl2tpd[454]: Connection established to 5.6.7.8, 55576.  Local: 34593, Remote: 6 (ref=0/0).  LNS session is 'default' 
 xl2tpd[454]: set queue size for /dev/pts/0 to 32768 
 xl2tpd[454]: Call established with 5.6.7.8, Local: 12914, Remote: 28785, Serial: 1 
 pppd[26068]: pppd 2.4.4 started by root, uid 0
 pppd[26068]: set_up_tty: Changed queue size of 12 from 1024 to 32768
 pppd[26068]: tty_establish_ppp: Changed queue size of 12 from 1024 to 32768
 pppd[26068]: Using interface ppp0
 pppd[26068]: Connect: ppp0 <--> /dev/pts/0
 racoon: INFO: 192.168.2.80[500] used for NAT-T 
 pppd[26068]: found interface sk0 for proxy arp
 racoon: INFO: 192.168.2.80[500] used as isakmp port (fd=22) 
 pppd[26068]: local  IP address 192.168.2.80
 racoon: INFO: 192.168.2.80[4500] used for NAT-T 
 pppd[26068]: remote IP address 192.168.2.81
 racoon: INFO: 192.168.2.80[4500] used as isakmp port (fd=23) 
 racoon: INFO: fe80:6::20d:88ff:fe6e:5b1c[500] used as isakmp port (fd=24) 
 racoon: INFO: fe80:6::20d:88ff:fe6e:5b1c[4500] used as isakmp port (fd=25) 
 racoon: INFO: deleting a generated policy. 
 racoon: INFO: purged IPsec-SA proto_id=ESP spi=236082834. 
 racoon: INFO: ISAKMP-SA expired 1.2.3.4[4500]-5.6.7.8[4500] spi:4f47a16084102305:a47415e957a56da4 
 racoon: INFO: ISAKMP-SA deleted 1.2.3.4[4500]-5.6.7.8[4500] spi:4f47a16084102305:a47415e957a56da4 
 xl2tpd[454]: control_finish: Connection closed to 5.6.7.8, serial 1 () 
 pppd[26068]: LCP terminated by peer (User request)
 xl2tpd[454]: control_finish: Connection closed to 5.6.7.8, port 55576 (), Local: 34593, Remote: 6 
 pppd[26068]: Connect time 1.3 minutes.
 pppd[26068]: Sent 1723454 bytes, received 389800 bytes.
 pppd[26068]: Terminating on signal 15
 pppd[26068]: Modem hangup
 pppd[26068]: Connection terminated.
 pppd[26068]: Exit.