From Wiki

A slightly more concise version of this incredibly good forum post. Thanks to Oichi for improving this page and for translating it into Japanese.

This works in Mac OS X and iOS. NAT traversal is included, so this will work well even if the client or server is behind a NAT router or firewall. L2TP is significantly more secure than PPTP, and only a few UDP ports are required to be open, so this poses no difficulty with even the crappiest broadband routers.

Start with a FreeBSD RELEASE 9 or 9.1 install including full sources and the ports collection. The excellent FreeBSD handbook will guide you through this process.

There are a number of things we need which are not in the GENERIC kernel, so you will need to recompile the kernel, but this is incredibly simple in FreeBSD compared with Linux:

# mkdir /root/kernels # cp /usr/src/sys/`uname -m`/conf/GENERIC /root/kernels/STOCKSY # sed -i -e 's/GENERIC/STOCKSY/g' /root/kernels/STOCKSY # cat <<EOF >>/root/kernels/STOCKSY options IPSEC options IPSEC_NAT_T device crypto options IPSEC_FILTERTUNNEL device enc options IPFIREWALL options IPFIREWALL_VERBOSE options IPFIREWALL_VERBOSE_LIMIT=5 options IPFIREWALL_FORWARD options IPFIREWALL_NAT options LIBALIAS options IPDIVERT EOF # ln -s /root/kernels/STOCKSY /usr/src/sys/`uname -m`/conf/STOCKSY # cd /usr/src # make buildkernel KERNCONF=STOCKSY && make installkernel KERNCONF=STOCKSY

Reboot to install the new kernel.

After this kernel configurations, FreeBSD does not accept all connections from any hosts. So you will need to change /etc/rc.conf. We added descriptions to /etc/rc.conf below:

# firewall firewall_enable="YES" firewall_script="/etc/rc.firewall" firewall_type="OPEN" firewall_quiet="NO" firewall_logiging="YES"

Please refer this page.

The VPN consists of two parts, racoon handles the encryption, whilst mpd5 handles the authentication. This is completely transparent to the user.

racoon is part of the IPSec tools port. It is necessary to to apply a patch to racoon to make it useful as a remote access VPN. Without this patch, it is impossible to connect from unknown IP addresses. Whilst it is less secure to share a pre-shared key between different clients from different IP addresses, the only danger is that different clients may be able to decrypt each other's data – this shouldn't be a concern for most people.

So, save this as /usr/ports/security/ipsec-tools/files/patch-zz-local-1.diff

