2014/05/21(Wed)LinuxをL2TPクライアントにする方法

2014/05/22 0:00 Software::Linux
タイトル通り、Linux環境からL2TPでトンネルを張る方法のまとめ。
最近IPv6環境を家庭まで届ける方法にIPoEやPPPoEを使うのが主流っぽいけど、L2TPトンネルで配ってる所もあったのでLinuxから繋げてみようかと。

環境

適当に転がってたVMでテストしたらFedora 18だったけど、特にディストリやバージョンに制約はないはず。

L2TPクライアントのインストール

xl2tpdというL2TPクライアント/デーモンをインストール。
xls2tpd自体は一つで二役、Client/Serverともに設定可能。(今回はクライアント側のみ使用)
$ sudo yum install xl2tpd

xl2tpdの設定

/etc/xl2tpd/xl2tpd.confに作成されるデフォルト設定を改変し、L2TPの認証周りの指定や、接続先を指定する。
クライアント側はLACセクションを新しく作ってそこに書けば良い。

マニュアル$ man xl2td.confをみると、
  • GLOBAL SECTION
  • LNS SECTION
  • LAC SECTION
と分かれているのだが、LAC SECTIONのコメントの所に"LAC SECTIONにはLNS SECTIONの設定も記述可"とあるので、結局LNS SECTIONの説明も読み落とさないように注意。

$ sudoedit /etc/xl2tpd/xl2tpd.conf

[global]
; 認証アカウントを記述するファイル。デフォルトは/etc/l2tpd/l2tp-secrets
auth file = /etc/ppp/chap-secrets


; クライアント側の設定
[lac myprovider]

; 接続先
lns = v6gw.example.com

; 認証が必要
require authentication = yes

; pppdに渡す設定値を書いたファイル
pppoptfile = /etc/ppp/peers/myprovider

; ビット長ヘッダーを確認する
length bit = yes

; CHAP認証を行う
require chap= yes

; PAP認証は拒否する
refuse pap = yes


; pppdがやりとりしているPPPの内容を確認できる、お好みで
ppp debug = yes

; リダイヤル設定
redial = yes

; リダイヤル前の待機秒数
redial timeout = 10

; リダイヤル試行回数
max redials = 6
これで、v6gw.example.comに対するL2TP設定myproviderが出来た。

認証アカウントの設定

先ほどのxl2tpd.confの[global]のauth fileに設定した場所に書く。
$ sudoedit /etc/ppp/chap-secrets

# Secrets for authentication using CHAP
# client                server   secret                  IP addresses
myusername@exmaple.com  *        "MySecretP@ssw0rd"      *
$ sudo chmod 600 /etc/ppp/chap-secrets

PPP周りの設定

pppdに対して、PPP認証アカウントの指定や、IP周りの設定をしておく。
$ sudoedit /etc/ppp/peers/myprovider
# 認証ユーザの指定
user myusername@exmaple.com
# MTU設定(とりあえず最初は無難に1280にしておく)
mtu 1280
# デフォルトゲートウエイ設定を無効
nodefaultroute
# IP通信を無効
noip
# ローカルIPアドレスの自動設定を無効
noipdefault
# IPv6を有効化
  1. ipv6
# DNSサーバが利用できるか問い合わせる usepeerdns # asyncmapネゴシエーション無効、両方向の通信で全制御文字をエスケープさせる default-asyncmap # プロトコルフィールド圧縮ネゴシエーションを無効 nopcomp # アドレス/コントロール圧縮を双方向で無効 noaccomp # CCP(圧縮制御プロトコル)を無効 noccp # TCP/IPヘッダ圧縮を無効 novj # BSD圧縮を無効 nobsdcomp # Deflate圧縮を無効 nodeflate # LCPエコーリクエストフレームを送信する感覚(秒) lcp-echo-interval 30 # 切断と判定するLCPエコーリクエスト送信失敗回数 lcp-echo-failure 4 # 排他アクセスのためのロックファイルを作成 lock # 相手側に自己証明を求めない noauth ##### 以下はお好みで #### # PPPの制御パケットをsyslogに記録 debug # カーネルレベルのPPPデバッグコードを有効(以下の合計値をセット、1:一般的なデバッグメッセージ、2:受信パケットの内容、4:送信パケットの内容) kdebug 1
$ sudo chmod 600 /etc/ppp/peers/myprovider

ここまで出来たら設定をxl2tpdに反映するため再起動
$ sudo systemctl restart xl2tpd.service

接続

接続はコントロールファイルに向かって指示を書き込むか、xl2tpd-controlというユーティリティを使用する。
# echo "c myprovider" > /var/run/xl2tpd/l2tp-control
または
# xl2tpd-control connect myprovider

切断

