_ chroot なデーモンを動かそうとしてごにょごにょ。が、chroot 先で必要となるデバイスファイルを作ろうとしてもうまくいかない。
# ls -l /dev/random # ホンモノを確認 crw-rw-rw- 1 root wheel 0, 18 Nov 5 05:52 /dev/random # mknod random c 0 18 # マネして作る # chmod 666 random # ls -l random crw-rw-rw- 1 root wheel 0, 18 Nov 23 19:38 random # dd if=random bs=16 count=1 | hexdump # が、使えない dd: random: Operation not supported # dd if=/dev/random bs=16 count=1 | hexdump # ホンモノはもちろん使える 1+0 records in 1+0 records out 16 bytes transferred in 0.000080 secs (199729 bytes/sec) 0000000 a35b b9f6 18b5 76cc 55cf 373e 3f8b 6f1a 0000010_ OS は FreeBSD 8.0-RC2。Linux 2.6 や Darwin 10.2 (Snow Leopard) 、FreeBSD であっても大昔の 5.4 ならばこのやりかたで何の問題もなく動く。いったいどゆこと?
6.0 以降では mknod でデバイスファイルを作ってもダメ、devfs 以外のものはデバイスとして使えない、ということらしい。えー。この変更のこと知らんかったんだけどもしかして常識ですか。ヒドい。/dev/random を1個作るだけなのにいちいちめんどくさい手順を踏んで devfs をマウントしなきゃいかんの? なんで? devfs の必要性は理解しているつもりだけど、今回のような場合は devfs によるメリットはゼロだよね。昔からの方法を潰さずに共存できるようにしてくれればそれでいいのに、なんで新しいやりかたを強要するかな。Linux や OSX や FreeBSD5 では devfs と mknod が共存できてるのに。こんなに手間をかけてまで chroot なんかしてやんないよ! (そして低下するセキュリティ)> man mknod ... As of FreeBSD 4.0, block devices were deprecated in favour of character devices. As of FreeBSD 5.0, device nodes are managed by the device file system devfs(5), making the mknod utility superfluous. As of FreeBSD 6.0 device nodes may be created in regular file systems but such nodes cannot be used to access devices._ devfs ではなく nullfs (Solaris でいうところの lofs、Linux の bindmount) を使って
してもダメだった。まあ、できたとしても、こんなことするくらいならふつーに devfs を使うが。# mount -t nullfs /dev /path/to/chroot/dev_ さらに調べてみたら、/dev/log (/dev にあるけどデバイスではなくただの UNIX ドメインソケット) は今では /var/run/log の方を優先的に使うので、syslogd の起動前までに devfs のマウントを済ませておかなきゃ、とかいうことまでは考えなくてもいいようだ。単純に /dev を無視して chroot 先に /var/run を掘って、syslogd -l /path/to/chroot/var/run/log とすればよし。
_ 正式なアナウンスはまだみたいだけど、まあもう入手できるので。
というわけで、 この前ハマった 8.0-RC2 の環境がさっそく 8.0-RELEASE になりましたとさ。7.x と比べて何が変わったかは例によってほとんど把握してない( もう記事も出てるようだけど、変更点が記事の内容だけではないだろうし)。eel:~[174]> uname -srm FreeBSD 8.0-RELEASE i386_ ふだんはソースから作りなおすんだけど、マシンが SSD な eeepcなんで、激しいディスクアクセスはさせたくないよね、とゆーことでバイナリから。公式配布のバイナリをそのまま使ってるので、freebsd-update を使って5分でアップグレード完了。はじめて使ったけどこりゃラクだわ。元が 8.0-RC2 なんで差分はほとんどないのはあたりまえなんだけど、/etc の下で更新されたのが /etc/motd だけというのはほんとにこれで足りてるのかちょと不安ではある。大丈夫だと思うけど。たぶん。
_ ちなみに、何の用途に使うのかはぜんぜん考えていない。
_ 何に使うのかまったく考えずにとりあえずインストールだけした eeepc900 + freebsd8。調べてみたらこいつの wireless NIC は AP にすることもできるらしい。ということでやってみた。
_ ……できない。AP にするどころか、そもそもクライアントとなって既存の AP に接続することすらできない。
まずこれでコケる。ぐぐってみても、誰もこんな基本的なところでひっかかってない。困った。# ifconfig ath0 inet 192.168.x.x netmask 255.255.255.0 ssid XXXX_ ath(4) の man を見ると、
なんて例があった。wlan(4) というのは、無線 LAN ドライバのそれぞれが 802.11 のしちめんどくさい機能をちまちまと実装しなくてもいいように、各ドライバの上にかぶせて抽象化する層らしい。これにしたがって wlan で試してみると、無事成功。ath(4) の man には wlan を使わない例もいっぱい出てるんだが、こいつらを試してみるとことごとく失敗する。うーん。ifconfig wlan0 create wlandev ath0 ifconfig wlan0 inet 192.168.0.20 netmask 0xffffff00 ssid my_net wepmode on wepkey 0x8736639624_ まあ、とりあえず wlan で無線インターフェイスを使えるようになったので、AP として使えるようにする。まず wlan0。man ath に書いてあるまんま。
次いでデーモンの設定。hostapd というのを使うらしいが、そんなもん ports に入ってない。どっかからソースを拾ってきて野良ビルドか、と思ったら、まったく逆、何もしなくてもすでに入ってた。え、最近の FreeBSD はこんなもんも標準装備なのか。# ifconfig wlan0 create wlandev ath0 wlanmode hostapそんなわけで、てきとーにこんな設定ファイルをでっちあげてみて、hostapd 起動。そこらのノート PC で接続してみると、おお、つながった。接続元は MAC アドレスで絞った方がいいかもとか、ログの設定をしてるのにまったく無言だとか(どのファシリティでログを吐いてるのか不明だが syslog.conf の設定から抜けてるんじゃないかと思う。たぶん)、気になるところはないでもないが、まあそのへんは後で直すとゆーことで。interface=wlan0 driver=bsd logger_syslog=-1 logger_syslog_level=2 logger_stdout=-1 logger_stdout_level=2 ctrl_interface=/var/run/hostapd ctrl_interface_group=wheel hw_mode=g # ssid=XXXX wpa=3 wpa_passphrase=XXXXXXXXX wpa_key_mgmt=WPA-PSK wpa_pairwise=TKIP CCMP_ ただし、つながったといっても、あくまで物理層としての無線がつながったというだけ。ちゃんと使えるようにするにはさらに上位層の面倒を見てやる必要がある。具体的にはパケットをルーティングしてやったり、クライアントに IP アドレスを割り当てたり。後者は、前者ができていれば単純に DHCP サーバを動かすだけ。前者はこんな感じ。
これで無線の ath0 (wlan0) から入ってきたパケットが有線の ae0 を通って外に出たり、その逆ができるようになる。# sysctl -w net.inet.ip.forwarding=1 # ifconfig bridge0 create # ifconfig bridge0 addm ae0 addm wlan0 up # ae0 は有線 LAN_ 最後の仕事。コマンドを手で叩くのではなく、OS 起動時にこれらが自動で実行される必要がある。/etc/rc.d/netif とか /etc/network.subr とかモロモロの初期化スクリプトを追いかけまわした結果、/etc/rc.conf の中身はこんな感じで落ちついた。
どうやら wlan0 を作成した後で hostap モードに変更することはできない(?)ようで、作成時にはじめから指定する必要がある。ということで、ifconfig_wlan0 ではなく、create_args_wlan0 で指定。それから、bridge0 はほかのインターフェイスと違ってふつーに作成しただけではなぜか up してないので、明示的に上げてやる必要がある模様。あと、カーネルによってはいくつかモジュールをロードする必要があるかもしれないけど、GENERIC ではとくに必要ない or 明示的にやらなくても勝手にロードしてくれるので設定なし。wlans_ath0="wlan0" create_args_wlan0="wlanmode hostap hidessid" cloned_interfaces="bridge0" autobridge_interfaces="bridge0" autobridge_bridge0="wlan0 ae0" ifconfig_bridge0="up" gateway_enable="YES" #ipv6_gateway_enable="YES" # v6 も必要ならば hostapd_enable="YES" #dhcpd_enable="YES" # うちでは別ホストで動いてるので不要_ ということで、無線 LAN AP ができました。が、Snow Leopard な MacBook Pro やら iPod Touch からはこれでまったく何の問題もなく使えてるんだけど、WinXP な Let's note がおかしい。接続当初は問題ないんだけど、無通信時間がしばらく続くと以後パケットがほとんど通らなくなる(まったく通らないわけではない)というわけわからん問題が発生して事実上使いものにならん。まったくつながらないというのであれば自分を疑うんだけど、なんだこりゃ。
_ つーか、こんなめんどくさいことしなくたって、うちにはすでに無線 LAN AP あるよ! そっち使えよ! いったい何に使うんだよ! 無駄なことしてるよ!