CUBE SUGAR CONTAINER

技術系のこと書きます。

Linux の Network Namespace で L2TP (IPsec なし) を試す

今回は L2TP の LAC (L2TP Access Concentrator) と LNS (L2TP Network Server) を Linux の Network Namespace の環境で動かしてみる。 L2TP はリモートアクセス VPN でよく使われるプロトコルの一つ。 ただし、今回は IPsec を組み合わせないため、単なるトンネリングプロトコルとしての検証になる。 LAC は接続を開始するクライアント、LNS は接続を待ち受けるサーバと考えれば良い。

使った環境は次のとおり。

$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.2 LTS"
$ uname -srm
Linux 5.15.0-71-generic x86_64
$ xl2tpd --version

xl2tpd version:  xl2tpd-1.3.16

もくじ

下準備

まずは必要なパッケージをインストールする。 L2TP の LAC / LNS としては xl2tpd(8) を使う。

$ sudo apt-get update
$ sudo apt-get install xl2tpd iputils-ping

インストールすると、その時点で xl2tpd のサービスが稼働してしまうため止めておく。

$ sudo systemctl stop xl2tpd
$ sudo systemctl disable xl2tpd

ネットワークを構築する

今回は 3 つの Network Namespace を使う。 laclns はそのまま LAC と LNS に対応する。 remote についてはリモートアクセス VPN をつないだ先にあるネットワークの適当なサーバとでも考えてもらえれば良い。

$ sudo ip netns add lac
$ sudo ip netns add lns
$ sudo ip netns add remote

続いては LAC と LNS の間をつなぐ。 ここは 203.0.113.0/24 のセグメントにする。

$ sudo ip link add lac-veth0 type veth peer name lns-veth0
$ sudo ip link set lac-veth0 netns lac
$ sudo ip link set lns-veth0 netns lns
$ sudo ip netns exec lac ip link set lac-veth0 up
$ sudo ip netns exec lns ip link set lns-veth0 up
$ sudo ip netns exec lac ip address add 203.0.113.1/24 dev lac-veth0
$ sudo ip netns exec lns ip address add 203.0.113.254/24 dev lns-veth0

そして LNS と remote の間をつなぐ。 ここは 192.0.2.0/24 のセグメントにする。

$ sudo ip link add lns-veth1 type veth peer name remote-veth0
$ sudo ip link set lns-veth1 netns lns
$ sudo ip link set remote-veth0 netns remote
$ sudo ip netns exec lns ip link set lns-veth1 up
$ sudo ip netns exec remote ip link set remote-veth0 up
$ sudo ip netns exec lns ip address add 192.0.2.254/24 dev lns-veth1
$ sudo ip netns exec remote ip address add 192.0.2.1/24 dev remote-veth0

LNS はルータとして機能させる。

$ sudo ip netns exec lns sysctl net.ipv4.ip_forward=1

remote にはデフォルトルートとして LNS のアドレスを設定しておく。

$ sudo ip netns exec remote ip route add default via 192.0.2.254

これでネットワークができた。

LNS をセットアップする

まずは LNS に必要な設定を追加していく。 xl2tpd の設定ファイルを用意する。 global セクションの debug から始まる項目については表示される内容が変わるだけなのでお好みで。

$ cat << 'EOF' | sudo tee /etc/xl2tpd/xl2tpd.lns.conf > /dev/null
[global]
port = 1701
access control = no
debug avp = no
debug network = yes
debug packet = no
debug state = yes
debug tunnel = yes

[lns default]
ip range = 198.51.100.10-198.51.100.20
local ip = 198.51.100.1
require authentication = yes
name = example
pppoptfile = /etc/ppp/options.l2tpd.lns
ppp debug = yes
EOF

ポイントとしては lns セクションの名前を default にするところ。 また、local ip は LNS のトンネル終端アドレス、ip range が LAC のトンネル終端アドレスになる。

次に pppd(8) の設定ファイルを用意する。 xl2ptd(8) は pppd(8) と連携して動作する。

$ cat << 'EOF' | sudo tee /etc/ppp/options.l2tpd.lns > /dev/null
require-mschap-v2
debug
logfile /var/log/pppd.lns.log
EOF

このとき、アカウントの認証方式としては MS-CHAPv2 を指定しておく。

pppd(8) が認証に使う、アカウント情報を記載した設定ファイルを用意する。 ここでは testuser というユーザ名で testpassword のパスワードでログインするユーザを作った。