接続の時と同様に
# echo "d myprovider" > /var/run/xl2tpd/l2tp-control
または
# xl2tpd-control disconnect myprovider

ブート時に自動接続

「systemdに自動接続用のserviceを作って、xl2tpdの起動待ちをしてから繋ぎに行けばいいな」と思いきや、ちょっと落とし穴。
xl2tpdは起動時に色々準備があるようで、コントロールファイルがすぐに出来ない。
なので、こんなサービス
[Unit]
Description=Automatic L2TP Connector
Requires=xl2tpd.service
After=xl2tpd.service

[Service]
Type=oneshot
ExecStart=/sbin/xl2tpd-control connect myprovider
ExecStop=/sbin/xl2tpd-control disconnect myprovider
RemainAfterExit=yes
Restart=on-abort

[Install]
WantedBy=multi-user.target
を作っても、(以下、/var/log/message)
systemd[1]: Starting Terminate Plymouth Boot Screen...
kernel: [   17.377593] PPP generic driver version 2.4.2
kernel: [   17.381727] NET: Registered protocol family 24
systemd[1]: Starting Wait for Plymouth Boot Screen to Quit...
kernel: [   17.630979] l2tp_core: L2TP core driver, V2.0
kernel: [   17.685403] l2tp_netlink: L2TP netlink interface
kernel: [   17.789071] l2tp_ppp: PPPoL2TP kernel driver, V2.0
systemd[1]: Started Level 2 Tunnel Protocol Daemon (L2TP).

systemd[1]: Starting Automatic L2TP Connector...
↑ここで起動を始めてしまって

systemd[1]: Started RPC bind service.
systemd[1]: Starting NFS file locking service....

xl2tpd-control[770]: Unable to open /var/run/xl2tpd/l2tp-control for writing: No such file or directory
↑コントロールファイルが無い、と怒られる

xl2tpd[769]: xl2tpd[769]: setsockopt recvref[30]: Protocol not available
xl2tpd[769]: xl2tpd[769]: Using l2tp kernel support.
xl2tpd[769]: xl2tpd[769]: xl2tpd version xl2tpd-1.3.1 started on f16-vm PID:769
xl2tpd[769]: xl2tpd[769]: Written by Mark Spencer, Copyright (C) 1998, Adtran, Inc.
xl2tpd[769]: xl2tpd[769]: Forked by Scott Balmos and David Stipp, (C) 2001
xl2tpd[769]: xl2tpd[769]: Inherited by Jeff McAdams, (C) 2002
xl2tpd[769]: xl2tpd[769]: Forked again by Xelerance (www.xelerance.com) (C) 2006
xl2tpd[769]: xl2tpd[769]: Listening on IP address 0.0.0.0, port 1701
systemd[1]: xl2tpd_auto.service: main process exited, code=exited, status=255/n/a
↑xl2tpdはここでようやくready

systemd[1]: Failed to start Automatic L2TP Connector.
systemd[1]: Unit xl2tpd_auto.service entered failed state.
てな具合にダメだったので、諦めて/etc/rc.d/rc.localに3秒ごとにコントロールファイルを確認して、起動してたらconnectするようなシェルスクリプトを仕込んでみる。
$ sudoedit /etc/rc.d/rc.local

#!/bin/bash
CTRL=/var/run/xl2tpd/l2tp-control
LNS=myprovider

for i in `seq 5`; do
        echo "connecting... $i"
        if [ -e $CTRL ]; then
                echo "c $LNS" > "$CTRL" && echo "connection OK (attempt:$i)" && break
        fi
        sleep 3
done
$ sudo chmod 755 /etc/rc.d/rc.local
これで接続時に自動的に繋がってくれたっぽい。以下、/var/log/messageより。
systemd[1]: Starting /etc/rc.d/rc.local Compatibility...
↑上に書いたシェルスクリプトが走り始める

systemd[1]: Started OpenSSH server daemon.
kernel: [   26.567033] l2tp_core: L2TP core driver, V2.0
systemd[1]: Started RPC bind service.
systemd[1]: Starting NFS file locking service....
kernel: [   26.596483] l2tp_netlink: L2TP netlink interface
rc.local[762]: connecting... 1
↑1回目のコネクション試行を開始。でもコントロールファイルはまだ出来ていないのでsleep

kernel: [   26.930771] l2tp_ppp: PPPoL2TP kernel driver, V2.0
systemd[1]: Started Level 2 Tunnel Protocol Daemon (L2TP).
xl2tpd[778]: xl2tpd[778]: setsockopt recvref[30]: Protocol not available
xl2tpd[778]: xl2tpd[778]: Using l2tp kernel support.
xl2tpd[778]: xl2tpd[778]: xl2tpd version xl2tpd-1.3.1 started on f16-vm PID:778
xl2tpd[778]: xl2tpd[778]: Written by Mark Spencer, Copyright (C) 1998, Adtran, Inc.
xl2tpd[778]: xl2tpd[778]: Forked by Scott Balmos and David Stipp, (C) 2001
xl2tpd[778]: xl2tpd[778]: Inherited by Jeff McAdams, (C) 2002
xl2tpd[778]: xl2tpd[778]: Forked again by Xelerance (www.xelerance.com) (C) 2006
xl2tpd[778]: xl2tpd[778]: Listening on IP address 0.0.0.0, port 1701
↑そうこうするうちに、xl2tpdが起動完了

