FreeBSD 9.1をIPsec対応L2TP VPNサーバにする

2017年7月2日FreeBSD,iPad/iPod/iPhone,Mac,パソコン・インターネット

一応、次の設定で外出先から自宅ネットワークに、VPN接続できています。

ですが、donation wareです。寄付しなくても使えますが、やはり気が引けます。それと、Macを持ち出している時は、VPN接続できません。

FreeBSDでVPNサーバを立てて、色々活用する事にしました。参考にした所は、次のウェブサイトです。

このウェブサイト(Wiki)の作者に連絡して、和訳して紹介する許可をいただいています。

Thank you, very much!

上記のWikiでは、9.0での方法が紹介されていますが、9.1でも全く同じ方法です。手順は、次の通りです。

  1. カーネル再構築
  2. rc.confの設定(1)
  3. リブート
  4. racoonのビルド
  5. mpd5のビルド
  6. racoonの設定
  7. mpd5の設定
  8. sysctl.confの設定
  9. rc.confの設定(2)
  10. pf.confの設定
  11. リブート
  12. 接続テスト
    1. ネットワーク内部からの接続テスト
    2. ネットワーク外部からの接続テスト

ちなみに、WAN側回線が、グローバルIPアドレスになっている必要が在ります。WAN側のIPアドレスが、192.168.?.?、172.16.?.?や10.?.?.?になっていたら(プライベートIPアドレス)、外部ネットワークからのVPN接続はできません。この先へ進む意味が在りませんので、諦めて下さい。
ネットワーク

1. カーネル再構築

では、rootになった後の作業を、順に進めて行きます。カーネルの名前は、著者に敬意を表して、"STOCKSY"のままにしています。

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

2. rc.confの設定(1)

実は、このカーネルにしてしまうと、そのFreeBSDへの外からの接続が、全くできなくなってしまいます。pingもsshも使えなくなります。

# ssh 192.168.1.1
ssh: connect to host 192.168.1.1 port 22: Operation timed out

/etc/rc.confに、firewallの設定をします。

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

次の所を参考にしました。

3. リブート

rc.confの設定が終わったら、リブートします。無事に起動、そしてサーバに接続できますでしょうか?

4. racoonのビルド

次に、racoonにパッチを充ててビルドします。まず、"/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 != '\n'; q++)

次に、ビルドします。

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

5. mpd5のビルド

次は、mpd5のビルドです。特にパッチを充てる必要は在りません。

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

6. racoonの設定

次に、racoonの設定です。

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

次のファイルの内容を記入します。ただし、6〜7行目の"w.x.y.z"は、L2TPサーバのIPアドレス(例えば、192.168.1.1)にします。

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];
        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;
}

次に、pre-shared keyを設定しておきます。

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

設定例は次の通りです。先頭の"*"は、どのIPアドレスからでも受け付ける為の設定です。なるべく、難しいパスワードにして下さい。

* thisismylongpassphrasedoyouliketurtles

また、root以外が読めない様に、permissionを設定して下さい。

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

次に、セキュリティポリシーを書きます。

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

7. mpd5の設定

次は、mpd5の設定です。

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

IPアドレスは、例えば次の様に変更して下さい。

  • w.x.y.x … 192.168.1.1 (L2TPサーバ)
  • w.x.y.from … 192.168.1.150 (割り当てるIPアドレスの開始番号)
  • w.x.y.to … 192.168.1.199 (割り当てるIPアドレスの終了番号)
  • w.x.y.dns … 192.168.1.254 (DNSサーバ)
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

次に、IPSecでVPN接続できるユーザの設定をします。

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

root以外に見えない様に、permissionを設定しておくのをお忘れなく。

# chmod 400 /usr/local/etc/mpd5/mpd.secret

8. sysctl.confの設定

IPフォワーディングの設定をしていなければ、設定します。

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

9. rc.confの設定(2)

いよいよ、rc.confに設定を書き込みます。

# vi /etc/rc.conf
# IPSec
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"

10. pf.confの設定

IPSecの接続のためには、サーバのUDPポートの1701, 500, 4500、およびESPを開けておく必要が在ります。

# vi /etc/pf.conf

人によって違うと思いますが、私の場合は、次の様に設定しています。ext_ifが、EthernetのI/F名なので、ifconfigコマンドで調べておいて下さい。

ext_if = "e0"
tcp_services = "{22, 80, 443}"
priv_nets    = "{127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 0.0.0.0, 255.255.255.255}"
set block-policy drop
set loginterface $ext_if
scrub in all
block all
pass quick on lo0 all
#antispoof log-all quick for $ext_if inet
pass in quick on $ext_if inet proto icmp from any icmp-type echoreq keep state
pass in on $ext_if inet proto tcp from any to ($ext_if) port $tcp_services flags S/SA keep state
pass out quick on $ext_if proto tcp all modulate state flags S/SA
pass out quick on $ext_if proto {udp, icmp} all keep state

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 $ext_if all

11. リブート

ここまでの設定が終了したら、リブートします。

12. 接続テスト

次は、いよいよ接続テストです。接続テストは、ネットワーク内部からL2TPサーバへの接続、ネットワーク外部からL2TPサーバへの接続の、2段階で実験します。ネットワーク内部からL2TPサーバへの接続ができないと、ネットワーク外部からの接続は絶対にできません。

12.1 ネットワーク内部からの接続テスト

リブート後、既にracoonとmpd5のサービスが動いています。メッセージを直接見たいので、いったんサービスを止めます。

# service racoon stop
# service mpd5 stop

1番目のターミナルで、次のコマンドを実行します。

# racoon -ddF

次に、2番目のターミナルを開きます。2番目のターミナルで、次のコマンドを実行します。

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

この状態で、iOSデバイス等から、L2TPサーバに接続します。iOSデバイスの設定方法は、次の記事等をご覧下さい。

もしかすると、3番目のターミナルを開くと良いかもしれません。3番目のターミナルでは、tcpdumpコマンドで、L2TPサーバ(192.168.1.1)への通信を観測します。

# tcpdump -n \( udp or esp \) and host 192.168.1.1

ここまでで、ネットワーク内部から、L2TPサーバに接続できる事を確認して下さい。

12.2 ネットワーク外部からの接続テスト

次は、いよいよネットワーク外部からの接続テストです。まずは、使用しているルータの設定をします。次のページ等をご参考にして下さい。

基本的には、UDPプロトコルのポートの500番と4,500番、プロトコル番号51と50(ESP)の全部をL2TPサーバに転送する様に設定します。ポートマッピングやポート解放と呼ばれます。

VPNパススルーの設定も必要です。使用されているルータによって、設定方法が全く違うので、ご自分でお調べください。

また、WAN側がグローバルIPアドレスになっていても、一般的な契約では、接続毎に違うIPアドレスが振られます。それでは困るので、ダイナミックDNSサービス等を使って、ドメイン名を取得します。このダイナミックDNSサービスへの接続設定も、使用されているルータによって、全く違います。ご自分でお調べください。

ルータの設定ができれば、12.1で設定した内容で、接続先を変更するだけで、VPN接続できるはずです。

なお、実際のFreeBSDマシンでなくても、Parallels等の仮想環境にインストールしたFreeBSDでも、同じ方法でL2TPサーバにする事ができます。

お疲れさまでした。

[amazonjs asin="B00CPG04JE" locale="JP"]

Posted by お市のかた