diff -rup srca/racoon/localconf.c srcb/racoon/localconf.c --- src/racoon/localconf.c 2012-01-29 21:17:41.000000000 +0000 +++ src/racoon/localconf.c 2012-01-29 21:19:09.000000000 +0000 @@ -207,7 +207,8 @@ getpsk(str, len) if (*p == '\0') continue; /* no 2nd parameter */ p--; - if (strncmp(buf, str, len) == 0 && buf[len] == '\0') { + if (strcmp(buf, "*") == 0 || + (strncmp(buf, str, len) == 0 && buf[len] == '\0')) { p++; keylen = 0; for (q = p; *q != '\0' && *q != '

'; q++)

Now build the ipsec-tools port:

# cd /usr/ports/security/ipsec-tools # make install clean

Next, mpd5 , no patching needed here:

# cd /usr/ports/net/mpd5 # make install clean

Press on with the configuration of racoon :

# mkdir /usr/local/etc/racoon # vi /usr/local/etc/racoon/racoon.conf path pre_shared_key "/usr/local/etc/racoon/psk.txt"; listen { # REPLACE w.x.y.z with the IP address racoon will listen on (if NAT translated, this is the INSIDE IP) isakmp w.x.y.z [500]; isakmp_natt w.x.y.z [4500]; # NOTE, you can specify multiple IPs to listen on isakmp p.q.r.s [500]; isakmp_natt p.q.r.s [4500]; strict_address; } remote anonymous { exchange_mode main; passive on; proposal_check obey; support_proxy on; nat_traversal on; ike_frag on; dpd_delay 20; proposal { encryption_algorithm aes; hash_algorithm sha1; authentication_method pre_shared_key; dh_group modp1024; } proposal { encryption_algorithm 3des; hash_algorithm sha1; authentication_method pre_shared_key; dh_group modp1024; } } sainfo anonymous { encryption_algorithm aes,3des; authentication_algorithm hmac_sha1; compression_algorithm deflate; pfs_group modp1024; }

Create a nice strong pre-shared key (the * indicates that the passphrase should be accepted from any source IP address - that's why we patched racoon):

# vi /usr/local/etc/racoon/psk.txt * thisismylongpassphrasedoyouliketurtles

Then it is better to change permission of "psk.txt" for security.

# chmod 400 /usr/local/etc/racoon/psk.txt

Create the security policies:

# vi /usr/local/etc/racoon/setkey.conf flush; spdflush; spdadd 0.0.0.0/0[0] 0.0.0.0/0[1701] udp -P in ipsec esp/transport//require; spdadd 0.0.0.0/0[1701] 0.0.0.0/0[0] udp -P out ipsec esp/transport//require;





Now the mpd5 configuration:

# vi /usr/local/etc/mpd5/mpd.conf startup: # configure mpd users set user super pwSuper admin # 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: load l2tp_server l2tp_server: # Define dynamic IP address pool - these are the IP addresses which will be # allocated to our remote clients when they join the LAN # REPLACE w.x.y.from - w.x.y.to with the IP addresses mpd5 will allocate IP address range. # e.g. set ippool add pool_l2tp w.x.y.150 w.x.y.199 set ippool add pool_l2tp w.x.y.from w.x.y.to # Create clonable bundle template named B_l2tp create bundle template B_l2tp set iface enable proxy-arp set iface enable tcpmssfix set ipcp yes vjcomp # Specify IP address pool for dynamic assigment. # This is the internal IP and netmask of the box # REPLACE w.x.y.z with the IP address for your VPN server set ipcp ranges w.x.y.z/24 ippool pool_l2tp # an accessible DNS server for clients to use # REPLACE w.x.y.dns with the IP address for your DNS server # e.g. set ipcp dns w.x.y.50 set ipcp dns w.x.y.dns # Create clonable link template named L_l2tp create link template L_l2tp l2tp # Set bundle template to use set link action bundle B_l2tp # Multilink adds some overhead, but gives full 1500 MTU. set link enable multilink set link no pap chap eap set link enable chap set link keep-alive 0 0 # We reducing link mtu to avoid ESP packet fragmentation. set link mtu 1280 # Configure L2TP # REPLACE with the IP address racoon will listen on (if behind NAT, this is the INSIDE IP) # Unfortunately, you can not specify multiple IPs here, so just comment the next line if you need that set l2tp self w.x.y.z set l2tp enable length # Allow to accept calls set link enable incoming

Add accounts for VPN connection.

# vi /usr/local/etc/mpd5/mpd.secret username password # chmod 400 /usr/local/etc/mpd5/mpd.secret

If you don't already have it enabled, check that IP forwarding is enabled in /etc/sysctl.conf:

# vi /etc/sysctl.conf net.inet.ip.forwarding=1 net.inet6.ip6.forwarding=1

Make sure everything that is required is enabled in /etc/rc.conf

# vi /etc/rc.conf ipsec_enable="YES" ipsec_program="/usr/local/sbin/setkey" ipsec_file="/usr/local/etc/racoon/setkey.conf" racoon_enable="YES" racoon_flags="-l /var/log/racoon.log" mpd_enable="YES"

Make sure that UDP 1701, 500 and 4500 are allowed as well as the ESP protocol. You'll also need to permit traffic in and out of the ngX interfaces which get created by mpd. For pf, this would be roughly:

# vi /etc/pf.conf pass in on $ext_if inet proto udp from any to (self) port { 1701, 500, 4500 } pass in on $ext_if inet proto esp # There is a better way to do this with ifconfig groups - you're welcome to try getting # mpd5 to do that! pass quick on ng0 all pass quick on ng1 all pass quick on ng2 all pass quick on ng3 all pass quick on ng4 all pass quick on ng5 all # . . . .

Reboot and everything should be fine. If you need to troubleshoot, it's easiest to stop the daemons and run them in the foreground with debugging:

# service racoon stop # racoon -ddF

Similarly for mpd5 :

# service mpd5 stop /usr/local/sbin/mpd5 -p /var/run/mpd5.pid