カテゴリー : 2008年 2月

FreeBSD 7.0-RELEASE


昨日 7.0 がとうとうリリースされたようです。
 
- SMP 環境でのパフォーマンス向上(ベンチマークや DB 処理について FreeBSD 6.X 系の 350% 〜 1500%, Linux 2.6.24 の 115% の性能)
- ULE スケジューラの大幅な改善(ただし7.0では 4BSD スケジューラがデフォルトで選択される。7.1 以降は ULE スケジューラがデフォルトになる予定)
- ファイルシステム Sun ZFS の試験的サポート。
- ジャーナルファイルシステムのセットアップに gjournal が使えるようになり、仮想ストレージデバイスを扱うのに gvirstor が使えるようになった。
- ファイルシステム XFS で読み込みのみ(Read-only)モードをサポート。
- ファイルシステム unionfs をフィックス。
- iSCSI initiator
- いくつかのネットワークドライバで TSO, LRO をサポート
- SCTP(Stream Control Transmission Protocol)の試験的サポート
- ワイヤレス(802.11)サポートの多量な改善。
- OpenBSD のネットワークリンクアグリゲーション(lagg(4))を取り込んだ。
- メモリアロケータ(malloc(3))として新しく高性能な jemalloc を採用。
- freebsd-update(8) でセキュリティフィックス,不具合修正だけでなくリリースバージョンのアップグレードを正式にサポートするようになった。
- X.Org 7.3, KDE 3.5.8, GNOME 2.20.2 に対応
- GCC 4.2.1 に対応
- BIND 9.4.2 に対応
 
アナウンスに従い freebsd-update-upgrade.tgz を取得後

sh freebsd-update.sh -f freebsd-update.conf -r 7.0-RELEASE upgrade

としたら

Looking up update.FreeBSD.org mirrors… 1 mirrors found.
Fetching metadata signature for 6.3-STABLE from update1.FreeBSD.org… failed.
No mirrors remaining, giving up.

と怒られてしまった。
たしかに http://update1.freebsd.org/ には STABLE がない。
同じバージョンであれば(uname -r とか sysctl kern.version では) RELEASE = STABLE だったと思うので

$ cat freebsd-upgrade.sh.patch
534a535
> sed -E ‘s,-STABLE,-RELEASE,’ |

とパッチをあててやり、マニュアルどおり

$ uname -r
6.2-STABLE
$ su
# sh freebsd-update.sh -f freebsd-update.conf -r 7.0-RELEASE upgrade
# sh freebsd-update.sh -f freebsd-update.conf install
# shutdown -r now
(リブート後 root でログイン)
# portmanager -u -f
(ports リビルド)
(※他自分でビルドしていたものがあれば個別にリビルドする)
# sh freebsd-update.sh -f freebsd-update.conf install # もういちど。
# shutdown -r now
(リブート後 一般ユーザでログイン)
$ uname -r
7.0-RELEASE

と、これでいけました。
ただし、jail 環境がある場合、freebsd-update-upgrade スクリプトは jail 環境を考慮してないのか

# ./freebsd-update.sh -f freebsd-update.conf -r 7.0-RELEASE -b /path/to/jail upgrade
freebsd-update.sh: Cannot upgrade from 7.0-RELEASE to itself

と jail 環境を更新するときも uname -r を見てカーネルが既にアップグレード済みだから更新の必要がない、といわれてしまいました。
 
このため jail 環境を更新するのに結局 /usr/src からいつもの手順を踏んで更新しました。

# cat /etc/supfile
  
 *default host=cvsup1.jp.FreeBSD.org
 *default base=/usr
 *default prefix=/usr
 *default release=cvs tag=RELENG_7
 *default delete use-rel-suffix
 *default compress
 src-all
 
# csup /etc/supfile
# cd /usr/src
# make buildworld
# JAILDIR=/path/to/jail
# make installworld DESTDIR=$JAILDIR
# mergemaster -D $JAILDIR
 
# shutdown -r now

あとはホストと同様に portmanager -u -f で ports を更新します。

$ su
# mount_null /usr/ports /path/to/jail/usr/ports
# jls
   JID IP Address Hostname Path
     1 192.168.2.11 myjail /path/to/jail
