サーバ運用のネタ帳(FreeBSD編)

手間をかけずに安定し,セキュアなサーバを運用するコツをまとめます.

日々の作業編

基本的な考え方は,freebsd-updateコマンドによる,OS自体の更新,追加のアプリケーションは,portsで管理し,portsを支援する各種ツール(portsnap/portupgrade/portsaudit)でアップデートしていきます.

OSのアップデート

freebsd-update fetch で,有無を確認,freebsd-update installでアップデートします.定期的な確認は,freebsd-update cronします.

portsのアップデート

インストール済みのportsは黙っていれば,そのうち色々問題を抱えます.脆弱性への対応は大変重要です.これには,portauditコマンドをつかいます.portauditは,/usr/ports/ports-mgmt/portaudit で,make installする必要があります.(もし,portsがないなら,ここを読み飛ばして,下にある,portsnapを実行して,戻ってきてください.)

実行すると,以下のような感じです.-aは,インストール済みアプリケーションの脆弱性確認,-Fは最新版データのダウンロードです.

# portaudit -aF
auditfile.tbz 100% of 75 kB 156 kBps
New database installed.
Affected package: openssl-1.0.0_10
Type of problem: OpenSSL -- integer conversions result in memory corruption.
Reference: http://portaudit.FreeBSD.org/7184f92e-8bb8-11e1-8d7b-003067b2972c.html

1 problem(s) in your installed packages found.

You are advised to update or deinstall the affected package(s) immediately.

上記のように,インストール済みopenssl に脆弱性があることがわかります.

脆弱性のあるアプリへの対応は,当該ports内にて,make && make deinstall && make install なのですが,portsupgrade コマンドを使えば簡単にアップデートできます.portupgradeは,/usr/ports/ports-mgmt/portupgradeで,make install してインストールしておきます.

作業の前に,portsツリーを最新に更新する必要があります.portauditは,portツリーの状況とは独立して問題点を調査,portupgradeは,現在のportsツリーを前提に実行されるからです.

portsを最新にするには,portsnap fetch と portsnap updateを使います.ちょっとお時間がかかるものなので,cronとして,入れとけばよいとおもいます.

# portsnap fetch
Looking up portsnap.FreeBSD.org mirrors... 4 mirrors found.
Fetching snapshot tag from portsnap5.FreeBSD.org... done.
Fetching snapshot metadata... done.
Updating from Mon Apr 9 02:37:18 JST 2012 to Tue Apr 24 00:13:24 JST 2012.
Fetching 4 metadata patches... done.
Applying metadata patches... done.
Fetching 4 metadata files... done.
(略)

# portsnap update
Removing old files and directories... done.
Extracting new files:
/usr/ports/GIDs
/usr/ports/LEGAL
/usr/ports/MOVED
/usr/ports/Mk/bsd.database.mk

cron(定期的にコマンドを実行する機能)で更新するなら,以下のようなファイルを /root/bin/hogehoge.shみたいに作っておいて,(もちろん chmod +x hogehoge.shしましょう)

#!/bin/tcsh
/usr/local/sbin/portaudit -Fda
/usr/sbin/portsnap fetch >& /dev/null
/usr/sbin/portsnap update >& /dev/null

crontab に組み込んでおけばよいでしょう.例えば,6時にセットは以下のようにします.上記のスクリプト&以下のcron設定では,portauditの結果がメールにて,cronのオーナーに送信されます(これは,cronの仕様です.). /etc/aliases などで,rootなどのmailフォワード先を,管理者へむけておきます.freebsd-upgradeについても,fetchについては,同様に入れても良いでしょう.

0 6 * * * /root/bin/hogehoge.sh

さて,porttreeアップデートが終わったら,portupgrade します.

