FreeBSDセットアップ「つまみぐい」その8 サーバを建ててみる # makeだのportupgradeだのrehashだのといった手順は省略して書いてある。 # インターネット越しに利用する場合、(ルーターなどの設定で)ポートの開放が # 必要な場合がほとんどだがこれも省略。 # また、設定やアップデートは原則としてデーモンを停止して行う。 # サーバソフトウェアは、今風でスッキリとしたデザインのものを中心に選んだ。 # sendmailとwu-ftpdについては触れない。apacheについてはその9を参照。 # その0のオマケの項目も読んでおくとよいかもしれない。 サーバの設置に関する情報は、 http://www.fkimura.com/server-menu.html が非常に参考になる。 ************************************************************ ********** いいかげんなことばかり書いてあるので ********** ********** 転んでも泣かない人専用!       ********** ************************************************************ 事前準備と予備知識 ネットワーク構成を見直す FreeBSDをいじり始める前に、まずはネットワーク関連のハードやソフトの設定を 見直しておく。少なくとも、NAT機能とファイアーウォール機能(といっても定義が あいまいだが、ここではパケットフィルタ機能のこと)のあるルーターか、 その代用になるゲートウェイマシンが必須だろうが、それらのインストールや 設定についてここでは扱わない。 # インターネット経由のアクセスをコントロールするのはもちろん、LAN内の # 「安全でない(もしくは安全度の低い)環境にあるコンピュータから他の # ローカルマシンへのアクセス」が可能にならないよう、十分配慮する必要がある。 # 具体的には、サーバマシンから他のローカルマシンへの通信を制限しておく。 # 他のマシンからサーバマシンへの通信もある程度制限しておくべきだが、SSHの # 秘密鍵に適切なパスフレーズを設定する(リムーバブルメディアに保存して、 # 必要なときだけマウントするとさらによい)など、それ以前の対策が # しっかりしていないと意味がない。 port設定の確認については https://www.grc.com/x/ne.dll?bh0bkyd2 http://scan.sygatetech.com/ あたりが定番になっているようだ。 ハードウェアを見直す 24時間稼動をさせるとなると、ハードディスクのトラブルがどうしても怖い。 そこで、読み書きの激しいswap、tmp、varあたりはまとめて(物理的に)別の ディスクに分けておくとよいだろう。できればディスク3台を使って、 /と/usrと/etc、swapと/tmpと/var、データ(/usr/homeとか/wwwとか/ftpとか)に 分けた方がよいのだろうが、最低限、/と/usrを入れるディスクと、swapと/tmpと /varを入れるディスクは分けた方がよいと思う。 ディスク2台でやるなら、第1ディスクに/と/usrと/etc、第2ディスクには スライスを2つ確保して、内側のスライスにswapと/tmpと/varと/usr/ports、 外側のスライスに/usr/homeとか/wwwとか/ftpとか/mailとかそのほかいろいろ、 といった構成が安定か。/etcや/varなどのバックアップは(外部メディアの他に 日常用として)第2ハードディスクに作る。スライスを3つ確保してあり、 とくに第1ディスクのパーティション数には余裕があるので、/usr/localや /rootなどを別に確保してもよいだろう。 リモートログインができればモニタとキーボードはなくてもよいのだが、SSHdが 落ちた(もしくは起動しなくなった)場合などに困るため、いざというときの 調達手段は確保しておく必要がある。長く使っているうちにケーブル類の差し込みが 緩んでくると思わぬトラブルになることがあるので、それもしっかり確認しておく。 パフォーマンスを気にするなら、HDDをつなぐIDEチャンネルも気にした方がよい (同じチャンネルだと帯域を共有することになる)。サウンドボードやビデオボードは (普通の使い方なら)必要ないので、もしインストールしてあるなら取り外しておく。 セキュリティパッチを当てる アップデートの方法自体にはすでに触れたが、すでにクラックされているシステムに パッチを当てようとしても意味がないので、新規にサーバを建てるのならば、 クリーンインストールからはじめた方がよい。耐久性を考慮して、ハードウェアも 適宜更新しておけばもっとよいだろう。 # そういう筆者はいつ壊れてもおかしくないオンボロハードウェアを使っているが。 インストール直後はセキュリティパッチが当たっていないため、パッチ適用 まではネットワークには接続せずスタンドアロン環境で作業するのが理想だが、 最低限ファイアーウォールの内側でインストールを行うようにしたい。 また、インストール用イメージやセキュリティパッチを入手するための環境自体が 安全かどうかを確実に確かめる方法はない(経路はSSLなどで保護するにしても、 ダウンロードに利用するコンピュータに穴があいていたら元も子もない)ので、 それまでの実績や運用環境から「正常に動作していると強く推測される」システムを 利用する、というあたりが現実的な選択となる。 # 企業機密でも扱うのならば、販売元にパッチ適用済みのインストールメディアを # 書留で郵送してもらうとか、身分証明書を持ったエンジニアを派遣してもらって # セットアップを任せるといった選択肢もあるだろうが、ここで扱うべき話題ではない。 もちろん、インストール用イメージのMD5SUMなどは十分にチェックしておく。 不要なデーモンを停止する > ps -ax | more などとして実行中のデーモンの一覧を確認、不要なものが動いているようなら /etc/rc.confや/usr/local/etc/rc.d/以下のファイルなどを見直して、 自動起動を無効にする # 本当に不要なものはアンインストールしてしまう ルーチンタスクを見直す http://x68000.q-e-d.net/~68user/unix/pickup?crontab /etc/crontabの内容を確認 # デフォルトでは、atrun(キューファイルを読んでコマンドを実行)、 # nwesyslog(ログローテーション)、adjkerntz(タイムゾーン調整)、 # periodic(ルーチンタスクを実行している本体)が # 定期実行される設定になっている(atrunはcronに統合する予定みたい) 分 時 日 月 曜日 実行権限 コマンド という書式になっており、 *がワイルドカードになっている。たとえば0 20 * * * root fsck と書くと、 何月でも、何日でも、何曜日でも、20時0分になったら、root権限でfsckを実行 という意味になる。 # 「*/5」で「5分毎(分が5で割り切れる数字の時刻)」とか、 # 「5,45」で「5分と45分」といった記述も可能 # 曜日は(sunとかmonといった具合に)小文字3文字で表現する。 # ddns利用時のIPアドレス確認やIRCサーバへのping送信などは、 # 毎分0秒前後に混み合うためsleepを利用して多少前後させてやるとよい。 デフォルトの設定ではシェルが/bin/shなので、.cshrcなどで指定した 環境変数は無視されることに注意(これも/etc/crontab内に書いてある)。 コマンドの部分は、shが処理できる書き方であれば、リダイレクトや パイプや連続実行も可能(tcshとの文法の違いに注意)。 # ちゃんとわかっているのでなければ、シェルの変更はしないほうが無難 標準出力と標準エラー出力が管理者宛てのメールで送られてくるので、 0 20 * * * root df 1> /dev/null などと標準出力を捨ててしまえば、 標準エラー出力のみをメールで受け取れる。 システムが定期的に実行するコマンドはperiodicというコマンドが管理しており、 /etc/periodic.confと/etc/periodic/以下のファイルで設定を行う # いじる必要はほとんどない とりあえずは、システムが勝手にやってくれるタスクの内容を確認し、 足りないものを自分で追加、とするのがよいだろう # /etc/periodic/daily/にある拡張子.shのファイルを直接参照してもよいが # daily run output というタイトルのメールが毎日届いているはず) # 詳しくは後述するが、メールデーモンが動いていないと、当然メールは届かない。 # メールデーモンが動いているのにメールが届かないようなら、シェルから # >periodic daily を実行してみて、きちんと動くことを確認し、 # さらに/etc/crontabでperiodicの実行設定がきちんとなされているかを確認。 通信を把握する http://x68000.q-e-d.net/~68user/unix/pickup?tcpdump http://x68000.q-e-d.net/~68user/unix/pickup?netstat ソケットの様子をモニタする> netstatと、パケットの出入りをモニタする > tcpdumpがある。ソケットとパケットは、高速の出入口とトラックのような関係。 パケットの中身をモニタするwireshark(旧ethereal)というソフトウェアも あるが、GUIを採用しているのでXが必要になる。 ソフトウェアの脆弱性をチェックする portsに入っているソフトなら、http://people.freebsd.org/~eik/portaudit/に 脆弱性情報が集約されているのでそれを参照する。security/portauditを 使えば、インストール済みのソフトウェアについて自動で情報を集めてくれる。 # http://www.freebsd.org/ports/portaudit/と同じページ インストールすると> /usr/local/sbin/portaudit -Fda を実行して データベースの更新をしろと指示されるのでその通りに実行すると、 上記のページから脆弱性情報をダウンロードしてその場でチェックを 行ってくれる(多少時間がかかる)。 # -Fはデータベースのダウンロード、-aは現在インストールされている # ソフトウェアの脆弱性表示、-dはデータベース作成の報告オプション。 あとは自動で情報を拾ってきてくれるが、当然ながら、ソースコードを入手して 自分でビルドしたソフトウェアなどは守備範囲外なので、手動で別途確認する。 認証とかパスワードとか暗号化とか実行権限の分離とか # 各プロトコルやデーモンなどの詳細は後述 パスワードが平文で流れるプロトコルとハッシュ化されて流れるプロトコルがあり、 前者だとパケットキャプチャなどで通信を傍受されただけでパスワードを 知られてしまう。パスワードを平文で流すプロトコルには、HTTPのbasic認証、FTP、 POP3、IMAP、SMTP-AUTHのLOGINとPLAIN、telnetなどがある。 パスワードをハッシュ化して流すプロトコルは、たいてい、サーバがその場限りの フレーズを通知、クライアントがそのフレーズと自身の持つパスワードを合成したのち ハッシュ化、サーバでも同じフレーズと秘密鍵を合成して同じ関数でハッシュ化、 クライアントがサーバにハッシュを送り、サーバの作成したハッシュと一致すれば 認証成功、という手順を踏む。ハッシュ化に用いられる関数としてはMD5がメジャーで、 CRAM-MD5というモードのあるプロトコルはこの方式をサポートしているはず。 # これをチャレンジアンドレスポンスといい、サーバが通知するその場限りの # フレーズがチャレンジ、クライアントが返すハッシュ値がレスポンスにあたる。 チャレンジアンドレスポンスを採用しているプロトコルにはsaslやAPOPなどがある。 上記のチャレンジアンドレスポンス方式では、構造上、サーバがパスワードを平文で 保存しなければならないため、パスワードが書かれたファイルを読み出せるアカウント が乗っ取られると、パスワードが流出してしまう。サーバとクライアントの両方が 秘密鍵を知らなければならない場合だけでなく、サーバとクライアントのうち 片方だけが秘密鍵を持てばよい方式でも、秘密鍵をサーバが保管する場合(たとえば SSLの秘密鍵をサーバに保管するとか)には同じことがいえる。この点、秘密鍵を クライアントが持ちかつそれを暗号化して保管するSSHは比較的安全度が高いと いえるが、クライアントを実行する環境が安全でないと意味がない。 チャレンジアンドレスポンス方式の延長として、あらかじめ信頼できる環境で 秘密鍵を交換し、それを任意回数(仮にm回とする)ハッシュ化してn回目の認証には m-n回ハッシュした値を使う、ワンタイムパスワードという方式があり、信頼できない 環境で実行されるクライアントを利用する場合には、これがもっとも妥当な方法に なるだろうか(信頼できない環境ではハッシュの計算ができないので、利用の都度 信頼できる環境でハッシュの計算を行うか、USBメモリなどの物理デバイスを利用回数分 用意して、利用の都度デバイスから鍵を読ませることになるが)。 ワンタイムパスワードを計算するソフトウェアとしてはS/KeyやOPIEが有名だが、 FFFTP(Window用)などのFTPクライアントにもワンタイムパスワード計算機能がある。 # サーバに秘密鍵を置かなければならないのはチャレンジアンドレスポンス方式と同じ。 サーバに秘密鍵を置かず、かつ信頼できない環境でクライアントを実行するとなると、 サーバに秘密鍵のハッシュを置いて秘密鍵自体を使い捨てにするしかない(多分)。 それでも、最初に秘密鍵を作ってサーバにハッシュを送る環境だけは、安全である 必要がある。 また、複数のデーモンを同じ実行権限で実行していた場合、どちらか片方が 乗っ取られた場合に、被害の範囲が拡大することになる。たとえば、apacheと sendmailを両方ともnobody権限で実行していた場合、どちらか片方が乗っ取られた 場合に、apacheからアクセスできるファイルとsendmailからアクセスできる ファイルの両方へアクセスを許してしまうことになる。これは、別々のアカウントで (たとえばapacheはwww、sendmailはmailとして)実行することで防げる。 また、rootは本当の意味で何でもできてしまうアカウントなので、ルート権限を 奪われたらどうにもならない事態になる。Unixのshadowパスワードは、サーバが パスワードを平文ではなくハッシュ(フィンガープリントと呼ぶ場合もある)で 保管する方式を採用しており、たとえrootユーザーでも暗号を破らずに他人の パスワードを知ることはできないが、パスワードを変更することは可能で、 ファイルへのフルアクセスが可能になることにも変わりがないので、権限を 分離してあってもroot権限を奪われたらやはりお手上げになる。これに対しては、 jailを利用することでかなりリスクを減らすことができる。 # 一般ユーザーがルートに昇格してしまう脆弱性や、jailの中のrootユーザーが # jailから抜け出せてしまう脆弱性がみつかることがあるので、 # それによって被害が拡大することもあるが、それはまた別問題。 SSHだのSSLだの # まずはSSLをアップデート。次いでSSHを入れる SSLのインストール すでにインストール作業は終了しているはずだが、念のためportupgradeでも しておくとよいだろう。 /etc/ssl/openssl.cnfを開いて中身を確認、とくに、CA_defaultの dirの項目とRANDFILEの項目、reqのdefault_bitsの項目は確認しておく。 # RANDFILEは、-randオプションで、default_bitsはopenssl実行時の引数で # それぞれ変更できるので、ここでは確認だけにとどめいじらなくてもよい。 default_days(証明書の有効期限)、countryName(国名:JPでよい)、 stateOrProvinceName(都道府県)、commonName(CN)(CAの名前) なども設定しておくとよいかもしれない。 SSHのインストール portsには ports/security/ssh/ # OpenSSHの古いバージョン ports/security/ssh2/ # 商用SSHのフリー版(xの有無とか、いろいろバージョンがある) ports/security/openssh/ # おそらく一番普及しているSSH(GUIバージョンもある) の3つがある。ここではsecurity/opensshを導入すると仮定して話しを進める。 OpenSSHの設定 http://www.fkimura.com/openssh0.html http://www.marronkun.net/linux/security/openssh_3.html http://pctraining.s21.xrea.com/lab/?cmd=read&page=Lab%2Fssh%A5%E1%A5%E2%2Fman%20sshd_config http://www.unixuser.org/~euske/doc/openssh/jman/ OpenSSHの設定ファイルは/etc/ssh/ssh_config、 ssh2(という名前でいいのか?)の設定ファイルは/usr/local/etc/ssh2/ssh2_config # sshdの設定ファイルもそれぞれ同じディレクトリ OpenSSHのsshdはデフォルトで/etc/rc.confにsshd_enable="YES"と書いて起動するが ssh2のsshdは/etc/rc.confから起動するのが作法らしい。 # どちらも、/usr/local/etc/rc.d/以下にスクリプトをおいて起動してもよい 実際にいじるのはsshd_configもしくはsshd2_configの方で、Listenポートは 最低限確認しておかなければならない。あとは必要なプロトコルと 認証方式を有効にしておくだけ(プロトコル2でPubkeyを有効にするのが 安定なのかな)。 ルート証明書はsecurity/ca_root_nssというportsでインストールでき、 /usr/local/share/certs/ca-root-nss.crtがデフォルトの保存場所。 SSHの運用 http://www.ne.jp/asahi/micnet/kaisekiya/vine_ssh-p.html http://www.sodan.ecc.u-tokyo.ac.jp/2002/article/tips/ssh/putty.shtml http://www.sodan.ecc.u-tokyo.ac.jp/2002/article/tips/ssh/winscp.shtml http://www.ac.ctrl.titech.ac.jp/~sadahiro/putty/ http://yebisuya.dip.jp/Software/PuTTY/ http://www007.upp.so-net.ne.jp/bemax/arita/putty.html http://bakkers.gr.jp/~kitani/manual/win/ssh2/putty_ssh/general_ja.html sshサーバとsshクライアントがセットになっているが、Windowsから使いたい 場合にはリモートマシンにもクライアントソフトを入れておく(Puttyが無難か)。 Puttyに付属しているツールも十分に使えるが、WinSCP2という ファイル転送ツールも便利そうだ(筆者は使った経験なし) RSA暗号を使う場合、安全な場所で秘密鍵と公開鍵を作り、公開鍵の 名前をリモートされるマシンのAuthorizedKeysFileで指定した場所と名前(デフォルトは ~/.ssh/authorized_keysだが、設定ファイル中では単に.ssh/authorized_keysと ~/をつけずに指定する)で保管し、秘密鍵は大切に保管する。 # 秘密鍵はリムーバブルメディアに保存して、必要なときだけマウントするとよい。 # 公開鍵のパーミッションも0400(ownerはログインするユーザー)にしておく。 秘密鍵は、FreeBSDからなら> ssh-keygen -t "秘密鍵の形式"(形式はrsaが よさそう)で、Puttyからならputtygen.exeで作成可能。 # 商用SSHとOPENSSHで、公開鍵の形式が違うので注意。Puttyの場合、 # OpenSSH用のキーを別に出してくれる。キーの長さも合わせておく。 SSHクライアントに秘密鍵を読ませてやって、あとはパスフレーズを 入力してやればログインできるはず。 SSL(もう少し詳しく) # .pemという拡張子が冗長でアレなので、ここではCA_defaultに # dir=/etc/ssl/CA # certificate = $dir/ca.crt # private_key = $dir/ca.key # と設定したことにして話しを進める。 # apacheでもこの名前を採用しているようだ。 CA(認証局=サーバ証明書の正当性を保証する機関のこと)の証明書を作る http://www.fc-lab.com/network/server/pki/ http://www.ginganet.org/ginga/memo/openvpn/ http://elug.gogo.homelinux.org/pukiwiki.php?SSL-DeleGate http://www.yggdrasil.jp/ygg16_1.html http://www.ysnet.org/pukiwiki.php?%5B%5BCA%B4%D8%CF%A2%5D%5D http://acorn.zive.net/~oyaji/www/certs.htm /etc/ssl/openssl.cnfでdirに指定したディレクトリに移動(なければmkdir)し、 certs、crl、newcerts、privateという4つのディレクトリを作成、 > chmod 0700 private > touch index.txt > echo 01 > serial としておく。 # データベースファイルを新規作成するのはいいとして、何のために手動で # シリアルナンバーを01に設定しているのか、筆者は理解していない。 # /etc/ssl/openssl.cnfをいじれば、ディレクトリ名は上記のとおりでなくてもよい。 > openssl gen暗号の種類 -rand ファイルのパス -out ca.key ビット長 暗号の種類は、たとえばRSAならgenrsa。-randオプションの引数には、 ある程度の長さがあって中身の予想できないファイルを指定する(30秒ほど 歌ってマイク録音して音声部分だけ抜き出すとか)。ビット長は1024が標準で、 長ければ長いほど強力な暗号になるが、処理にも時間がかかる。 これでca.keyという秘密鍵ファイルができる。以後、CAとしてこのファイルを 使って署名(証明書の発行)を行う。 > openssl req -new -key ca.key -out ca.csr 順に質問に答えていくとca.csrというx509証明書発行要求ファイルができる。 > openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt これでca.crtという証明書ファイル(base64エンコード)ができる。 # 上記の作業2つは # > openssl req -new -x509 -key ca.key -out ca.crt # とまとめて実行しても結果は同じ。 ca.keyは、privateディレクトリに保管する(ca.key自身のパーミッションも 400にしておく)。ca.csrは削除してしまって問題ない。ca.crtは証明書の 本体で、dirに指定したディレクトリに保管する(書き込みを許さなければ パーミッションは444なとでもよい)。 # ファイルの名前や場所は/etc/ssl/openssl.cnfでの指定次第で変わる。 CAの証明書について ちょっと考えればわかることだが、これだと「オレが安全だって言ってるんだから 安全なんだよ」と言っているのと同じで、当然、ブラウザなどが証明書を 読んだときに「信頼していない発行機関云々」などと警告が出る。 # 上記のように、要求ファイルと証明書ファイルの発行に同じ(自分の) # 秘密鍵ファイルを使うことを自己署名と呼ぶ。 VerisignやInstantSSLなどの、ルート証明機関として一般に信用されているCAに お金を払って証明書を発行してもらえば(証明書発行要求ファイルを送って 証明書ファイルを送り返してもらう)、このような警告は出なくなる。 http://www.verisign.co.jp/ http://www.instantssl.com/ これは、暗号化「だけ」が目的なら、必須な作業ではない。たとえば HTTPの代替としてHTTPSを利用する場合、認証を得ていない証明書であっても、 通信を暗号化して接続先に届ける役割自体は果たせる。ただ、その「接続先」が 自分の意図した通りの相手なのかどうか、HTTP接続をしていたときと同等の 確かさでしかないということになる。 暗号化して送るデータというのは、平文で送るデータに比べて他人に見られると 困るものが多いわけで、なんだHTTPと同レベルに戻るだけか、という理解は 少し甘いといえる。自分が管理するネットワーク上の自分が管理するサーバに 自分のコンピュータだけからアクセスするような場合は、自前で発行したCA証明書を 「信頼する証明書」として登録してしまえばよい。 # たとえLAN内であっても、DNSサーバに虚偽のデータをキャッシュとして # 送り込まれたり、DNSサーバ自体をクラックされたり、hostsファイルを # 書き換えられたりすることで、意図しない接続先に誘導される危険はある。 それ以外の場合でも、自分で発行したca.crtを何かしらの手段で配布して、ユーザーに 「信頼する証明機関」として認めてもらうという方法がなくはないが、証明書を確実に 受け渡す方法が乏しい(PGPなどを利用しただけではこちらの身元が証明できない)。 書留郵便か何かでパスワード通知してもらって、それをもとに証明書を暗号化して送る というのが比較的安全(写真つきの身分証明書を見せながら物理メディアに入れた 証明書を直接手渡せばもっと確実)だが、ユーザー数が多いと手間がかかりすぎるし、 万が一秘密鍵を盗まれた場合に、自分を信用してくれたユーザーに大迷惑がかかる。 身元の証明ができない場合、(暗号化自体は機能するので平文でデータをやり取り するのに比べれば安全度は高まるが)正規の証明書を用いた場合に比べると確実に 安全度が落ちるということを(自分自身で認識しておくのはもちろん)ユーザーにも きちんと知らせておくべきだろう。 # 信頼できない経路で証明書を配布してユーザーに信頼してもらうのに比べれば、 # 身元の証明ができていないことを承知で、信用せずに利用してもらう方が、 # 不十分ではあってもまだ無難な選択といえる(毎回警告されるので不便だが)。 心配性になってみる # 推測でモノを言っている部分が多いので、読むときはそのつもりで。 上記の問題はデジタル署名のネックで、本当に厳密に考えると、たとえばWindowsの場合 「信頼する証明機関」のリストをWindows Update で 更新するが、このときリストに 入る証明機関については(多分上に挙げたよりももっと厳密で手間のかかる方法で) 身元の確認がなされているはずである一方、証明書のリストを提供する アップデートサイトそのものもデジタル署名を用いて身元証明を行っているため、 少なくとも最初の1回は証明書(恐らくMicroSoftが自己署名したもの)の受け入れを しなければならない。 たとえば、OSのインストールメディアに証明書も入っていて、それを利用するのなら (パッケージ内のメディアがすりかえられていない限り)安全だろうが、そうすると 今度は証明書の有効期限が問題になる。FreeBSDなら、最新のインストールCDや インストールイメージを使えば(多分)問題ないだろうが、筆者にはインストールを 開始してからSSLが使えるようになるまでの流れや仕組みが理解できていないため、 詳しいことがわからない。 セキュリティパッチの項目でも触れたが、インストール直後のセキュリティパッチが 当たっていない状態でネットワークに接続すると穴を突かれる可能性があるので、 証明書が手元にない場合も、現在正常に動いている(と強く推測される)システムを 経由して入手するのが恐らく現実的なのだろう。 サーバの証明書を作る > openssl genrsa -out server.key ビット長 > openssl req -new -key server.key -out server.csr > openssl ca -infiles server.csr -out server.crt # 自前のca.keyを使って署名され、ca.keyがなければ署名なしになる(はず)。 # -nodesオプションをつけると、パスフレーズの入力がスキップされる。 としてサーバ用の証明書を発行する。 # commonNameは、サーバプログラムを実行するユーザーの名前とか # サーバの公開URLなどが入るが、場合によって違うので確認が必要 上記で作成したserver.keyとserver.crt(場合によってはca.crtのコピーも)を、 各サーバソフトウェアの設定ファイルで指定したディレクトリに置き、 パーミッション(CAの秘密鍵や証明書と同様)を設定する。 # Postfixなら、main.cf内のsmtpd_tls_で始まる項目で設置場所を設定する ca.crtについては、どうせ信用してもらえない証明書なので、置かなくても 問題ないといえば問題ない(はず)。 # クライアントが吐く警告メッセージが、「ルート証明書がありません」から # 「ルート証明書がありますが信用していない機関が発行したものです」に # 変わる程度。 もちろん、CAの鍵や証明書と同様、 > openssl req -x509 -nodes -newkey rsa:1024 -keyout \ /etc/ssl/private/server.key -out /etc/ssl/private/server.crt > chmod 400 /etc/ssl/private/server.* # \は、表示上の都合で改行しているが、実際には改行しないという意味。 と、一気に作業することも可能。 server.keyとserver.crtをデーモンごとに作成する(管理しなければならない 秘密鍵の数が増える)のと、複数のデーモンで使いまわす(一つのサービスで 秘密鍵が流出すると、他のサービスにも影響が及ぶ)のと、どちらが安全なのか なんともいえないので、好みで選べばよいだろう。 ただし、秘密鍵のコピーは作らないというポリシーは守るべきなので、 使いまわすとはいっても、鍵の方をコピーするのではなく、複数のデーモンが 同じファイルを参照する形にするべき。 利用の流れ # RSA方式の場合、恐らくこんな感じ CAの作業 ・秘密鍵ファイルを作る。以後、このCA秘密鍵を使って署名(証明書の発行)を行う。 ・秘密鍵を使って証明書発行要求(CSR)ファイルを作る。 ・ベリサインなどの上位CAにCSRを送り、証明書ファイルを作って(署名して) もらう。もしくは自分自身の暗号鍵で署名する(自己署名)。 上位CAの作業 ・CSR送信者の身元がCSRの内容と一致するかどうか確認する。 ・送られてきたCSRに署名してできたCA証明書に、自分自身(=上位CA)の証明書を 添えて送り返す。 # ベリサインクラスのCAなら、すでにルートCA証明書は世界中に配布済みなので、 # これについては考慮しなくていいはず。 CAの作業 この時点で手元には、 ・CA暗号鍵(自分が作ったもの) ・CA証明書(CA暗号鍵をもとにCSRを作り、それに上位CAもしくは自分が署名したもの) があるはずなので、それぞれSSLdの設定で指定した場所に保管する。 ここまでが下準備。 サーバ管理者の作業 ・秘密鍵ファイルを作る。このサーバ秘密鍵は後で認証に使う。 ・秘密鍵を使って証明書発行要求(CSR)ファイルを作る。 ・CSRをCAに送って署名してもらう。 CAの作業 ・CSR送信者の身元がCSRの内容と一致するかどうか確認する。 ・CA秘密鍵を使ってCSRに署名し、サーバ証明書を作成。 ・(必要ならCA証明書を添えて)サーバ証明書を送り返す。 サーバ管理者の作業 この時点で手元には、 ・サーバ暗号鍵(自分が作ったもの) ・サーバ証明書(サーバ暗号鍵をもとにCSRを作り、それにCAが署名したもの) があるはずなので、それぞれサーバの設定で指定した場所に保管する(CAの証明書も 必要な場合があった気がする)。 # 上位CA云々の個所は、自分で試したことないのでよくわかってない。 # 証明書のインポート(マージ?)なんかが必要な場合もあるそうな。 SSLの利用 http://wiki.spc.gr.jp/tunnel/?DigByStone http://www.dream-seed.com/server/stone.html http://www.gcd.org/sengoku/stone/Welcome.ja.html http://solaris.bluecoara.net/servers/misc/stone.phtml http://rat.cis.k.hosei.ac.jp/article/security/protocol.html SSL上でなら、FTPなど、本来セキュアではない通信を安全に行うことが できる(TLSと呼ばれるものもほぼ同じことを指している)。 # ちなみに、FTP on SSL/TLS のことをSFTP、HTTP on SSL/TLS のことを # HTTPSなどと呼ぶことが多い。 これには、サーバとクライアントの両方でSSLに対応することが必要だが、 stoneなどの、SSL対応パケット中継ソフトウェアを使えば(って別に、 ハードウェアでパケット転送をしてもまったく問題はないのだが)、SSL未対応の ソフトウェアからでもSSLを利用できる。FreeBSDだとsecurity/bjorbあたりか。 その他 ports/net/ssltelnetというソフトウェアもあり、SSHの代用として使えそうな雰囲気。 chrootとjail chrootコマンド > chroot ディレクトリ コマンド とすると、仮想rootディレクトリを指定してコマンドを実行できる。 # たとえば、chrというユーザーがいたとして、 # > chroot /usr/home/chr/ ls /usr/local/ # とやると、/usr/home/chr/を/とみなしてlsを実行する # つまりlsが/usr/home/chr/usr/local/を見に行くわけだが、 # このとき/usr/home/chr/bin/などのパスが通る予定のディレクトリにlsが # インストールされていないと、lsの実行自体ができないので注意が必要 これを利用して、たとえば > mkdir /usr/home/sandbox/ > mkdir /usr/home/sandbox/bin/ > cp 危険なコマンド /usr/home/sandbox/bin/ # たとえば/usr/sbin/dangerとか > chroot /usr/home/sandbox/ 危険なコマンド # 上記の例なら> chroot /usr/home/sandbox/ danger # > chroot /usr/home/sandbox/ /bin/danger でも同じ。 # (chrootを介すと/usr/home/sandbox/bin/が/bin/に見えるので) とやれば、他のシステムに影響を与えずに危険なコマンドをテストできる # ライブラリや外部コマンドが足りないと言われる場合は、 # /usr/home/sandbox/bin/などに必要なファイルをコピーしてやる chrootを前提にした運用 http://solaris.bluecoara.net/servers/apache/jail.phtml 上記をさらに押し広げて、/usr/home/sandbox/以下に、普段動いている FreeBSDの環境(/bin/とか/sbin/とか/etc/とか)を丸ごとコピーしてしまえば、 常時chrootすることを前提としたもうひとつの環境を作成できる。 サーバソフトなどを「余計なコマンドが利用可能できない環境」で動かして、 セキュリティを向上させることもできる。また、たとえば/usr/home/sandbox/を /と見立ててapacheやpostfixを動かした場合、サーバがクラックされても、 被害は/usr/home/sandbox/の中だけに留めることができる。 # 一部のソフトウェアでは、これが容易になるよう、portsの設定で # インストール時にどのディレクトリを/とみなすか聞いてくれる # 聞いてくれない場合でも、prefixを指定しておけば問題ないし、 # インストールが終わってからバイナリをコピーしてもかまわない chrootされていると/usr/binなどが見えなくなるので、chroot環境から呼ばれる ソフトウェアについて > ldd ソフトウェアのパス として、依存する環境を調べ、適宜chroot先にコピーしておく。 # たとえば、chrootしたapacheからperlを使う場合、perlとperlの依存環境を # まとめてchroot先にコピーする必要がある。場合によっては、chroot先を # prefixに指定して、改めてインストールしたほうが早いかもしれない。 もっと手軽なchroot http://www.wind.ne.jp/tamura/FreeBSD/www.htm http://www.intaa.net/~gato/ftpserver/oldftpd.html 標準でインストールされている/usr/libexec/ftpdなどには、もっと手軽に chroot環境で実行できるよう工夫がなされている。 ftpdの例でいえば、etc/ftpchrootにユーザー名を書いておくだけで、 ユーザーのホームディレクトリを/に見立てた状態で実行できる。 # ftpdの実行に必要なファイルは、すべてftpd自身が用意するので、 # これ以外の作業は必要ない ユーザーのログインパスワードが平文で流れることには変わりないので、 FTP接続専用のユーザーを作成しておけばよいだろう。 etc/ftpusersにftpdの利用を禁止するユーザーを指定できるので、上記の FTP接続専用ユーザー以外の全員を書いておけばよい。 # このような環境で実行すればftpdもそこそこ安全だが、ftpdは起動せずsshを # 経由してファイルをやり取りした方がより安全なので、特に必要がなければ # このような設定をする必要はない jail http://www.f-bell.net/FreeBSD/jail.html http://www.fkimura.com/jail0.html http://www.bichir.ddo.jp/bit/settings/jail_scripts.html http://www.pcc-software.org/security/jail-apache.html http://www.jp.freebsd.org/cgi/mroff.cgi?subdir=man&lc=1&cmd=&man=jail&dir=jpman-5.2.0%2Fman§=0 chrootの強力版らしいのだが、よくわからないのでリンクのみ。 時計を合わせる http://www.bsddiary.net/doc/ntpd.html http://acorn.zive.net/~oyaji/ntp/ntp.htm http://www.yomaigoto.jp/freebsd/ntp.html http://www.freebsddiary.org/xntpd.php # サーバの時計は、狂っているとはた迷惑なので、きちんと合わせておく デーモンを使わない場合 > ntpdate 近くのサーバ名 とすれば問い合わせ先のサーバの時計を基準に時刻設定される。 crontabに書いておけば自動実行も可能だが、cronとの相性はありあまりよくない。 # もしやむを得ずcronから実行するなら、他のルーチンタスクと近い時刻を避ける。 # ntpdateはntp.confを参照せず、またntpdと併用できないことに注意 デーモンを使う場合 デーモンは最初からインストールされているが、必要なら、公式ページから ソースを取ってくるなりports(netセクションかな?)を使うなりして最新にする。 /etc/ntp.confと/etc/ntp.driftというファイルを作る。 /etc/ntp.confに server サーバ名 restrict ルール という書式でサーバをいくつか書き、どこかの行に driftfile /etc/ntp.drift と書いておく。 # ルールは、上に書いたものが下に書いたもので順次上書きされてゆく。 いったんntpdateを行ってから > ntpd としてデーモン(クライアントとサーバの機能を兼ねている)を起動。 問題なく動いているようなら、/etc/rc.confに 3.x系なら xntpd_enable="YES" 4.x系なら xntpd_enable="YES" xntpd_flags="-c /etc/ntp.conf -p /var/run/ntpd.pid" 5.x系なら ntpd_enable="YES" と書いておく。 # xntpdという名前からntpdという名前に変更された影響 代表的な公開サーバは http://wiki.nothing.sh/page/NTP http://plamo.minidns.net/ntpmemo.html などで紹介されている。 しばらくたったら、 > ntpq -p で状態を確認してみる。 他のローカルマシンから時刻情報を参照する場合 /etc/ntp.confに restrict 192.168.0.0 mask 255.255.255.0 nomodify notrap notrust などと書く仕様だったはずだが、いつからか知らないが「notrust」を 記述すると問い合わせが弾かれるようになった。 設定ファイルの基本的な内容としては、 driftfile /etc/ntp.drift #logfile /var/log/ntp.log server サーバのアドレス1 server サーバのアドレス2 server サーバのアドレス3 #server 127.127.1.0 #fudge 127.127.1.0 stratum 10 restrict default ignore restrict 127.0.0.1 restrict サーバのアドレス1 mask 255.255.255.255 nomodify notrap noquery restrict サーバのアドレス2 mask 255.255.255.255 nomodify notrap noquery restrict サーバのアドレス3 mask 255.255.255.255 nomodify notrap noquery restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap などとなる。 127.127.t.u(tがクロックタイプでuがクロックタイプ番号)は特殊な指定で、 t=1のu=0(つまり127.127.1.0)だとローカルクロックを指す。 ネットワーク障害時の保険として低優先度サーバとして指定する。 authenticateなどは必要な場合だけ記述すればよい。 起動スクリプトについて /usr/local/etc/rc.dに.shという拡張子のファイルを実行権限つきで 置いておくと、起動時にstartという引数をつけて自動実行してくれる。 普通のシェルスクリプト(書き方についてはその9のオマケ参照)である場合と、 rc.subr-styleと呼ばれるスクリプト(/bin/shに読ませるスクリプトであることは 変わりないが)である場合があって、多少扱いが違う。 # 最後の行がrun_rc_command "$1"で終わっていればまず間違いなくrc.subr-style。 # 最初の方に# PROVIDE: で始まる行があるのも特徴。 後者の場合、nameとかrcvarとかcommandといった変数が特別な意味を持ち、 一見コメントに見える# PROVIDE:や# REQUIRE:で始まる行もちゃんと 意味を持っているのでヘタにさわらない方がよい。また、/etc/rc.confに 起動するかどうかを書き込む必要がある。 これはrcvarの値="YES|NO"という書き方で、たとえばrcvar=mydaemonとあれば mydaemon="YES"とすればよいのだが、rcvar=`set_rcvar`としているスクリプトが 多く(rcvar=${name}_enableと同義)、多少はソースを追わないと判別がつかない 場合がある。 # たいていの場合enableでソースを検索すればそれらしき行がすぐ見つかる。 この設定をしていないと、シェルから> mydaemon.sh start などとしても 動かないので注意が必要。 これはNetBSD1.3(rc.dサポートは1.5)が起源の方法で、上記の PROVIDEやREQUIREなどの値を使って起動順序の制御(このデーモンの 前にあのデーモンを起動しておきたいとか)などを行っている。 従来inetdやdaemontoolsなどのスーパーデーモンで行っていたきめ細かい デーモン制御の一部を、スクリプトで実装したものなのだろう。 詳しくはrc.subrのmanを参照(FreeBSD5.0で実装された機能で、2005/10/12現在、 http://www.jp.freebsd.org/man-jp/search.htmlではエントリが 見つからないので、日本語のmanはまだ用意されていないのかもしれない)。 DynamicDNSを利用する(必要なら) http://iris.homeunix.net/yayoi/freebsd/setting/ddclient.asp http://www.fkimura.com/ddclient0.html http://www.sonorilo.net/dyndns.html ちょっと面倒な問題 DNSの正引き(ホスト名をもとにAレコードを参照してIPアドレスを特定する)と 逆引き(IPアドレスをもとにPTRレコードを参照してホスト名を特定する)は 別の仕組みで動いており、ダイナミックDNSは普通「正引きのみ」を提供する。 ここで注意が必要なのは、グローバルIPをプロバイダから借りた際に ホスト名もすでに借りているということ。たとえばプロバイダに 123.456.789.012というIPアドレスと012.myprovider.netというホスト名を 借りた場合、「012.myprovider.netは123.456.789.012です」というAレコードと 「123.456.789.012は012.myprovider.netです」というPTRレコードが すでに有効になっている。 ここにダイナミックDNSを使って「myhost.myddns.netは123.456.789.012です」 というAレコードを追加するのは、そんなに難しくない(というかごく普通の ダイナミックDNSサービスがやっているのはこれ)。DDNSサーバがmyddns.net以下の ドメインネームを管理しているので「myhostはここ」という情報を自前で提供できる。 しかし同じ条件で逆引きをかけるとプロバイダのDNSサーバが先に 「123.456.789.012は012.myprovider.netです」と答えてしまう。 つまり、123.456.789.012というホストが「私はmyhost.myddns.netです」と 名乗っても、逆引きされると「123.456.789.012は012.myprovider.netです」 という情報しか流れない。これで困ることはあまりないが、一応覚えておくべきだろう。 なお2014年5月現在、仕様上は、 http://www.ietf.org/rfc/rfc2181.txt There is no implication in that section that only one PTR record is permitted for a name. No such restriction should be inferred. とあるように、「123.456.789.012は012.myprovider.netとmyhost.myddns.netです」と 答える動作も認められているが、実装上「逆引きは1つ教えたら終わり」「もし複数 教えてもクライアントが最初の1つしか見ない」という例がほとんどらしい。 もちろん、プロバイダがPTRレコードの権限委譲(「このIPアドレスの逆引きはこの サーバに任せます」という登録)をしてくれれば、逆引きも自前で管理することが 不可能ではないが、大規模な固定IP契約や専用線契約でないと難しいことが多いようだ。 # myhost.myddns.netのAレコードを管理しているのはddnsサーバだが、 # 123.456.789.012のPTRレコードを管理しているのはプロバイダの # DNSサーバであることに注意。 自宅サーバでなく、専用ホスティング(大規模なデータセンターなどに設置してある ホストを丸ごと貸してくれる)やハウジング(場所と回線だけ借りてハードウェアは 自前で用意する)なら、専用線が引っ張ってあるはずなので上記のような問題は 生じにくいと思われる(多分)。 # 最近はVPS(virtual private server)を使ったホスティングが廉価になってきている。 DDNSサービスの利用登録をする。 http://www.dyndns.org/ が最大手でサービスも安定していたが、無料アカウントの新規募集を停止した。 日本語表示のサービスだと以下のようなものがあるらしい (サービス内容までは確認していない)。 http://www.ieserver.net/ http://f5.si/ http://www.mydns.jp/ # ここではdyndns.orgを利用することを前提に話を進める。 追記:dyndns.orgが http://dyn.com/ に移転した。これに伴いddclient用の設定ファイル生成スクリプトができたので、 下記の手動設定は必要なくなったが、キャッシュ対策に加えて定期ログインが 必要になった(この項の最後を参照)。無料サービスを終了したという情報は 当たらずも遠からずで、2014年5月現在、既存ホストの継続利用はできるが、 無料アカウントでの新規ホスト名取得はできない(30日間ログインを怠って ホスト名が失効すると復活できなくなる)。 http://sourceforge.net/apps/trac/ddclient/wiki/Faq http://sourceforge.net/apps/trac/ddclient/wiki/Usage ports/dns/ddclientをインストールする。 # dyndns.orgとの相性がよい更新ソフト。ddupという古風なツールもある。 > cp /usr/local/etc/ddclient.conf.sample /usr/local/etc/ddclient.conf としてから/usr/local/etc/ddclient.confをエディタで開いて use=の項目を設定(To obtain...のすぐ下の行コメントアウトを解除すれば楽) loginとpasswordも設定(DDNSサーバの提供元から発行されたものを書く) その下のprotocol、proxy、serverの項目、もしくは、dyndns.orgを使うなら dyndns.org dynamic addresses の項目を設定。必要であればmax-interval (ここで設定した時間を経過すると、キャッシュがヒットしても強制的に 更新を行う:デフォルトはmax-interval=15dらしい)。 > ddclient -daemon=0 -verbose -noquiet # /var/tmp/ddclient.cacheに現在のアドレスが記録されていないと # Invalid Value for keyword 'ip' = ''というエラーが出るが、 # 初回起動時であれば記録がなくて当然なので気にしなくてよい。 うまく動いているようなら > cp /usr/local/etc/rc.d/ddclient.sh.sample /usr/local/etc/rc.d/ddclient.sh # 2011年3月追記:最近のportsでは、この作業は必要ない で自動起動させる。HTTPに80番以外のポートを使う場合はWebHopを併用すると便利。 なお、DNS設定を手動で変更した場合、/var/tmp/ddclient.cacheの情報と 実際の設定が食い違うため、場合によりキャッシュを初期化する必要がある。 # うまく動かない場合、キャッシュを削除するか-forceオプションを使う またdyndnsの仕様変更で「ウェブサイトでのログイン」を30日以上行わないと アカウントが失効してしまう(以前はIPアドレスを更新していればOKだった)。 これはddclientの問題でもアップデートが失敗しているのでもなく 単にログインしていないのが原因。事情やワークアラウンドは以下を参照。 http://www.dyncommunity.com/questions/34037/my-hostname-suddenly-disappeared-nothing-works-any.html http://www.dyncommunity.com/questions/32854/how-to-use-wget-or-curl-to-login.html http://www.dyncommunity.com/questions/33613/having-your-computer-log-into-your-account-so-you.html wget(別途インストールする必要あり)を利用する方法が手軽そうなのだが、単純に #! /bin/sh USER=myusername PASS=mypass UA='Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6' MULTIFORM=$(wget -U "$UA" --save-cookies cookies.txt https://account.dyn.com/ -O - | grep -m1 multiform | tr '=' '\n' | tail -1 | cut -d "'" -f 2) wget -U "$UA" --directory-prefix=/var/log/ddclient --post-data "username=$USER&password=$PASS&iov_id&multiform=$MULTIFORM" https://account.dyn.com/ などとしても「DigiCert High Assurance CA-3」という証明書を確認できないらしく 手元では正規のSSL接続ができない。--no-check-certificateという危険な オプションがあるにはあるのだが、送るのがパスワードだけにちょっと躊躇われる。 結局筆者は月に数回くらいは動かしているWindowsマシンを使い、ログインページを タブブラウザのスタートアップに入れておくというワークアラウンドにした。 追記: すでに触れたがルート証明書はsecurity/ca_root_nssというportsでインストールできる。 デフォルトの保存場所は/usr/local/share/certs/ca-root-nss.crtらしい。 SMTP # spamの踏み台になることがないよう、リレー関連の設定には特に注意を払う。 # インターネット越しの利用を許可する場合には、それなりの設定が必要。 メールサーバの必要性 これからどんなサーバを立てるにしても、自分のサーバが他人に迷惑を かけた場合に苦情メールを受信する必要があるため、sendmailを使っても qmailを使ってもよいが、とにかくメールを受信できる環境だけは 作っておく必要がある。 # 名前の最後にmasterがついているメールアカウントが管理者の連絡先になる。 # たとえばSMTP(メール)サーバならpostmaster@サーバ名が管理者のアドレス また、デーモン君からも毎日daily run output というタイトルで報告メールが届く # その場で必要にならなくてもある程度の期間は保管しておく。 # SMTPサーバの生存確認にもなるし、苦情を放置しないためにも、受信はこまめに。 有名なSMTPサーバ Postfix http://www.fkimura.com/postfix1.html http://www.postfix.org/ http://www.kobitosan.net/postfix/ http://solaris.bluecoara.net/servers/postfix/ sendmailとの互換性を重視したSMTPサーバ。スッキリとしたデザインで 機能も豊富、普及率も高い。コンパイルオプションでSMTP AUTH に対応。 SSL対応パッチもある。 http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/ qmail http://www.fkimura.com/qmail0.html http://cr.yp.to/qmail.html http://www.jp.qmail.org/ セキュリティの非常に堅いSMTPサーバ。publicfileやdjbdnsの 作者でもあるD. J. Bernstein (略してdjb)という人が作っている。 更新停止を機にCourierプロジェクトなどが立ち上げられた。 Postfixを使う http://hk-tech.homeip.net/pcserver/postfix.html http://sakura.take-labo.jp/freebsd/mail_postfix.php?stype=simple http://www.hijiki.net/archives/000040.html http://www.fkimura.com/postfix1.html http://www.kobitosan.net/postfix/conf/main.cf.jp http://suken.jp/~tet/freebsd/free24.html http://www.postfix.org/ 本体のインストール インストールの前に、/etc/rc.confのsendmail_enable="YES"という行を sendmail_enable="NONE"に書き換えていったんリブートしておく。 ルーターの設定なども適宜行い、ports/mail/postfixをインストール。 # 追記:設定方法が変わったのでインストール時に表示される説明を参照 /usr/local/etc/postfix/main.cfを、バックアップをとってから適当に編集。 myhostname、mydomain、mydestination、mynetworks、alias_maps、 home_mailbox(もしくはmail_spool_directory)あたりが最低限の設定。 header_checksも設定しておくべきだろう。 # home_mailboxをMaildir/にした場合の設定はcourierの項目を参照 プロバイダのSMTPサーバ以外に向けた25番ポートの通信を遮断しているプロバイダが あるので、その場合 relayhost = 中継サーバのアドレス という1行を追加しておく必要がある。 # 中継サーバのアドレスは普通、[address]:portという書き方になり、たとえば # relayhost = [smtp.example.com]:123456 # と書くとsmtp.example.comのポート番号123456を指定したことになる。 # []で括ってあるのは、MX lookup を行わないという意味で、ポート番号を # 省略すると25番宛てになる(たいていの場合省略してもOKなはず)。 myhostnameにはDDNSで登録したサーバ名、mydomainには/etc/rc.confに書いてある hostnameの一つめのピリオドの後ろをそのまま書けば問題ないだろう。alias_mapsは hash:/etc/mail/aliasesが標準っぽいが、新しめのFreeBSDでは、 /etc/aliasesと/etc/mail/aliasesがハードリンクになっている模様。 設定後は > postfix check として設定ミスがないか確認しておいた方がよい。 Mailbox方式とMaildir方式 Mailbox方式は、古くからあるメール保存方式で、複数のメールを一塊の ファイルにして保存する。sendmailが採用している。 Maildir方式は、qmailが採用し始めたメール保存方式で、受信メールを一塊の ファイルに書き込まず、メールボックスをディレクトリとして確保し、1メール 1ファイルの形で管理する。 # この形式だと、> mail ではメールが読めなくなるので一応注意が必要 Postfixの場合、Mailbox方式とMaildir方式の両方に対応しているので、 好きな方を選べる。 エイリアスの追加と変更 http://gabacho.reto.jp/tech-note/aliases.html http://www.kobitosan.net/postfix/jman/postalias.1.html http://www.jp.freebsd.org/cgi/mroff.cgi?sect=1&cmd=&lc=1&subdir=man&dir=jpman-5.2.0%2Fman&subdir=man&man=newaliases /etc/mail/aliasesを適当に編集。エイリアス元: エイリアス先という書式で、 エイリアス先は,で区切って複数書ける。,の直後なら改行してもよい。 エイリアス先には外部のメールアドレスを指定してもよい。 たとえば support: root, user1, root@example.com とすれば、support@myhostname宛てのメールを、root@myhostnameと、 user1@myhostnameと、root@example.comに配達することになる。 # myhostnameには/usr/local/etc/postfix/main.cfで指定した # 自分のサーバ名が入る。 このとき、support@myhostnameというアカウントがあったとしても、そちらには 配達されなくなるので注意。エイリアス先に\supportと\をつけて書いてやれば、 support@myhostnameにも配達が行われるが、外部のメールアドレスと併記すると 無限ループができてしまう可能性があるので避ける。 # この場合の解決法は上記のリンク参照 ひとつのアドレスからの転送先が非常に多い場合は エイリアス元: include:リスト名 として1行1アドレスの書式で書いたリストを読んでもよい # リスト内の区切り文字は改行のみで,は不要 root: メールが届いたときにすぐ気づける宛て先 postfix: root の2行は最低限書いておく # FreeBSDデフォルトの設定ファイルを使っているなら、postmaster宛てのメールは # 最初からrootに届けるよう設定されているはずだが、こちらも一応確認する。 > postalias /etc/mail/aliases # これで/etc/mail/aliasesを元に/etc/mail/aliases.dbというファイルが # 作成(すでに存在するなら更新)される # sendmailの場合は> newaliases(> sendmail -bi でも同じ)とするらしい 動作テスト 適当なディレクトリ(/tmpあたり)に移動して、適当な名前の テキストファイル(testとか)を新規作成する(中身もなんでもよい) > mail root@サーバ名 < ファイル名 # サーバ名は、mydestinationにlocalhostを指定していればコンピュータの名前、 # localhost.$mydomainを指定してあれば/etc/rc.confに書いてあるhostname、 # 両方書いてあればどちらでもよい > mail として先ほど送ったメールが届いていればきちんと動作している。 外部公開する場合、続いて25番のポートを空けた後、プロバイダの メールアドレスなどを使ってDDNSで設定したサーバ名での送受信を 試しておく。 # mydestinationの項目に$myhostnameが書かれていることを確認しておく 自動実行の設定 /etc/rc.confに sendmail_enable="YES" と追記しておく。sendmailをreplaceしていなかった場合は、 自分で/usr/local/etc/rc.d/postfix.shを作成する # 上記のリンク先のほか、postfix.shでぐぐればいくらでもサンプルがある /etc/periodic.confを新規作成して daily_status_mail_rejects_enable="NO" daily_status_include_submit_mailq="NO" daily_submit_queuerun="NO" と記入。 /etc/syslog.confの/var/log/sendmail.stの行をコメントアウト 管理 /usr/local/etc/postfix/main.cfをさらに設定。 最低限、message_size_limit(とmailbox_size_limit)は設定しておく オンラインでのセキュリティチェックをしてくれる団体があるので、 > telnet relay-test.mail-abuse.org > /var/log/smtptest などとして、設定のチェックをしておく。 http://www.mail-abuse.com/ http://www.hijiki.net/archives/000063.html 必要に応じて、pflogsummやprocmailあたり(mailセクション)を インストールしておく。 # ログファイルは/var/log/maillog インターネット越しのメール送信が必要な場合 http://solaris.bluecoara.net/servers/postfix/smtpauth.phtml http://solaris.bluecoara.net/servers/postfix/tls.phtml http://www.kobitosan.net/postfix/install-report-sasl.html http://www.paken.org/linux/linux-tips/postfix.html http://www.dream-seed.com/linux/postfix.html http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/ SMTP-AUTH(CRAM-MD5)などを利用して、何らかの認証を行うことが必要。 SMTP-AUTH単独だと、認証はできても送信メールが丸見えなので、特に理由が ない限りSSL/TLSも併用する。 # 認証なしだと、サーバのアドレスとポート番号がばれただけでspamerの餌食になる。 # 上記のmail-abuse.orgなども活用して、リレーのチェックも必ずしておく。 SMTP-AUTHについて、上記リンク先ではコンパイルオプションを手動で書き換える 方法が紹介されているが、portsから入れれば、最初に設定を聞いてくれる。ここで sasl2を有効にすれば、SMTP-AUTHに必要なコマンド(cyrus-sasl関係)はすべて 入るので、前もってインストールしておく必要はない。以下では、sasl関係の コマンドはすべて最後に2がつく方を使うので、saslを使う場合は適宜読み替える。 その前にsasl関連コマンドの紹介。saslpasswd2は: -p(パイプモード、プロンプトを出さず標準入力からパスワードを読む) -c(クリエイト、meshsにアカウントを作成させる) -d(ディスエイブル、meshsにアカウントを無効化/削除させる) -n(ノーユーザーパスワード、平文のユーザーパスワードプロパティを設定しない) -f ファイル名(sasldbを指定) -a アプリ名(アプリケーション名を指定) -u ドメイン名(ドメイン名を指定) -v (バージョン、バージョンを表示して終了) というオプションを持つ(> saslpasswd2 -helpの内容を訳しただけ)。 実際の登録では > saslpasswd2 -c -u ドメイン名 ユーザー名 のように指定する。 登録情報の確認にはsasldblistusers2を使い、オプションは-fと-v(働きは saslpasswd2のオプションと同じ)。 > saslpasswd2 -c -u `postconf -h myhostname` ユーザー名 # postconfはmain.cfの設定を補助するコマンドで、-hオプションだと引数に # 設定された値を表示する。自分でドメイン名を入力してももちろんかまわない。 でsaslで認証を行うユーザー名とパスワードを設定すると、 /usr/local/etc/sasldb2.dbが作成されるので、 > chgrp mail /usr/local/etc/sasldb2.db > chmod 640 /usr/local/etc/sasldb2.db などとしてpostfixを実行するユーザー権限でsasldb2.dbが読めるようにしておく。 メールクライアントとローカルサーバの間でSMTP認証をする場合、main.cfに smtpd_sasl_auth_enable = yes smtpd_recipient_restrictions = permit_sasl_authenticated, permit_auth_destination, reject の2行を書いておくとcyrus-saslを利用したSMTP-AUTHが有効になる。 # smtpd_recipient_restrictionsは、メール送信要求(RCPT TO コマンド)を # 受け付ける相手を限定するためのコマンドで、デフォルトでは書かれていない。 # 省略した場合 # smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination # と書いたのと同じ扱いになる。接続そのものを拒否する場合(DOS対策など)は # smtpd_client_restrictionsを使えばよく、その他のコマンドにも # smtpd_*****_restrictionsで制限できるものがある。 # http://www.postfix.org/postconf.5.html smtpd_recipient_restrictionsのルールについて主なものを挙げておくと、 http://www.postfix.org/postconf.5.html#smtpd_recipient_restrictions http://www.postfix.org/postconf.5.html#generic reject:接続を拒否する(エラーコード554を返す) defer:接続せずに、後でもう一度接続してみるよう伝える(エラーコード450) defer_if_permit:以後のルールでpermitされたらdeferする(デバッグ用?) reject_unauth_destination:auth_destination以外はrefuseする # 上記4つのうち最低1つは必須(設定しないとうまく動かない) permit_mynetworks:mynetworksで定義したホストは(認証なしで)許可 check_recipient_access:accessデータベースで識別する # accessというのは、Postfix access table のデータベース形式のこと # http://www.postfix.org/access.5.html permit_sasl_authenticated:saslで認証されたユーザーからの接続を許可 # sasl認証に失敗した場合はエラーコード535が返る。 permit_auth_destination:auth_destinationは許可 permit:すべて許可(あまり使わない方がよいと思う) ルールは、先に書いたものから順に適用されてゆく(NATテーブルなどと同じ)。 auth_destinationというのは、relay_domainsで定義したホストへの転送メールと、 mydestination、inet_interfaces、proxy_interfaces、virtual_alias_domains、virtual_mailbox_domains のいずれかがあて先になっているメール(要は受信メール)を指す。 # いずれの場合も、sender-specified routing (user@elsewhere@domain) が # 含まれてはならないらしい smtpd_recipient_restrictions = reject_unauth_destination と書いても smtpd_recipient_restrictions = reject_unauth_destination, permit と書いても smtpd_recipient_restrictions = permit_auth_destination, reject と書いても同じ結果になる(はず)。 # 筆者は、permit_auth_destination, reject と書くのが好み # (すべてのルールを明示的に示せてルールの追加もしやすいので) デフォルトの設定をなぞるだけなので必須ではないが、念のため /usr/local/lib/sasl2/smtpd.confに pwcheck_method: auxprop auxprop_plugin: sasldb mech_list: cram-md5 digest-md5 plain login # 後半2行は必要ないかも。mechの行は許可するものを任意に選択。 main.cfに smtpd_sasl_application_name = smtpd と書いておいた方がいいらしい。 追記:パスの設定が、バージョン2.3から以下のように変わった。 旧:smtpd_sasl_application_name = smtpd 新:smtpd_sasl_path = smtpd ローカルサーバとリレー先サーバ(プロバイダなど)の間で SMTP認証が必要な場合は、main.cfで以下の設定を行い、 smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/usr/local/etc/postfix/認証ファイル smtp_sasl_security_options = 適当なオプション # オプションについては次の段落を参照。 上で指定した場所にパーミッション0600で認証ファイルを作成して [ホスト名]ポート番号 ユーザー名:パスワード # ホストとポートはrelayhostと同じにする。 # ユーザー名は「そのサーバでメール送信ができる」ユーザー名で、 # @以下を省略しないで書く。 という書式でアカウント情報を保存し、 > postmap /usr/local/etc/postfix/認証ファイル としてハッシュファイルを作成、平文の認証ファイルを削除しておく。 必要に応じてmain.cfに smtpd_sasl_security_options = noanonymous, noplaintext # 匿名接続と平文でのパスワードのやり取りを禁止 broken_sasl_auth_clients = yes # OutlookExpress5系など、LOGIN 認証 しかできないクライアントのための設定 あたりも設定するとよいだろう。 # 動かない場合は> postfix checkを忘れずに。 設定が終わったら、プロバイダが提供しているアドレス(自分のアドレスを使うこと) など、外部のネットワークにパスワードなしでメール送信をしてテストをしておく。 SSL/TLSを利用する場合、main.cfにsmtpd_tls_で始まる項目を作って適当に編集し、 サーバの証明書を作るの項目を参照して鍵と証明書を作り、指定のディレクトリに置く。 # > grep tls < main.cf.default | cat >> main.cf とでもしてから # main.cfを編集すると楽かも。 spam避け http://www.amulet.co.jp/solutions/postfix-filtering.html http://www.ansi.co.jp/tech/mail/spam/sender_restrictions.html http://www.ansi.co.jp/tech/mail/spam/content_filtering.html http://vine.1-max.net/postfix-filter.html http://www.kozupon.com/mail/postfix2.html main.cfに header_checks = regexp:ブラックリストのパス body_checks = regexp:ブラックリストのパス # pcre:ブラックリストのパス と書いておけばperl互換の正規表現が使えて # 便利になるが、正規表現ライブラリを別に組み込む必要があるらしい。 と書いておくと、それぞれヘッダと本文の内容からフィルタリングができる。 ブラックリストにはFreeBSD標準の正規表現が使える。 # はずなのだが、筆者の環境ではregexpでは何故かREJECTができなかった # (IGNOREはできる)。pcreにするとアッサリ動いた。 ブラックリストは /条件/ 処理 # 大文字と小文字を区別する場合は/条件/i 処理 という書式で書き、処理にはOK(受信する)、IGNORE(ヒットした行を削除)、 REJECT(受信しない:送信元にはエラーが返る)の3つがある。たとえばメール本文の ブラックリストに /^(|[^>].*)hoge/ REJECT と書いておけば本文にhogeを含むメールの受信を拒否する。ヘッダのブラックリストに ついては、 /^Subject:.*moge/ REJECT とすればサブジェクトによるフィルタリングが、 /name=.*\.拡張子/ とすれば添付ファイルによるフィルタリングが、 /^X-Mailer:.*page/ REJECT とすればメールクライアントによるフィルタリングが、 /From:.*アドレスの一部/ REJECT とすればFromアドレスによるフィルタリングが、 /^Return-Path:.*<#.*@.*>/ とすればReturnアドレスによるフィルタリングが可能。 main.cfに smtpd_client_restrictions = check_client_access hash:ブラックリストのパス smtpd_sender_restrictions = reject_non_fqdn_sender hash:ブラックリストのパス と書いておくと、それぞれ送信元IPアドレスとenvelope-fromによるフィルタリングが 可能。ブラックリストの書式はそれぞれ、 IPアドレス 処理 # 192.168.0.1/16 REJECT とか 電子メールアドレスもしくはドメイン 処理 # spammer@example.com REJEC Tとか # spammers.org REJECT とか やはり> postmap ブラックリストのパス でデータベースを作るが、なぜ データベース形式がregexpではなくhashなのか(というより、hashというのが どんな形式なのか)、筆者はわかっていない。 # 利用できる書式は> postconf -mで確認できる。 hash方式を利用する場合、> postmap ブラックリストのパス としてデータベース(.dbファイル)を作っておく必要がある(らしい)。 # header_checks = やbody_checks = では.dbをつけずに指定する。 ブラックリストを公開しているすばらしいページがあるので紹介しておくが、 注意書きにもある通り、サイト管理者が個人的、実験的に試した事、又は独自に 調査したもので、情報に誤りがある可能性も多分にあるので、鵜呑みにせず、 あくまで自己責任の元で利用すること。 http://akionweb.com/archives/2004/12/postfix_ipspam.shtml また、main.cfに mailbox_command = フィルタリングソフトのパス と書いておくか、~/.forwardというファイル(メール受信の際に実行される スクリプト)を作成することで、外部フィルタリングソフトに処理を任せることもできる (main.cfだと全ユーザー一括だが、~/.forwardならユーザーごとに処理を変えられる)。 postfix用のフィルタリングソフトとしてはProcmailが有名。 # 筆者はインストールしてみただけで使っていない。 http://suken.jp/~tet/FreeBSD/procmail.rhtml http://www.linux.or.jp/JM/html/procmail/man1/procmail.1.html http://www.rcnp.osaka-u.ac.jp/Divisions/CN/computer/ibm/manual/procmail/setting_procmail http://www.club.kyutech.ac.jp/support/manual/procmail.html http://www.jp.redhat.com/manual/Doc72/RH-DOCS/rhl-rg-ja-7.2/s1-email-procmail.html http://www.jaist.ac.jp/~fjt/procmail.html portsからインストールして > cp /usr/local/share/examples/procmail/forward ~/.forward としてから ~/.forwardのYOUR_LOGIN_NAMEとなっている部分をログインIDで書き換える。 # "|IFS=' ' && p=/usr/local/bin/procmail && test -f $p && exec $p -Yf- || exit 75 #ユーザー名" # となるはずだが、 # "|exec /usr/local/bin/procmail" # でもprocmailの起動自体は可能(書き方はどうでもいいといえばどうでもいい)。 同様に/usr/local/share/examples/procmail/にある1procmailrc〜3procmailrcの どれか(ちゃんと見ていないのでわからないが、多分似たような内容なので 筆者は1を使った)を~/にコピーする。 POP3(とIMAP) # POP3もIMAPもパスワードが平文で流れるので、POP認証にログインパスワードは # 使用せず、インターネット越しに利用する場合は最低限APOPを使う。 # その場合ルーターの設定なども必要なので忘れて慌てないように。 # SMTPサーバが溜めているメールをクライアントに送るためのサーバなので、 # そもそも公開サーバにする必要があまりないが。 有名なPOP3サーバ courier-imap http://www.courier-mta.jp/ http://mjm4u.net/oss/courier-imap/index.html http://www.courier-mta.org/ もとはqmail代替を目指したMTAだったらしいが、各コンポーネントの単独利用ができる。 Maildir方式とSSLに対応し、IMAP対応版もあるPOP3サーバ。利用者が非常に多い。 仕様変更(とくに認証関係)が非常に頻繁なので、アップデート時は注意が必要。 # IMAPというのは、Webメールなどで利用するプロトコルのこと。 APOP対応パッチもある。 http://www.hiemalis.org/%7Ekeiji/software/ solid-pop3d http://packages.debian.org/stable/mail/solid-pop3d http://solidpop3d.pld.org.pl/ 本家ページがステキなPOP3サーバ。Maildir方式、Mailbox方式、APOPに対応。 # 2005/10/10現在、本家ページが落ちているし、ソフトの更新も止まっている感じ。 qpopper http://www.emaillab.org/djb/qmail-pop/qpopper.html http://www.eudora.com/products/unsupported/qpopper/ Berkeley "popper"をQualcomm社(EUDORAの開発元でもある)が拡張したPOP3サーバ。 Mailbox方式とAPOPに対応、コンパイルオプションでSSLにも対応。ちょっと古め。 courier-imapを使う http://mjm4u.net/oss/courier-imap/index.html http://www.fkimura.com/courier-imap1.html http://www.f-bell.net/FreeBSD/courier-imap.html http://solaris.bluecoara.net/servers/courier-imap/imap1.phtml http://solaris.bluecoara.net/servers/courier-imap/imap2.phtml http://www.tom.comm.waseda.ac.jp/~hama/admin/smtpauth.html 本体インストール # 記述が古くなっているので、後半の「追記」を参照 ports/mail/courier-imapをインストール(ports/mail/courierはSMTPdも セットになった別のデーモンなので、postfixを使うならこれは入れない)。 /usr/local/etc/courier-imap/にある設定ファイルのうち、必要なものをコピー。 # > cp pop3d-ssl.dist pop3d-ssl とかなんとか # 追記:最近のバージョン(4以降)ではコピーしなくても用意されるはず。 ports/mail/courier-authlib(userdbとか、その辺のコマンド)が同時に インストールされるはずだが、認証がうまくいかないときはまずこちらを疑う。 # authdaemonが落ちて(もしくは起動に失敗して)認証できなかった場合はsyslogに # authdaemon: s_connect() failed: No such file or directory # というログが残る(これ以外のログは/var/log/mail)。 # 追記:いつからかわからないが、security/courier-authlibに移動した。 # configureでWITH_USERDBを有効にしておく必要がある、と思う。 suなり再ログインなりでメールを使うユーザーになって > maildirmake /メールディレクトリを作りたい場所/Maildir # たとえば> maildirmake /usr/home/user1/Maildir とか としておく(別にこの名前である必要はないのだが)。 パーミッションは700のはず(間違うとMaildir invalid というエラーになる)。 # postfixを使っているなら、何かメールを送ってやるだけでmain.cfで指定した # 場所にMaildirができるので、そちらを利用した方が簡単。 rootユーザーについては少し注意が必要で、メールボックスを~/Maildir (つまり/root/Maildir)にすると、/のあるパーティションにメールを 溜め込むことになるので、/usr/home/以下あたりに適当なディレクトリを作って、 そこをメールボックスとして使った方がよい(~/にはシンボリックリンクを貼る)。 Maildir/courierpop3dsizelistというファイルが自動作成されて、2行目以降に 配送済みだがサーバに残っているメールのリストが書き込まれる(多分)。 # 1行目の意味はよくわからない。 このファイルの2行目以降を全削除してからサーバにアクセスすると、サーバに 残っているメールを全部受信できる(はず)。おそらく、一度配送の終わった メールを再受信するコマンドなどもあるのだろうが、調べていない。 設定 /usr/local/etc/postfix/main.cfのhome_mailboxの項目をMaildir/に設定しておく。 # courierはMailbox方式に対応していないので、これは必須 /usr/local/etc/courier-imap/pop3d(と/usr/local/etc/courier-imap/imapd)を 開いて適当に編集。 # いじらないとどうしても動かないという個所はないはず /usr/local/etc/authlib/authdaemonrcにも一応目を通す。 # 必須ファイルだが、修正しないと動かない個所はないはず。 /etc/passwdでuidやgidを調べて、 > userdb ユーザー名 set home=/ホームディレクトリ/ mail=/メールディレクトリ/ uid=番号 gid=番号 としてユーザーデータベースを作り、 # /usr/local/etc/authlib/userdbというプレーンテキストを操作するだけなので、 # 書式がわかるなら手動でやっても別に構わない(はず) > userdbpw | userdb ユーザー名 set pop3pw(もしくはimappw) としてPOP3のパスワードを登録し > makeuserdb # /usr/local/etc/authlib/userdbをもとに/usr/local/etc/authlib/userdb.datを # 作成するコマンド。userdbのパーミッションは0600などでなくてはならない。 # 追記:保存先が/usr/local/etc/以下に変わった。 でデータベースを有効にする。 # やらなくてもログインパスワードでアクセスは可能だが、 # セキュリティ上好ましくない(rootユーザーが他のコンピュータから # ログインパスワードでPOP3アクセスするなんてのはもってのほか) > userdb -show でユーザーの一覧(ユーザー名のみの一覧)、 > userdb -show ユーザー名 でユーザー情報が表示できるほか、 > userdb ユーザー名 に続けてunsetでデータの削除、delでユーザーの削除ができる。 # いずれも、-fオプションでuserdbファイルのパスを手動指定できる。 また、aliasというユーザー名を使うとキャッチオールアカウントが作れるらしい。 # 試していないのでよくわからない。 起動設定は、portsを使った場合/usr/local/etc/rc.d/にシンボリックリンクが 自動生成されているはずなので、気にしなくてよい。 # なければ、/usr/local/libexec/courier-imap/ディレクトリにある # pop3d.rc(とimapd.rc)を/usr/local/etc/rc.d/にコピーしてやれば # 問題ない(popd.shのように、拡張子を.shに変えておく) 追記: rc.confに courier_authdaemond_enable="YES" courier_imap_pop3d_enable="YES" と書くタイプのスクリプトに変更された模様(バージョン4.0.6で確認)。 追記: userdbの書式が変わり、 メールアカウント uid=UID|gid=GID|home=ホームディレクトリ|systempw=* UID= UNIXアカウント のような書式になった(2行で1アカウント、2行目はUIDからの逆引き)。 pw2userdbというスクリプト(portsからcourier-authlib-userdbを インストールすると勝手に入る)を実行すると、新しい書式のuserdbを 自動作成できる。たとえば > pw2userdb > ~/dbtmp などとして雛型を作り、必要な部分だけ残してcatなどで /usr/local/etc/userdbに転送する。 SSL 鍵と証明書はpostfixのものと共用する。 > cat postfixのSSL鍵 postfixのSSL証明書 >> courier.key.crt などとして鍵と証明書を結合してしまい、 /usr/local/etc/courier-imap/pop3d-ssl(とimapd-ssl)のTLS_CERTFILEの行に TLS_CERTFILE = /ディレクトリ名/courier.key.crt と書いておく(例によってパーミッションには注意)。 # 試したことはないが、qmailと併用した場合も似たようなものだろう。 バージョン4.0.2,1ではAPOPに対応していないが、パッチを当てれば利用可能らしい。 # SSLを扱えないクライアントがある場合は必要になるが、筆者は試していない。 認証に失敗するときのチェックリスト(本家FAQの訳) ・設定ファイル(usr/local/etc/courier-imap/pop3dなど)で適切にAUTHMODULESを 選択したか ・authdaemon認証proxyを利用する場合はauthdaemonrcの設定は正しいか ・authdaemondは起動しているか(psなどで確認) ・認証モジュールの設定は正しいか(authldapとauthmysqlは設定ファイルが別にある) ・authpamを利用している場合、PAMライブラリの設定が必要 ・LDAPやMySQL(利用しているなら)はダウンしていないか ・maildirを利用しているか(mailboxはサポート外) 認証に失敗するときのチェックリスト(筆者による追加) ・とりあえず> grep courier /usr/ports/UPDATING(必須) ・userdbのパーミッションは正しいか(0700という解説もあるが、 0600でOKなはず) ・userdbの設定は正しいか(ユーザー登録をやり直してみる) ・makeuserdbは実行したか(/usr/local/etc/userdbのタイムスタンプも確認) ・courier-imapとcourier-authlibのどちらかが、片方だけ古くないか ・courier-imapのインストールオプションで必要な認証機能を有効に しているか(/var/db/ports/courier-imap/optionsで確認) everything was done according to the proper protocol. but the port maintainer has not though it would be nice to provide some info : - courier-authlib was split in : databases/courier-authlib-mysql databases/courier-authlib-pgsql databases/courier-authlib-userdb databases/courier-authlib-usergdbm mail/courier-authlib-vchkpw net/courier-authlib-ldap security/courier-authlib security/courier-authlib-base and then, after portupgrade courier-authlib from 0.55 to 0.57, you have to install courier-authlib-userdb to restore CRAM-MD5 authentication. - userdb files have moved to /usr/local/etc/ from /usr/local/etc/authlib/ - CRAM-MD5 authentication has moved from a dedicated module to authuserdb. - one should remove "authcram" from authmodulelist directive in file authdaemonrc. When you know that, you don't lose 1 hour and a half wondering why everything is broken after portupgrade. 新しめのPOP3サーバ teapop http://www.toontown.org/teapop/index.php http://svn.toontown.org/ToonTown/Teapop/main/doc/INSTALL http://www02.so-net.ne.jp/~nsasaki/sendmail/teapop.html http://www02.so-net.ne.jp/~nsasaki/sendmail/teapop-man-ja.html http://www.fkimura.com/openwebmail0.html Mailbox/Maildir方式、APOP、バーチャルユーザー(apache用のhtpasswdによる 認証を含む)、各種データベースとの連携などに対応している。ネイティブ環境は 多分OpenBSD。FreeBSDのPortsからバージョン0.3.8を入れると、インストール時に ./configureがうまく動かなかったり、/usr/local/etc/teapop.passwdで オプション設定のはずのuidとgidがなぜか必須だったり、ロックファイルを いつまでも抱えたりしてうまく動かない(筆者の設定が悪いのかもしれない) virtualmail-pop3d http://www.reedmedia.net/software/virtualmail-pop3d/ 1つのユーザーアカウントで複数のmailboxを扱える、IPベースのバーチャルドメイン、 各種データベースとの連携やpamの利用が可能、といった特徴がある。 HTTP いろいろなものがあるが、apache以外のHTTPDには軽量コンパクトなものが多い。 外部ユーザーが直接ファイルにアクセスするサービスなので、セキュリティには 注意を要する。CGIを利用するならなおさら。 有名なHTTPサーバ # apacheがダントツのシェアを持っているが、これについてはその9で触れる。 micro_httpdとmini_httpdとthttpd http://www.acme.com/software/micro_httpd/ http://www.acme.com/software/mini_httpd/ http://www.acme.com/software/thttpd/ micro_httpdは、必要最小限の機能に絞ってあり、コードが150行しかないらしい。 mini_httpdは、CGIやVirtualHostやBasic認証のほか、SSLやIPv6にも対応。 thttpdは、正式名称tiny/turbo/throttling HTTP server で、CGI、CHROOT、Basic認証、 VirtualHost(っぽい機能?)、帯域制限、IPv6などに対応。FreeBSDネイティブで 開発されているらしく、apache以外のHTTPDの中ではユーザーも多い。 いずれもportsからインストール可能。 Monkey(Monkey HTTP Daemon) http://monkeyd.sourceforge.net/ CGI、Multithreading、VirtualHost、Denyリストなどに対応しつつ、 コンパクトにまとめてある。コードのサイズが本当に小さい。元はLinux用だが Zaurusの一部機種でも動くらしく、FreeBSD用のportsも用意されている。 高度に洗練された印象で、ポテンシャルも高い。 Mathopd http://www.mathopd.org/ HTTP/1.1とCGI/1.1に対応。コンパクトではあるがきめ細かい設定が可能で、 設定ファイルも(thttpdほどアッサリしてはいないが)整然としている。 シングルプロセスでの動作にこだわっているらしい。Debianで採用されており、 FreeBSDでもportsからインストール可能。 publicfile http://cr.yp.to/publicfile.html httpdと読み出し専用ftpdがひとつになったもので、CGIは使えない。 セキュリティを重視しているらしい。portsからインストール可能だが、 現在は利用できない模様(メンテが終了したのかも)。qmailやdjbdnsの 作者でもあるD. J. Bernstein (略してdjb)という人が作っている。 Wyvern http://www.mysticwall.com/software/wyvern/ サブノートでの運用を前提に開発されたらしい。SuExecを利用したCGIやSSLなど、 セキュアな機能がいろいろと使える。ドキュメントが日本語。 FreeBSDネイティブのようで、portsからインストール可能(バージョンが古いが)。 esehttpd http://sourceforge.jp/projects/esehttpd/ 高速・スケーラブルな実装、HTTPSのサポート、rubyスクリプトの直接実行、 サーバ自身がchroot可能、といった感じらしい。ドキュメントが日本語。 その他 dhttpd:Debianのhttpdで、ファイル閲覧だけに機能を絞ってある boa:Zaurusの一部機種でも動くらしい CERN httpd:w3cのhttpdで、プロクシ機能もあるらしい fhttpd:FTPサーバを兼ねており、以前はPHPをモジュールとして扱えたらしい khttpd: カーネルモードで動くらしい この他にもいろいろなものがあり、シェルスクリプトで書かれたもの、 Qtやgtkなどのツールキットを使うもの、JAVAで書かれたものなどもある。 thttpdを使う http://www.acme.com/software/thttpd/ http://www.lanceweb.jp/hard/hard04j.html インストールと設定 まず本体をインストールする。ここではportsを使ったと前提して話を進める。 /usr/local/etc/thttpd.conf.sampleを/usr/local/etc/thttpd.confという 名前でコピーしておく。 # もちろん、名前や場所は上記と違ってもかまわないが、chrootしたときに # 見えなくなる場所がよいだろう。中身はたった5行のテキストファイル。 コンパイルオプションはMakefileではなくconfig.hに記入するようだ。 このファイルのコメントは/**/で、#はコメントではないので注意。#defineで 設定を有効に、#undefで設定を無効にする。 http://www.acme.com/software/thttpd/options.html # 2011年1月追記:いつからかわからないがextra-patch-config.hという名前に変わった。 > thttpd -C /usr/local/etc/thttpd.conf としてthttpdを起動。 # 起動スクリプトを使わず、かつ-Cオプションなしで直接起動すると、 # コンフィグファイルを読まずに立ち上がるのだが、そのとき/usr/local/etc/が # ドキュメントルートになっていて非常に心臓に悪い。 ブラウザからローカルIP直打ちでアクセスし、きちんと動いていることを確認。 # ドキュメントルートのディレクトリ一覧が表示されるはず。 /usr/local/etc/rc.d/thttpd.sh.sampleを/usr/local/etc/rc.d/thttpd.shという 名前でコピーして、/etc/rc.confにthttpd_enable="YES"と書いておけば > thttpd -C /usr/local/etc/thttpd.conf というオプションで自動起動する。 もう少し設定してみる このままでも動くが、/usr/local/etc/thttpd.confを適当に設定しておく。 デフォルトだと、ドキュメントルートは/usr/local/www/data/、 簡易chroot有効、拡張子が.cgiのものをCGIと判断、といった設定になっているが、 何も書かなくても、nobody権限で実行、待ち受けポート80、といった設定はされる模様。 # cgipatの行をコメントアウトしておけばCGIを禁止できる。 # 待ち受けポートを変更するなら、port=8080などと書いておけばよい。 また、HTMLファイルのヘッダ部分にアスキー文字以外を使う予定があるなら、 /usr/local/etc/thttpd.confにcharset=shift_jis(とかcharset=euc-jpとか charset=iso-8859-1とかcharset=utf-8)などと書いておく。 # IEの場合、Shift_JISと大文字で書くと認識してくれないようだ。 文字化けの問題については、ブラウザの実装によってさまざまな状況が考えられるが、 HTTPヘッダのコード設定とHTMLヘッダのコード設定(と、もちろん実際の コード設定も)を一致させておけば、とりあえず問題ないだろう。 http://www.asahi-net.or.jp/~jy3k-sm/i_net/charset.html 簡易chroot機能を使う # 簡易chroot機能というのは、筆者が勝手にそう呼んでいるだけで、公式な用語ではない。 設定ファイルにchrootという行を書いておくと、FreeBSD標準のftpdのような 簡易chrootが利用できる。このとき、ドキュメントルートが/に見立てられる。 # /usr/local/etc/thttpd.conf.sampleをコピーしたのなら、最初から # 有効になっているはず。nochrootに変更すれば無効にできる。 /usr/local/www/data/dev/というディレクトリを作成したうえで、 /etc/rc.confにsyslogd_flags="-l /usr/local/www/data/dev/log" と 書いておくと、chrootしていてもsyslogdが利用できるらしい。 # デフォルトでは/dev/logへの出力しか拾っていないsyslogdに # /usr/local/www/data/dev/logへの出力も拾え、と命令している。 CGIを使う場合は、CGIが使うファイル(インタープリタなど)を導入しておく。 # chrootを前提にした運用の項目を参照。 ドキュメントルートのひとつ上のディレクトリにchrootできると、 ライブラリなどをドキュメントルート外に置けて便利なのだが、 設定方法がよくわからない。ソース(thttpd.c)のChroot if requested の 項目を見てみると、カレントディレクトリ(cwd)を/に見立てるように なっているようだが、どこをどういじればよいのかわからなかった。 # 最低限Basic認証をかけておけば問題ないのだろうが、 # 本格的に使うなら、普通にchrootから実行した方が楽かもしれない # http://www.acme.com/software/thttpd/notes.html#chroot 多重起動 設定が柔軟なので多重起動も簡単。dir、logfile、pidfile、portを 現在立ち上がっているthttpdのものと別にしてコンフィグファイルを作り、 -Cオプションで指定してやる。たとえば公開用にthttpd.conf.www、 ローカル用にthttpd.conf.localと2種類の設定を作るなど。 起動スクリプト(/usr/local/etc/rc.dなどに置く)は自分で 書かなければならないが、非常に簡単に複数のHTTPdを利用できる。 また、chrootと合わせて使っても便利だろう。 注意点 2004年現在、HUP(1番)シグナルへの対応がいまひとつ(logファイルを 開けなくなる)なので、ログローテーション(後述)には注意を要する。 マニュアルには「現在の所、もっとも確実なログファイルの入れ替え方法は、 USR1シグナルを送ってthttpdを停止し、ログファイルを入れ替えてから、 再度thttpdを起動するというものでしょう」とあるが、これを手動でやるのは面倒。 解決策の1つとして、ログローテーションの直後にcronでrestartをかけてしまう手が 考えられる。乱暴だが、楽な方法ではある。 もうひとつの案として、定期的にもしくはログファイルのサイズによって、 thttpdにUSR1(30番)を送る>thttpdが終了するのを待つ>ログファイルを リネームする>thttpdを起動する という動きをするスクリプトをcronで走らせるのがよいだろう。設定ファイルの ページにthttpdlog.sh.sampleというサンプルを用意した。 Monkeyを使ってみる # バージョン0.8.4_1を試した まず本体をインストールする。ここではportsを使ったと前提して話を進める。 本体は小さいが、GNUのツールがいろいろと入るので、思ったよりは容量が膨れる。 筆者の環境ではエラーがでたため、/usr/local/etc/rc.d/monkey.shを修正した。 上のほうの行でPREFIXを定義している部分をまとめてコメントアウトして、代わりに PREFIX=/usr/localと書いたところ問題なく動いた。 # 環境によって違うが、動かない場合、たいていは同様の修正で動くはず。 # 0.8.5で直った模様。 さらに、デフォルトで設定されている-Dオプション(バックグラウンド実行)が ついているとなぜかまともに動かなかったので、-Dオプションを外してシェルから バックグラウンド実行し、ついでに出力も捨てておいた。 # 結局、monkeyのあるディレクトリ/monkey > /dev/null 2>&1 & という書き方になる。 あとは/usr/local/etc/monkey/monkey.confを適当にいじればよく、 最低限必要な設定は待ち受けポートの番号くらいだが、筆者の環境では cgi-binディレクトリにアクセスできなかった。Server_ScriptAliasが効いて いないのか、telnetでアクセスしてもブラウザでアクセス(ローカルプロクシで 通信内容を記録した)しても、HTTP/1.0でもHTTP/1.1でも、無反応になって タイムアウトする。pkg_addで入れたバイナリでも同じ症状だったので コンパイルエラーではないようだが、筆者には原因を突き止めることができなかった。 # 0.8.5を試したところ、ディレクトリへのアクセスはできて、CGIも動いたが、 # CGI経由でファイルをアップロードするとファイルが壊れるという原因不明の # トラブルがあった。その他は特に問題なく動いていたので、スクリプトの方に # 問題があったのかもしれない。 それ以外は特に問題なく動いているようなので、CGIを使わないのならば 気にする必要はないだろう(多分)。 追記: バージョンが0.9に上がったので再度試してみたが、動作に必要な /usr/local/etc/monkey/monkey.mimeというファイルがない。 本家サイトで「Sources Tarball」を入手すればconfディレクトリに 入っているのでそれを流用する(その他のパッケージは2005/10/12現在 まだアップロードされていないようだ)。 動作はかなり安定し、-Dオプションをつけても問題なく動く。起動スクリプトは rc.confを見ないタイプで、やはりprefixを決定する部分でコケるが、そこさえ 書き換えてやれば起動自体はすんなり行える。cgi-binディレクトリ(に限らず CGIを実行可能なディレクトリ)では通常のファイル閲覧ができない仕様(すべて 実行ファイル扱い)らしく、使い方が多少限られるが、CGIも普通に動く。 コンセプトがよいだけにこういった熟成は嬉しい。 # あとはもうちょっと(英語だけでも)ドキュメントが増えてくれれば # メインで使うのもアリだと思う。 追記: バージョン0.9.1に上げてみたが、portsでのアップデート時に /usr/local/www/data/index.htmlを勝手に書き換えられてズッコケた。 そういえばそんな確認メッセージが出たような気もしないでもないが、 複数のアップデートをまとめてやっていたので惰性でyを選んでしまったようだ。 # monkeyに罪があるわけではなく筆者の単純なミスなのだが、 # 他のデーモンで公開しているはずのページが差し変わっていて驚いた。 その他いろいろ アクセス解析 # 後述のログローテーションも参照 analogかwebalizerあたりを入れておく。 http://jp.analog.cx/index.html.ja http://freebsd.sing.ne.jp/FreeBSD/15.html http://d-net.robata.org/inetbuild-analog.html http://www.iwakimu.ac.jp/~yoshida/solaris2.6/analog-4.1.html http://www.ep.sci.hokudai.ac.jp/~epwww/dvlop.old/2002-06-03/analog.html http://solaris.ddo.jp/analog.html thttpdの場合、アクセスログの形式は「all fairly similar to CERN Common Log Format」だそうだが、analogではLOGFORMAT COMBIND(apacheと同じ)で動く。 # 何か問題が起きない限り、LOGFORMATは設定しないことが推奨されている。 analogの場合、複数のログを別々に解析するときは設定ファイル(デフォルトは /usr/local/etc/analog.cfg)を複数用意して > analog -G +g/usr/local/etc/analog.cfg2 などとする。+gオプションの後にスペースを挟まずに設定ファイルのパスを 書くことに注意。 # 筆者はコンフィグファイル変更のオプションを-cだと勘違いして # 軽くハマった。なぜそんな勘違いをしたのか謎だが。 -Gはデフォルトの設定ファイルを読まないオプション、+gは設定ファイルを 指定して読み込むオプション。-Gを指定せず+gのみ指定すると、設定が 追加される(累積する)ことになる。よって、これらを組み合わせて、 マシンにインストールされているサーバ全体のログや個別のログを 別々に吐かせることができる。また、FILEEXCLUDEやHOSTEXCLUDEを使って 自分自身のアクセスやアイコンの表示などがカウントされることを防げる。 http://www.jp.analog.cx/jp5.24/quickref.html .htpasswdを作ってBASIC認証を行う .htpasswd(この名前でなくてもよい)は > htpasswd -c ファイル名 ユーザー名 として新規作成する(-cオプションがファイルの新規作成を表す)。パスワードを 求められるので適当に設定する。あとは、 > htpasswd ファイル名 ユーザー名 としてやれば、既存のユーザー名を指定した場合はパスワード変更、そうでなければ ユーザーの追加ができる。ユーザーの削除は、エディタで直接行った方が早いだろう。 thttpdなら、アクセス制限を行いたいディレクトリに(.htpasswdという名前で) ファイルを置くだけで認証を行ってくれる(はず)。apacheの場合、httpd.confで 認証を行うように設定しなければならない。 # httpd.confではなく.htaccess(エディタで手書きするのが普通)でも認証の # 設定はできるが、自分がroot権限をもっているなら.htaccessを使う必要はない。 # http://cvs.apache.jp/svn/httpd-docs/1.3/htdocs/manual/howto/htaccess.html.ja.jis#when FTPD # ユーザーに直接のディスク書き込みを許すサービスなので、セキュリティには # 細心の注意を払う。また、パスワードが平文で流れることを忘れない。 # インターネット越しに利用する場合ルーターの設定が絡んでくるが、 # それについてはPureFTPdの項目で後述する。概要は以下のページを参照。 # http://www.aconus.com/~oyaji/router/pasv.htm # PASVモードの方がクライアントに左右されにくく、グローバルIPアドレスが # 変わった際に、FTPdがクライアントに通知するアドレスを変更できればそれでよい。 ProFTPD http://www.fkimura.com/ProFTPD1.html http://www.proftpd.org/ http://www.infoscience.co.jp/technical/proftpd/ wu-FTPDの後釜として最有力。Highly configurable GPL-licensed FTP server software らしく、非常に強力な機能を備えている。設定ファイルがapacheと似ている。 vsftpd http://www.fkimura.com/vsftpd0.html http://vsftpd.beasts.org/ ProFTPDの対抗馬。Probably the most secure and fastest FTP server for UNIX-like systems. らしく、OpenBSDにも採用されている。 PureFTPd http://www.fkimura.com/pureftpd0.html http://www.pureftpd.org/ http://pureftpd.sourceforge.net/ Troll-FTPdをベースにBSDライセンスで開発されている。Secure FTP made easy! らしく、革新的な機能の採用にも意欲的。 # 2004年8月29日現在、「PureFTPd」でぐぐると、スペル修正候補として # 「Proftpd」が出てくるのはどういうことなんだか・・・<google PureFTPdを使う http://www.fkimura.com/pureftpd0.html http://homepage.mac.com/proc/pureftpd/pureftpd-option.html http://www.pureftpd.org/README # 設定も簡単でセキュリティ関連の機能も充実している 普通に使う とりあえずインストールして、 > cp /usr/local/etc/pure-ftpd.conf.sample /usr/local/etc/pure-ftpd.conf として/usr/local/etc/pure-ftpd.confを適当に編集するが、ぱっと見で何を 設定しているかわかるので、非常に楽。動かすだけならデフォルトのままでOKだが、 最低限認証に関する部分は見直しておく。 UnixAuthentication と書いておけばUnixのアカウントで認証(デフォルトはこっちだったと思う)、 PureDB puredbのデータベースファイル(デフォルトはpureftpd.pdb)の絶対パス と書いておけばpuredbのアカウントで認証できる。SQLデータベースとの連携も 可能(コンパイルオプションの追加が必要)。 # この他、chroot関連、BrokenClientsCompatibility、待ち受けport関連(Bind)、 # anonymousFTP関連、アクセス制御関連の項目くらいは見直しておいた方がよい。 PASVモードを使うなら、ForcePassiveIP(IPアドレスかサーバ名)の項目と PassivePortRangeも設定。ForcePassiveIPを設定していないと、PASVコマンド (FTPクライアントが、FTPサーバにIPアドレス通知を要求するコマンド)を 受け取った際に、FTPクライアントにローカルIPを通知してしまう(NATがちゃんと 機能していれば自動で書き換えられるので、気にしなくてもよいはずなのだが)。 同じ理由で、通常モードだと、PORTコマンド(FTPクライアントが、FTPサーバに 自分のIPアドレスを通知するコマンド)を実行した際にローカルIPアドレスを 返してくるクライアント(というよりはルーターの問題か?)が通信に 失敗することがある。 # その場合、PASVモードで接続させるのがいちばん手っ取り早いだろう。 # PORTコマンドの結果を無視して(port番号だけ信用して)、最初の接続元に # 接続する方法があれば便利なのだが、よくわからない。 FreeBSD4.xなら、 /etc/pam.confに pure-ftpd auth sufficient pam_skey.so pure-ftpd auth requisite pam_cleartext_pass_ok.so #pure-ftpd auth sufficient pam_kerberosIV.so try_first_pass pure-ftpd auth required pam_unix.so try_first_pass pure-ftpd account required pam_permit.so pure-ftpd session required pam_permit.so と書いておく。 rehashしたあと > pure-ftpd & としてみてきちんと起動することを確認。いったんkillしてから > pure-config.pl /usr/local/etc/pure-ftpd.conf と、pure-config.pl経由で起動してみる。 # pure-config.plは、引数で指定したコンフィグファイルの設定を # コマンドラインオプションに変換してpure-ftpdに送ってくれるperlスクリプト。 問題なく動いているようなら、/etc/rc.confにpureftpd_enable="YES"と追記しておく。 virtual users を使う # /usr/local/share/doc/pure-ftpd/README.Virtual-Usersを適当に訳しただけ。 > portinstall -m "--with-puredb" ftp/pure-ftpd と、コンパイルオプションに--with-puredbを追加してコンパイルし、 普通に/usr/local/etc/pure-ftpd.confを作成、編集する。 >pw groupadd ftpgroup >pw useradd ftpuser -g ftpgroup -d /dev/null -s /etc などとしてftp専用ユーザーを作っておく # 既存のnobodyユーザーやftpユーザーを利用してもよいが、こちらが推奨されている。 # -s /etc ではなく-s /sbin/nologin の方がよさそうに思えるが、まあいいだろう。 ftpユーザー専用のパーティション(仮に/ftpにマウントしたとする)も確保して ユーザーごとにディレクトリを作り、所有者のアカウントが属するグループに アクセス権限を与える(たとえば/ftp/user1のパーミッションを770にして > chgrp user1が所属するグループ /ftp/user1 などとする)とよりよいだろう。 # FTPのhome directory を各ユーザーの~/以下に作ろうと思うと、パーミッションの # 設定で面倒なことになるので、シンボリックリンクを使った方が楽だろう。 /usr/local/etc/pure-ftpd.confのMinUIDという行の指定(デフォルトは100) よりも小さなUIDのユーザーだと「Sorry, but I can't trust you」と言われて ログインできないので注意。 > pure-pw useradd ユーザー名 各種オプション という文法でpure-pwを実行する。 # パスワード入力とパスワード入力確認がある。オプションの種類や内容については後述。 たとえば、 > pure-pw useradd joe -u ftpuser -d /home/ftpusers/joe で、ユーザー名joe、実行権限ftpuser、chroot先ディレクトリ/home/ftpusers/joe という設定で新規ユーザーが登録される。-jオプションもつけておけば、 /home/ftpusers/joeが存在しない場合ログイン時に自動作成される。 # はずだが、ディレクトリが存在していないとアカウント作成そのものに # 失敗するので、pure-pw経由の場合はあまり意味がない。 作成されたユーザー情報は、/etc/pureftpd.passwd(以前は場所が違った)に :::::::::::::::::