$ cat << 'EOF' | sudo tee /etc/ppp/chap-secrets > /dev/null
testuser * testpassword *
EOF

これで LNS に必要な設定は揃った。 設定ファイルを指定して xl2tpd を起動する。 このとき -D オプションをつけるとデーモンにならずフォアグラウンドで動作する。

$ sudo ip netns exec lns \
    xl2tpd -D \
      -c /etc/xl2tpd/xl2tpd.lns.conf \
      -p /var/run/xl2tpd.lns.pid \
      -C /var/run/xl2tpd/l2tp-control.lns

LAC をセットアップする

続いては LAC をセットアップする。

先ほどと同じように xl2tpd の設定ファイルを用意する。

$ cat << 'EOF' | sudo tee /etc/xl2tpd/xl2tpd.lac.conf > /dev/null
[global]
port = 1701
access control = no
rand source = dev
debug avp = no
debug network = yes
debug packet = no
debug state = yes
debug tunnel = yes

[lac mylac]
lns = 203.0.113.254
require chap = yes
refuse pap = yes
require authentication = yes
pppoptfile = /etc/ppp/options.l2tpd.lac
ppp debug = yes
EOF

ポイントとしては lac セクションの名前に default 以外をつける。 そして lns には LNS が待ち受けている IP アドレスを指定する。

続いて、先ほどと同様に pppd(8) の設定ファイルを用意する。 namepassword では、先ほど設定したアカウントの情報を使う。

$ cat << 'EOF' | sudo tee /etc/ppp/options.l2tpd.lac > /dev/null
defaultroute
noauth
debug
logfile /var/log/pppd.lac.log
name "testuser"
password "testpassword"
EOF

これで LAC の設定が終わった。 設定ファイルを指定して xl2tpd を起動する。

$ sudo ip netns exec lac \
    xl2tpd -D \
      -c /etc/xl2tpd/xl2tpd.lac.conf \
      -p /var/run/xl2tpd.lac.pid \
      -C /var/run/xl2tpd/l2tp-control.lac

トンネルを作る

そして xl2tpd-control(8) を使って LAC にコネクションを開始するように指示する。 このとき -c オプションで LAC 側の xl2tpd に指定した制御用のソケットファイルを指定する。 また、引数には先ほど xl2tpd の設定ファイルで lac セクションの名前に設定したものを入力する。

$ sudo xl2tpd-control -c /var/run/xl2tpd/l2tp-control.lac connect-lac mylac

上手くいけば次のようにトンネルインターフェイス (ppp0) が作成されて、トンネル終端アドレスが割り振られる。

$ sudo ip netns exec lac ip address show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 3
    link/ppp 
    inet 198.51.100.10 peer 198.51.100.1/32 scope global ppp0
       valid_lft forever preferred_lft forever
    inet6 fe80::4cad:b8b3:fb08:36cd peer fe80::9090:8d17:86c2:3f4e/128 scope link 
       valid_lft forever preferred_lft forever
10: lac-veth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:00:5e:00:53:01 brd ff:ff:ff:ff:ff:ff link-netns lns
    inet 203.0.113.1/24 scope global lac-veth0
       valid_lft forever preferred_lft forever
    inet6 fe80::200:5eff:fe00:5301/64 scope link 
       valid_lft forever preferred_lft forever

ルーティングテーブルを確認すると、デフォルトルートがトンネルインターフェイスに向いている。

$ sudo ip netns exec lac ip route show
default dev ppp0 scope link 
198.51.100.1 dev ppp0 proto kernel scope link src 198.51.100.10 
203.0.113.0/24 dev lac-veth0 proto kernel scope link src 203.0.113.1 

試しに LAC から remote の IP アドレスに ping を打ってみると、ちゃんと疎通がある。

$ sudo ip netns exec lac ping -c 3 192.0.2.1 -I 198.51.100.10
PING 192.0.2.1 (192.0.2.1) from 198.51.100.10 : 56(84) bytes of data.
64 bytes from 192.0.2.1: icmp_seq=1 ttl=63 time=1.91 ms
64 bytes from 192.0.2.1: icmp_seq=2 ttl=63 time=1.49 ms
64 bytes from 192.0.2.1: icmp_seq=3 ttl=63 time=1.44 ms

--- 192.0.2.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 1.441/1.612/1.906/0.208 ms

なお、xl2tpd-control connect-lac するときに tcpdump(1) を使うと L2TP のやり取りが確認できる。

めでたしめでたし。

参考

manpages.ubuntu.com

manpages.ubuntu.com

datatracker.ietf.org