pc7# portupgrade openssl
[Updating the portsdb <format:bdb_btree> in /usr/ports ... - 23514 port entries found .........1000.........2000.........3000.........4000.........5000.........6000.........7000.........8000.........9000.........10000.........11000.........12000.........13000.........14000.........15000.........16000.........17000.........18000.........19000.........20000.........21000.........22000.........23000..... ..... done]
---> Upgrading 'openssl-1.0.0_10' to 'openssl-1.0.1_1' (security/openssl)
---> Building '/usr/ports/security/openssl'
===> Cleaning for openssl-1.0.1_1
===> License check disabled, port has not defined LICENSE
===> Found saved configuration for openssl-1.0.0_5
=> openssl-1.0.1a.tar.gz doesn't seem to exist in /usr/ports/distfiles/openssl-1.0.1a.
=> Attempting to fetch http://www.openssl.org/source/openssl-1.0.1a.tar.gz
openssl-1.0.1a.tar.gz 90% of 4352 kB 327 kBps 00m01s
(略)

完了したら,portauditしてみましょう.

# portaudit -a
0 problem(s) in your installed packages found.

すばらしい状態にもどりました.

とまあ,一見簡単なのですが,たまに,地雷があります.特に大事なのは,依存される具合が大きいライブラリ/アプリケーションがアップデートされたときです.脆弱性のportsを使っているバイナリを作り直す必要があるか?という点です.依存関係も含めてコンパイルする場合は,portupgrade -r /-R /-f オプションを併用します.

portupgrade -r オプションは,更新するportsを依存している他portsもアップグレードするという事になります.例えば,glibおよび,glibをつかっているパッケージを更新するなら,

portupgrade -r glib

となります.この場合,gtk関連が全部makeされなおされます.-Rは,その逆で,当該パッケージが使用しているportsがmakeされるということになります.-fは,バージョンを維持/ダウングレードして更新なのですが,やったことありませんので知りません.pkgtools.confの設定が必要でめどくさそうです.

portsupgradeの難しい所は,-r /-Rしないといけないかどうかの判断です.-rによる portupgradeは,インタラクティブ(途中で質問に答えること)や,コンパイル時間がかかりますので,コストが大きい作業です.コストが大きいということは,うまくいかなくなるリスクもあるということです.

この場合,portupgradeの -n(改変などの実行をしないという意味) を併用して,実際にどんなことが行われるかを確認するとよいです.とくに今インストールされているライブラリとバージョンが異なる時は,そのライブラリだけを更新しても,依存するアプリケーションは,動きません.なので,覚悟を決めて,portupgrade -rせざるを得ないでしょう.

portupgradeしたあとは,portsclean -L による古いライブラリの掃除,pkgdb -aFによる依存関係の組み直しが推奨されています.後者はまだしも,前者は,portsでインストールしてないアプリが,古いライブラリを参照していたなんてバイナリがあるかもしれませんので,注意が必要です.

portsで,無駄なアプリケーションを入れてません?

よくあるのが,インタラクティブなおconfig(オプションの選択画面)で,「デフォじゃボケ−,オラ!エンター!,バシ!」みたいに景気よくしていると,無限にcompileが進む場合があります.よくあるのが,

「サーバなのに,なんでghostscriptをmakeしとるんやー」

というところで,気づくやつ(おいら)です.これは,configの画面に, デフォで,DOCに[X}とか入っていて,DOCを作るのに ghostscriptだ(なんでかは作者のみぞ知るです.)ということで粛々とportsがmakeされるためです.X11使わないとかは,configに書けば対応できるんですが,DOCの例のように,細かい罠があるので,チェックは重要です.依存関係は,porttree (ports/ports-mgmt/porttree)コマンドでわかります.

もちろん,入れてもいいんですけど,入れる=portupgradeの依存関係が膨らむ,portauditの範囲が広がるということで,ここで楽しても,後のdaily workで苦しむだけなので,がんばりましょう.

アップデート後のエラー編

BIND98を起動するとopenssl “initializing DST: openssl failure” で落ちる

これは,chroot化されたBIND98において,chrootである, /var/named/ 配下に libgost.so が無いために発生します.named のchrootは,/etc/defaults/rc.default の中に記載されています.

% grep chroot /etc/defaults/rc.conf
named_chrootdir="/var/named" # Chroot directory (or "" not to auto-chroot it)
named_chroot_autoupdate="YES" # Automatically install/update chrooted
named_symlink_enable="YES" # Symlink the chrooted pid file

ということで,

mkdir -p /var/named/usr/local/lib/engines
cp /usr/local/lib/engines/libgost.so /var/named/usr/local/lib/engines

で解決です.

[もどる]