Linux network namespace 上でPPPoE接続検証

## 概要
pppoeの勉強用にLinux network namespace(ns)上でPPPoE接続検証を行う。

## 環境
* osxのmultipass上で動作するUbuntu20.04
* pppoe : 3.12-1.2ubuntu2
* pppoeconf : 1.21ubuntu1

## 動作確認
* 環境構築
routerとwanの2つのnsを作成する。
routerには仮想ネットワークインタフェースgw-veth1を作成し、
wanには仮想ネットワークインタフェースwan-vethを作成する。

<pre>sudo ip netns add router
sudo ip netns add wan
sudo ip link add wan-veth0 type veth peer name gw-veth1
sudo ip link set wan-veth0 netns wan
sudo ip link set gw-veth1 netns router
sudo ip netns exec wan ip link set wan-veth0 up
sudo ip netns exec router ip link set gw-veth1 up
sudo ip netns exec wan ip a add 203.0.113.1/24 dev wan-veth0</pre>

* pppoeのインストール
<pre>sudo apt-get install pppoe pppoeconf</pre>

* pppoeサーバのchap有効化
chap認証を行うために、/etc/ppp/optionsを開き、#+chap の#を削除する。

* pppoeサーバのサーバの設定
pppoe-server-optionsを開き、以下の記載を行う。
<pre>require-chap
lcp-echo-interval 60
lcp-echo-failure 5
logfile /var/log/pppd.log</pre>

* pppoeサーバの認証情報の設定
/etc/ppp/chap-secrets を開き、認証情報を記載する。
以下の例は、ユーザtest01に対してパスワードpass01で認証を行い、IPアドレス10.0.0.10を払い出す設定である。
<pre>"test01" * "pass01" 10.0.0.10</pre>

* pppoeサーバの起動
以下例では、インタフェースwan-veth0にて、10.0.0.1のIPアドレスでpppoeサーバを起動する。
<pre>$ sudo ip netns exec wan pppoe-server -I wan-veth0 -L 10.0.0.1</pre>

* pppoeクライアントの設定
以下により設定画面が表示される。以下設定を行う。
<pre>$ sudo ip netns exec router pppoeconf gw-veth1
OKAY to MODIFY : yes
POPULAR OPTIONS : no
ENTER USERNAME : test01
ENTER PASSWORD : pass01
USE PEER DNS : yes
LIMTED MSS PROBLEM : yes
DONE : no
ESTABLISH CONNECTION : no</pre>

* dsl-provideファイルの修正
なぜか、ネットワークインタフェース名が"nic-gw-veth1-veth1"となるので、nic-gw-veth1に修正する。
<pre>sudo vi /etc/ppp/peers/dsl-provide</pre>

* 認証情報ファイルの修正
nsを使う場合ファイルがサーバとクライアントで共有となるため、pppoeクライアントの設定をすると、認証情報ファイルが更新されるため元に戻す。

<pre>sudo vi /etc/ppp/chap-secrets 
"test01" * "pass01" 10.0.0.10</pre>

* PPPoE接続開始
<pre>sudo ip netns exec router pon dsl-provider
Plugin rp-pppoe.so loaded.</pre>

* PPPoE接続確認
以下の通り、wan、routerに、ppp0とppp1が作成され、PPPトンネルができていることが確認できる。

<pre>sudo ip netns exec router plog
Jun  5 08:47:31 pppoe pppd[4093]: pppd 2.4.7 started by ubuntu, uid 0
Jun  5 08:47:31 pppoe pppd[4093]: Using interface ppp0
Jun  5 08:47:31 pppoe pppd[4093]: Connect: ppp0 <--> /dev/pts/1
Jun  5 08:47:34 pppoe pppd[4092]: CHAP authentication succeeded: Access granted
Jun  5 08:47:34 pppoe pppd[4092]: CHAP authentication succeeded
Jun  5 08:47:34 pppoe pppd[4092]: peer from calling number 96:BE:58:42:B1:D5 authorized
Jun  5 08:47:34 pppoe pppd[4093]: local  IP address 10.0.0.1
Jun  5 08:47:34 pppoe pppd[4093]: remote IP address 10.0.0.10
Jun  5 08:47:34 pppoe pppd[4092]: local  IP address 10.0.0.10
Jun  5 08:47:34 pppoe pppd[4092]: remote IP address 10.0.0.1

