ネットワーク経由で La Fonera にパッケージをインストール
La Fonera (FON ソーシャル ルータ) のベースとなっている OpenWrt は、 パッケージ管理システムとして ipkg を利用している。 La Fonera 用の ipkg feed を 作ってみた。 この feed を使うには、 以下のように /etc/ipkg.conf に 「src gcd http://www.gcd.org/fonera」 を追加し、 「ipkg update」 を実行する。
root@OpenWrt:/# echo "src gcd http://www.gcd.org/fonera" >> /etc/ipkg.conf root@OpenWrt:/# ipkg update Downloading http://www.gcd.org/fonera/Packages Updated list of available packages in /usr/lib/ipkg/lists/gcd Done.
すると、feed のリスト (パッケージ名の一覧) が /usr/lib/ipkg/lists/gcd に保存される。 あとは、「ipkg install パッケージ名」などと実行するだけで、 パッケージをネットワーク経由で La Fonera にインストールできる。
例えば stone をインストールするには、 次のように「ipkg install stone」と実行するだけでよい。
root@OpenWrt:~# ipkg install stone Installing stone (2.3c-2.2.4.12) to root... Downloading http://www.gcd.org/fonera/stone_2.3c-2.2.4.12_mips.ipk Installing libopenssl (0.9.8d-1) to root... Downloading http://www.gcd.org/fonera/libopenssl_0.9.8d-1_mips.ipk Installing zlib (1.2.3-3) to root... Downloading http://www.gcd.org/fonera/zlib_1.2.3-3_mips.ipk Installing libpthread (0.9.28-8) to root... Downloading http://www.gcd.org/fonera/libpthread_0.9.28-8_mips.ipk Configuring libopenssl Configuring libpthread Configuring stone Configuring zlib Done.
stone の実行に必要な、libopenssl, zlib, libpthread パッケージの インストールも自動的に行なわれている。 このようにパッケージの依存関係も管理してくれるので便利なのであるが、 残念ながら現行の La Fonera 上の ipkg にはバグがある。 インストールしたパッケージをアンインストールしようとして、
ipkg remove stone
などと実行してはいけない。 /usr/bin/stone だけでなく、 /usr/bin ディレクトリまでもが削除されてしまう。 なぜこんなバグがあるかというと、 mini_fo の rmdir の実装にバグがあるからだ。 すなわち、空でないディレクトリに対して rmdir を行なっても、 ディレクトリが削除されてしまうことがある。 試しに、あまり重要そうでないディレクトリに対して rmdir してみる:
root@OpenWrt:/www/images# ls -a table . bottom-right.gif logo.gif top-left.gif .. bottom.gif right.gif top-right.gif bottom-left.gif left.gif sidebar.gif top.gif root@OpenWrt:/www/images# rmdir table root@OpenWrt:/www/images# ls table ls: table: No such file or directory
La Fonera のファイルシステムは mini_fo (mini fan-out) を使っている。 つまり squashfs を read only でマウントした「上」に、 jffs を重ねてマウントしている。 前述の例で言えば、 /www/images/table ディレクトリは squashfs 上にあり、 jffs 上には /www/images/table ディレクトリは存在しない。 「rmdir table」などファイルシステムに対する変更は、 「上」に重ねられた jffs に対して行なわれるが、 ディレクトリが空か否かの判断まで、 「上」のファイルシステムに対してのみ行なっているのだろう、 jffs 上では /www/images/table ディレクトリの中にはファイルが存在しない (ディレクトリが存在しないので当然だが) ため、 rmdir がエラーにならずにディレクトリの削除が行なわれてしまう。
La Fonera の ipkg (busybox に含まれている) のソース ipkg_remove.c を 確認してみると、
for (iter = installed_dirs.head; iter; iter = iter->next) { file_name = iter->data; if (rmdir(file_name) == 0) { ipkg_message(conf, IPKG_INFO, " deleting %s\n", file_name); removed_a_dir = 1; str_list_remove(&installed_dirs, &iter); } }
などとなっている。 つまりディレクトリが空かどうかは判断せず、 いきなり rmdir してみて成功すればヨシとしている。 このため、「ipkg remove パッケージ名」を実行すると、 空でないディレクトリまで削除してしまうのだろう。
空でないディレクトリに対して rmdir を実行したら ENOTEMPTY を返すのがスジであるので、 mini_fo 側を修正すべきだとは思うのだが、 とりあえず sh スクリプト版の ipkg を拾ってきて、 rmdir するまえに中身の確認をするように変更し、 /usr/bin/ipkg を この修正済み sh スクリプトで置き換えてみた。
root@OpenWrt:~# wget http://www.gcd.org/fonera/ipkg-0.9-1.32.sh Connecting to www.gcd.org[60.32.85.216]:80 ipkg-0.9-1.32.sh 100% |*****************************| 27925 00:00 ETA root@OpenWrt:~# chmod 755 ipkg-0.9-1.32.sh root@OpenWrt:~# mv ipkg-0.9-1.32.sh /usr/bin/ipkg
などと置き換えるとよいだろう。 これで安全にパッケージをアンインストールできるようになる。
root@OpenWrt:~# ipkg remove stone ipkg_remove: Removing stone... ipkg_remove: Warning: Not removing the following directories since they are not empty: /usr /usr/bin Done.
/usr および /usr/bin ディレクトリが空でなかったので削除できなかった旨が、 表示されている。
La Fonera の自動アップデートのまとめ
La Fonera の自動アップデートは、 cron から呼び出される /bin/thinclient プログラムによって行なわれている。 このアップデートは ipkg とは独立した形で行なわれているので、 ipkg でパッケージのインストールを行なう場合は、 この自動アップデートで何が行なわれているか把握しておく必要がある。 確認できたアップデートについてまとめてみた。
- 0.7.0 rev 2 -> 0.7.0 rev 3 (upgrade.fon)
- 修正: /usr/lib/webif/validate.awk
- 0.7.0 rev 3 -> 0.7.0 rev 4 (upgrade.fon)
-
[WiFi] 暗号方式のデフォルトを WPA+TKIP に変更
修正: /etc/init.d/rcS /sbin/ifup /www/cgi-bin/webif/*.sh
変更: /lib/modules/2.4.32/wlan.o /lib/modules/2.4.32/ath_ahb.o
追加: /etc/hotplug.d/iface/10-ppp_hack - 0.7.0 rev 4 -> 0.7.1 rev 1 (upgrade.fon) 2006-11-21 0.7.1 rev 1
-
[Web interface] 多言語サポート
[Web interface] ポートフォワード機能
[NTP] ntpclient による時刻同期
修正: /bin/thinclient /etc/functions.sh /usr/lib/webif/*
変更: /usr/bin/webif-page
追加: /etc/config/ntpservers /etc/config/openports /etc/config/webif /etc/init.d/N45ntpclient /usr/lib/webif/lang /usr/sbin/adjtimex /usr/sbin/ntpclient /www/cgi-bin/webif/adv_pf.sh /www/cgi-bin/webif/language.sh - 0.7.1 rev 1 -> 0.7.1 rev 2 (upgrade.fon) 2007-01-04 01:00 JST
-
[Web interface] 任意のコマンドを実行させられてしまう脆弱性を修正
[NTP] crontab に複数の ntpclient 呼び出しが登録されてしまうバグを修正
修正: /etc/init.d/N45ntpclient /usr/lib/webif/validate.awk /www/cgi-bin/webif/*.sh
変更: /usr/bin/haserl
特に重要なのが、0.7.1 rev 2 で行なわれた、 Web インタフェースにおける脆弱性の修正だろう。 POST した入力データのチェックが厳密になった。 La Fonera に ssh でログインする最も手軽な方法が、 この脆弱性を利用する方法だっただけに、 0.7.1 rev 2 にアップデートする際は注意が必要である。
どうも。初めてコメントさせていただきます。いつもstoneを有り難く使わせていただいております。(ウチでは支社とのfilemakerをSSLでラップするのに欠かせません)
さて、Fonera用のipkg feedを有り難く使わせていただきました。厚かましい御願いで恐縮なのですが、仙石様が公開されているWake-On-Lan(wol.c)も一緒にFeedしていただけませんでしょうか。
これができれば、自宅の計算機の電源をすべて落とす事ができ、細君に怒られずに済みます。(^^;
Comment by kiro — 2007年3月22日 @ 17:35