はじめに
この記事は BBSakura Networks Advent Calendar 2023 の 12 日目の記事です。 adventar.org
こんにちは、BBSakura Networks 株式会社の佐藤です。
「インターネット」をテーマに色々と調べていたら、登 大遊さんが書いた資料「230610 講演 第1部 (登) - 配布資料その1 - 秘密の NTT 電話局、フレッツ光、インターネット入門.pdf」を見つけました(こちらからダウンロードできます)。
資料の中ではフレッツ光の内部構成が紹介がされており、宅内 PC・ルータが PPP セッションを経由して ISP に接続するまでの通信フローの解説はとても興味深いものでした。
この記事では検討編と称してフレッツ光網内で PPP セッションが生成されるまでのフローを OSS の組み合わせで再現できるかを検証するために検討したことを紹介します。 余力があれば今後「実装編」を書く予定です。
なお上記の資料は資料内でも述べられているとおり NTT 公式の資料ではないです。資料内に掲載されている内部構成図についても「観測結果だけから検証して作った図」と述べてます。 このため本記事で扱うネットワークは、フレッツ光網に似た「疑似フレッツ光網」となります。
疑似 NTT フレッツ光と PPP セッションの関係
疑似 NTT フレッツ光の概要
疑似 NTT フレッツ光は宅内の PC ・ルータと ISP を中継するネットワークです。上記資料の pp.44-60 でその詳細が説明されています。中継機能の根幹を担う機器が、フレッツ収容ルータと網終端装置です。フレッツ収容ルータは宅内ルータからの通信を L3 終端するゲートウェイとして機能し、網終端装置は ISP との接続点としての役割を果たします。
PPP セッション確立までの流れを資料から読み解く
上記の資料ではフレッツ収容ルータ・網終端装置の振る舞いが記述されています。その一部を下記に抜粋します。
1.ユーザ名(@ より後)で表を検索して接続先となる ISP を決定する(pp.58-59)
(a) 収容ルータは、ユーザーが PPPoE 接続を自宅側から開始したとき、それをどの ISP に接続するか、決定しなければならない。これは、PPPoE 接続におけるユーザー名 username@example.org のような文字列のうち @ よりも後の文字列をもとに、表を検索して決定する。
2.フレッツ収容ルータと網終端装置の間は L2TP を利用する(pp.57-58)
(a) と (b) との間は、PPPoE トンネル (PPPoE: Point-to-Point Protocol over Ethernet。詳しくは後述する。) が張られるが、より正確には、PPPoE の中の PPP というプロトコルを収容ルータで取り出して、これを L2TP (Layer-2 Tunneling Protocol) という UDP プロトコルの一種 (このあたりは、固有名詞なので、分からなくても差し支え無い。今後の続編で詳しく述べる。) に入れ、L2TP の UDP パケットとして飛ばす。
3.ユーザ認証は網終端装置を経由して ISP 毎に設置された RADIUS サーバに問い合わせる(pp.58)
PPPoE の接続は、ユーザー認証を必要とする。ISP は契約しているユーザーからの接続のみを受付けたいためである。そこで、網終端装置から ISP の RADIUSサーバー (ユーザー認証サーバーのことである。詳しくは続編で述べる予定である。) に認証のお伺いが届く。
このように NTT フレッツ光では、接続時のユーザ情報から経由する ISP を判断し、通信経路の生成・決定をしています。
PPP セッション確立までの流れを整理
上記の振る舞いを通信フローとしてまとめたのが下図になります。
最初にフレッツ収容ルータは以下の処理を実行します。
1. 宅内ルータとの間に PPPoE セッションを生成
2. ユーザ名( @ の後ろ )をキーとして接続先となる網終端装置を問い合わせ
3. 網終端装置との間に L2TP セッションを生成
以降、網終端装置に PPP セッション処理を引き継ぎ、通信を中継に徹します。
処理を引き継いだ網終端装置はフレッツ収容ルータと連携して以下の処理を実行します。
4. ISP 内の RADIUS サーバにユーザ情報を送信 & 認証結果受け取り
5. 結果を宅内ルータに送信し、残りの PPP ネゴシエーションを実施
上記が完了後、宅内ルータと網終端装置の間に PPP セッションが確立して ISP を経由したインターネットへの通信が可能になります。
今回のテスト項目を検討
おおまかな通信の流れが整理できたので今回のテスト項目を整理します。また、OSS で動作検証するためのネットワークを検討します。
テスト項目
動作検証のためのネットワークで以下を実現することを本検証の目的とします。
- 宅内ルータと網終端装置の間で PPP セッションを確立できること
- ユーザ名に応じて接続先となる網終端装置・ISP が区別されること
- PPP セッション確立後は ISP を経由した通信ができること
検証用ネットワーク
以下の図のネットワークを netns, bridge, veth を利用して Linux 上に構築します。
構成要素: netns
netns 名 | 疑似フレッツ上の役割 | OSS | 検証用ネットワーク上の役割 |
---|---|---|---|
home-1,2 | 宅内ルータ | rp-pppoe | PPPoE クライアント |
sse | フレッツ収容ルータ | accel-ppp | PPPoE サーバ・L2TP クライアント・RADIUS クライアント |
dispatch | 振り分けサーバ | free-radius | RADIUS サーバ |
nte-1,2 | 網終端装置 | accel-ppp | L2TP サーバ・RADIUS クライアント |
isp-rt-1,2 | ISP ルータ | - | 経路制御 |
isp-radius-1,2 | ISP RADIUS | free-radius | RADIUS サーバ |
構成要素: bridge
bridge 名 | 疑似フレッツ上の役割 |
---|---|
onu-sw | home-1,2 - sse 間のネットワーク |
core-sw | バックボーン内のネットワーク |
isp-sw-1,2 | ISP 内のネットワーク |
成否の判断
まず、home-1 - nte-1 および home-2 - nte-2 でそれぞれ PPP セッションが確立することを確認します。その後、home-1 から home-2 に ping を実行して ISP 1, 2 経由で疎通が確認できたら検証成功と判断します。
選択した OSS と今回の要件の比較
今回のネットワーク構成の肝となるのは、フレッツ収容ルータ・網終端装置が連携して PPP セッションを確立する機能です。今回は accel-ppp の利用を検討しました。
accel-ppp
PPP, PPPoE, L2TP を実装した OSS はいくつかありますが、 accel-ppp は下記の点で優れていると判断しました。
- PPP(PPPoE, L2TP , RADIUS) に関するサーバ・クライアントの機能を標準で多数有している
- 各機能がモジューラブルに設計されており、今回のような PPP 機能をカスタムするケースに有利と判断
- ルータ OS として人気がある VyOS で採用されている
参考にした資料
サーバを中継して PPP セッションを確立するためのフロー
Cisco が公開しているページを参考にしました。 こちらには L2TP セッションを利用して PPP ネゴシエーションを引き継ぐための通信フローが掲載されており大変参考になりました。
accel-ppp が提供する機能
公式サイトのドキュメントと Github 上のソースコードを参考にしました。
比較結果
双方の資料を比較した結果、accel-ppp は PPPoE 、L2TP といったプロトコルのサーバ・クライアントを独立した機能として提供することは可能ですが、それらの各機能を連携させて動作させる仕組みを有していないことがわかりました。
今回の検証を実現するために不足している機能を下記に列挙します。
- PPP ネゴシエーションの過程で L2TP セッションを生成する機能(L2TP セッションの生成は CLI/Telnet からのコマンド実行でのみ可能)
- ユーザ名をキーにして L2TP サーバを選択する機能
- PPPoE セッションと L2TP セッションで生成されたネットワークインタフェース(例:
/dev/ppp0
,/dev/l2tp0
)間の通信を中継する機能 - PPPoE セッションの生成過程でクライアントから取得したネゴシエーション情報( LCP、ユーザ情報 )を L2TP セッション側に渡す機能
accel-ppp のソースコードを改修して機能を追加する
フレッツ収容ルータ・網終端装置間の通信を実現するため以下の機能を accel-ppp に追加します。
追加機能の一覧
機能名 | 処理内容 |
---|---|
LT2P セッション動的生成機能 | 宅内ルータからユーザ情報を受け取ったタイミングで、そのユーザ名から接続先となる網終端装置を決定、その網終端装置との間に L2TP セッションを生成する |
PPP セッション間通信中継機能 | PPPoE セッションと L2TP セッションの通信を中継する |
PPP ネゴシエーション情報中継機能 | 宅内ルータから受信したネゴシエーション情報を網終端装置側に転送する |
各機能の詳細
L2TP セッション動的生成機能
ユーザ名を利用して網終端装置を決定して、その網終端装置との間に L2TP セッションを生成するため、宅内ルータ側からユーザ名を届く Chap Response のタイミングで以下の処理を追加します。
- ユーザ名の @ 後ろの文字列を振り分けサーバに送信して接続先(網終端装置の IP アドレス)を取得
- 接続先に対して L2TP セッションの生成を開始する
この機能を実装するときに accel-ppp のモジューラブルな構成が役立ちます。accel-ppp ではユーザ情報取得後の認証処理をハンドラとして組み替えることが可能です。この仕組みを利用してローカルファイルを参照する方法と RADIUS に問い合わせる方法を設定ファイルで選択可能にしています。今回はハンドラとして上記の機能を追加することで、独立性を高め疎結合を保ちます。
PPP セッション間通信中継機能
宅内ルータとフレッツ収容ルータ間で確立した PPPoE セッションと L2TP セッションを紐づけて双方の通信を中継する仕組みが必要です。
それぞれのセッションが確立したタイミングでネットワークインタフェース(例: /dev/ppp0
, /dev/l2tp0
)が OS 上に生成されるため、L2TP セッションが生成されたタイミングでこの2つのネットワークインタフェースの通信を中継させるプロセスを動的に生成する機能を設けます。
PPP ネゴシエーション情報中継機能
標準の機能で PPPoE セッションと L2TP のセッションを生成した場合、独立した2つの PPP セッションが生成されるだけとなります。この独立した2つのセッションを宅内ルータと網終端装置を両端とした1つの仮想的な PPP セッションとして扱うため、PPPoE セッション生成時に受け取ったネゴシエーション情報を網終端装置に渡します。 渡した情報をもとに網終端装置がネゴシエーションを引き継ぐことで仮想的な1つの PPP セッションが生成されます。
各機能の実行タイミング
上記機能の実行タイミングを整理します。
機能名 | 実行タイミング |
---|---|
L2TP セッション動的生成機能 | 宅内ルータから CHAP Response を受信した後 |
PPP セッション間通信中継機能 | L2TP セッション確立時(ユーザ認証に失敗した場合は即削除) |
PPP ネゴシエーション情報中継機能 | 網終端装置に PPP ネゴシエーション情報を渡す時 |
以下のフローは、Cisco のページにある通信フローをベースに今回発生する通信を付け加えたものです。
sequenceDiagram participant HR as 宅内ルータ<br>(home) participant SR as フレッツ収容<br>(sse) participant DS as 振り分けサーバ<br>(dispatch) participant N as 網終端装置<br>(nte) participant RA as RADIUS<br>(isp-radius) HR->>SR: PADI SR->>HR: PADO HR->>SR: PADR SR->>HR: PADS Note over HR,SR: PPPoE ネゴシエーション完了 HR->>SR: LCP Configuration-Request SR->>HR: LCP Configuration-Ack SR->>HR: LCP Configuration-Request HR->>SR: LCP Configuration-Ack Note over HR,SR: LCP ネゴシエーション完了 SR->>HR: CHAP challenge HR->>SR: CHAP challenge Response Note over HR,SR: CHAP(ユーザ情報受信まで) rect rgb(191, 223, 255) Note over SR: 実行:LT2P セッション動的生成機能<br>(接続先の取得・L2TP セッション生成を依頼) SR->>DS: Access-Request DS->>SR: Access-Response Note over SR,DS : RADIUS(接続先の取得) SR->>N: SCCRQ N->>SR: SCCRP SR->>N: SCCCN N->>SR: ZLB Note over SR,N: L2TP ネゴシエーション(トンネル) SR->>N: ICRQ N->>SR: ICRP SR->>N: ICCN N->>SR: ZLB Note over SR,N: L2TP ネゴシエーション(セッション) end rect rgb(168, 168, 255) Note over SR: PPP セッション間通信中継機能<br>(宅内ルータからのユーザ情報を転送) end N->>SR: LCP Configuration-Request SR->>N: LCP Configuration-Ack rect rgb(153, 255, 153) Note over SR : 実行:PPP ネゴシエーション情報中継機能<br>(宅内ルータからの LCP 情報を転送) SR->>N: LCP Configuration-Request N->>SR: LCP Configuration-Ack Note over N,SR: LCP ネゴシエーション完了 N->>SR: CHAP challenge SR->>N: CHAP challenge Response Note over SR,N: CHAP(ユーザ情報転送) end N->>RA: Access-Request RA->>N: Access-Response Note over N,RA: RADIUS(ユーザ認証) rect rgb(168, 168, 255) Note over HR,N: PPP セッション間通信中継機能実行後<br>仮想的な PPP セッションとして宅内ルータ - 網終端装置 で通信 N->>HR: CHAP success/failure Note over N, HR: CHAP(認証結果の送信) Note over HR,N: IPCP Complete( IPv4 アドレスの取得) Note over HR,N: 仮想的な PPP セッションを利用したデータ通信 end
おわりに
疑似フレッツ光網の通信を OSS で再現するために検討したことをここまで書きました。上記の検討により実装方針の大枠が定まりましたので、後は実装を進めていくだけとなります。
登 大遊さんの資料を初めて読んだときは OSS の標準的な機能で実現できるだろうと軽い気持ちで考え、netns の環境構築から着手しましたが、検討を進めていく過程で機能追加が必要なことを知り、当初の想定を超える作業が必要であることがわかりました。
普段の業務ではあまり馴染みの無いプロトコルを調査した今回の経験は、今後の業務において良いアイディアを生むきっかけとなりそうです。 せっかくここまで準備したので、機能実装とテストを実施して、その内容をまとめた記事を「実装編」として書きたいと思います(3ヶ月以内ぐらいを目標に)。