KlabのTCP/IPプロトコルソケット自作開発において、TUN/TAPデバイスの作成というのがあり、はじめましてという感じだったので理解を深めてみた。
iproute2パッケージとは
Linuxにおけるネットワーク設定やルーティングの制御を行うためのコマンド群などを提供するパッケージです。GNU GPL v2の下で配布されています。
ネットワークの制御と監視を主な役割としており、具体的にはネットワーク設定(ipアドレスの付与等)、ルーティング設定、トンネル、帯域制御、ネットワークデバイスドライバなどその機能は多岐に渡ります。
同じような機能を持つものに、net-toolsというものが存在します。CentOS7から従来同じ役割を持っていたnet-toolsからiproute2が正式に採用される用になりました。(2014年頃の話)
ネットの記事などを探すと、ちょうどこの切り替わりの時期に、net-toolsとiproute2のコマンドの対応表などが多く出回っていることが確認できます。
https://enakai00.hatenablog.com/entry/20140712/1405139841
TUN/TAPとは
TUN (Network TUNnel): IPパケット(L3)フレームを仮想インターフェースに転送する。
TAP (Network TAP): Ethernetパケット(L2)フレームを仮想インターフェースに転送する。
→TAPはブリッジ生成に使われ、TUNはルーティングに使われる。
OSがTUN/TAPデバイスに送ったパケットは、そのデバイスに接続しているユーザープログラムに送信される。また、ユーザープログラムからTUN/TAPデバイスにパケットを送ることもできる。その場合、TUN/TAPデバイスはそれらのパケットをOSのプロトコルスタックに渡すので、OS側からはあたかも外部からパケットを受け取ったように見える。
(一部Wikipediaより)
上記の資料を参照すると、TUN/TAPの主な利用シーンはトンネリングであるという記述があります。主にVTunというトンネリングをアプリケーションに利用されているということが具体例として上がっていたことから、VPNの実装シーンにおいて用いられるという意味合いであると理解しています。
TAPを利用することで、仮想のネットワークデバイス(Ethernetデバイス)とすることができ、物理メディアからパケットを受信する代わりに、ユーザー空間内でパケットの流れを処理することを可能とします。たとえば、tap0 で IPv6 を構成した場合、カーネルが IPv6 パケットを tap0 に送信すると、そのパケットはアプリケーション(VTun) に渡され、パケットの処理を行った後に通信相手へと返されるような処理となります。相手側のアプリケーションは受信したパケットを処理し、TAPデバイスに書き込みを行います。TAPデバイスはユーザー空間でのパケット処理を可能にすることで、トンネリングを実現させているということなのかなと思いました。
TUN/TAPの説明に関しては以下を参考とした。
https://docs.kernel.org/networking/tuntap.html
https://baturin.org/docs/iproute2/#ip-tuntap
https://ja.wikipedia.org/wiki/TUN/TAP
TAN/TUPのコマンド集
TUN/TAPデバイスを表示する
ip tuntap show
ip tuntapで省略も可能
rootユーザーにおけるTUN/TAP仮想デバイスの設定
ip tuntap add dev <interface name> mode <mode>
『interface name』において、例から一般的にtap0,tap1,tap2のように命名していくことが多そう。
『mode』 tun/tapのどちらかを指定する
一般ユーザーにおけるTUN/TAP仮想デバイスの設定
ip tuntap add dev <interface name> mode <mode> user <user> group <group>
『user』 任意のユーザー名(UID 1000以降が振られていく)
TUN/TAPデバイスの削除を行うことができる
ip tuntap delete dev <interface name> mode <mode>
その他にもマニュアルを参照するといくつかの使用例が載っている。
コマンド参照
使うシーン
今回においては、プロトコルスタックの実装だったので、OSのプロトコルスタックを通さないで処理を行いたい時などに使う。
最後に
以上のようなざっくりとした理解の後に、以下のようなサイトを見つけたが非常に参考になったので参照してみると良いかもしれないです。
https://syuu1228.github.io/howto_implement_hypervisor/part19.html
(画像抜粋:ハイパーバイザの作り方~ちゃんと理解する仮想化技術~ 第19回 bhyveにおける仮想NICの実装より)
・tap経由でパケット送信をする場合、パケットをwrite()システムコールで/dev/net/tunへ書き込むような処理を行なっている
・OpenVPNなどVPNソフトにおけるTAP/TUNの処理の理解