USB メモリを使う
ftpd の設定をしていないのでファイルの受け渡しなどが不便です。ネットワーク経由では無いのですが、USB メモリを使って解決しました(あまりホームサーバとは関係ありません・・・)。Prinston の FLASHDIO があるので挿してみたらそのまま認識しました。
umass0: Diography Flashdio FDU100A, rev 1.10/1.02, addr 2
GEOM: create disk da0 dp=0xc1527050
da0 at umass-sim0 bus 0 target 0 lun 0
da0: <GENERIC FlashDIO FDU100 1.02> Removable Direct Access SCSI-2 device
da0: 1.000MB/s transfers
da0: 125MB (256000 512 byte sectors: 64H 32S/T 125C)
そのまま
mount -t msdosfs /dev/da0s1 /mnt
でマウントに成功。読み書きも出来ました。終わったら umount を忘れずに。
umass0: Diography Flashdio FDU100A, rev 1.10/1.02, addr 2
GEOM: create disk da0 dp=0xc1527050
da0 at umass-sim0 bus 0 target 0 lun 0
da0: <GENERIC FlashDIO FDU100 1.02> Removable Direct Access SCSI-2 device
da0: 1.000MB/s transfers
da0: 125MB (256000 512 byte sectors: 64H 32S/T 125C)
そのまま
mount -t msdosfs /dev/da0s1 /mnt
でマウントに成功。読み書きも出来ました。終わったら umount を忘れずに。
バーチャルホストの設定
間があきましたが、apache の設定をします。/usr/local/apache2/conf/httpd.conf が設定ファイルなのでこれを編集します(今回はかなりいいかげん、トライ&エラーです)。
1)文字化け対策
デフォルトで言語が指定されていると、日本語の文字化けが起きるので AddDefaultCharset ISO-8859-1 をコメントに。
2)apache の名前、バージョンを表示しない
エラーページでは、デフォルトで Apache/2.0.51 (Unix) Server at x.x.x.x Port 80 が表示されるようになっていますが、これを止めてしまいます。 ServerSignature Off で止まります。
3)CGI を使う
CGI を使いたいので AddHandler cgi-script .cgi のコメントを外します。また、CGI のスクリプトを置く <Directory>に、Options ExecCGI を記述しておきます。あと、httpd.conf とは関係ないのですが、このままでは 403 Forbidden となりました。apache が nobody で動く設定になっているので、スクリプトを置くディレクトリの owner を nobody にしてしまいました(これは正しいやり方なのか、不明です)。
chown nobody .
でカレントディレクトリ owner が変わります。
4)バーチャルホスト
IPアドレスが固定ではないので、偶然の一致でアクセスされた場合というのは望まないアクセスなので弾くことにします(dummy の <Directory>で Deny form all を記述)。IPアドレスの場合と、ダイナミック DNS のドメイン名の場合とを、両方記述しておきます。
NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot /usr/www/dummy
ServerName 192.x.x.x
ErrorLog logs/dummy-error_log
CustomLog logs/dummy-access_log common
</VirtualHost>
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot /usr/www/xxx
ServerName xxx.xxx.jp
ErrorLog logs/dummy-error_log
CustomLog logs/dummy-access_log common
</VirtualHost>
正しいのかな? でも思い通りに動いているようです。
1)文字化け対策
デフォルトで言語が指定されていると、日本語の文字化けが起きるので AddDefaultCharset ISO-8859-1 をコメントに。
2)apache の名前、バージョンを表示しない
エラーページでは、デフォルトで Apache/2.0.51 (Unix) Server at x.x.x.x Port 80 が表示されるようになっていますが、これを止めてしまいます。 ServerSignature Off で止まります。
3)CGI を使う
CGI を使いたいので AddHandler cgi-script .cgi のコメントを外します。また、CGI のスクリプトを置く <Directory>に、Options ExecCGI を記述しておきます。あと、httpd.conf とは関係ないのですが、このままでは 403 Forbidden となりました。apache が nobody で動く設定になっているので、スクリプトを置くディレクトリの owner を nobody にしてしまいました(これは正しいやり方なのか、不明です)。
chown nobody .
でカレントディレクトリ owner が変わります。
4)バーチャルホスト
IPアドレスが固定ではないので、偶然の一致でアクセスされた場合というのは望まないアクセスなので弾くことにします(dummy の <Directory>で Deny form all を記述)。IPアドレスの場合と、ダイナミック DNS のドメイン名の場合とを、両方記述しておきます。
NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot /usr/www/dummy
ServerName 192.x.x.x
ErrorLog logs/dummy-error_log
CustomLog logs/dummy-access_log common
</VirtualHost>
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot /usr/www/xxx
ServerName xxx.xxx.jp
ErrorLog logs/dummy-error_log
CustomLog logs/dummy-access_log common
</VirtualHost>
正しいのかな? でも思い通りに動いているようです。
ダイナミックDNS
固定 IP アドレスではないので、ダイナミック DNS を使うことにします。無料のサービスがいくつかあるようですが、家サーバー・プロジェクト(ieserver.netを利用させてもらうことにしました。便利ツールにあるIPアドレスを設定するスクリプトを使ってみます。 wget が必要なので、package から入れてみます。名前は、wget-1.8.2_5 です。
次にスクリプト(ddns-update.pl)を編集。
$ACCOUNT = "";
$DOMAIN = "";
$PASSWORD = "";
を設定するくらいです。chmod +x して実行可能にしておきます。
(2004/9/23追記)
IPアドレスが登録されたか確認するには、
dig xxx.xxx.jp
します。しかるべきネームサーバ(/etc/resolv.conf で指定したもの)に問い合わせて、答えが返ってくればOK。ただし登録してから DNS に反映されるまでに時間がかかる場合もあります。hosts とか設定していたら違う結果になるかも知れません。そんな場合は LAN の外から確認。携帯電話からアクセスしてみたり、ダイヤルアップした PC から見てみましょう。
次にスクリプト(ddns-update.pl)を編集。
$ACCOUNT = "";
$DOMAIN = "";
$PASSWORD = "";
を設定するくらいです。chmod +x して実行可能にしておきます。
(2004/9/23追記)
IPアドレスが登録されたか確認するには、
dig xxx.xxx.jp
します。しかるべきネームサーバ(/etc/resolv.conf で指定したもの)に問い合わせて、答えが返ってくればOK。ただし登録してから DNS に反映されるまでに時間がかかる場合もあります。hosts とか設定していたら違う結果になるかも知れません。そんな場合は LAN の外から確認。携帯電話からアクセスしてみたり、ダイヤルアップした PC から見てみましょう。
サーバ置き場
はじめて24時間運転をしました。サーバにしたノート PC を居室に置いていたのですが、寝るときには結構うるさく感じました。ディスクやファンの回転音と、よく分からない高周波っぽい音が聞こえ、ほかの音が無くなる深夜には耳障りです。なので、台所に移動します。といっても、10mの LAN ケーブルを買ってきて普通につなぐだけですが。電話機、ADSL モデム、ルータ、ハブが一緒に置いてあるので、電話の線に沿って台所まで引っ張りました。見た目はともかく、つまづいたり引っかかったりする心配はなさそうです。LAN ケーブルの太さの分だけ、襖に隙間が空くようになりました。冬の寒い時期までに何とかしたほうがよさそうです。
perl をインストールする
perl は package からインストールしてしまいます。/stand/sysinstall を使い、p5-DB_File-Lock-0.05 を入れました。perl-5.6.1_15 でもいいのかもしれません・・・。終わったら where perl を実行して /usr/local/bin/perl であることを確認します(/usr/bin/perl は /usr/local/bin/perl へのシンボリックリンクのようです)。
apacheをダウンロードする
WEB サーバには apache を使ってみます。ダウンロードとインストールはwww.apache.jpに詳しい説明があるのでそれを参考にします。ftp ができれば問題なくダウンロードできるかと思います。ダウンロードしたら念のためハッシュの確認もしておきます。
%md5 -r httpd-2.0.51.tar.gz;cat httpd-2.0.51.tar.gz.md5
ab93c56b88ca1b9ce71ba12e74bbc5de httpd-2.0.51.tar.gz
ab93c56b88ca1b9ce71ba12e74bbc5de httpd-2.0.51.tar.gz
とりあえず目視で確認。合っているようです。
tar -xvzf httpd-2.0.51.tar.gz
して、
./configure
make
make install
すると apache が出来ます。/usr/local/apache2/conf/httpd.conf に基本的な設定(www.apache.jpにある内容)を行い、/usr/local/etc/rc.d/ に httpd.sh を作って以下を記述。
#!/bin/sh
case "$1" in
start)
/usr/local/apache2/bin/apachectl start
;;
stop)
/usr/local/apache2/bin/apachectl stop
;;
*)
echo "Usage: `basename $0` {start|stop}" >&2
;;
esac
exit 0
これで自動起動も出来るかと思います。
%md5 -r httpd-2.0.51.tar.gz;cat httpd-2.0.51.tar.gz.md5
ab93c56b88ca1b9ce71ba12e74bbc5de httpd-2.0.51.tar.gz
ab93c56b88ca1b9ce71ba12e74bbc5de httpd-2.0.51.tar.gz
とりあえず目視で確認。合っているようです。
tar -xvzf httpd-2.0.51.tar.gz
して、
./configure
make
make install
すると apache が出来ます。/usr/local/apache2/conf/httpd.conf に基本的な設定(www.apache.jpにある内容)を行い、/usr/local/etc/rc.d/ に httpd.sh を作って以下を記述。
#!/bin/sh
case "$1" in
start)
/usr/local/apache2/bin/apachectl start
;;
stop)
/usr/local/apache2/bin/apachectl stop
;;
*)
echo "Usage: `basename $0` {start|stop}" >&2
;;
esac
exit 0
これで自動起動も出来るかと思います。
時計を合わせる
ネットワークにつなぐと、ログを取ったり、時刻を返したり、と時計を正確にしておいたほうが便利です。メールサーバはまだ作りませんので必須とまではいえないかもしれませんが、まあ時刻合わせ位はしておきます。ntp で時刻を合わせるために ntpd を使用します。rc.conf に以下を追加。
ntpd_enable="YES"
ntpd_flags="-c /etc/ntp.conf"
また、/etc/ntp.conf を作って
server ntp1.jst.mfeed.ad.jp
server ntp2.jst.mfeed.ad.jp
server ntp3.jst.mfeed.ad.jp
driftfile /etc/ntp.drift
を記述します。ntp では上位サーバの port 123 に送信、上位サーバからローカルの port 123 に受信をしますので、IPFilter で該当する接続を許可します。/etc/ntp.drift も作っておきます。rc.conf を変更してから reboot すると ntpd が動きますので、ntpq -p などで様子を見ます。
%ntpq -p
remote refid st t when poll reach delay offset jitter
==============================================================================
+ntp1.jst.mfeed. mf-isdn4.mfeed. 2 u 524 1024 377 61.515 -1.425 0.872
+ntp2.jst.mfeed. mf-isdn1.mfeed. 2 u 469 1024 377 58.434 -0.956 0.273
*ntp3.jst.mfeed. mf-isdn4.mfeed. 2 u 462 1024 377 59.204 -0.356 0.258
このような表示になって、* がついている ntp サーバと同期していれば OK です。
ntpd_enable="YES"
ntpd_flags="-c /etc/ntp.conf"
また、/etc/ntp.conf を作って
server ntp1.jst.mfeed.ad.jp
server ntp2.jst.mfeed.ad.jp
server ntp3.jst.mfeed.ad.jp
driftfile /etc/ntp.drift
を記述します。ntp では上位サーバの port 123 に送信、上位サーバからローカルの port 123 に受信をしますので、IPFilter で該当する接続を許可します。/etc/ntp.drift も作っておきます。rc.conf を変更してから reboot すると ntpd が動きますので、ntpq -p などで様子を見ます。
%ntpq -p
remote refid st t when poll reach delay offset jitter
==============================================================================
+ntp1.jst.mfeed. mf-isdn4.mfeed. 2 u 524 1024 377 61.515 -1.425 0.872
+ntp2.jst.mfeed. mf-isdn1.mfeed. 2 u 469 1024 377 58.434 -0.956 0.273
*ntp3.jst.mfeed. mf-isdn4.mfeed. 2 u 462 1024 377 59.204 -0.356 0.258
このような表示になって、* がついている ntp サーバと同期していれば OK です。
SSH を使う
管理を楽にするために、SSH を使ってログインできるようにします。
これはとても簡単で、/etc/rc.conf に
sshd_enable="YES"
を記述するだけで、sshd が起動するようになります。
また IPFilter で接続を制限している場合は、
pass in quick proto tcp from x.x.x.x/xx to any port 22 flags S/SA group 100
などして、接続できるようにしておきます。
デフォルトでは root でのログインは出来なくなっています。wheel グループのユーザでログインし、su コマンドで root になりましょう。/etc/group で設定できます。
これはとても簡単で、/etc/rc.conf に
sshd_enable="YES"
を記述するだけで、sshd が起動するようになります。
また IPFilter で接続を制限している場合は、
pass in quick proto tcp from x.x.x.x/xx to any port 22 flags S/SA group 100
などして、接続できるようにしておきます。
デフォルトでは root でのログインは出来なくなっています。wheel グループのユーザでログインし、su コマンドで root になりましょう。/etc/group で設定できます。
パケットフィルタリングを有効にする
インターネットに接続する前に変なことが起こるのを減らす必要があります。要するにセキュリティについて考えましょう、ということです。どのような手法があり、どのような対策を行うか、ということはとても範囲が広いので、今ここで記述することはできません(知識的にも、時間的にも)。
境界ルータでパケットフィルタリングを行っているのですが、ホームサーバにも基本的なパケットフィルタリングを付けることにします。FreeBSD に標準で含まれている IPFilter を有効にします。おそらく未来永劫、使い続けると思うのでカーネルに組み込んでしまうことにします(試していませんがカーネルを変更しない方法もあるようです。man kldstatとかで調べられそうです)。
/usr/src/sys/i386/conf/GENERIC を元にして
options IPFILTER # ipfilter support
options IPFILTER_LOG # ipfilter logging
options IPFILTER_DEFAULT_BLOCK # block all packets by default
を追加、カーネルの再構築を行います。手順は色々な場所に乗っているのでごく簡単に。
cp GENERIC k20040918
vi k20040918
config k20040918
cd ../compile/k20040918/
make depend; make
ここで、2時間強かかりました。使用するマシンの性能によります。
エラーが無ければ、
make install
shutdown -r now
無事に起動したら、IPFilter を有効にするための設定を行います。/etc/rc.conf に
ipfilter_enable="YES"
ipfilter_rules="/etc/ipf.rules"
ipmon_enable="YES"
ipmon_flags="-D /var/log/ipflog"
を追加。
touch /var/log/ipflog
も念のために実行しておきます。
そして /etc/ipf.rules を作成。
全て通す設定にすれば、とりあえず試すことが出来ます。
pass in all
pass out all
運用時にはpass in all,pass out allの代わりに色々な設定をすることになります。リモートから ssh で操作している場合、ssh をブロックすると大変なことになるかと思います。ルールの作成には注意が必要です。
参考リンク
Firewall 構築ガイド
ASH multimedia lab.より
F.Kimura.com より
境界ルータでパケットフィルタリングを行っているのですが、ホームサーバにも基本的なパケットフィルタリングを付けることにします。FreeBSD に標準で含まれている IPFilter を有効にします。おそらく未来永劫、使い続けると思うのでカーネルに組み込んでしまうことにします(試していませんがカーネルを変更しない方法もあるようです。man kldstatとかで調べられそうです)。
/usr/src/sys/i386/conf/GENERIC を元にして
options IPFILTER # ipfilter support
options IPFILTER_LOG # ipfilter logging
options IPFILTER_DEFAULT_BLOCK # block all packets by default
を追加、カーネルの再構築を行います。手順は色々な場所に乗っているのでごく簡単に。
cp GENERIC k20040918
vi k20040918
config k20040918
cd ../compile/k20040918/
make depend; make
ここで、2時間強かかりました。使用するマシンの性能によります。
エラーが無ければ、
make install
shutdown -r now
無事に起動したら、IPFilter を有効にするための設定を行います。/etc/rc.conf に
ipfilter_enable="YES"
ipfilter_rules="/etc/ipf.rules"
ipmon_enable="YES"
ipmon_flags="-D /var/log/ipflog"
を追加。
touch /var/log/ipflog
も念のために実行しておきます。
そして /etc/ipf.rules を作成。
全て通す設定にすれば、とりあえず試すことが出来ます。
pass in all
pass out all
運用時にはpass in all,pass out allの代わりに色々な設定をすることになります。リモートから ssh で操作している場合、ssh をブロックすると大変なことになるかと思います。ルールの作成には注意が必要です。
参考リンク
Firewall 構築ガイド
ASH multimedia lab.より
F.Kimura.com より