# jexec 1 bash # jail に接続
# cd /usr/ports/ports-mgmt/portmanager/
# make install
# portmanager -u -y -f
# exit # jail から切断
# /etc/rc.d/jail restart

 
追記(2008-03-21):
portmanager では更新もれがある場合、Shared Library まわりで色々エラーが出ます。
たとえば、FreeBSD 6.2 のとき ports インストールした emacs を FreeBSD 7.0 にしてから実行しようとすると libz.so.3 がないと怒られる。あるいは新しく ports からプログラムをインストールしようとしたら lib*.so.* という共有ライブラリがないためにコンパイル中に色々エラーがでてインストールできなかった。というような現象です。
 
この場合の対策は

portupgrade -rf “問題のあるport”

でリビルドしてみる。それでだめなら

pkg_deinstall -r “パッケージ名”

でいったん該当のパッケージと依存パッケージを削除して

portinstall -r “パッケージ名”

で削除したものを再び入れなおすと解決します。

CAcert.org のセキュリティ上の問題点


いまさらネタですが、最近になってようやく CAcert.org を使ってみました。
 
しかし少し触ってみた結果、CAcert.org をルート証明書に入れるように人に勧めることはとてもできないという結論に至りました。
気をつけるべき箇所を把握した上でルート証明に加えるなら問題はないのですが。。
 
大事な点は、身分証明や本人確認を
「電子メール証明なら対象メールアドレス、サーバ証明なら対象ドメインのwhois の Administrative Contact に書かれたメールアドレスへのメールを読めるかどうか?」
だけで判断しているため、少なからず第三者がサーバ証明書を作る危険性がある点(ただし既に CAcert.org で誰かに登録されたメールアドレス/ドメインは不可)と、
「誰でも無料で登録、即時証明書発行ができる」
という点。
CAcert.org では第三者に保証人になってもらいポイントを増やすことで信頼を重ねたりもできますが、実際のところはそんなものがなくても、(CAcert.org がルート証明機関に入ったブラウザであれば) https 通信で警告が出ないサーバ証明書を作ることができます。
 
CAcert.org に限りませんが、たとえば g00gle.com みたいな、ターゲットドメインに類似した名前のドメインを正規にとり、そのサーバ証明書を作ってフィッシングサイトを作る、なんてこともありえます。
 
クライアントが証明書を適切にチェックするようになればこういった問題を考える必要はないのですが、現実にはそうもいきません。
今日日数十ドルで証明書を発行してくれるルート証明機関もいますが、CAcert.org のような無料で証明書を発行できる組織が、そういうユーザが使うブラウザのルート証明機関に入るのはリスクの増大に他ならないかなという結論に至ったわけです。
 
参考:
CAcert.org は Windows のルート証明書に含まれるようになるのか?(yamk 日記)

作業中のプロセスを残したまま端末を終了する


何かをビルドしていて、時間が予想外にかかってしまい、nohup もしていないためになかなか端末を閉じることができずに予定が狂って結局残業時間がのびる、なんてことありませんか?
 
そういうときは disown を使うと実行中のジョブを端末から切り離すことができます。
(以下は bash の例です)

$ make # 何か時間のかかる作業
## 出力は略。途中で端末接続を切りたくなった(Ctrl-Z) ##
^Z
[1]+ Stopped make
 
$ bg # バックグラウンドで実行を再開
## 略。出力再開 ##
 
$ disown # 端末を切ってもプロセスが残るようにカレントジョブ( %1 )を端末から切り離す
$ exit # 終了

nohup と違い端末を切ると標準出力、エラー出力はどこにも出力されなくなりますが、これで端末を切断してもプロセスが実行されたままになります。
 
参考:
一度 tty から起動したプロセス(PBD)
一度 tty から起動したプロセス (csh/ksh 版)(にぽたん研究所)

公式マニュアルの場所