sudo ip netns exec router ip a
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
3: gw-veth1@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 42:18:0b:ae:fb:67 brd ff:ff:ff:ff:ff:ff link-netns wan
    inet6 fe80::4018:bff:feae:fb67/64 scope link 
       valid_lft forever preferred_lft forever
30: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1492 qdisc fq_codel state UNKNOWN group default qlen 3
    link/ppp 
    inet 10.0.0.10 peer 10.0.0.1/32 scope global ppp0
       valid_lft forever preferred_lft forever
Jun  5 08:45:38 pppoe pppd[3954]: remote IP address 10.0.0.1

sudo ip netns exec wan ip a
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
4: wan-veth0@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 96:be:58:42:b1:d5 brd ff:ff:ff:ff:ff:ff link-netns router
    inet 203.0.113.1/24 scope global wan-veth0
       valid_lft forever preferred_lft forever
    inet6 fe80::94be:58ff:fe42:b1d5/64 scope link 
       valid_lft forever preferred_lft forever
8: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1492 qdisc fq_codel state UNKNOWN group default qlen 3
    link/ppp 
    inet 10.0.0.1 peer 10.0.0.10/32 scope global ppp0
       valid_lft forever preferred_lft forever</pre>

* pppoe切断
<pre>sudo ip netns exec router poff -a</pre>