rpc.statd[785]: Version 1.2.7 starting
sm-notify[786]: Version 1.2.7 starting
systemd[1]: Started NFS file locking service..
systemd[1]: Starting NFS Server...
kernel: [   27.421950] NFSD: starting 90-second grace period (net c0c464c0)
systemd[1]: Started NFS Server.
systemd[1]: Starting NFS Mount Daemon...
systemd[1]: Starting NFS Remote Quota Server...
systemd[1]: Starting NFSv4 ID-name mapping daemon...
rpc.mountd[814]: Version 1.2.7 starting
systemd[1]: Started NFS Mount Daemon.
systemd[1]: Started NFS Remote Quota Server.
systemd[1]: Started NFSv4 ID-name mapping daemon.

rc.local[762]: connecting... 2
rc.local[762]: connection OK (attempt:2)
↑2回目のコネクション指向で接続指示完了。

systemd[1]: Started /etc/rc.d/rc.local Compatibility.
↑シェルスクリプトはこれで終了している

systemd[1]: Starting Terminate Plymouth Boot Screen...
systemd[1]: Starting Wait for Plymouth Boot Screen to Quit...
xl2tpd[778]: xl2tpd[778]: Connecting to host v6gw.example.com, port 1701
xl2tpd[778]: xl2tpd[778]: Connection established to 192.0.2.123, 1701.  Local: 28539, Remote: 24125 (ref=0/0).
xl2tpd[778]: xl2tpd[778]: Calling on tunnel 28539
xl2tpd[778]: xl2tpd[778]: Call established with 192.0.2.123, Local: 9808, Remote: 12217, Serial: 1 (ref=0/0)
↑v6gw.example.com(192.0.2.123)に対して、L2TPトンネルが張れた

systemd[1]: Started Terminate Plymouth Boot Screen.
systemd[1]: Started Wait for Plymouth Boot Screen to Quit.
systemd[1]: Starting Getty on tty1...
systemd[1]: Started Getty on tty1.
systemd[1]: Starting Login Prompts.
systemd[1]: Reached target Login Prompts.

pppd[821]: Plugin pppol2tp.so loaded.
pppd[821]: pppd 2.4.5 started by root, uid 0
pppd[821]: Using interface ppp0
pppd[821]: Connect: ppp0 <-->
pppd[821]: Overriding mtu 1500 to 1280
pppd[821]: Overriding mru 1500 to mtu value 1280
pppd[821]: Overriding mtu 1500 to 1280
pppd[821]: Overriding mru 1500 to mtu value 1280
↑MTU変更

pppd[821]: CHAP authentication succeeded
pppd[821]: CHAP authentication succeeded
↑CHAP認証OK

pppd[821]: peer from calling number 192.0.2.123 authorized
pppd[821]: local  LL address fe80::xxxx:xxxx:xxxx:xxxx
pppd[821]: remote LL address fe80::xxxx:xxxx:xxxx:xxxx
↑PPPを確立完了
以下のようにppp0が出来ている。
$ ifconfig

[kero@f16-vm ~]$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.xxx.xxx  netmask 255.255.255.0  broadcast 192.168.xxx.255
        inet6 fe80::xxxx:xxxx:xxxx:xxxx  prefixlen 64  scopeid 0x20<link>
        ether xx:xx:xx:xx:xx:xx  txqueuelen 1000  (Ethernet)
        RX packets 272  bytes 28893 (28.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 282  bytes 51894 (50.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 19  base 0x2000

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 0  (Local Loopback)
        RX packets 12  bytes 840 (840.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 12  bytes 840 (840.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ppp0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1280
        inet6 fe80::xxxx:xxxx:xxxx:xxxx  prefixlen 10  scopeid 0x20<link>
        inet6 2001:db8:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx  prefixlen 64  scopeid 0x0<global>
        ppp  txqueuelen 3  (Point-to-Point Protocol)
        RX packets 16  bytes 1180 (1.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3  bytes 76 (76.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

参考文献

man xl2tpd
man xl2tpd.conf
man pppd
L2tp - SixXS Wiki
Fedora 9 で OCNのトンネル経由の IPv6 設定
Man page of PPPD
~nabeken/diary/: Debian GNU/Linux で OCN IPv6 へ接続する