OsaruSystem

Ubuntu 20.04 へ L2TP/IPsec クライアントの構築

作成日:2020/11/05
最終更新日:2020/12/08

概要

Peer to Peer(P2P)でVirtual Private Network(VPN)を実現する手法の1つとしてL2TP/IPsecがあります。L2TP/IPsecはUDPを用いてL2のネットワークを仮想的に結ぶために用いるプロトコルであるL2TPとL3で通信を暗号化してセキュアな通信を実現するために用いるプロトコルであるIPsecを組み合わせます。今回はUbuntuを導入した端末をクライアントとして運用するための方法としてL2TPのプロトコルスタックにxl2tpd[1]を、IPsecのプロトコルスタックにstrongSwan[2]をそれぞれ用います。

導入

aptを用いてxl2tpdとstrongSwanをインストールします。

コマンド1. xl2tpdとstrongSwanのインストール
langur@client:~$ sudo apt install xl2tpd strongswan

設定

L2TP/IPsec接続するために作成・修正する必要があるファイルは4つあります。実際の通信としてはIPsecで暗号化した通信路を確立した後にL2TPを用いてユーザ認証を行い、L2トンネルを確立する形になるので、IPsecから設定します。

  • /etc/ipsec.conf
  • /etc/ipsec.secrets
  • /etc/xl2tpd/xl2tpd.conf
  • /etc/ppp/vpn.options.xl2tpd

ipsec.conf

ipsec.confにはIPsec通信のための設定を記載します。細かい設定項目はstrongSwanのユーザドキュメントを参照してください。

IPsecは対向の端末とP2Pでセキュアな通信をするためのトランスポートモードと、それぞれの端末がゲートウェイとなり確立した通信路を共有してセキュアな通信をするためのトンネルモードがあります。L2TP/IPsecは対向の端末との間の通信を暗号化するので、トランスポートモードで接続します。

IKEやESPの設定項目は対向の端末と合わせる必要があります。対向の設定によっては現状あまりセキュアではない通信方法を選ぶ必要があります。また、IKEは通常500番ポートを使用しますが、対向の端末までにNAT超えをする必要がある場合はNATトラバーサルの設定をします。その場合はポート番号が4500番になります。

strongSwanというかSwan系のIPsecの実装の場合、通常自分の端末をleft、対向の端末をrightとして設定を記載します。leftidは任意のIPアドレスを、rightidは対向の端末に合わせて設定します。このときreftidは対向から見てユニークな値になっている必要があります。rightにはIPアドレスやFQDNを指定可能です。なのでDDNSサービスを利用してIPアドレスが変動する環境でも通信が可能です。

ソース1. ipsec.conf
config setup
	# strictcrlpolicy=yes
	# uniqueids = no

conn vpn
	type=transport
	authby=secret
	rekey=yes
	keyingtries=1
      	keyexchange=ikev1
	ike=aes128-sha-modp1024
	esp=aes128-sha1
	left=%any
	leftikeport=4500
	leftprotoport=udp/l2tp
	leftid=192.0.2.1
        right=203.0.113.100
        rightid=198.51.100.1
	rightprotoport=udp/%any
	rightikeport=4500
	forceencaps=yes
	auto=add

ipsec.secrets

ipsec.secretsには事前共有鍵の設定を記載します。このとき、対向の端末のグローバルアドレスとローカルアドレスに対する設定を入れておくと通信がうまく確立することが多いです。どちらを設定すべきかは対向の端末によります。

複数の相手との通信を書いておくと対向のローカルアドレスが重複することがあります。そのとき事前共有鍵が異なっていると通信を確立できなくなるので注意が必要です。

ソース2. ipsec.secrets
203.0.113.100 : PSK "hogehoge"
198.51.100.1 : PSK "hogehoge"

xl2tpd.conf

xl2tpd.confには使用するポート番号やL2TP自体の通信パラメータを設定します。ユーザ認証に関わる部分やMTU、MRUの設定などはpppoptfileで指定したファイル(今回の場合は/etc/ppp/vpn.options.xl2tpd)に記載します。

