[[OpenVPN のための Solaris 用 TAP ドライバ]] #norelated *目次 [#m61115b7] #contents *ご注意 [#tc5ca38a] ここで紹介しているプログラムは、カーネルモジュールを含んでいます。そのため、プログラム上に問題があった場合にはシステムがパニックもしくはハングし、システムに重大な障害を引き起こす可能性があります。以下のプログラムはテストプログラムで、十分な検証を行ってはいません。したがってあくまで個人の検証ためにお使いいただき、重要なシステム上では動作させないでください。本プログラムの使用により発生したトラブルなど、いかなる損害についても一切の責任を負いかねます。ご利用は自己責任にてお願いいたします。 *概要[#c24015bf] [[OpenVPN:http://openvpn.net/]] で利用する Solaris 用の TAP ドライバと、 TAP デバイスを利用するための OpenVPN の差分ファイル(tun.c のみ)です。 これらを使うことで、Solaris 上で OpenVPN を使って レイヤ 2(Ethernet レベル)の VPN を構築することが できるようになります。 |もともとは 「Solaris で SoftEther もどきを動かそう」の仮想 HUB と 仮想 NIC デーモン間で利用するプロトコルの参考にしようと OpenVPN のコードを参照していたのですが、Solaris 用 TAP ドライバが無いことが分かったので、TUN ドライバと以前書いた仮想 NIC ドライバを元に TAP ドライバを作ってみることにしました。| ** TUN ドライバと TAP ドライバについて [#tb15c37d] OpenVPN は 仮想ネットワークに接続するため仮想ネットワークドライバとして [[Universal TUN/TAP ドライバ:http://vtun.sourceforge.net/tun]] (もしくは互換ドライバ)を利用しています。 TUN/TAP ドライバは Windows/Linux/BSD/MAC 等、各 OS 上で実装されたものが公開・配布されており、 この TUN/TAP デバイスを使って OpenVPN の仮想ネットワークを構成することができます。&br; ドライバ名にある「TUN」と「TAP」は別々の機能を有したネットワークドライバで、 各々以下のような特徴を持っています。 :TUN ドライバ|IP トンネルを行うための 仮想 Point-To-Point ネットワークデバイスのドライバ。 :TAP ドライバ|Ethernet トンネルを行うための仮想 Ethernet ネットワークデバイスのドライバ。 TUN ドライバと TAP ドライバを比べた場合、VPN 上で単にユニキャストパケット しか伝送しないのであれば、利用する側としてはほとんど差はないと思います。しかし、たとえば ブロードキャストパケットやマルチキャストパケットを伝送する必要がある場合や、 レイヤ 3 プロトコルとしてIP 以外のプロトコルを使う場合には TAP(=Ethernet ネットワークデバイス) を使う必要があります。&br; ほとんどの OS の場合には、この2つのドライバは一緒に配布されており、TUN、TAP デバイス共 に利用可能です。しかし、Solaris 用の TUN/TAP ドライバには残念ながら「TUN」ドライバ、つまり Point-To-Point ネットワークデバイスのドライバしか含まれておりません。&br; ** TUN/TAP ドライバの変更点 [#a1702d24] Solaris 用の TUN ドライバの最終更新日(2000/06/20)を見る限り、今後 Solaris 用の TAP ドライバ がリリースされる可能性は残念ながら少なそうです・・(やはり Solaris というところでしょうか) そこで、既存の Solaris 用 TUN ドライバを改造し、OpenVPN で利用可能な TAP ドライバを作成いたしました。&br; 主な変更点は以下のとおりです。 -04/28/2006 --新しい PPA の割り当てを行う tun_alloc_ppa() に自身の MAC アドレスをセットする処理を追加 --DL_INFO_REQ を処理する tun_info_req() に MAC アドレスを返す処理を追加 --DL_BIND_REQ を処理する tun_bind_req() に MAC アドレスを返す処理を追加 --DL_PHYS_ADDR_REQ を処理する tun_physaddr_req() に MAC アドレスを返す処理を追加 --DL_UNITDATA_REQ を処理する tun_unitdata_req() 内から tun_eth_hdr() を呼ぶように変更した。 --DL_UNITDATA_IND を処理する tun_unitdata_ind() 内で、実際の宛先・送信元 MAC アドレスをセットするように変更した。 --Ethernet ヘッダを追加する tun_eth_hdr() 内で、Ethernet ヘッダに実際の宛先・送信元 MAC アドレスをセットするように変更した。 --Ethernet フレームのルーティングを行う tun_frame() 内から tun_frame_is_eligible() を呼ぶように変更した。 --DL_SET_PHYS_ADDR_REQ を処理する tun_set_physaddr_req() 関数を追加した。 --DL_ENABMULTI_REQ を処理する tun_enabmulti_req() 関数を追加した。(現在のところ実際にはなにもしない) --DL_DISABMULTI_REQ を処理する tun_disabmulti_req() 関数を追加した。(現在のところ実際にはなにもしない) --Ethernet ヘッダーのフレームタイプや宛先アドレスをチェックする tun_frame_is_eligible() 関数を追加した。 **OpenVPN 側の変更点 [#q20bb3fa] 現在のところ(Version 2.0.7) OpenVPN 側も Solaris 用の TAP デバイス(/dev/tap)を処理するルーチン が存在せず、そのままでは TAP ドライバを作ったとしても OpenVPN の設定ファイルで「dev tap」などと してもエラーになってしまいます。Solaris 用の TAP ドライバが存在しないので、当然といえば当然かもしれませんが・・。 そこで、OpenVPN 側のコードも併せて変更、追加を行い、Solaris 上でも「dev tap」が利用できるように しました。主な変更点は以下のとおりです。 -04/28/2006 --Solaris 用の open_tun() 関数の中で /dev/tap を Ethernet ネットワークインターフェースとして plumb する処理を追加した。 --do_ifconfig() 関数内の Solaris 用の処理の中に「dev tap」の場合の ifconfig コマンドの構文を追加した。 >>>Ethernet ネットワークデバイスとして plumb するのに必要な処理については OpenSolaris の [[ifconfig コマンドのソース:http://cvs.opensolaris.org/source/xref/on/usr/src/cmd/cmd-inet/usr.sbin/ifconfig/ifconfig.c]]と、ifconfig に対する truss(1M) コマンドの出力を参考にしています。全ての Solaris バージョンに通用するのかは疑問ですが、少なくとも Solaris 9 と Solaris 10、OpenSolaris 上では期待通りに動作するようです。 *ソースコードとダウンロード [#y33ac555] **Solaris 用 TAP(および TUN) ドライバソースファイル [#k6003c4d] >>[[tuntap.tar.gz:http://www.whiteboard.ne.jp/~admin2/tuntap/source/tuntap/tuntap.tar.gz]] |>|CENTER:tar ファイルに含まれるファイル|h |[[Makefile.in:http://www.whiteboard.ne.jp/~admin2/tuntap/source/tuntap/Makefile.in]]|configure スクリプトが使う Makefile の雛形| |[[configure:http://www.whiteboard.ne.jp/~admin2/tuntap/source/tuntap/configure]]|configure スクリプト| |[[if_tun.h:http://www.whiteboard.ne.jp/~admin2/tuntap/source/tuntap/if_tun.h]]|ヘッダーファイル| |[[install-sh:http://www.whiteboard.ne.jp/~admin2/tuntap/source/tuntap/install-sh]]|インストール用スクリプト| |[[tap.conf:http://www.whiteboard.ne.jp/~admin2/tuntap/source/tuntap/tap.conf]]|TAP ドライバ用 dirver.conf(4) ファイル| |[[tun.conf:http://www.whiteboard.ne.jp/~admin2/tuntap/source/tuntap/tun.conf]]|TUN ドライバ用 dirver.conf(4) ファイル| |[[tun.c:http://www.whiteboard.ne.jp/~admin2/tuntap/source/tuntap/tun.c]]|ドライバのソースコード| >>>'''本コードは http://vtun.sourceforge.net/tun/ の TUN/TAP ドライバのコードを元にしており、本コードの配布は GPL に準じます。''' **Solaris 用 TAP デバイス対応のための OpenVPN の差分ファイル [#qb4575cd] |[[tun.c:http://www.whiteboard.ne.jp/~admin2/tuntap/source/openvpn/tun.c]]|OpenVPN の TUN/TAP ドライバへの操作が書かれているソースコード| >>>'''本コードは http://openvpn.net の tun.c のコードを元にしており、本コードの配布は GPL に準じます。''' *動作確認済み Solaris バージョン [#p23d16d4] TAP ドライバおよび 変更後の OpenVPN の動作確認状況は以下のようになっています。 |プラットフォーム&br;Solarisバージョン|Sparc(32bit)|Sparc(64bit)|x86&br;(VMWare上)|h |CENTER:|CENTER:|CENTER:|CENTER:|c |Solaris 8 以前|?|?|?| |Solaris9|○|○|?| |Solaris10|-|○|○| >>○:動作確認済み ×:動作不可 ?:未確認 -:該当なし&br; 私の環境に限りがあるので全てを調べきれてませんが、Solaris 9 以上であれば(希望も含めて)動くのではないかと思います。 *コンパイル&インストール [#fca41256] **Solaris 用 TAP(および TUN) ドライバのコンパイル [#k7cab5ad] コンパイルには gcc を使います。上記の [[tuntap.tar.gz:http://www.whiteboard.ne.jp/~admin2/tuntap/source/tuntap/tuntap.tar.gz]] ファイルを展開し tuntap ディレクトリに移動後、configure, make を実行すると「tun」と「tap」という2つのドライバが 作成されます。コンパイル終了後、make install にてファイルのコピーと、システムへのデバイスの追加が行われます。 (configure スクリプトも少々変更しており、64bit Solaris で実行された場合には 32bit モジュール ではなく、64bit ドライバをビルドし、ドライバが適切な場所にコピーされるようにしています。) # ./configure checking for gcc... gcc checking for C compiler default output file name... a.out checking whether the C compiler works... yes checking whether we are cross compiling... no checking for suffix of executables... checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for gcc option to accept ANSI C... none needed checking for a BSD-compatible install... ./install-sh -c checking for isainfo... : configure: creating ./config.status config.status: creating Makefile # make gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DTUN_VER=\"1.1\ 04/23/2006\" -O2 -Wall -D_KERNEL -I. -m64 -c tun.c -o tun.o -DTUNTAP_TUN gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DTUN_VER=\"1.1\ 04/23/2006\" -O2 -Wall -D_KERNEL -I. -m64 -c tun.c -o tap.o -DTUNTAP_TAP ld -r -o tun tun.o ld -r -o tap tap.o # make install ld -r -o tun tun.o ld -r -o tap tap.o ./install-sh -c -m 644 -o root -g root if_tun.h /usr/include/net ./install-sh -c -m 644 -o root -g root tun /usr/kernel/drv/sparcv9 ./install-sh -c -m 644 -o root -g root tap /usr/kernel/drv/sparcv9 ./install-sh -c -m 644 -o root -g root tun.conf /usr/kernel/drv ./install-sh -c -m 644 -o root -g root tap.conf /usr/kernel/drv /usr/sbin/rem_drv tun >/dev/null 2>&1 /usr/sbin/rem_drv tap >/dev/null 2>&1 /usr/sbin/add_drv tun /usr/sbin/add_drv tap # **差分ファイルを使った OpenVPN のコンパイル [#x4990a4d] 特別な操作はありません。[[OpenVPN のダウンロードページ:http://openvpn.net/download.html]] より OpenVPN 2.0.7 のソースコードをダウンロードしてきて展開し、展開後のディレクトリ内にある tun.c を上記の [[tun.c:http://www.whiteboard.ne.jp/~admin2/tuntap/source/openvpn/tun.c]] ファイルで置き換え、通常通り configure((私の環境では lzo(圧縮ライブラリ) がインストールされていないため、--disable-lzo を指定しています。)), make, make install を行います。 # unzip openvpn-2.0.7.zip # cd openvpn-2.0.7/ # cp /download_files/tun.c . # ./configure --disable-lzo checking for ifconfig... /usr/sbin/ifconfig checking for ip... ip checking for route... /usr/sbin/route ... 略... # make make all-am if gcc -DHAVE_CONFIG_H -I. -I. -I. -I. -g -O2 -MT base64.o -MD ... 略... # make install test -z "/usr/local/sbin" || /var/tmp/openvpn-2.0.7/install-sh -d "/usr/local/sbin" ./install-sh -c 'openvpn' '/usr/local/sbin/openvpn' test -z "/usr/local/man/man8" || /var/tmp/openvpn-2.0.7/install-sh -d "/usr/local/man/man8" ./install-sh -c -m 644 './openvpn.8' '/usr/local/man/man8/openvpn.8' # >>''** tun.c は OpenVPN 2.0.7 に含まれている tun.c ファイルを元に作成しておりますので、2.0.7 以外のバージョンの OpenVPN のソースコード群と一緒にコンパイルするとエラーになってしまうかもしれません。'' *使い方 [#yd27bdea] インストール後は通常通り OpenVPN を利用可能です。 TAP デバイスを使う場合は設定ファイルに「dev tap」と指定するか、openvpn コマンドの起動オプション として「--dev tap」を指定します。&br; 「OpenVPN の設定例」に私がテストで利用した設定ファイルをサンプルとして載せてありますのでこちらも参照いただければと思います。ただこれはもっとも単純な場合の設定例になると思いますので、詳細については[[公式ページのマニュアル:http://openvpn.net/howto.html]]をご参照ください。&br; また、Google 等で検索すると Linux や BSD での設定方法について日本語で詳しく解説されているページ見がつかりますので、 そちらも参考になるのではないかと思います。&br;