First, we need to build a kernel with IPSEC NAT support.

Download the source code if it is not installed.

We build kernel with the following options:

options IPSEC   # Already there should be a kernel, check in a file
options IPSEC_NAT_T
options LIBALIAS
device enc
device crypto   # Already there should be a kernel, check in a file

In versions of FreeBSD above 11.0, you do not need to rebuild the kernel.

After building the kernel, restart the server.

Next, we need to install a set of ipsec-tools utilities. We will put it from the ports.
If you do not have ports installed, then we perform the following actions.

# portsnap fetch
# portsnap extract

But before installing ipsec-tools, we need to patch this program,
since in the default assembly it is not possible to accept connections from all ip addresses.
Go to

# cd /usr/ports/security/ipsec-tools/files
# vi patch-zz-local-1.diff

and create a patch file with the following content

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 */
-        if (strncmp(buf, str, len) == 0 && buf[len] == '\0') {
+        if (strcmp(buf, "*") == 0 ||
+            (strncmp(buf, str, len) == 0 && buf[len] == '\0')) {
             keylen = 0;
             for (q = p; *q != '\0' && *q != '\n'; q++)

Install ipsec-tools.

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

Next, install mpd5.
Since mpd does not need to patch us, we put it from the repositories.

# pkg ins mpd5

Ipsec is put together with the racoon daemon, which will listen for connections on the port and start or discard those connections.
We need to configure it.
Create the settings file.

# cd /usr/local/etc/racoon
# vi racoon.conf

path pre_shared_key "/usr/local/etc/racoon/psk.txt";


        isakmp  [500];
        isakmp_natt [4500];

remote anonymous
        exchange_mode    main;
        passive          on;
        proposal_check   obey;
        support_proxy    on;
        nat_traversal    on;
        ike_frag         on;
        dpd_delay        20;

                encryption_algorithm  aes;
                hash_algorithm        sha1;
                authentication_method pre_shared_key;
                dh_group              modp1024;

                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;

We create a file with a secret key and indicating the connection option from all ip "*", then we patch.

# vi psk.txt

* supersecretkey1

Of course you need to create a more complex key.
Set access to the file.

# chmod 400 psk.txt

Configure security policies for IPsec.

# vi setkey.conf

spdadd[0][1701] udp -P in ipsec esp/transport//require;
spdadd[1701][0] udp -P out ipsec esp/transport//require;

Next, setup mpd5.

# cd /usr/local/etc/mpd5
# vi mpd.conf

        # configure mpd users
        set user super Psww0rd admin
        # configure the console
        set console self 5005
        set console open
        # configure the web server
        set web self 5006
        set web open

        load 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 - 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

# 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 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

# 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
        set l2tp enable length
# Allow to accept calls
        set link enable incoming

Create a VPN user.

# vi mpd.secret

mpd_user Passw0rd

# chmod 400 mpd.secret

Enable IPsec, racoon, mpd.

# vi /etc/rc.conf

racoon_flags="-l /var/log/racoon.log"

Configuring logging.

# vi /etc/syslog.conf

 At the end of the file before the line !*, Add the following lines

*.* /var/log/mpd.log

Creating log.

# touch /var/log/mpd.log
# touch /var/log/racoon.log
# chmod a+w /var/log/mpd.log
# chmod a+w /var/log/racoon.log

Reboot the server to apply the settings.

When routing a VPN server through NAT, use ports 1701, 500, 4500.

For work from windows need to add a key to registry:

RegValue: AssumeUDPEncapsulationContextOnSendRule
Data Value: 2

and then reboot the computer.