ソース3. xl2tpd.conf
[global]
port = 1701

[lac vpn]
lns = 203.0.113.100
require chap = yes
refuse pap = yes
require authentication = yes
pppoptfile = /etc/ppp/vpn.options.xl2tpd
length bit = yes
redial = yes
redial timeout = 10
max redials = 100

vpn.options.xl2tpd

L2TPにおけるユーザ認証に関わる部分やMTU、MRUの設定などを記載します。ファイルは新規に作る必要があります。

本来はちゃんと計算して設定すべきですが、MTUやMRUは小さめに設定しておくとトラブルを起こしにくいです。

ソース4. vpn.options.xl2tpd
noauth
mtu 1200
mru 1200
nodefaultroute
logfile /var/log/vpn.log
name "langur"
password "password"

接続

VPN接続するにはroot権限で以下のコマンドを発行します。初回は接続のためのコマンドを発行する前に systemctl restart ipsec と systemctl restart xl2tpd を実行しておく必要があります。最終的にpppNインタフェースが生成され、IPアドレスが付与されていれば成功です。

再度VPN接続する際に、接続がうまく行かなくなったときは systemctl restart ipsec と systemctl restart xl2tpd を実行するとうまく接続できたりします。

コマンド2. VPN接続
root@client:~# ipsec up vpn
root@client:~# ipsec status vpn
Security Associations (1 up, 0 connecting):
         vpn[1]: ESTABLISHED 5 seconds ago, 192.168.100.100[192.0.2.1]...203.0.113.100[198.51.100.1]
         vpn{1}:  INSTALLED, TRANSPORT, reqid 1, ESP in UDP SPIs: c13d6c12_i 030e0d57_o
         vpn{1}:   192.168.100.100/32[udp/l2f] === 203.0.113.100/32[udp]
root@client:~# echo 'c vpn' > /var/run/xl2tpd/l2tp-control
root@client:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether XX:XX:XX:XX:XX:XX brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.100/24 brd 192.168.100.255 scope global dynamic noprefixroute wlan0
       valid_lft 1777sec preferred_lft 1777sec
3: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1200 qdisc fq_codel state UNKNOWN group default qlen 3
    link/ppp 
    inet 198.51.100.100 peer 198.51.100.1/32 scope global ppp0
       valid_lft forever preferred_lft forever
root@client:~# 

このままだと、対向の機器の属するLANへの経路がないため通信ができないので経路を追加します。

コマンド3. 経路の追加
root@client:~# ip route
default via 192.168.100.1 dev wlan0 proto dhcp metric 600 
169.254.0.0/16 dev wlan0 scope link metric 1000 
192.168.100.0/24 dev wlan0 proto kernel scope link src 192.168.100.100 metric 600 
198.51.100.1 dev ppp0 proto kernel scope link src 198.51.100.100
root@client:~# 
root@client:~# ip route add 198.51.100.0/24 dev ppp0
root@client:~# 
root@client:~# ip route
default via 192.168.100.1 dev wlan0 proto dhcp metric 600 
169.254.0.0/16 dev wlan0 scope link metric 1000 
192.168.100.0/24 dev wlan0 proto kernel scope link src 192.168.100.100 metric 600 
198.51.100.0/24 dev ppp0 scope link    ★追加した経路
198.51.100.1 dev ppp0 proto kernel scope link src 198.51.100.100
root@client:~# 

切断

接続時とは逆にL2TPから切断しIPsecを切断します。

コマンド4. VPN切断
root@client:~# echo 'd vpn' > /var/run/xl2tpd/l2tp-control
root@client:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether XX:XX:XX:XX:XX:XX brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.100/24 brd 192.168.100.255 scope global dynamic noprefixroute wlan0
       valid_lft 1269sec preferred_lft 1269sec
root@client:~# ipsec down vpn
root@client:~# ipsec status vpn
Security Associations (0 up, 0 connecting):
  no match
root@client:~# 

参考文献

  1. Xelerance Corp., xl2tpd, Xelerance, 2016-2020
  2. strongSwan project, strongSwan, strongSwan, 2005-2020