-
001328
諸事情で HP ML115 を 13,750 円で購入し、2GB のノー・ブランド DIMM DDR2 SDRAM 二枚を 7,760 円で購入して突っ込み、CentOS5.2 をインストールし、MySQL で大きめな統計処理をぐるぐると回しておりました。 が、あまりにも遅い。 同じ処理を RAM 512MB の Dell SC430 でも実行していたのだけれど、その数倍の時間をかけても完了しません。 おかしい・・・。
vmstat をみても、block in / block out がさして多いわけでもなく、CPU usage が 100% 近辺をさまよっています。 ディスクを使わず、メモリ上で CPU がブン回っている理想的な状態です。 が、しばらく見ていると、たまに cpu wait が跳ね上がります。 確かに、データベースを使っていて disk I/O を 0 にするのは厳しいので、これは仕方ない。 が、しかし、よくよく見ると I/O wait が 100% 近くになったまましばらくまたされます。 SC430 はもう少し頻繁に Disk I/O が発生していますが、ML115 ほど I/O wait が跳ね上がったままの状態が続かないぞ・・・。 確かに CPU 性能には差がありますが(AMD Athlon 64 3500+ / Intel Pentium D 2.8GHz)、それは I/O wait 時間に関係がありません。 となると、ディスク性能があやしくなってきます。
まずは dbench を実行してみました。
以下の手順でコンパイルし、
$ wget http://samba.org/ftp/tridge/dbench/dbench-4.0.tar.gz $ tar zxf dbench-4.0.tar.gz $ cd dbench-4.0 $ ./autogen.sh $ ./configure $ make
実行。
ML115 $ ./dbench -c client.txt 1 ... 1 30795 8.61 MB/sec warmup 21 sec latency 201.968 ms 1 31612 8.50 MB/sec warmup 22 sec latency 500.014 ms 1 32777 8.41 MB/sec warmup 23 sec latency 810.937 ms ...
SC430 $ ./dbench -c client.txt 1 ... 1 257768 53.93 MB/sec warmup 26 sec latency 21.852 ms 1 272487 54.93 MB/sec warmup 27 sec latency 21.601 ms 1 287121 55.80 MB/sec warmup 28 sec latency 21.750 ms ...
桁違いです・・・。 スループットもレイテンシーも文字通り桁が違います。 参った・・・。
続いて hdparm を走らせてみます。
ML115 $ sudo hdparm -t /dev/sda /dev/sda: Timing buffered disk reads: 222 MB in 3.00 seconds = 73.93 MB/sec
SC430 $ sudo hdparm -t /dev/sda /dev/sda: Timing buffered disk reads: 216 MB in 3.02 seconds = 71.61 MB/sec
あれ? 殆ど同じ数値です。 何度か取り直しても殆ど同じ。 あれれ・・・うーむ・・・
ここではたと気付いたのですが、hdparm は "disk reads" だけを測定しているんですね。 一方の dbench はもちろん read / write 双方。 これは怪しい。 そこで、ディスクの情報を確認してみると、
ML115 $ sudo hdparm -i /dev/sda /dev/sda: Model=FB080C4080 , FwRev= HPF0, SerialNo=6RW2A54G Config={ HardSect NotMFM HdSw>15uSec Fixed DTR>10Mbs RotSpdTol>.5% } RawCHS=16383/16/63, TrkSize=0, SectSize=0, ECCbytes=4 BuffType=unknown, BuffSize=8192kB, MaxMultSect=16, MultSect=?16? CurCHS=16383/16/63, CurSects=16514064, LBA=yes, LBAsects=156301488 IORDY=on/off, tPIO={min:120,w/IORDY:120}, tDMA={min:120,rec:120} PIO modes: pio0 pio1 pio2 pio3 pio4 DMA modes: mdma0 mdma1 mdma2 UDMA modes: udma0 udma1 udma2 AdvancedPM=no WriteCache=disabled Drive conforms to: unknown: ATA/ATAPI-1 ATA/ATAPI-2 ATA/ATAPI-3 ATA/ATAPI-4 ATA/ATAPI-5 ATA/ATAPI-6 ATA/ATAPI-7 * signifies the current active modeSC430 $ sudo hdparm -i /dev/sda /dev/sda: Model=ST3320620AS , FwRev=3.AAD , SerialNo= 3QF0KHCA Config={ HardSect NotMFM HdSw>15uSec Fixed DTR>10Mbs RotSpdTol>.5% } RawCHS=16383/16/63, TrkSize=0, SectSize=0, ECCbytes=4 BuffType=unknown, BuffSize=16384kB, MaxMultSect=16, MultSect=?8? CurCHS=16383/16/63, CurSects=16514064, LBA=yes, LBAsects=268435455 IORDY=on/off, tPIO={min:240,w/IORDY:120}, tDMA={min:120,rec:120} PIO modes: pio0 pio1 pio2 pio3 pio4 DMA modes: mdma0 mdma1 mdma2 UDMA modes: udma0 udma1 udma2 AdvancedPM=no WriteCache=enabled Drive conforms to: Unspecified: ATA/ATAPI-1 ATA/ATAPI-2 ATA/ATAPI-3 ATA/ATAPI-4 ATA/ATAPI-5 ATA/ATAPI-6 ATA/ATAPI-7 * signifies the current active modeなんと ML115 は Write Cache が disabled です! こいつか・・・。 この設定を変えるには以下のようにします。
$ sudo hdparm -W1 /dev/sda
これで WriteCache enabled になります。 dbench の結果も改善されました。
ML115 $ ./dbench -c client.txt 1 ... 1 290707 63.28 MB/sec warmup 25 sec latency 48.369 ms 1 302699 63.30 MB/sec warmup 26 sec latency 48.974 ms 1 314756 63.30 MB/sec warmup 27 sec latency 44.975 ms ...
めでたい!
と、さらっと書いていますが、ここまで 12h 近くが経過してしまいました。 ふぅ、大変だった。 さて、計算のやり直しだ。
[ permalink ] [ 0 comment(s) ] [ 0 trackback(s) ] -
001322
先週 2008/06/24 に CentOS 5.2 がリリースされました。
- [CentOS-announce] Release for CentOS-5.2 i386 and x86_64
- Manuals/ReleaseNotes/CentOS5.2 - CentOS Wiki
ぼくの自宅サーバーは CentOS 4.6 が稼動しており、そろそろバージョンを上げたいなと思っていたところなので、せっかくだからと、最新版に手を出してしまいました。 これが間違いの元だった・・・。 なにやらいろいろと苦労したのでメモを残して起きます。
CentOS 5.2CentOS 5.2 はリリースされてからまだ日も浅く、それほど情報はありませんが、4.x から 5.1 にアップグレードした記録を見る限りは yum upgrade では上げられそうにありません。 ここは素直に DVD の ISO イメージを手に入れ、インストーラーでアップグレードすることにします。 いや、それでもあまりオススメされていない手順ですけどね。
ここでまず最初の問題に遭遇。 自宅サーバーの光学ドライブは CD-ROM でした・・・。 これは自分の問題であって CentOS の問題ではないので仕方ない。 筐体をあけて、余っていた DVD を読み書きできるコンボ・ドライブを装着して事なきを得ました。 アップグレード・インストールの手順自体は至って簡単。 パッケージをインストールするのに非常に時間がかかりましたが、これはリリース・ノートにも書かれているようなメモリー容量の問題のような気がしています。 まぁ、待てば終わるので気長に。
アップグレードが終わったら、
$ wget http://ftp2.riken.jp/Linux/centos/5.2/os/i386/RPM-GPG-KEY-CentOS-5 $ sudo rpm --import RPM-GPG-KEY-CentOS-5 $ sudo yum update
としてパッケージを最新の状態にしておきましょう。
Apacheアップグレード直後の起動時に、サービスの起動がいくつか FAILED になっているのが見えました。 まぁ、バージョンを大幅に上げたからねぇ。 予想される範囲内。
そのフェールしているものの一つが Apache でした。 CentOS4.6 では Apache2.0 だったのが、CentOS5.2 では Apache2.2 になっています。 これに伴い、モジュールの構成などが大幅に変わっています。 特に認証周りが顕著。
LoadModule ディレクティブなどを新しい設定ファイル(/etc/httpd/conf/httpd.conf.rpmnew として保存されている)を参考にして書き直します。 そして /etc/rc.d/init.d/httpd start として Apache を起動します。
dovecotIMAP サーバーとして導入している dovecot は 0.99 から 1.0 に上がっています。 メジャー・バージョンが変わっているだけあって、設定ファイルにいろいろと変更が発生していました。
プロトコルごとの LISTEN の設定は次のようにブレースでまとめるようになっていました。
protocols = imap imaps protocol imap { listen = *:143 ssl_listen = *:993 }続いては SSL の設定です。
ssl_cert_file = /etc/ssl/service.crt ssl_key_file = /etc/ssl/common.nokey
最後に認証の設定。 ここもブレースでまとめるように変更されていました。 認証は dovecot 用のユーザー・ファイルを独自にメンテナンスしていたので、それを指定します。
login_dir = /var/run/dovecot/login passdb passwd-file { args = /etc/dovecot.passwd } userdb passwd-file { args = /etc/dovecot.passwd }最後に /etc/rc.d/init.d/dovecot restart として dovecot を再起動します。
SquirrelMailApache と dovecot が動くようになると、次は WebMail システムの SquirrelMail の設定を見直しました。 なかなか動かなかったのですが、結局は
$ sudo chown -R apahce:apache /var/lib/php
が正解。 それって SquirrelMail というよりも PHP の問題・・・。
BINDbind は 9.2.4 から 9.3.4 に上がりました。 RPM が古い設定ファイルを /var/named/chroot/etc/named.conf.rpmsave としてバックアップするので、これを新しい named.conf に上書きすると問題なく動作しました。 Apache といい、この BIND といい、きちんと backward compatibility が保たれているのは素晴らしいですな。
PostgreSQL一番苦労したのが PostgreSQL。 CentOS4.6 では 7.4 だったものが 8.1 になっています。 PostgreSQL は小数点以下一桁目が変わるとデータのマイグレーションが必要になります。 今回はそもそも最上位桁が上がっているのでもう必要も必要。 本来は OS のアップグレード前に pg_dumpall で書き出しておくべきだったのですが、まったく気にせずにアップグレードしてしまいました。
残念というか当然というか PostgreSQL8.1 では 7.4 のデータ・ファイルを読むことができません。 CentOS5.2 上に PostgreSQL7.4 を導入することも検討したのですが、なかなか難しそうだったので結局は VMware 上に CentOS4.6 を導入してデータを吸い出すことにしました。
新たに導入した CentOS4.6 の PostgreSQL7.4 を停止し、/var/lib/pgsql の中身をごっそりと旧データ・ファイルで上書きして再起動します。 最初はセオリーどおり
@vmware $ sudo su postgres @vmware $ pg_dumpall > backup.dmp @vmware $ scp backup.dmp postgres@real:~/
@real $ sudo su postgres @real $ psql -f ~/backup.dmp
としたのですが、データの不正が発生してうまくいきません。 最終的には新マシンで
@real $ pg_dumpall -h vmware -U popsql | psql
として、直接パイプで流し込むことで移行できました。 失敗ケースが 7.4 の pg_dumpall で吸い出して 8.1 の psql で読んでいるのに対して、成功したケースは 8.1 の pg_dumpall を 7.4 のサーバーにつないで、その出力を 8.1 の psql で読んでいる状態です。 ということは、やはり一時的に両方のバージョンを用意する必要があったんですね。
移行とは直接関係ないのですが、PGDATA を切り替える方法です。
@real $ sudo /etc/rc.d/init.d/postgresql stop @real $ sudo vi /etc/sysconfig/pgsql/postgresql PGDATA=/opt/pgsql/data @real $ PGDATA=/opt/pgsql/data @real $ initdb @real $ sudo /etc/rc.d/init.d/postgresql start
SubversionSubversion は、その裏で使っている BerklyDB のバージョンが 4.2 から 4.3 へ上がっており、過去のリポジトリをそのままは読めない場合があります。 そのときは以下の手順を踏むことで解決するようです。
過去と同じバージョンの BerklyDB を持つ環境で、
$ svnadmin recovery ~/svnrepo $ rm `svnadmin list-unused-dblogs ~/svnrepo` $ rm ~/svnrepo/db/__db.00*
として余計なファイルを消しておきます。 多分、OS のアップグレード前に実施しておくのが本当は正しいんだろうね。 今回は PostgreSQL のアップグレードに使った CentOS4.6 環境を使いました。
TracTrac は、その稼働環境であるところの Python が 2.3 から 2.4 に上がっています。 Trac そのものの問題ではないのかもしれないけれど、案の定うまく動きませんでした。 そういえば WebAdmin plugin が Python2.3 用のものだったような気も・・・。 そこで一旦 rpm --erase trac してからあらためて yum install trac としてインストールしなおしました。 WebAdmin plugin も入れなおし。
$ wget http://trac.edgewall.org/raw-attachment/wiki/WebAdmin/TracWebAdmin-0.1.2dev_r4240-py2.4.egg.zip $ mkdir TracWebAdmin $ cd TracWebAdmin $ unzip ../TracWebAdmin-0.1.2dev_r4240-py2.4.egg.zip $ cd .. $ sudo easy_install TracWebAdmin-0.1.2dev_r4240-py2.4.egg
その他自作ツールPHP が 4.3 から 5.1 に上がったため、自作のツールの一部が動かなくなりました。 結構直したつもりなのだけれど、まだいくつか調子がおかしいです。
というわけで、軽い気持ちで始めた CentOS4.6 から 5.2 へのアップグレードはなかなか大変な作業でした。 でもま、最新版ってのは気持ちがいいですな。
-
001261
先日、どうもメールが届いてこないと思ったら /var があふれていました。
$ df -h | grep var /dev/mapper/VG00-LV05 2.0G 2.0G 0.0G 100% /var幸いこのマシンでは LVM を使用してディスクを運用していたので、以下の手順でパーティションが拡張できました。
状況確認まずはボリューム・グループ (VG) の状況を確認します。
$ sudo vgdisplay VG00 --- Volume group --- VG Name VG00 System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 9 VG Access read/write VG Status resizable MAX LV 0 Cur LV 6 Open LV 6 Max PV 0 Cur PV 1 Act PV 1 VG Size 297.81 GB PE Size 32.00 MB Total PE 9530 Alloc PE / Size 4992 / 156.00 GB Free PE / Size 4538 / 141.81 GB VG UUID xxxxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxxxx
320GB のディスクの半分程度しか使っていません。 142GB 近い十分な未使用領域が残っています。
続いてボリューム・グループ (VG) の状況も確認。
$ sudo lvdisplay /dev/VG00/LV05 --- Logical volume --- LV Name /dev/VG00/LV05 VG Name VG00 LV UUID xxxxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxxxx LV Write Access read/write LV Status available # open 1 LV Size 2.00 GB Current LE 64 Segments 2 Allocation inherit Read ahead sectors 0 Block device 253:4
論理ボリューム (LV) の拡張現在 2GB の /var を、倍の 4GB に拡張します。
$ sudo lvextend -L +2G /dev/VG00/LV05ファイル・システムの拡張論理ボリュームを拡張しただけではファイル・システムとして利用可能な状態になりません。 以下のようにファイル・システムを拡張する必要があります。
$ sudo ext2online /dev/VG00/LV05番外 : yum が使っている領域の開放未使用領域が潤沢だったので、/var の使用状況を調査せずに拡張してしまいましたが、よくよく状況を確認すると yum がかなりの容量を消費していることが分かりました。 ダウンロードした *.rpm ファイルなどは以下のコマンドで削除することができます。
$ sudo yum clean packages
以上の作業で、/var は現在こんな感じになりました。
$ df -h | grep var /dev/mapper/VG00-LV05 4.0G 1.5G 2.4G 38% /var- 001206
自宅サーバーを常時稼動させているのですが、その稼動状況をあまりきちんと把握しておりませんでした。 よろしくない。 そこで、今月の Software Design で取り上げられていた Cacti をインストールすることにしました。
"Cacti" は「カクタイ」と発音するそうです。 Cacti は MRTG の後継であるグラフ化ツールであるRRDTool のフロントエンドとして振る舞い、各種ステータスをグラフ化して表示する Web アプリケーションです。
MRTG は古くから使われていて実績のあるグラフ化ツールではあるものの、二系統しかグラフ化できないなどの制約があり使い勝手はさすがに見劣りしてきています。 そこで開発されたのが RRDTool で、MRTG の蓄積を生かしつつ(開発者は同じ人)機能の拡充がなされています。 がしかし、欠点としてその扱いが複雑になってしまったようです。 という経緯で、この Cacti のようなフロントエンドが必要になるわけですな。
Cacti は SNMP にも対応しているので、今回は Linux サーバーだけではなく Windows XP マシンも監視対象に入れてみたいと思います。
Cacti をセットアップします自宅サーバーは CentOS なのでインストールは簡単。 RPMForge.net から、こんな具合にインストールできます。
$ yum install cacti
インストールが終わったら、DB スキーマの作成です。 Cacti はバックエンドのデータストアとして MySQL を使います。
$ sudo su - mysql $ mysqladmin -u root create cacti $ mysql -u root cacti < /var/www/cacti/cacti.sql $ mysql -u root mysql mysql> grant all on cacti.* to cactiuser@localhost \ identified by '<password>'; mysql> flush privileges
続いて、作成した DB への接続情報を Cacti に設定します。 設定ファイルは /var/www/cacti/include/config.php になります。
$database_type = "mysql"; $database_default = "cacti"; $database_hostname = "localhost"; $database_username = "cactiuser"; $database_password = "<password>"; $database_port = "3306";
念のため、Apache の設定を確認してから起動します。 Apache 用の設定は /etc/httpd/conf.d/cacti.conf に置かれます。 httpd.conf に "Include conf.d/*.conf" というディレクティブがあるので、自動的に Apache の設定として読み込まれます(ぼくはこの動きが気持ち悪いので当該ディレクティブを無効化していますが)。
$ sudo /etc/rc.d/init.d/httpd restart
設定した URI(たとえば http://example.net/cacti/)にアクセスすると、初回アクセス時のコンフィギュレーション画面が表示されます。 ぼくの場合は特に設定を変更すべき箇所が見当たらなかったので、そのまま次へ次へと。 やがてログイン画面が表示されるので admin/admin にてログインしましょう。 新しいパスワードを聞かれるので適当なパスワードを設定すれば起動完了。
デフォルトでは Localhost が登録されています。 crond を使って五分間隔で値を取得しているので、しばらく待つとグラフが表示される状態になります。 左上の "graph" タブをクリックしましょう。
Windows XP マシンの稼動状況をグラフ化するCacti のインストールが終わったので、Windows XP マシンの稼動状況を SNMP で取得してグラフ化してみましょう。 Windows XP Professional には標準で SNMP Agent 機能が用意されています。 "サービス" に "SNMP Service" がリストされているはずです。 これが存在しない場合は "コントロールパネル > プログラムの追加と削除 > Windows コンポーネントの追加と削除" から "管理とモニタツール" を追加してください。 続いて、"サービス > SNMP Service" のプロパティを開き "セキュリティ" タブを開きます。 デフォルトのコミュニティ名 "public" を変更しましょう。 また、必要に応じて接続元ホストも絞りましょう。 今回の Cacti 用には Linux サーバーの IP アドレスを指定しておけば問題ないでしょう。
SNMP Service が起動してなければ起動します。 必要に応じてファイアウォールの設定も変更してください。 以上で Windows マシン側の設定は完了です。
続いて Cacti の設定です。 箇条書きで。
- 先ほどの Web の "console" タブ画面のメニューから "Devices" をクリックします。
- 画面右上の "Add" リンクをクリックします。
- 以下のように入力します。
Description 何か分かりやすい表示名 Hostname Windows マシンのホスト名 Host Template Windows 2000/XP SNMP Community 先ほど指定したコミュニティ名 SNMP Version Version 2 SNMP Port 161 SNMP Timeout 適当に - "create" ボタンをクリックして設定を作成します
続いてグラフ定義の作成です。
- 表示された画面の "Create Graphs for this Host" リンクをクリックします
- すべてのグラフにチェックをつけて "create" ボタンをクリックします
- メニューの "Devices" をクリックします
- 先ほど作成した Windows マシンの設定にチェックをつけます
- "Cheese an action" の "Place on a Tree (Default Tree)" を選択して "go" をクリックします
- "yes" をクリックします
以上でグラフの追加は完了です。 "graph" タブから Windows マシンのグラフを表示して見ましょう。
- 001205
ぼくは CentOS のパッケージ管理に yum を使っています。 CentOS の公式リポジトリだけでもそれなりには使えるのですが、やはりほかにもパッケージが必要になる場合もあります。 そこで、非公式リポジトリをいくつか yum に登録することにしました。 非公式リポジトリを利用するにあたって注意したいのが、リポジトリが継続的にメンテナンスされるかという点。 そのリポジトリからパッケージをインストールしたはよいけれど、その後のアップデートがなくてセキュリティ・ホールもそのまま放置、なんてことになるのは非常にまずいです。 ということで、Web でもそこそこ言及の多い三つのリポジトリを選びました。
CentOS ExtrasCentOS の開発者の一人、Karanbir Singh 氏が公開しているリポジトリ。 Fedora Extras から持ってきたパッケージを CentOS 用にパッケージングしたものだそうです。
設定方法はこんな具合。
$ cd /etc/yum.repos.d $ sudo wget http://centos.karan.org/kbsingh-CentOS-Extras.repo
いたって簡単です。
digこちらは Dag Wieers 氏が個人的に公開しているリポジトリ。
氏のリポジトリは理研の FTP サイトでもミラーされているので、日本からはそちらを使うのが吉でしょう。 というわけで、以下のような内容で /etc/yum.repos.d/dag.repo ファイルを作成します。
[dag] name=Dag RPM Repository for Fedora Core baseurl=http://ftp.riken.jp/Linux/dag/redhat/el$releasever/en/$basearch/dag enabled=1 gpgcheck=1
続いて PGP key をインポートします。
$ sudo rpm --import http://ftp.riken.jp/Linux/dag/packages/RPM-GPG-KEY.dag.txtRPMForge前述の Dag 氏のサイトでも紹介されているリポジトリです。 Dag 氏を含む何名かのメンバーが中心になりメンテナンスを行っているようです。
設定には rpmforge-release という RPM パッケージが便利です。 これをインストールすると yum 用にリポジトリ設定ファイルが出来上がります。
$ wget http:// ftp.belnet.be/ packages/ dries.ulyssis.org/ fedora/ fc4/ i386/ RPMS.dries/ rpmforge-release-0.2-2.2.fc4.rf.i386.rpm
$ sudo rpm -i rpmforge-release-0.2-2.2.fc4.rf.i386.rpm
これでいろいろなパッケージをお手軽にインストールできるようになります。 便利便利。 ただし、ちょっと問題もあって、公式リポジトリからインストールしたパッケージが非公式リポジトリのパッケージで上書きされてしまう場合もあります。 ちょっと気持ち悪いけれど、バージョンが進むわけなので良しとするか。
- 001203
さて、ipchains と iptables - 麦酒堂 でも触れたとおり、我が家のルーターが FORWARD 全面停止となりました。 これは不便だ。 不便というか、そもそもクライアント PC から外に出られない。 というわけで、こいつを導入。
HTTP proxy サーバーの Squid である。 これがあれば、少なくとも Web は見られるようになる。 さらに、最近のサービスでは HTTP proxy をトンネルに使っているものもあるので、そういうサービスも使えちゃう(Skype とか)。 素敵、HTTP Proxy。
まずはインストール。 対象ディストリビューションは CentOS 4.5。 我が家の場合はすでにインストールされた状態でしたが、もし入っていない場合は yum などで入れてしまいましょう。
$ rpm -q squid squid-2.5.STABLE14-1.4E # インストールされてますね
# インストールされていない場合は yum で入れます $ sudo yum install squid
続いて設定です。 設定ファイルは /etc/squid/squid.conf にあります。 が、デフォルトのものは長いので、いったん全部消してから必要な設定項目のみを記述しましょう。 参考になるのはこのあたりです。
- Squid Configuration Basics - Squid User's Guide
- Squid 2.6.STABLE16 configuration file
- Squid 2.6 Configuration Manual
今回の環境では Cache としての役割をほとんど期待せず、アクセス制御ポイントを集約する程度の役割しか担わせないことにします。
# Squid が聴くポートを指定 # icp は分散キャッシュ間の調停に使われるもののようなので今回は disabled # --------------------------------- http_port 172.16.100.254:8080 http_port 172.16.200.254:8080 icp_port 0 # QUERY_STRING を含む URI へのアクセスはキャッシュしないことにする # --------------------------------- acl QUERY urlpath_regex cgi-bin \? no_cache deny QUERY # キャッシュに使用するメモリ容量 / ディスク容量 # デフォルトではメモリ 8MB、ディスク 100MB なのだけれど # そんなにいらないのでそれぞれ 2MB / 16MB に変更しました # --------------------------------- cache_mem 2 MB cache_dir ufs /var/spool/squid 16 16 128 # これは "suggested" と書いてあったのでとりあえずそのまま残す # --------------------------------- refresh_pattern ^ftp: 1440 20% 10080 refresh_pattern ^gopher: 1440 0% 1440 refresh_pattern . 0 20% 4320 # アクセス制御 # アクセス先のポートを制限するのだけれど、そもそもこの Linux box は # iptables で outgoing のパケットをかなり絞ってあるので、 # ここでどう設定しようがあまり影響はない。 # ひとまず 80 / 443 はあけておくことにした。 # 相変わらず icp は拒否。 # --------------------------------- acl all src 0.0.0.0/0.0.0.0 acl home src 172.16.100.0/24 acl jail src 172.16.200.0/24 acl localhost src 127.0.0.1/255.255.255.255 acl Safe_ports port 80 # http acl Safe_ports port 443 # https acl SSL_ports port 443 acl CONNECT method CONNECT http_access deny !Safe_ports http_access deny CONNECT !SSL_ports http_access allow home http_access allow jail http_access deny localhost http_access deny all http_reply_access allow all icp_access deny all # メールアドレス、クラッシュ時の core 吐き場所など # --------------------------------- cache_mgr admin@example.net coredump_dir /var/spool/squid
設定が終わったら起動しましょう。
$ sudo /etc/rc.d/init.d/squid start
最後にクライアントの設定を忘れずに。 これで HTTP および HTTP をトンネルするタイプのサービスは使えるようになりました。
- 001202
我が家では Linux box をルーターとして使用していて、iptables でフィルタリングを行っています。 かつて、Linux kernel 2.2 の頃は ipchains を使っていて、当時使っていたフィルター設定スクリプトに少しずつ手を入れながら今もそれで設定を行っています。
で、本日驚愕の事実が。 ipchains と iptables とでは built-in のチェーンがいろいろと変更されているのですが、その変更にきちんと追随できておりませんでした。 いやー、自分でもびっくりした。 あれだけ言われていたのに。 そしてその仕組みを、自分ではきちんと理解していたつもりだったのに。
具体的に説明しましょう。 ipchains 時代は INPUT-FORWARD-OUTPUT が一本道になっていて、INPUT チェーンと OUTPUT チェーンをがっちり締めておけば IP masquerading も堅くなる仕組みでした。 ぼくの使っていたスクリプトも、もちろんこの仕組みをベースにして作成されていました。 ところが、iptables になると INPUT-OUTPUT と FORWARD が分離されて(ほかにいくつかテーブルも追加されて)、FORWARD の前後で INPUT-OUTPUT のフィルターが適用されなくなりました。 つまり FORWARD 自体をがっちり締めないと丸裸。 IP masquerading があるので完全な素通しではないけれど、意図しないパケットが外向きに出て行ってしまう危険性があります。
というわけで、早急に対策を施しました。
# フォワードする UDP のポート T="" HOME_UDP_FORWARD=${T} # フォワードする TCP のポート T="" HOME_TCP_FORWARD=${T} # フォワードする UDP のポート T="" JAIL_UDP_FORWARD=${T} # フォワードする TCP のポート T="" JAIL_TCP_FORWARD=${T} # チェーンの追加 ${IPTABLES} -N FORWARD_HOME ${IPTABLES} -N FORWARD_JAIL function forward { PROTOCOL=$1 CHAIN=$2 USING_PORTS=$3 ## 使用サービスの outgoing (request) パケット for port in ${USING_PORTS}; do ${IPTABLES} -A ${CHAIN} -p ${PROTOCOL} --dport ${port} -j ACCEPT done } # FORWARD チェーンの振り分け設定 ${IPTABLES} -P FORWARD DROP ${IPTABLES} -A FORWARD -s ${HOME_NETWORK} -j FORWARD_HOME ${IPTABLES} -A FORWARD -s ${JAIL_NETWORK} -j FORWARD_JAIL ${IPTABLES} -A FORWARD -m conntrack ! --ctstate ESTABLISHED -j LOGGED_DROP # ########## # FORWARD_HOME echo configuring FORWARD_HOME chain... ## UDP forward "udp" "FORWARD_HOME" "${HOME_UDP_FORWARD}" ## TCP forward "tcp" "FORWARD_HOME" "${HOME_TCP_FORWARD}" ## ICMP ## termination ${IPTABLES} -A FORWARD_HOME -j LOGGED_DROP # ########## # FORWARD_JAIL echo configuring FORWARD_JAIL chain... ## UDP forward "udp" "FORWARD_JAIL" "${JAIL_UDP_FORWARD}" ## TCP forward "tcp" "FORWARD_JAIL" "${JAIL_TCP_FORWARD}" ## ICMP ## termination ${IPTABLES} -A FORWARD_JAIL -j LOGGED_DROP結局やっていることは、FORWARD の全拒否です。 "JAIL" "HOME" などは以下のエントリの "UNKNOWN" "KNOWN" と同等です。
経験を過信するのは恐ろしい、と再認識した次第です。
- 001061
Linux に samba を立ててファイルサーバーにしました。
要件は以下の通り。
- ホーム・ディレクトリは所有ユーザーのみが読み書き可能
- "ro" ディレクトリは任意ユーザーが読み取り可能(書き込みは出来ない)
- "rw" ディレクトリは認証済みユーザーのみがそのユーザー権限で読み書き可能
samba の設定は smb.conf ファイルに記述されています。 swat などの便利ツールは今回使用しませんでした。 勇ましく設定ファイルの直接編集で。
smb.conf - 全体の設定最初に samba 全体の設定を行います。
所属するワークグループとサーバーの説明を設定します。
workgroup = example.com server string = Samba Server %v@%h
samba がポートを開くインタフェースと接続を許可するホストを指定します。
interfaces = 192.168.100.0/24 hosts allow = 192.168.100. 127.
プリンタは使用しません。
; printcap name = /etc/printcap ; load printers = yes ;cups options = raw
名前解決関連の設定を行います。 このサーバーの名前解決順は以下の通りです。
- WINS サーバーに問い合わせる
- lmhosts ファイルを参照する
- ブロードキャストにより問い合わせる
また、WINS サーバーとして振舞います。
name resolve order = wins lmhosts bcast wins support = yes
ユーザー認証関連の設定です。 認証を通っていないユーザーはゲスト扱いで、ゲストは UNIX アカウント "nobody" として扱われます。 ユーザー認証に使用するパスワードは暗号化されて "/etc/samba/smbpasswd" ファイルに格納します。
map to guest = bad user guest account = nobody encrypt passwords = yes smb passwd file = /etc/samba/smbpasswd
smb.conf - home の設定まずはユーザーのホーム・ディレクトリの共有設定です。 このあたりは samba の決り文句的な設定になります。
[homes] comment = Home Directories browseable = no public = no guest ok = no writable = yes create mask = 0644 directory mask = 0755 hosts allow = 192.168.100.0/24smb.conf - 読取専用の設定続いて読取専用ディレクトリの共有設定です。 "guest ok" としているので誰でも参照できますが "writeable = no" により書き込みは行えません。
[ro] comment = Read Only Directory path = /var/ro guest ok = yes guest account = nobody writable = no hosts allow = 192.168.100.0/24smb.conf - 読み書き可能の設定最後に読み書き可能なディレクトリを設定します。
[rw] comment = Read Write Directory path = /var/rw public = no guest ok = no writable = yes create mask = 0644 directory mask = 0755 hosts allow = 192.168.100.0/24ここで注意しなければならないのは「書き込まれたファイルは誰のもの?」というパーミションの問題。 認証を通ったユーザーは誰でも書き込み可能なので 777 にしておく必要がありそうです。 しかし単純にそう設定すると、たとえばユーザーAが作成したファイルをユーザーBが削除できてしまいます。 これを避けるために、Linux では sticky bit を使用することができます。 /tmp などにも用いられているもので、これが立っているディレクトリではファイルの所有者とディレクトリの所有者以外はファイルを削除できません。 sticky bit の本来の意味からは離れているようですがこの際気にしません。
$ sudo mkdir /var/rw $ sudo chmod 1777 /var/rw $ ls -dl /var/rw drwxrwxrwt 3 root root 4096 Feb 7 00:06 /var/rw
others の実行権限部分が "t" になっているのが sticky bit が立っている状態です。
smbpasswd の設定認証が必要なユーザーのパスワードを設定します。
$ sudo smbpasswd -a user001 New SMB password: <password> Retype new SMB password: <password> Added user user001.
動作確認samba を起動して Windows マシンでエクスプローラから "\\example.com\rw" などを開きファイルを参照 / 作成 / 削除できることを確認します。
$ sudo /etc/rc.d/init.d/samba start
- 001054
最近 HTML をちくちくといじる事が多いので、HTML の書式チェッカーを手元に置きたくなりました。 で、これをインストール。
インストール手順は以下のような感じでした。 すでに Apache は動いているという前提で、CGI モードで動作させるよう設定しています。
ファイルの入手以下から htmllint.zip をダウンロードします。
ファイルの展開ファイルを展開します。 カレント・ディレクトリにフラットにどばっと吐かれるので、ひとつディレクトリを掘っておきます。
$ cd /var/web $ mkdir htmllint $ cd htmllint $ unzip ~/htmllint.zip
Another HTML-lint の設定変更設定ファイルを用意します。 サンプル設定のコピーで充分です。
$ cp htmllintenv htmllint.env必要に応じて *.cgi ファイルの Perl のパスを変更します。
#!/usr/bin/perl
*.cgi ファイルを実行可能にします。
$ chmod +x *.cgiApache の設定変更Apache の適当な VirtualHost に以下の設定を追加します。
Alias /htmllint /var/web/htmllint <Location /htmllint> AddDefaultCharset iso-2022-jp Options +ExecCGI AddHandler cgi-script .cgi </Location>htmllint が吐く HTML は iso-2022-jp でエンコードされているので "AddDefaultCharset" で指定します。 また、拡張子 "cgi" を持つものは CGI として扱うように設定しています。
動作確認Apache を再起動して http://example.com/htmllint/ など適切な URI にアクセスします。
で、まずは手始めに麦酒堂をチェックしたところ、あちらこちらにほころびが……。 直すの面倒くさいなぁ。
- 001041
メール関連セットアップ の続き。 ぼくが契約している ISP では Outbound Port25 Blocking を実施しています。
まぁ、最近多いですよね。 これまでの設定(qmail使用)ではこの規制に引っかかったことがなかったので全く気にしていなかったのですが、Postfix で運用を開始したとたんに引っかかってしまいました。 何故。
引っかかってしまったものは仕方がないので対策を考えます。 ISP の Web サイトをよく読んでみると、以下の二つの手の併用で抜けられるようです。
- 外に出て行くメールをすべて ISP の SMTP サーバーにリレーさせる
- ISP の SMTP サーバーに接続する際に SMTP Auth を使う
一つ目は既に設定済みなので、さっそく Postfix に SMTP Auth の設定を行います。
Postfix での SMTP Auth の設定は、以下のドキュメントに詳しく書かれています。
main.cf の設定SMTP で接続する場合に SMTP Auth を使うように設定します。 "smtp_sasl_password_maps" は使用するパスワードを指定するファイル(後述)です。
smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd smtp_sasl_type = cyrus
パスワードの指定SMTP Auth に使用するパスワードをファイルに保存します。 ファイル名は先ほど指定したものです。 接続先の SMTP サーバーごとに使用するパスワードを切り替えられますが、今回は外に出てゆくすべてのメールを同一のの SMTP サーバーに渡すのでエントリは一行だけです。
[<SMTP サーバー名>] <アカウント名>:<パスワード>
SMTP サーバー名 / アカウント名 / パスワードは ISP から指定されたものを使います。 アカウント名 / パスワードは POP のものと同一とは限らないのでご注意を。
いつものごとく postmap にて形式変換を行います。
$ postmap /etc/postfix/sasl_passwd設定反映Postfix に設定を読み込ませます。
$ /etc/rc.d/init.d/postfix reload
- 001040
メール関連セットアップ の最後。 Web Mail 環境を構築します。 外出時も自宅メールをチェックできるので重宝します。 CentOS 4.4 には SquirrelMail が含まれているのでこれを利用します。
再度繰り返しになりますが、要件は以下の通り。
- UNIX アカウントAに届いたメールは POP / IMAP (WebMail) の双方で「独立して」アクセスできる。 POP 側でメールを削除しても IMAP 側に影響を与えない。逆もまた然り。
- 非 UNIX アカウントBに届いたメールは他ドメインのアカウントB'に転送する。
- 非 UNIX アカウントCに届いたメールは IMAP (WebMail) でのみアクセスできる。
このうち要件1,3に書かれている IMAP アクセスを Web Mail から利用できるように設定します。
参考リンクです。
SquirrelMail の公式サイトです。 以前のバージョンでは UNIX コマンドで各種設定を行っていたのですが、現在のバージョンは Web のインタフェースから大部分の設定を行うことが出来ます。
インストールSquirrelMail がインストールされていることを確認します。
$ rpm -qa | grep -i squirrelmail squirrelmail-1.4.8-2.el4.centos4インストールされていない場合は何らかの方法でインストールします。 以下は yum を利用した場合の例です。
$ sudo yum install squirrelmailパーミションの設定CentOS 4.4 の標準では Apache を apache ユーザーで実行するように設定されていますが、ぼくの環境では www ユーザーで実行するようになっています。 そのため、いくつかのファイル / ディレクトリについて所有者を変更する必要がありました。
$ sudo chown -R www:www \ > /var/spool/squirrelmail/attach $ sudo chown -R www:www \ > /var/lib/squirrelmail/pref $ sudo chgrp -R www /etc/squirrelmail/
設定変更今回の環境では特に設定すべきことはないのですが、設定の方法だけを一応ご説明します。
$ sudo /usr/share/squirrelmail/config/conf.pl SquirrelMail Configuration : Read: config.php (1.4.0) --------------------------------------------------------- Main Menu -- 1. Organization Preferences 2. Server Settings 3. Folder Defaults 4. General Options 5. Themes 6. Address Books 7. Message of the Day (MOTD) 8. Plugins 9. Database 10. Languages D. Set pre-defined settings for specific IMAP servers C Turn color off S Save data Q Quit Command >>たとえば IMAP サーバーとは別のノードに SquirrelMail を立てる場合などは "2. Server Settings" > "A. Update IMAP Settings" を変更します。
ターミナルの設定によっては設定値が読めない場合があります。 その場合は "C Turn color off" を選択して色設定をオフにしてください。Apache の起動CentOS 4.4 の SquirrelMail はインストール直後に既に Apache の設定が完了しています。 ひとまず何も設定を変更せずに Apache を起動します。 この際、インターネット接続を切っておくことをおすすめします。
$ sudo /etc/rc.d/init.d/httpd start動作確認SquirrelMail の動作を確認します。 ブラウザから http://example.com/webmail にアクセスします。

IMAP アカウントとパスワードを入力してログインします。

自アカウント宛にメールを送るなどして正常に機能することを確認します。

アカウントごとの設定SquirrelMail 1.4.8-2 では Web から様々な設定を行うことが出来ます。 日本語を扱えるようにするには "Options" > "Display Preferences" > "Language" の値を "Japanese" に変更します。


他にも設定項目がいろいろあるので、必要に応じて設定を変更しておきます。
以上で SquirrelMail の設定は完了です。 ただ、この状態だとパスワードがプレーン・テキストで流れてしまうので必要に応じて SSL と組み合わせて利用してください。
- 001039
メール関連セットアップ の第二弾。 Postfix の設定に続いては POP3 / IMAP サーバーの設定です。 CentOS 4.4 に含まれる標準 POP3 / IMAP サーバーは Dovecot となります。 バージョンは 0.99.11 です。 このバージョンではぼくが使いたい機能の一部(APOPなど)が未実装ですが、1.0.x では実装される予定なので今後に期待して標準品をそのまま使用します。
繰り返しになりますが、要件は以下の通り。
- UNIX アカウントAに届いたメールは POP / IMAP (WebMail) の双方で「独立して」アクセスできる。 POP 側でメールを削除しても IMAP 側に影響を与えない。逆もまた然り。
- 非 UNIX アカウントBに届いたメールは他ドメインのアカウントB'に転送する。
- 非 UNIX アカウントCに届いたメールは IMAP (WebMail) でのみアクセスできる。
要件2は IMAP / POP3 には関係ありません。 要件1,3について設定を進めてゆきます。 要件1は二箇所(~/Maildir と ~/Webmail)に配信されたメールをそれぞれ別のアカウントを用意してアクセスできるように設定します。 ただし UNIX アカウントを追加するのは好ましくないので、Dovecot の passwd-file を利用することにします。 要件3についても同様です。
参考リンクです。
但し、上記サイトの記述は Dovecot 1.0.x のものになっています。 0.99.11 には適用できない説明もあるのでご注意ください。 正確を期するためには /usr/share/doc/dovecot* 以下にインストールされたドキュメントを参照してください。
今回の設定のキモは passwd-file の記述方法です。 取り立てて複雑な設定を行っているわけではないのですぐに設定が完了するはずです。
では、以下手順です。
インストールSquirrelMail がインストールされていることを確認します。
$ rpm -qa | grep -i squirrelmail squirrelmail-1.4.8-2.el4.centos4インストールされていない場合は何らかの方法でインストールします。 以下は yum を利用した場合の例です。
$ sudo yum install squirrelmailプロトコルの設定Dovecot が使用するプロトコルを設定します。 設定ファイル /etc/dovecot.conf を編集して以下の設定を行います。
protocols = imap pop3
認証 / ユーザー情報の設定認証 / ユーザー情報を設定します。 設定ファイル /etc/dovecot.conf を編集して以下の設定を行います。
auth_userdb = passwd-file /etc/dovecot.passwd auth_passdb = passwd-file /etc/dovecot.passwd
"auth_userdb" はユーザー名やMaildir の場所などの問い合わせ先です。 次項で定義する passwd-file を指定します。 "auth_passdb" はパスワードの問い合わせ先です。 デフォルトでは PAM を使用するようになっていますが、今回はすべてのユーザー情報を passwd-file に集約します。
passwd-file の設定今回の設定のキモ、passwd-file の設定です。 前項で passwd-file のパスを "/etc/dovecot.passwd" と指定しました。 このファイルを以下の内容で作成します。
Apop3:{md5}xx:1000:1000::/home/A/::userdb_mail=maildir:/home/A/Maildir Aimap:{md5}xx:1000:1000::/home/A/::userdb_mail=maildir:/home/A/Webmail C:{md5}xx:5000:5000::/home/vmailbox/::userdb_mail=maildir:/home/vmailbox/C各フィールドの説明です。
1 アカウント名 2 パスワード(PLAIN-MD5 使用時のパスワード文字列生成方法は後述) 3 uid。要件3のアカウントには Postfix の設定時に作成した vmailbox ユーザーの uid を指定します。 4 gid。要件3のアカウントには Postfix の設定時に作成した vmailbox ユーザーの gid を指定します。 5 - 6 ホーム・ディレクトリ(上記 uid / gid の権限でアクセスできること) 7 - 8 各種オプション。今回の設定ではここでメール・ボックスの場所を指定する。 パスワード文字列は以下のコマンドで生成できます。
$ md5sum --string=<パスワード文字列>コマンド履歴に残したくない場合は以下のような方法もあります。
$ md5sum --string=`cat` <パスワード文字列>^M ^D
起動 / 動作確認Dovecot を起動します。
$ sudo /etc/rc.d/init.d/dovecot startPOP3 / IMAP を話す MUA を使用して動作を確認してください。 "MTA / MDA - Postfix のセットアップ" で送信したテスト・メールが参照できれば問題ありません。
- 001038
メール関連セットアップ - overview でも書いた通り、以下の要件を満たすべくまずは MTA / MDA として Postfix のセットアップを行います。
- UNIX アカウントAに届いたメールは POP / IMAP (WebMail) の双方で「独立して」アクセスできる。 POP 側でメールを削除しても IMAP 側に影響を与えない。逆もまた然り。
- 非 UNIX アカウントBに届いたメールは他ドメインのアカウントB'に転送する。
- 非 UNIX アカウントCに届いたメールは IMAP (WebMail) でのみアクセスできる。
それぞれの要件について、メールをメールボックスに届けるまでは MTA / MDA の役割になります。 要件1については Postfix は通常どおりメールを配送し、その後 procmail で二つのメールボックスに同時に配信します。 要件2については Postfix の virtual alias 機能を利用して転送します。 要件3については Postfix の virtual map 機能を利用して特定のディレクトリに配信します。
以下、説明となります。 以降の説明ではドメインとして example.com を用います。
最初に参考リンクです。
最低でも Architecture Overview の "How Postfix receives mail" と "How Postfix delivers mail" は事前に目を通しておくべきです。 Postfix のメール配信の流れ / 各デーモンの機能が説明されており、これを把握しておくと設定項目の理解が格段に深まるはずです。 それら設定項目の個別の説明は Configuration Parameters に詳しいです。 また、要件2,3で非 UNIX アカウントを処理するために利用する Virtual 系の設定は Virtual Domain Hosting Howto で詳しく説明されています。 Address Rewriting ではメール送受信時のさまざまなタイミングで、エンベローブとヘッダのアドレス情報をどのように加工できる / 加工されるかを詳しく説明しています。 一般的な Postfix の設定は "/etc/postfix/main.cf" ファイルが主となりますが、今回はいくつかの設定ファイルを追加します。 これらの設定ファイルの中身、設定ファイル処理コマンドなどは Manual Pages に記載されています。
インストールPostfix がインストールされていることを確認します。
$ rpm -qa | grep -i postfix postfix-2.2.10-1.RHEL4.2もし存在しなければ何らかの方法でインストールします。 以下は yum を利用した場合の例です。
$ sudo yum install postfixMTA の切り替えCentOS 4.4 では MTA として Postfix と Sendmail を選択できるようになっています。 デフォルトでは Sendmail が起動しているので、停止した後に Postfix に切り替えます。
最初に Sendmail を停止します。
$ /etc/rc.d/init.d/sendmail stop続いて MTA を切り替えます。
$ sudo /usr/sbin/update-alternatives --config mta There are 2 programs which provide 'mta'. Selection Command ----------------------------------------------- *+ 1 /usr/sbin/sendmail.sendmail 2 /usr/sbin/sendmail.postfix Enter to keep the current selection[+], or type selection number: 2
基本的な設定Postfix を動かすにあたっての基本設定です。 主にメール・アドレスの "@" 以降に関する設定です。 各設定項目の詳細は "Postfix Configuration Parameters" を参照してください。
# 自サーバー名です myhostname = mailserver.example.com # 自サーバーのドメイン名です mydomain = example.com # メール・アドレスの補完などに使用されるドメイン名です myorigin = $mydomain # Postfix が聴くインタフェースです inet_interfaces = all # 自サーバーが最終処理を行う必要のあるドメイン名です mydestination = $mydomain, $myhostname, localhost.$mydomain, localhost(実際は一行)
上流 SMTP の設定野良 SMTP サーバーからの接続を受け付けない SMTP サーバーが世には存在するため、外部に送るメールは一度プロバイダの SMTP を経由させます。 外部に送るメールは smtp(8) が処理します。 main.cf に以下の行を追加します。
default_transport = smtp:[<プロバイダの SMTP サーバー>]
"[]" で囲まないと SMTP サーバーの指定ではなくドメイン名の指定と見なされ、MX レコードによる解決が行われてしまいます。 必ず "[]" で囲みましょう。
ローカル配信に procmail を使用するための設定ローカル配信は local(8) がキックします。 デフォルトでは所定のファイルに書き出されるのですが、処理を渡す外部コマンドを mailbox_command により設定することも可能です。 main.cf に以下の行を追加します。
mailbox_command = /usr/bin/procmail
そして各 UNIX アカウントのホーム・ディレクトリに procmail のレシピ・ファイル ~/.procmail を作成します。 今回は "~/Mailbox/" (POP3用)と "~/Webmail/"(IMAP用)の二箇所にメールを配信するので以下のような具合です。
:0 c ${HOME}/Webmail/ :0 ${HOME}/Maildir/メールを受信する各 UNIX アカウントの権限で配信先ディレクトリを作成します。
$ mkdir ~/Mailmail $ mkdir ~/Webmail
非 UNIX アカウント宛のメールの設定(転送)特定のアドレスに届いたメールを他ドメインに転送するには virtual_alias_map が利用できます。 この設定は cleanup(8) の挙動に影響を与えます。 値にはアカウントのマッピングを記述したマップ・ファイルのパスを指定します。 マップ・ファイルの詳細はvirtual(5) に記述されています。
virtual_alias_maps = hash:/etc/postfix/virtual
マップ・ファイル(/etc/postfix/virtual)は以下のように設定します。 "B@example.com" 宛のメールを他ドメインの "B'@otherdomain.example.net" に転送する設定です。
B@example.com B'@otherdomain.example.net
マップ・ファイルを編集した際には以下のコマンドが必須です。
$ sudo postmap /etc/postfix/virtual非 UNIX アカウント宛のメールの設定(IMAP 用ローカル配信)非 UNIX アカウント宛メールを IMAP でアクセスさせるためには別エントリで後述予定の Dovecot の機能と組み合わせる必要があります。 大まかな流れは以下の通りです。
- Postfix の Virtual Alias 機能により対象メールのエンベローブを書き換える。具体的には、メールの宛先を次の Virtual Domain 機能の適用対象となるように変更する。
- Postfix の Virtual Domain 機能により変更後のメールを捕捉 / 受信 / 指定したディレクトリに配信する。
- Dovecot にて上記配信先ディレクトリを当該ユーザーのメール・ボックスとして扱う
ここではこのうちの 1,2 について説明します。
最初に Virtual Alias 機能です。 これは前項でも説明しているので詳細は割愛します。 設定のキモは内部的な一時ドメイン(ここでは仮に "vmailbox.example.com" とする)の利用です。
C@example.com C@vmailbox.example.com
$ sudo postmap /etc/postfix/virtualこの設定で C@example.com 宛のメールのエンベローブが内部的に C@vmailbox.example.com に書き換えられ incoming キューに入ります。
続いて Virtual Domain の設定です。 Virtual Domain は virtual(8) により処理されます。 main.cf に以下の設定を追加します。
virtual_mailbox_domains = vmailbox.example.com virtual_mailbox_base = /var/spool/postfix/vmailbox virtual_mailbox_maps = hash:/etc/postfix/vmailbox virtual_minimum_uid = 100 virtual_uid_maps = static:5000 virtual_gid_maps = static:5000
1行目で Virtual Domain として扱うドメイン名 "vmailbox.example.com" を指定しています。 2行目はメールの保存先となるディレクトリ名です。 このディレクトリ以下にアカウントごとのディレクトリが掘られます。 3行目は Virtual Domain のアカウントを定義している設定ファイルを指定しています。 4~6行目はメールを保存する際に使用する uid / gid の指定です。
ユーザー / グループを追加し保存先ディレクトリを作成します。
$ sudo groupadd -g 5000 vmailbox $ sudo useradd -g vmailbox -d /dev/null \ > -s /bin/false -u 5000 vmailbox $ sudo mkdir /var/spool/postfix/vdomain $ sudo chown vmailbox:vmailbox \ > /var/spool/postfix/vdomain
Virtual Domain のアカウント設定するためにマッピングファイル(/etc/postfix/vmailbox)を作成し postmap コマンドで処理します。 マッピング・ファイルはアカウント名と保存先ディレクトリの組です。 保存先ディレクトリは上で指定した virtual_mailbox_base からの相対パスとして処理されます。
C@vmailbox.example.com C/
$ sudo postmap /etc/postfix/vmailbox起動と動作確認Postfix を起動します。
$ sudo /etc/rc.d/init.d/postfix start簡単な動作確認を行います。 尚、"^D" は Ctrl+D、"^M" は Ctrl+Mです。
最初に A@example.com 宛のメールです。 ~A/Mailbox と ~A/Webmail の双方にメールが届けば問題ありません。
$ mail A@example.com Subject: Test Mail 1 Test Mail 1 ^D Cc: ^M $ find ~A/Mailbox $ find ~A/Webmail
B@example.com 宛のメールです。 指定した外部のメール・アカウントに届けば問題ありません。
$ mail B@example.com Subject: Test Mail 2 Test Mail 2 ^D
最後に C@example.com 宛のメールです。 設定どおりのディレクトリに届けば問題ありません。
$ mail C@example.com Subject: Test Mail 3 Test Mail 3 ^D $ sudo find /var/spool/postfix/vmailbox/C
以上でメールの配信 / 配送の設定が完了しました。 大規模環境などでは "Postfix Performance Tuning" などの設定を行う必要があるのでしょうが、今回はそこまで気にする必要はないため割愛です。
- 001037
年末年始の長期休暇を利用してサーバー環境を Dell PowerEdge SC430 上の CentOS 4.4 に移行しています。 いくつかのサービスを移行した中でもっとも難航したのがメール関連。 これまでは qmail を使用していましたが、公開サービスは RPM で管理しまうのがなにかと便利なので CentOS 4.4 標準の Postfix に乗り換えることにしました。 ただメール絡みの要件が少々厄介で、以下のような具合です。
- UNIX アカウントAに届いたメールは POP / IMAP (WebMail) の双方で「独立して」アクセスできる。 POP 側でメールを削除しても IMAP 側に影響を与えない。逆もまた然り。
- 非 UNIX アカウントBに届いたメールは他ドメインのアカウントB'に転送する。
- 非 UNIX アカウントCに届いたメールは IMAP (WebMail) でのみアクセスできる。
"UNIX アカウント" は当該マシンに存在する(/etc/passwd にエントリがある)ユーザー、"非 UNIX アカウント" はその逆で当該マシンに存在しない(/etc/passwd にエントリがない)ユーザーを指します。 個々にはそれほど複雑な要件ではないのですが、どのソフトウェアのどの機能をどのように利用すれば実現できるのかを見極めるところでなかなか苦戦しました。
セットアップ手順はそれぞれ以下のような別エントリに分けます。
- 001018
半ば死蔵されかかっている Dell PowerEdge SC430 に火を入れるべく、まずは形からということで HDD を増強しました。 購入したのは容量単価が非常に低い Seagate Barracuda 7200.10 の 320GB です。
RAID を組むためにこれを二台と、接続するための SATA 用ケーブルを購入。 一時期、購入半年で HDD がバタバタと死んでゆく経験をしたため、HDD には500円の追加で10ヶ月保証をつけておきました。 ケーブルは Dell PowerEdge SC430 の HDD 取り付け位置から考えて、片側L字コネクタを選択。
HDD メーカー Seagate 型番 Barracuda 7200.10 (ST3320620AS) インタフェース SATA II (3Gb/s) 容量 320GB 速度 7,200rpm キャッシュ 16MB SATA ケーブル メーカー Ainex 型番 SAT-3007LBL インタフェース SATA ケーブル長 70cm コネクタ 片側L字(ラッチなし) 我が家には Dell PowerEdge SC430 が二台あるので、既存の2台の HDD を片側に寄せて、購入した2台を空いたマシンに載せました。 ケーブルは、既存 HDD を真似て取り回そうとすると 70cm では微妙に足りませんでした。 ただ、コネクタの形状は正解。 ストレート型のコネクタだと間違いなくケースと干渉するし、ラッチ付だと M/B 側のコネクタが干渉しそう。
さぁ、投資した分使うぞ。
- 000894
ぼくの自宅環境では DHCP サーバーが稼動しているので、ハブに PC をつなぐだけでインターネット環境に出られるようになっています。 これまでは既存の自宅 LAN に直接参加させていたのですが、セキュリティ上はあまり好ましくない状況です。 そこで今回、dhcp による IP アドレスのアサインと iptables によるフィルタリングを組み合わせることで、登録されていない PC は仮想的に分離された別の LAN に参加させるように設定します。
今回の設定で実現できる動作今回の設定では以下のような振る舞いを実現します。
PC をハブにつなぐと、自動的に IP アドレスなどの情報が設定されます。 この情報を用いることでインターネットへの NAPT 経由のアクセスが可能となります。 さらに、登録済みの PC の場合は自宅 LAN 内のサービスを利用できます。 しかし、登録していない PC からは自宅 LAN へは接続できません。基本アイディアはシンプルで、同一の Ethernet セグメントに異なる IP サブネットワークを重畳させることで仮想的な分離を実現します。 一方のサブネットワークは通常の LAN で、比較的自由に振舞うことのできる環境です。 LAN 内のサーバーが提供する各種サービスはすべて利用可能です。 もう一方のサブネットワークは制限された LAN で、インターネットに出ることのみに行動を制限します。 LAN 内のサービスは(DHCP / DNS など必須のもの以外は)利用できません。 互いのサブネットワーク間の IP による通信はすべて禁止とします。
同一の Ethernet に二つの IP サブネットワークが載っている状態は慣れないと直感的には理解しにくいかもしれませんが、Ethernet と TCP/IP のプロトコル・スタックはこういったことができるような設計になっています(詳細はここでは取り上げませんが、ARP が今回の構成のキモとなります)。 しかし、ある程度ネットワークの知識のある方なら思い当たるでしょうが、この構成にはいくらでも抜け穴があります。 制限された LAN の中でも、もう一方の LAN で使用している IP アドレスを覗き読むことが可能です。 IP アドレスがわかれば、DHCP に頼らずに直接 NIC にアドレスを指定でき、もう一方の LAN に入ってゆけます。 インターネット層よりも上での分離なので、これは仕方のないことです。 完全な分離を目指すのであれば他の方法を検討すべきでしょう。 ここではあくまでも、自宅 LAN へ参加する障壁を高くすることでリスクを少しでもおさえることを目的とします。
必要なツール / コマンド / 機能Linux Kernel 2.6 の機能を使用しますので、相応のディストリビューションを用意します。 その他に以下のツール / 機能も使用します。
- IP alias
- IP alias を使用すると、ひとつの NIC に複数の IP アドレスを割り当てることができます。Linux Kernel の機能で、ifconfig コマンドで設定することが可能です。
- dhcpd
- ネットワーク関連の設定を自動化するデーモンです。登録の有無を判断してクライアントPCを適切なサブネットワークに所属させるために使用します。
- iptables
- Linux の IP パケットフィルタリング・ルールの制御を行うコマンドです。各サブネットワークに適切なサービスのみを提供し、サブネットワーク間の通信を制御するために使用します。
これらを組み合わせることで、LAN の仮想的な分離を実現します。 Kernel コンパイルのコンフィギュレーションによっては iptables / IP alias が機能しないかもしれません。 その場合は insmod でモジュールを読み込むか、設定を変更して Linux Kernel の再構築を行ってください。
それぞれのコマンドについてのリファレンスをご紹介します。
- Setting up IP Aliasing on A Linux Machine Mini-HOWTO - JF
- Manpage of dhcpd-options - JM
- Manpage of IPTABLES - JM
iptables については、コマンドそのものよりも Linux の IP パケットフィルタリングについてきちんと理解しておくことが非常に重要です。 その目的には、以下のドキュメントは非常に役立ちます。 TCP/IP の基礎のお勉強にもなりますのでざっと目を通してください。。
- Iptables Tutorial 1.2.0
- Iptablesチュートリアル 1.2.0(Tatsuya Nonogaki 氏による日本語訳)
想定する構成以降の説明では各ネットワークを以下のように想定します。
目的 Subnet NIC GLOBAL 0.0.0.0/0 ppp0 自宅 LAN 172.16.100.0/24 eth0 制限された LAN 172.16.200.0/24 eth0:0 NIC に複数の IP アドレスを割り当てる設定ファイル /etc/sysconfig/network-scripts/ifcfg-eth0:0 を以下の内容で作成します。 ifcfg-eth0 を雛形にすると良いでしょう。
DEVICE=eth0:0 BOOTPROTO=static BROADCAST=172.16.200.255 IPADDR=172.16.200.254 NETMASK=255.255.255.0 NETWORK=172.16.200.0 ONBOOT=yes TYPE=Ethernet続いて eth0:0 を有効化します。
# ifup eth0\:0ifconfig などで 172.16.200.254 のアドレスを持つ NIC を確認してください。
dhcpd の設定多くの Linux で採用されている ISC の dhcpd は、設定ファイルにマッピング情報をもつことで、NIC の MAC アドレスから割り当てる IP アドレスを判断することが出来ます。 設定ファイルにマッピング情報が登録されていない PC (正確には NIC)は “unknown-clients” として扱われます。 この機能を利用すると、登録済みの PC と未登録の PC とで割り当てる IP アドレスを切り分けることが可能になります。 設定ファイルは /etc/dhcpd.conf となります。 まず、登録済み PC に対する設定を行いましょう。
pool { deny unknown-clients; range 172.16.100.1 172.16.100.253; option subnet-mask 255.255.255.0; option broadcast-address 172.16.100.255; option routers 172.16.100.254; option domain-name-servers 172.16.100.254; default-lease-time 86400; max-lease-time 2592000; host registered01 { hardware ethernet 00:11:22:33:44:55; fixed-address 172.16.100.1; } }1行目で未登録 PC への IP アドレス割り当てを拒否しています。 以降は 172.16.100.0/24 のサブネットワークの設定です。 最後に記述のある “host ~” の部分が PC の登録となります。 NIC の MAC アドレスと割り当てる IP アドレスの対が記述されていますね。
続いて、未登録 PC に対する設定です。
pool { allow unknown-clients; range 172.16.200.1 172.16.200.127; option subnet-mask 255.255.255.0; option broadcast-address 172.16.200.255; option routers 172.16.200.254; option domain-name-servers 172.16.200.254; default-lease-time 300 ; max-lease-time 300 ; }こちらは未登録 PC の接続を許可しています。 未登録のものはこちら側の pool から IP アドレスを割り当てられるので、172.16.200.0/24 を使用することになります。
以上の設定を含む dhcpd.conf 全体のサンプルは以下となります。
この設定により、登録済みの PC と未登録の PC は分離されたサブネットワークに所属することになります。
iptables の設定続いて、サブネットワークごとに提供サービスを切り分ける構成を iptables によるフィルタリングで実現します。 最初に各ネットワークに便宜上の名前をつけます。
名前 NIC Subnet 概要 GLOBAL ppp0 0.0.0.0/0 いわゆるインターネット。 KNOWN eth0 172.16.100.0/24 登録済み PC が参加するネットワーク。GLOBAL への NAPT および LAN 内のサービスを全て利用可能。 UNKNOWN eth0:0 172.16.200.0/24 未登録 PC が参加するネットワーク。GLOBAL への NAPT は制限なく利用できるが、LAN 内のサービスは一部を除いて利用不可。 繰り返しになりますが、iptables を利用する前に以下にざっと目を通しておいてください。 TCP/IP プロトコル・スイートの基本的な動作と、Linux の IP パケット・フィルタリングの動作原理を理解していないと iptables を使いこなすのは難しいでしょう。
- Iptables Tutorial 1.2.0
- Iptablesチュートリアル 1.2.0(Tatsuya Nonogaki 氏による日本語訳)
特に“Chapter 6. Traversing of tables and chains(日本語訳:テーブルとチェーンの道のり)”が重要です。 3つのテーブルと、それぞれのテーブルに属するビルトイン・チェーンの役割分担はしっかりと理解してください。 ipchains 時代を知る人が陥りがちなのが、転送パケットには INPUT / OUTPUT が適用されない点。 転送パケットは PREROUTING / FORWARD / POSTROUTING のみが適用され、INPUT / OUTPUT が適用されるのは当該 Linux Box 自身が発信元 / 送信先であるパケットのみです。 ipchains は転送パケットを INPUT => FORWARD => OUTPUT と処理していたため、これを想定すると iptables では痛い目を見ます。 ご注意ください。
これ以降、これら 3 つのテーブル、5 種類のビルトイン・チェーンに対して、ユーザー定義チェーンとルールを追加することで、様々なフィルタリングを実現します。
iptables 実行時の注意iptables を実行する際はスクリプトなどで一括設定を行いましょう。 実環境にて手作業でチクチクと設定変更を行うと、その過程で一時的にセキュリティが低下するタイミングが発生する恐れがあります。 さらに、スクリプト言えども0秒で設定が完了するわけではありません。 スクリプトの最初に以下の3行を入れておきましょう。
iptables -I INPUT -j DROP iptables -I OUTPUT -j DROP iptables -I FORWARD -j DROP
これは、パケットの出入りと転送全てを停止します。 そして最後に以下の3行で停止状態を解除します。
iptables -D INPUT -j DROP iptables -D OUTPUT -j DROP iptables -D FORWARD -j DROP
停止している間に届いたパケットはすべて破棄されます。 TCP であれば再送機能でリカバリされるはずですが、UDP などの場合の挙動はアプリケーション依存です。 ご注意ください。
ネットワークごとの処理振り分け一つの Linux Box は1セットの IP table を持ちます。 “NIC ごとに1セット”ではなく Linux Box につき1セットです。 つまり、GLOBAL から入ってくるパケットも KNOWN から入ってくるパケットもどちらも同一の INPUT チェーンで処理されます。 出てゆくパケットも同様です。 そこで、ルールの設定をシンプルにするために INPUT と OUTPUT の最初の時点で GLOBAL / KNOWN / UNKNOWN を別チェーンに振り分けてしまいます。
最初に、ユーザー定義チェーンを追加します。
iptables -N INPUT_GLOBAL iptables -N INPUT_KNOWN iptables -N INPUT_UNKNOWN iptables -N OUTPUT_GLOBAL iptables -N OUTPUT_KNOWN iptables -N OUTPUT_UNKNOWN
続いて、INPUT 側のパケットを振り分けます。 ここで注意したいのですが、iptables は “eth0” と “eth0:0” を区別できません。 そこで、KNOWN と UNKNOWN の識別にはネットワーク・アドレスを使用します。
iptable -P INPUT DROP iptable -A INPUT -i lo -j ACCEPT iptable -A INPUT -i ppp0 -j INPUT_GLOBAL iptable -A INPUT -s 172.16.100.0/24 -j INPUT_KNOWN iptable -A INPUT -s 172.16.200.0/24 -j INPUT_UNKNOWN
OUTPUT についても同様です。
iptables -P OUTPUT DROP iptables -A OUTPUT -o lo -j ACCEPT iptables -A OUTPUT -o ppp0 -j OUTPUT_GLOBAL iptables -A OUTPUT -d 172.16.100.0/24 -j OUTPUT_KNOWN iptables -A OUTPUT -d 172.16.200.0/24 -j OUTPUT_UNKNOWN
これ以降、各ネットワーク・インタフェースを出入りするパケットは、それぞれ対応する INPUT_* チェーンと OUTPUT_* チェーンでフィルタリングします。
サービスの提供 / 利 - 001206



