今回は 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 を使う。
lac
と lns
はそのまま 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) の設定ファイルを用意する。
name
と password
では、先ほど設定したアカウントの情報を使う。
$ 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 のやり取りが確認できる。
めでたしめでたし。