FreeBSD 4.4Rそのままだと、ifconfig の仕様が以前と変わったのに(gifインターフェースの clone 化の影響と思われる)一部整合性が取れず ifconfig tun0 down delete が出来なくなっています。4.5Rでは直る模様。
vtun-2.4の暗号化は定常的に使うには弱すぎます(使ってる関数は BF_ecb_encrypt)最初に交換した共通鍵をいつまでも同一のまま使って、転送の各パケットを暗号化しています。例えばpingの場合、連続してほとんど同じ内容を暗号化した結果、似たようなパケットが連続して流れるため共通鍵を推定することはかなり容易と思われます。
せめてcbc(共通鍵+前回のパケットを次回の共通鍵の元にする)にしてくれればましなんですが…
どうせOpenSSLを呼んでいるだけなのでソースの改変することを検討しましたが、とりあえず stone/SSL で暗号化経路を確保した上でvtunを通すことにしました。
# 実は本当に改変したんだけど、参照したWeb上のAPIマニュアルが新しすぎて安定版として公開されている 0.9.6b/c に実装されていなかったのにがっくりして中断…
OpenVPNベースのページを作成しました。できましたらそちらをまず参照して下さい。
OpenBlockSS CF起動またはハードディスク環境においてvtunクライアントにするための設定です。
zImage.initrd.treeboot.vtun tunデバイスを有効にしたカーネル2.4.10イメージ = ファームウェア。MD5 (zImage.initrd.treeboot.vtun) = da8ae520653615d5897d6a2a1ec713cc
stone stone
vtund vtund
以下はソース+コンパイルオブジェクトのかたまり
stone-2.1d-openblocks.tar.gz
vtun-2.5b1-openblocks.tar.gz
OpenSSLについては、OpenVPNのページから取得してください。(OpenSSL-0.9.6e アップグレードに伴う追記)
設定ファイル集。
/etc/ld.so.conf
/usr/lib /lib /local/lib /usr/local/lib/etc/rc.d/rc.local (/etc/rc.d/rc.sysinit を編集してこのスクリプトを起動するようにする)
#!/bin/sh /local/sbin/ldconfig /local/sbin/sshd /local/bin/stone -l vtunserver.example.com:963/ssl localhost:962 & /local/sbin/vtund sayama localhost
クロスコンパイル環境にて。クロスコンパイル環境で実行するには source /usr/local/obS/example/.setup でクロスコンパイル向け環境を設定する。
基本的にはOBSS のカーネル再構築を参照。コンフィグファイルの CONFIG_TUN の行をCONFIG_TUN=y
としてから make oldconfig を実行する。
この方法ではトンネルデバイスファイルは作ってくれないため、mkdir /dev/net
, mknod /dev/net/tun c 10 200
を実行する必要がある。
クロスコンパイル環境にて。クロスコンパイル環境で実行するには source /usr/local/obS/example/.setup でクロスコンパイル向け環境を設定する。
./configure; make
でさくっと完成。
インストールはコンパイル済みイメージをFTPで転送して、make install
。ただしなぜか実行に必要なランダムデバイス /dev/urandom, /dev/randomがないため、mknod /dev/random c 1 8
, mknod /dev/urandom c 1 9
を一度実行する必要がある。
SSL付きで普通にコンパイル
stone SSLの設定の仕方は http://www.gcd.org/sengoku/docs/NikkeiLinux00-09/Welcome.ja.html を参照
いちおーSSL付きでコンパイル。
vtund-openblocks.tar.gz 以下で利用しているOpenBlocks用のバイナリ。めんどくさいのでソースは省略。
ドライバのコンパイルはimacにインストールされたHOLON Linux上で行った。ぷらっとホームにあるOpenBlockSの開発環境に従って開発環境を設定。ただspecs fileはインストールされているファイルをspecファイルを上書きするのではなく、gcc(スクリプト)の中を書き換えて別の場所に保管する方法で実現した。
Universal TUN/TAP driverよりドライバをダウンロードして、make 。上記のOpenBlocks開発環境上だと Kernel 2.2.13 用のオブジェクトが作成できる。(そのためimacに make install でインストールしても使えない)
OpenBlocksに作成された linux/tun.o を転送
通常のmake installだとcreate_devスクリプトが呼ばれるのだが、OpenBlocksではcreate_devを実行するための環境が不足しているので、結果として行われる以下のコマンドをOpenBlocksの起動時のスクリプトに埋め込んだ。
もちろん起動デバイスをCFやHDDにした場合は1回やればよい。スクリプトにしたのは当初ramdisk起動だったため。
/sbin/insmod /ext1/lib/tun.o rm -f /dev/tun0 /dev/tun1 /dev/tun2 /dev/tun3 rm -f /dev/tap0 /dev/tap1 /dev/tap2 /dev/tap3 mknod /dev/tun0 c 90 0 mknod /dev/tun1 c 90 1 mknod /dev/tun2 c 90 2 mknod /dev/tun3 c 90 3 mknod /dev/tap0 c 90 128 mknod /dev/tap1 c 90 129 mknod /dev/tap2 c 90 130 mknod /dev/tap3 c 90 131
とりあえずvtunホームページよりソースを持ってきてimac上でコンパイル。出来上がった vtund を OpenBlocksの /ext1/bin に転送。
OpenBlocks上でダイナミックリンクライブラリが不足しているのでldd でライブラリを調査するとlibz.so.1とlibcrypto.so.0を追加で利用している。これをimacからOpenBlocksの /ext1/lib に転送、ldconfig も OpenBlocksの /ext1/bin に転送。
そこで /etc/ld.so.conf に /ext1/lib を追加して以下のようなファイルにする。
/lib /usr/lib /ext1/lib/etc/ld.so.conf は /etc/flashcfg に追加してフラッシュメモリに書き込まれるようにし、またOpenBlocksの起動時に /ext1/bin/ldconfig を呼ぶようにする。
# options { port 5000; # Connect to this port. timeout 60; # General timeout # Path to various programs ifconfig /sbin/ifconfig; route /sbin/route; } # TUN example. Session 'sayama'. sayama { pass ********; # Password device tun1; # Device tun1 persist yes; # Persist mode up { ifconfig "%% 192.168.255.2 pointopoint 192.168.255.1 mtu 1450"; route "add -net 192.168.0.0 netmask 255.255.0.0 gw 192.168.255.1"; }; down { ifconfig "%% down"; }; }
FreeBSDの /usr/ports/net/vtun にて make install
/usr/local/etc/vtund.conf はこんな感じ
# options { port 5000; # Listen on this port. # Path to various programs ifconfig /sbin/ifconfig; route /sbin/route; } # Default session options default { compress no; # Compression is off by default speed 0; # By default maximum speed, NO shaping type tun; proto tcp; comp lzo:1; encr yes; # Encryption keepalive yes; # Keep connection alive multi deny; } # TUN Session 'sayama'. sayama { pass ********; # Password up { ifconfig "%% 192.168.255.1 192.168.255.2 netmask 0xffffffff mtu 1450"; route "add -net 192.168.200.0 -netmask 255.255.255.0 192.168.255.2"; }; down { ifconfig "%% delete down"; route "delete -net 192.168.200.0 -netmask 255.255.255.0"; }; }
#!/bin/sh /usr/local/sbin/vtund -s echo -n ' vtund'
FreeBSD同士 vtun で接続したセグメントは管理がめんどくさくなってきたので OSPF を導入してみた。将来的には OpenBlocks にも導入予定
FreeBSD の /usr/ports/net/zebra で make install
起動は /usr/local/sbin/zebra -k -d ; /usr/local/sbin/ospfd -d
特定のインターフェースを有効にするには、interface ---
とnetwork x.x.x.x/x area x
を記述するのがミソであった。
/usr/local/etc/zebra/ospfd.conf
! -*- ospf -*- ! $Id: vtun.html,v 1.4 2006/05/10 17:49:07 h Exp $ ! OSPFd configuration file ! hostname ospfd password ******** enable password ******** ! interface fxp0 interface fxp1 interface fxp2 ! for vtun interface tun0 ip ospf cost 100 ip ospf network point-to-point interface tun1 ip ospf cost 100 ip ospf network point-to-point interface tun2 ip ospf cost 100 ip ospf network point-to-point ! router ospf ospf abr-type standard router-id 192.168.0.3 network 192.168.0.0/24 area 0 network 192.168.1.0/24 area 0 network 192.168.255.1/32 area 0 network 192.168.255.2/32 area 0 network 192.168.255.3/32 area 0 network 192.168.255.4/32 area 0 network 192.168.255.5/32 area 0 network 192.168.255.6/32 area 0 passive-interface fxp2 ! log file /var/log/ospfd.log
/var/log/ospfd.log 640 5 700 * Z /var/run/ospfd.pid 30
imac上でGNU zebra をコンパイルし出来上がったバイナリ zebra と ospfd を OpenBlocks の /ext1/bin に転送する。今回は不足しているダイナミックリンクライブラリはないのでそのまま動作する。
zebra.conf はとりあえずパスワードの設定以外どうでもよいのでサンプルを参考に /ext1/etc/zebra.conf として適当に作成する。起動はzebra -k -d -f /ext1/etc/zebra.conf
以下のような /ext1/etc/ospfd.conf を作成し、ospfd の起動は ospfd -d -f /ext1/etc/ospfd.conf
! -*- ospf -*- ! $Id: vtun.html,v 1.4 2006/05/10 17:49:07 h Exp $ ! OSPFd configuration file ! hostname ospfd password ******* enable password ******** ! interface eth0 interface eth1 ! for vtun interface tun1 ip ospf cost 100 ip ospf network point-to-point ! router ospf ospf abr-type standard router-id 192.168.200.2 network 192.168.200.0/24 area 200 network 192.168.255.3/32 area 0 network 192.168.255.4/32 area 0 passive-interface eth1 !
# options { port 963; # Connect to this port. timeout 60; # General timeout # Path to various programs ifconfig /sbin/ifconfig; route /ext1/etc/zebraall.sh; firewall /ext1/etc/zebrakill.sh; } # TUN example. Session 'sayama'. sayama { pass ********; # Password device tun0; # Device tun0 persist yes; # Persist mode up { ifconfig "%% 192.168.255.2 pointopoint 192.168.255.1 mtu 1450"; route ""; }; down { ifconfig "%% down"; firewall ""; }; }/ext1/etc/zebraall.sh
#!/bin/sh /ext1/bin/zebra -k -d -f /ext1/etc/zebra.conf /ext1/bin/ospfd -d -f /ext1/etc/ospfd.conf # /ext1/bin/ripd -d -f /ext1/etc/ripd.conf/ext1/etc/zebrakill.sh
#!/bin/sh PATH=/bin:/sbin:/usr/bin:/ext1/bin export PATH /bin/kill -TERM `head -1 /var/run/ospfd.pid` `head -1 /var/run/zebra.pid` # `head -1 /var/run/ripd.pid` sleep 3
vtun開通時に設定されるルーティングも全部OSPFまかせにできるようになったので、サーバ側の vtund.conf は以下のように変更した。
OSPFは状況の変化をほとんど勝手に見つけてくれるはずなのだが、tunデバイスそのものが増減するのにはいまいち対応しきれてないようだったのでSIGHUPを送ってみた。
上にあるようにOpenBlocks側ではSIGHUPでもうまくいかなくて SIGHUPじゃなくてプロセスを完全に再起動 というようにしてある。
# options { port 963; # Listen on this port. # Path to various programs ifconfig /sbin/ifconfig; route /local/bin/zebrahup.sh; } # Default session options default { compress no; # Compression is off by default speed 0; # By default maximum speed, NO shaping type tun; proto tcp; comp lzo:1; encr yes; # Encryption keepalive yes; # Keep connection alive multi deny; } # TUN Session 'sayama'. sayama { pass ********; # Password up { ifconfig "%% 192.168.255.1 192.168.255.2 netmask 0xffffffff mtu 1450"; route ""; }; down { ifconfig "%% delete down"; route ""; }; }/local/bin/zebrahup.sh
#!/bin/sh /bin/kill -HUP `head -1 /var/run/ospfd.pid` `head -1 /var/run/zebra.pid`
更にADSLルータにルーティング情報を伝達させるために、OSPFで設定されたルーティング情報をRIPで流すようにしてみた。例によって ripd -d -f /ext1/etc/ripd.conf で起動。
ADSLルータはRIPv2を解釈しないらしく、RIPv1にしないとうまくいかなかった。当初v2だったのがいけなかったのか、192.168.1.0/24向けゲートウェイとして192.168.1.0が登録されるという謎の事態が発生。
! hostname ripd password ******** enable password ******** ! interface lo ! interface eth0 ip rip send version 1 ! interface eth1 ! interface tun1 ! router rip redistribute ospf metric 3 network 192.168.200.0/24 network eth0 neighbor 192.168.200.1 ! line vty ! end
このままだと zebra や ospf に向かってどこからでもtelnet接続できるのでIPフィルタリングの設定も書いた方がよい。それはまた後日。
当初あまりにもすぐにswapしはじめるので「本当にメモリー少ないなあ」と思ってたんですが、16M中ramdiskに6M使ってたのが最大の原因なのが判明。CFでブートするようにするとずいぶんと楽になりました。
Plathomeに記載されている手順が基本ですが、
/etc/mkcfrt を編集しようとしたら中身が「tgzファイルを作ってから展開する」というちょっとCFにやさしくないスクリプトになっていたので
このスクリプトを使う代わりに rsync で一気に転送する方法です。
エスケープするのがめんどかったので<>は2バイト文字になっています。rsyncはOpenBlockS Users の部屋にあります。
mke2fs /dev/hda1 mount /dev/hda1 /ext1 (どっかからrsyncをもってくる) rsync -avz --exclude=/proc --exclude=/ext1 / /ext1/ mkdir /ext1/proc cat > /ext1/etc/fstab << __EOF__ /dev/hda1 / ext2 defaults 1 1 /dev/hda2 swap swap defaults 0 0 /proc /proc proc defaults 0 0 __EOF__
同じメーカーのCFデバイスを、毎回fdiskでパーティション設定するのも面倒になってきた。
カードスロットのあるLinuxノートパソコンにて、以下の内容を CF128-linux.out としてファイルを作成しておくと、sfdisk /dev/hdg < CF128-linux.out
を実行するだけでパーティションが作成できる。
このファイルを作成するためのコマンドは、作成元となるCFデバイスが /dev/hde だったとして、sfdisk -d /dev/hde > CF128-linux.out
# /dev/hde のパーティションテーブル unit: sectors /dev/hde1 : start= 32, size= 250848, Id=83 /dev/hde2 : start= 0, size= 0, Id= 0 /dev/hde3 : start= 0, size= 0, Id= 0 /dev/hde4 : start= 0, size= 0, Id= 0
パーティション作成だけ自動化できれば、後はmke2fs
、mount
してファイルを展開するだけである。まずダンプのとり方。
dump -0u -f /var/tmp/CFall.dmp /dev/hde1