* パケット確認
<pre>〜Discoveryステージ〜
17:54:17.418940 PPPoE PADI [Service-Name]
17:54:17.419061 PPPoE PADO [AC-Name "pppoe"] [Service-Name] [AC-Cookie 0x58DB3576F43DF4B50CC5DF9712C186B3BC0C0000]
17:54:17.419084 PPPoE PADR [Service-Name] [AC-Cookie 0x58DB3576F43DF4B50CC5DF9712C186B3BC0C0000]
17:54:17.419303 PPPoE PADS [ses 0x1d] [Service-Name]
〜PPPセッションステージ〜
17:54:17.420451 PPPoE  [ses 0x1d] LCP, Conf-Request (0x01), id 1, length 16
17:54:18.479848 PPPoE  [ses 0x1d] LCP, Conf-Request (0x01), id 1, length 21
17:54:18.479915 PPPoE  [ses 0x1d] LCP, Conf-Ack (0x02), id 1, length 21
17:54:20.441121 PPPoE  [ses 0x1d] LCP, Conf-Request (0x01), id 1, length 16
17:54:20.441392 PPPoE  [ses 0x1d] LCP, Conf-Ack (0x02), id 1, length 16
17:54:20.441464 PPPoE  [ses 0x1d] LCP, Echo-Request (0x09), id 0, length 10
17:54:20.441506 PPPoE  [ses 0x1d] LCP, Echo-Request (0x09), id 0, length 10
17:54:20.441537 PPPoE  [ses 0x1d] LCP, Echo-Reply (0x0a), id 0, length 10
17:54:20.441566 PPPoE  [ses 0x1d] CHAP, Challenge (0x01), id 127, Value c53c4dba966be5c4de02efdbece2a5f5b1, Name pppoe
17:54:20.441674 PPPoE  [ses 0x1d] CHAP, Response (0x02), id 127, Value 4d8e942727aeed6d7a715d1296f4d37d, Name test01
17:54:20.441825 PPPoE  [ses 0x1d] LCP, Echo-Reply (0x0a), id 0, length 10
17:54:20.442321 PPPoE  [ses 0x1d] CHAP, Success (0x03), id 127, Msg Access granted
17:54:20.443604 PPPoE  [ses 0x1d] IPCP, Conf-Request (0x01), id 1, length 24
17:54:20.443653 PPPoE  [ses 0x1d] CCP, Conf-Request (0x01), id 1, length 17
17:54:20.443689 PPPoE  [ses 0x1d] CCP, Conf-Request (0x01), id 1, length 6
17:54:20.443700 PPPoE  [ses 0x1d] CCP, Conf-Reject (0x04), id 1, length 17
17:54:20.443729 PPPoE  [ses 0x1d] IPCP, Conf-Request (0x01), id 1, length 18
17:54:20.443761 PPPoE  [ses 0x1d] IPCP, Conf-Reject (0x04), id 1, length 12
17:54:20.443856 PPPoE  [ses 0x1d] IPCP, Conf-Reject (0x04), id 1, length 18
17:54:20.443895 PPPoE  [ses 0x1d] IPCP, Conf-Request (0x01), id 2, length 12
17:54:20.443975 PPPoE  [ses 0x1d] CCP, Conf-Ack (0x02), id 1, length 6
17:54:20.444072 PPPoE  [ses 0x1d] CCP, Conf-Request (0x01), id 2, length 6
17:54:20.444107 PPPoE  [ses 0x1d] CCP, Conf-Ack (0x02), id 2, length 6
17:54:20.444190 PPPoE  [ses 0x1d] IPCP, Conf-Request (0x01), id 2, length 12
17:54:20.444226 PPPoE  [ses 0x1d] IPCP, Conf-Ack (0x02), id 2, length 12
17:54:20.444304 PPPoE  [ses 0x1d] IPCP, Conf-Nack (0x03), id 2, length 12
17:54:20.444340 PPPoE  [ses 0x1d] IPCP, Conf-Request (0x01), id 3, length 12
17:54:20.445519 PPPoE  [ses 0x1d] IPCP, Conf-Ack (0x02), id 3, length 12
17:54:40.499030 PPPoE  [ses 0x1d] LCP, Echo-Request (0x09), id 1, length 10
17:54:40.499171 PPPoE  [ses 0x1d] LCP, Echo-Reply (0x0a), id 1, length 10
〜Ping疎通〜
17:54:57.387617 PPPoE  [ses 0x1d] IP 10.0.0.10 > 10.0.0.1: ICMP echo request, id 4352, seq 1, length 64
17:54:57.388148 PPPoE  [ses 0x1d] IP 10.0.0.1 > 10.0.0.10: ICMP echo reply, id 4352, seq 1, length 64
17:54:58.440321 PPPoE  [ses 0x1d] IP 10.0.0.10 > 10.0.0.1: ICMP echo request, id 4352, seq 2, length 64
17:54:58.440462 PPPoE  [ses 0x1d] IP 10.0.0.1 > 10.0.0.10: ICMP echo reply, id 4352, seq 2, length 64
17:54:59.529147 PPPoE  [ses 0x1d] IP 10.0.0.10 > 10.0.0.1: ICMP echo request, id 4352, seq 3, length 64
17:54:59.529306 PPPoE  [ses 0x1d] IP 10.0.0.1 > 10.0.0.10: ICMP echo reply, id 4352, seq 3, length 64
〜切断〜
17:55:00.523978 PPPoE  [ses 0x1d] LCP, Echo-Request (0x09), id 2, length 10
17:55:00.524150 PPPoE  [ses 0x1d] LCP, Echo-Reply (0x0a), id 2, length 10
17:55:03.173093 PPPoE  [ses 0x1d] LCP, Term-Request (0x05), id 2, length 18
17:55:03.173430 PPPoE  [ses 0x1d] LCP, Term-Request (0x05), id 2, length 18
17:55:03.173467 PPPoE  [ses 0x1d] LCP, Term-Ack (0x06), id 2, length 6
17:55:03.173532 PPPoE  [ses 0x1d] LCP, Term-Ack (0x06), id 2, length 6
17:55:03.186272 PPPoE PADT [ses 0x1d] [AC-Cookie 0x58DB3576F43DF4B50CC5DF9712C186B3BC0C0000]
17:55:03.186977 PPPoE PADT [ses 0x1d] [Generic-Error "Received PADT"]
</pre>

## 参考
https://kxz18.github.io/2020/11/14/Netns/