http://svnbook.red-bean.com/
オライリー本「Subversion によるバージョン管理」(原題: `Version Control with Subversion’)をオンラインで読むことができます。
 
公式サイトの Documentation が最終更新2004年なため、ちゃんとした公式ドキュメントがないのかとてっきり思っていたら、Additional Resources の Subversion Book が正式なマニュアルなんですね。
man svn して初めて気づいた。。

tips – キャッシュあれこれ


- キャッシュの中身を見るには?
Firefox の場合, IE の Temporary Internet Files のようにキャッシュディレクトリに直接ファイルが置かれないためエクスプローラからはキャッシュの中身を見ることができません。

about:cache

を URL に指定するとメモリキャッシュ、ディスクキャッシュ両方の中身を見ることができます。
 
- キャッシュフォルダの場所を変更するには?

about:config

を URL に指定して設定画面を開き、「右クリック→新規作成→文字列」を選択して

設定名: browser.cache.disk.parent_directory
文字列: c:\path\to\cache

のように設定すると次回起動時からこの指定先がキャッシュフォルダとして利用されるようになります。
 
参考:
- about:mozilla(Mozilla Page by Yotti)
about: からはじまる擬似 URL の一覧。

/tmp を自動で削除するには


FreeBSD は標準では /tmp の中身は削除されないようになっていますが、FreeBSD には削除処理を自動で行ってくれる二つの手段が提供されています。
 


- 起動時に中身をクリアする
 
/etc/rc.conf に以下の設定を追加すると FreeBSD の起動時に /tmp の中身を削除するようになります。

clear_tmp_enable=”YES” # Clear /tmp at startup

 
この機能は /etc/rc.d/tmp で実装されており、/etc/rc.d/rc.conf にデフォルト設定があります。

clear_tmp_enable=”NO” # 起動時に /tmp をクリアする
clear_tmp_X=”YES” # /tmp 内の X11 関連のディレクトリをクリアして再構築する


- 定期的に古いファイルを削除する
/etc/periodic.conf に以下の行を設定することで /tmp の中身のうち一定期間アクセスがないファイルを削除するようになります。

daily_clean_tmps_enable=”YES”

 
rc.conf の clear_tmp_enable を YES にすると起動時に /etc/rc.d/tmp が実行されて /tmp のすべてのファイルを削除します。
 
この機能は /etc/periodic/daily/110.clean-tmps で実装されており、/etc/default/periodic.conf にデフォルトの設定があります。

daily_clean_tmps_enable=”NO” # 不要ファイルを毎日削除する
daily_clean_tmps_dirs=”/tmp” # このディレクトリ以下を削除する
daily_clean_tmps_days=”3″ # 指定期間アクセスがないもののみ対象
daily_clean_tmps_ignore=”.X*-lock quota.user quota.group” # 削除対象外のファイル
daily_clean_tmps_ignore=”$daily_clean_tmps_ignore quota.user quota.group”
 
daily_clean_tmps_verbose=”YES” # 削除したファイル名を出力する

ruby でランダムな文字列を生成


“ランダムなパスワードを生成する” の ruby バージョン。
[2005-04-25] (JavaScript 版)
[2005-05-31] (PHP 版)

# ランダムな文字列を生成する。
# 引数 _length_ を指定すると生成桁数を指定することができます(デフォルト 8 桁)。
def getRandomString (length = 8)
  source=(“a”..”z”).to_a + (“A”..”Z”).to_a + (0..9).to_a + ["_","-","."]
  key=”"
  length.times{ key+= source[rand(source.size)].to_s }
  return key
end
 
# 10 桁の文字列を取得
p getRandomString 10

FreeBSD6 + jail + httpd22 + fcgid/fastcgi + Ruby on Rails


久しぶりにものすごくはまったのでメモ。
 
目的:
FreeBSD jail 上の httpd + suexec 環境に ruby on rails を入れたが、
CGI で動かすと遅いので fcgi 対応にしたい。
 
手順:
- jail host の /etc/rc.conf に以下の記述を追加

sysvipc_enable=”YES”
jail_sysvipc_allow=”YES” # jail 環境で httpd を動かしている場合のみ追加

- fastcgi を追加(ruby_fcgi 用)

$ wget http://www.fastcgi.com/dist/fcgi-2.4.1-SNAP-0311112127.tar.gz # http://www.fastcgi.com/dist/ の fastcgi の最新版
$ tar xvzf fcgi-2.4.1-SNAP-0311112127.tar.gz
$ cd fcgi-2.4.1-SNAP-0311112127
$ ./configure –prefix=/usr/local/fastcgi # /usr/local/fastcgi 以下に展開(*1)
$ sudo make install

- ruby_fcgi を追加(gem install fcgi では each_cgi がないと怒られる場合があるため、ソースからビルド)

$ wget http://rubyforge.org/frs/download.php/11368/ruby-fcgi-0.8.7.tar.gz
$ tar xvzf ruby-fcgi-0.8.7.tar.gz
$ cd ruby-fcgi-0.8.7
$ ruby install.rb config — –with-fcgi-dir=/usr/local/fastcgi # (*1) で指定したフォルダ。(*1)で –prefix を指定しなかった場合、ここで config を実行しなくてよい。
$ sudo ruby install.rb

- mod_fcgid または mod_fastcgi をビルド/インストール
mod_fastcgi の場合:

$ wget http://www.fastcgi.com/dist/mod_fastcgi-2.4.6.tar.gz
$ tar xvzf mod_fastcgi-2.4.6.tar.gz
$ cd mod_fastcgi-2.4.6
$ cp Makefile.AP2 Makefile
$ make
$ sudo make install
$ # httpd2 が /usr/local/apache2 になければ Makefile を編集して top_dir を変更するか、次のようにする
$ sudo make top_dir=/opt/httpd/2.0.40
$ sudo make install top_dir=/opt/httpd/2.0.40

mod_fcgid の場合:

$ wget http://downloads.sourceforge.net/mod-fcgid/mod_fcgid.2.2.tgz?modtime=1185976592&big_mirror=0
$ tar xvzf mod_fcgid.2.2.tgz
$ cd mod_fcgid.2.2
$ make
$ sudo make install
$ # httpd2 が /usr/local/apache2 にない場合はmod_fastcgi の場合と同様の手法で top_dir 変数を変更する。

- mod_fcgid または mod_fastcgi を httpd にロード/設定
httpd.conf:

# mod_fastcgi を使う場合コメントアウト:
#LoadModule fastcgi_module modules/mod_fastcgi.so
<IfModule fastcgi_module>
   AddHandler fastcgi-script .fcgi
# ソケットの場所(省略時は httpd の log/fastcgi/ )
# FastCgiIpcDir /var/run/fastcgi
   FastCgiConfig -autoUpdate -idle-timeout 20 -killInterval 3600 -maxClassProcesses 2
   # suexec を使う場合必要
   FastCgiWrapper /usr/local/apache2/bin/suexec
</IfModule>
# mod_fcgid を使う場合コメントアウト:
#LoadModule fcgid_module modules/mod_fcgid.so
<IfModule fcgid_module>
   AddHandler fcgid-script .fcgi
   SocketPath /tmp/fcgidsock
   SharememPath /tmp/fcgidshm
   IPCCommTimeout 40
   IPCConnectTimeout 10
   # suexec を使う場合も使わない場合も FCGIWrapper は設定しなくてよい
</IfModule>
 
# suexec 例(SuexecUserGroup が肝):
<VirtualHost 192.168.10.123>
    ServerAdmin webmaster@example.com
    DocumentRoot /usr/local/apache2/htdocs/
    ServerName example.com
    SuexecUserGroup john web
</VirtualHost>

 
- rails の設定を変更
{rails_root}/public/.htaccess

- AddHandler fastcgi-script .fcgi
- RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
+ RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
- DefaultInitEnv RAILS_ENV development
+ SetEnv RAILS_ENV development

DefaultInitEnv とか SetEnv で変数がわたらない環境の場合は
{rails_root}/config/environment.rb の次の項目をコメントアウトして編集する

# Uncomment below to force Rails into production mode when
# you don’t control web/app server and can’t set it the proper way
#ENV['RAILS_ENV'] ||= ‘production’

 
- エラーが出る場合のヒント
http://ontherails.jp/2007/10/13/25 などを参考に。
ログファイルを見る:

httpd の error_log, suexec_log
rails の log/fastcgi.crash.log, log/development.log, log/production.log

など。
特に fastcgi/fcgid をかませた時のみ

Application error
Rails application failed to start properly

とページ表示される場合は rails の fastcgi のログを見るのが有効そうです。
 
参考:
- configuration – The mod_fcgid Home Page
- Apache2 + fcgid + Ruby on Railsメモ – sakuramateo
- FreeBSD + Apache2 + mod_fcgid + Ruby On Rails(ふわふわな毎日)
- _ fcgid(valda’s diary)
- FastCGI 化(ふぇみにん日記)
- Rails Apache + FastCGI 環境構築のはまりパターン
- lighttpd + fcgi で each_cgi なるメソッドは知らないといわれる(Don’tStopMusic)

mdconfig の使い方色々(tmpfs, .iso のマウント, GEOM など)


md (/sbin/mdconfig) を使うと任意のファイルやメモリ領域をファイルシステム化することができます。
これを使うと、 Linux の tmpfs のようにメモリ領域にファイルを置いたり、CD イメージデータなどを仮想ファイルシステムとしてマウントすることができます。
 


■Linux の tmpfs (/dev/shm) のように使う
書式:

mdconfig -a -t swap -s <サイズ> [ -u <デバイス番号>] # swap 込みで確保(推奨)
mdconfig -a -t malloc -o reverse -s <サイズ> [ -u <デバイス番号>] # malloc (9)によるメモリ確保。大容量には向かない

 例:

$ su
# mdconfig -a -t swap -s 10m # あいているデバイス番号でメモリ 10MB を割り当て(0 〜 )
md0 # /dev/md0 が作成された
# newfs /dev/md0 # /dev/md0 に結びついた領域にファイルシステム作成
# mount /dev/md0 /mnt # アクセスできるようにマウント
# df -h | grep md0 # マウントできたか確認。
/dev/md0 9.4M 4.0K 8.7M 0% /mnt
# dd if=/dev/zero of=/mnt/foo.txt bs=1m count=5 # 適当にデータ書き込み
5+0 records in
5+0 records out
5242880 bytes transferred in 0.063932 secs (82007207 bytes/sec)
# dd if=/dev/zero of=/tmp/foo2.txt bs=1m count=5 # 比較用。/tmp より /mnt に書くほうが早くなっているはず
5+0 records in
5+0 records out
5242880 bytes transferred in 0.159325 secs (32906800 bytes/sec)
# ls -l /mnt
total 5138
drwxrwxr-x 2 root operator 512 2 4 17:15 .snap
-rw-r–r– 1 root wheel 5242880 2 4 17:18 foo.txt

 開放手順:

# umount /mnt # マウントポイントから切り離す
# mdconfig -d -u 0 # /dev/md0 をデタッチ


■任意のファイルをファイルシステムとして扱う
 (CD イメージ,ハードディスクイメージなどをマウントする)
 書式:

mdconfig -a -t vnode -f <ファイル名> [ -u <デバイス番号> ] # 指定したファイルをファイルシステムとして扱う

 例:

$ su
# ls /root/cd.iso # マウント対象の CD-ROM イメージ
cd.iso
# mdconfig -a -t vnode -f /root/cd.iso -u 1 # cd.iso を /dev/md1 に結びつける(今回は -u 1 で md1 を明示的に確保)
# mount -t cd9660 /dev/md1 /mnt # CD-ROM なので cd9660 をファイルシステムに指定してマウント。
# ls /mnt # CD-ROM の中身へのアクセス成功。
boot.cat f2.txt f6.txt initrd.gz splash.rle
boot.txt f3.txt f7.txt isolinux.bin
f1.txt f4.txt f8.txt isolinux.cfg
f10.txt f5.txt f9.txt linux

 開放手順: (前述の例と同じ)

# umount /mnt
# mdconfig -d -u 1 # /dev/md1 をデタッチ


■ zip 圧縮してサイズを節約する(geom_uzip: GEOM の利用例)
GEOM_UZIP を使うと、vnode 用イメージファイルをZIP圧縮してサイズを節約することができます。読み込み専用でしかマウントできないという欠点はありますが、CDイメージの保存やデータのバックアップなどの用途には有用です。
 例:

$ dd if=/dev/acd0 of=cdimg.iso bs=2352 # ファイルシステムのイメージデータ(なんでもよいがここでは CDドライブから吸出し(cd9660形式)) (1)
$ mkuzip -o cdimg.uzip cdimg.iso # 元のファイルシステムを geom_uzip で使える形式(*.uzip) に圧縮(2)
$ rm cdimg.iso # cdimg.iso はもう不要 (3)
$ su
# kldload geom_uzip # geom_uzip がカーネルに組み込み済みでなければここでロードする(4)
# mdconfig -a -t vnode -f cdimg.uzip # cdimg.uzip を vnode 形式で仮想ディスク化
md0
# ls /dev/md0* # geom_uzip が認識されていれば,geom_uzip 用イメージを mdconfig すると /dev/md*.uzip が同時に作成される
/dev/md0 /dev/md0.uzip /dev/mdctl
# mount -t cd9660 -r /dev/md0.uzip /mnt # /dev/md*.uzip を元のファイルシステム(この例ではcd9660)で read-only (-r)でマウントする。

 開放手順: (前述の例と同じ)

# umount /mnt
# mdconfig -d -u 1 # /dev/md1 をデタッチ

 
(1) 〜 (3) をまとめて次のように記述することもできます。

dd if=/dev/acd0 bs=2352 | mkuzip -o cdimg.uzip /dev/stdin

恒常的に geom_uzip を使う場合は、(4)のかわりに geom_uzip をカーネルバイナリに組み込むか /boot/loader.conf に次の一文を追加すると起動時に自動でロードされます。

geom_uzip_load=”YES”

 
(4)以降については *.uzip が代用される以外は前述の vnode の例と同じです。


■ geli を使った仮想ファイルシステムの暗号化:
mdconfig を geli(GEOM_ELI) や gdbm(GEOM_DBM) と組み合わせると、TrueCrypt や pgpdisk のように暗号化仮想ファイルシステムを構築することができます。今回は geli の例を紹介します。
 
geli を使うと既存のストレージがファイルシステムごと暗号化され、専用のラッパデバイス(/dev/*.eli) からしかアクセスできなくなります。/dev/*.eli をアタッチするには認証(パスフレーズ+鍵ファイル)が必要なため、必要な時のみアタッチ、マウントすることでデータの機密性を保つことができます。/dev/*.eli を使うユーザからは暗号化がされていない時と同様に利用できるため、大きな変更なしで簡単に利用できます。
 
 /boot/loader.conf:

geom_eli_load=”NO” # Disk encryption driver (see geli(8))

例:

# dd if=/dev/random of=/root/eli.key bs=64 count=1 # geli での認証用鍵ファイル(64byte)
# dd if=/dev/zero of=img.eli count=10 bs=1m # 仮想ファイルシステム用イメージファイル作成(ここでは 10MB=10*1m)。
# su
# mdconfig -at vnode -f img.eli
md0
# geli init -s 4096 -K /root/eli.key /dev/md0 # /dev/md0 を geli 用のファイルシステムとして初期化(暗号化)
Enter new passphrase:
Reenter new passphrase:
# geli attach -k /root/eli.key /dev/md0 # /dev/md0 に透過的にアクセスするためのデバイス取得(/dev/md0.eli が作成される)
Enter passphrase:
# newfs /dev/md0.eli # ファイルシステムは UFS 形式として初期化(暗号化された領域内)
/dev/md0.eli: 10.0MB (20472 sectors) block size 16384, fragment size 4096
        using 4 cylinder groups of 2.50MB, 160 blks, 192 inodes.
super-block backups (for fsck -b #) at:
 160, 5280, 10400, 15520
# mount /dev/md0.eli /mnt # あとは普通に(UFSとして)マウント。

 解放手順:

# umount /mnt # /dev/md0 のマウント先をアンマウント
# geli detach md0.eli # /dev/md0.eli を解除
# mdconfig -du 0 # /dev/md0 を解除

 
最初に作成した鍵ファイル(例では/root/eli.key) はフラッシュメモリなど暗号化デバイスとは別の場所に保存するのが望ましいです。
また、

geli init

の引数に -K <keyfile> を含めない場合はキーレス認証(パスフレーズのみ)での暗号化になり、 -P を追加するとパスフレーズレス認証(鍵ファイルのみ)での暗号化になります。
注意点として、geli init をするとデバイスに結びついたファイルシステムが初期化されることにも気をつけて下さい。詳細については geli(4) を参照のこと。
 


参考:
- mdconfig(8)
- mdだって凄いんです。(404 Blog Not Found)
- Linux で仮想 CD ドライブをマウントする(Hermit Complex 楽天支店)

# mount -t iso9660 -o loop /home/tagosuck/tagosucd.iso /mnt/tagosucd0