さて。 やっとこさベースシステムが完成しました。で、このサーバーは現在、inetd経由でtelnetサーバーが動いています。
このinetdはいろいろと弱点がありますので、daemontools経由で動くように変更してみましょう。
daemontoolsはとてもややこしいと言われています。確かに、パッケージを入れてポン!ってわけにはいきませんが、パターンが解ればそんなにたいしたことがありません。是非、慣れてください。
基本的な流れ
daemontoolsでのサーバーソフトの管理の設定は、以下の流れとなります。
- デーモンを動かすユーザーの決定or新設
- デーモンが出すログを受け取るユーザーの決定or新設
- デーモンの起動スクリプトの設置
- デーモンのログを受け取るスクリプトの設置
- 起動スクリプトのディレクトリを、/servece 以下にリンクする。(デーモン起動)
- 動作確認。
- 問題なければ一旦停止させる
- セキュリティ用の設定をする
- 動作確認。完成
まず、inetdの停止
現在はinetd経由でtelnetが動いていますので、これを一旦停止させます。
当然ですが、これ以降はtelnetではなくコンソールで作業しましょう。(^^;)
まず、inetd の設定ファイルから、telnetの部分をコメントアウトします。
/etc/inetd.conf ・ ・ #ftp stream tcp nowait root /usr/sbin/tcpd in.proftpd #telnet stream tcp nowait root /usr/sbin/tcpd in.telnetd #gopher stream tcp nowait root /usr/sbin/tcpd gn ・ ・
そして、inetd を再起動します。すると、telnetは停止します。
# /etc/init.d/inet reload
デーモンが出すログを受け取るユーザーの決定or新設
これまでの inetd 経由だと、telnetデーモンのログはsyslogに出力されていましたが、daemonntoolsでは、ユーザー権限での出力が可能です。なので、ログ専用のユーザーを作って、その権限で動かしましょう。
ウチのサーバーの場合は、 djblogグループを作り、ここに所属のtellogユーザーにて行うことにしました。まずは、このユーザーとグループを作成します。
# groupadd djblog # mkdir /home/djblog # chgrp djblog /home/djblog # adduser tellog -g djblog -d /home/djblog/tellog -s /bin/false
デーモンの起動スクリプトの設置
さて、それでは、デーモンの起動スクリプトを設置しましょう。まあ、場所はどこでもいいんですが、私は /var/service ディレクトリを作り、この中にまとめることにしました。
# mkdir /var/service # chmod 755 /var/service
では、/var/service 以下に、telnetデーモン用のディレクトリを作ります。そしてこのディレクトリには、ログ取り専用のユーザー、tellog も書き込みを行うので、 tビットを設定しておきます。終わったら、telnetディレクトリに下ります。
# cd /var/service # mkdir telnet # chmod +t telnet # cd telnet
ここに、run という名前でスクリプトを書くと、これにしたがってデーモンが動きだすというわけです。
スクリプトは、基本的にはこんな感じです。
#!/bin/sh exec env - PATH="$PATH" \ tcpserver 0 telnet /usr/sbin/in.telnetd 2>&1
こういう書式になります。
tcpserver | オプション | 動かすホスト名。特に決めなければ 0 | ポート番号orサービス名 | プログラム | ログの出力用の決まり文句 |
tcpserver のオプションは、こちらにあります。
そんなわけで、私の場合は、こういう風にセッティングしました。
#!/bin/sh exec env - PATH="$PATH" \ tcpserver -l0 -R -H -v -c 3 0 telnet /usr/sbin/in.telnetd 2>&1
-l0 | ローカルホスト名を調べるのをやめて、localname を TCPLOCALHOST にセットする |
-R | IDENTを行わない。 |
-H | リモートホスト名を調べない。 |
-v | すべてのメッセージを出力する |
-c 3 | 最大同時接続数を3つにする |
さて、このスクリプトを run という名前で保存したら、実行属性と付けます。
# chmod 755 ./run
デーモンのログを受け取るスクリプトの設置
上記の設定で、telnetデーモンは走りますが、telnetデーモンが出力するログは、もうsyslogには記録されません。そこで、 multilog を使ってログを受けており、記録するスクリプトを書きます。
まず、/var/service/telnet/ に、ログ用のディレクトリを作ります。ここはログ取り専用のユーザー tellogが書き込みと管理を行うので、オーナーを変更しておきます。終わったら、logディレクトリに下ります。
# mkdir log # chown tellog:djblog log # cd log
ここに、さらに runというスクリプトを書きます。
#!/bin/sh exec env - PATH="/usr/local/bin:$PATH" \ setuidgid tellog multilog t ./main
ちなみにこの「setuidgid tellog」は、multilog を tellogユーザーの権限で実行させるためのものです。
telnetデーモンはまあ、しょうがないのですが、こういう手のデーモンは、可能な限りroot以外の権限で実行させておいたほうが、万が一の時もリスクが少なくなります。
run スクリプトに、実行権限を与えます。
# chmod 755 run
起動スクリプトのディレクトリを、/servece 以下にリンクする。(デーモン起動)
さあ、それではいよいよこれで設定完了です。デーモンを起動させてみましょう。
daemontoolsでデーモンを起動させるには、/service に、/var/service/telnet のリンクを張ります。リンクが張られたあと数秒で、これまで作った run スクリプトにしたがってデーモンを起動し、制御します。
# cd /service # ln -s /var/service/telnet
さて、どうでしょう。他のマシンからtelnetをかけてみて、動くかどうか確認してみてください。
動作確認
動作を確認します。 まず、daemontoolsがちゃんと動いている場合は、例の /var/service/telnet 以下に、このようなディレクトリが作られているはずです。
# ls /var/service/telnet log/ run supervise/ # ls /var/service/telnet/log main/ run supervise/
また、ログはちゃんと記録されていますが? ログを確認してみます。
ちなみに、multilogで取られるログはとんでもなく正確で細かい時間まで記録していますので、ちょっと普通に見ただけでは何時なのかよく解りません。
# teil /var/service/telnet/log/main/current @40000000417f9a050820e8e4 tcpserver: status: 0/3 @40000000417f9a050821043c tcpserver: status: 1/3 @40000000417f9a0508210c0c tcpserver: pid 2230 from 192.168.1.33 @40000000417f9a05082113dc tcpserver: ok 2230 0:192.168.1.44:23 :192.168.1.33::2600 @40000000417f9eae33a92e7c tcpserver: status: 0/3 @40000000417f9ebb061a6e6c tcpserver: status: 1/3 @40000000417f9ebb062090bc tcpserver: pid 519 from 192.168.1.33 @40000000417f9ebb06209c74 tcpserver: ok 519 0:192.168.1.44:23 :192.168.1.33::2617
multilog のログを見る時には、tai64localというツールに通してみるとが普通です。
# tail /var/service/telnet/log/main/current |tai64nlocal 2004-10-27 21:52:11.136374500 tcpserver: status: 0/3 2004-10-27 21:52:11.136381500 tcpserver: status: 1/3 2004-10-27 21:52:11.136383500 tcpserver: pid 2230 from 192.168.1.33 2004-10-27 21:52:11.136385500 tcpserver: ok 2230 0:192.168.1.119:23:192.168.1.33::2600 2004-10-27 22:12:04.866725500 tcpserver: status: 0/3 2004-10-27 22:12:17.102395500 tcpserver: status: 1/3 2004-10-27 22:12:17.102797500 tcpserver: pid 519 from 192.168.1.44 2004-10-27 22:12:17.102800500 tcpserver: ok 519 0:192.168.1.33:23:192.168.1.44::2617
異常がある。停止or再起動
daemontoolsは、管理しているデーモン(ここではtelnetとか)が万が一バグがあったり攻撃されて耐えられなくなって落ちてしまった場合でも、フルオートで再起動してデーモンのサービスを維持しようとします。(こういうのがinetdよりいい所) しかしその副作用として、例の /service 以下のリンクを削除しただけでは、デーモンを停止してくれません。
スクリプトがうまく動いていない時などに停止させたいときは、こうします。
# rm /service/telnet # svc -xd /var/servide/telnet/log # svc -xd /var/servide/telnet
これでtelnetデーモンは停止します。
起動したい時は、再び /service にリンクを張ればよろしい。
問題なければ一旦停止させる
さて、うまく動きましたか?
接続・ログなどがキチンと意図通りに動作したら、一旦停止させましょう。
# rm /service/telnet # svc -xd /var/servide/telnet/log # svc -xd /var/servide/telnet
一番最初、inetd でtelnetを起動した時、「ないよりはマシ」という程度で、hosts.allowとhosts.denyにて接続の制限をかけましたね。
今、telnetはdaemontools経由で動いていますから、この制限は効きません。daemonntools自身には、接続の制限をする機能がないのでしょうか?
そこで、tcpserver が持っている機能で接続の制限をかけましょう。
まず、一旦、telnetデーモンを止めます。
# rm /service/telnet # svc -xd /var/servide/telnet/log # svc -xd /var/servide/telnet
現在、/var/servicd/telnet/run スクリプトはこうなっていますね。
exec env - PATH="$PATH" \ tcpserver -l0 -R -H -v -c 3 0 telnet /usr/sbin/in.telnetd 2>&1
これを、以下のように書き換えます。
exec env - PATH="$PATH" \ tcpserver -l0 -R -H -v -c 3 -x ./tcp.telnet.cdb 0 telnet /usr/sbin/in.telnetd 2>&1
この -x のオプションは、 ./tcp.telnet.cdb という接続制御ファイルの通りに接続を制限しろ! という意味です。
スクリプトを保存したら、さっそくこの tcp.telnet.cdb ファイルを作成します。
まずは、tcp.telnet というファイルを作り、こんな内容を書き込みます。
tcp.telnet
192.168.1.:allow 127.:allow :deny
これで、発信元が192.168.1.xxな所からの接続は許可され、それ以外からの接続は全て拒否されます。 (127.:allow は、ループバックと言って自分自身のことを表しますので、通常は全て受け入れます。まあ、おまじないみたいなものと思っておいてください。)
ちなみに、この定義ファイルは上から評価されますので、もうすこし細かくコントロールしたい場合は、たとえば
192.168.1.22:allow 192.168.1.126:allow 192.168.1.8:allow 192.168.1.211:allow 192.168.1.:deny 127.:allow :deny
こんな書き方をすることもできます。
さあ! これでようやっと完成・・・・・ではありません。
daemontoolsは、この定義ファイルにとんでもない量を書き込んでも速度が落ちないように、バイナリ(ハッシュテーブル)に変換しなくてはいけません。
しかし、そのコマンドはちょっと面倒くさいです。
なので、/var/service/telnet/ に、make_cdb なんてスクリプトファイルを作っておきましょう。
make_cdb
#!/bin/sh tcprules tcp.telnet.cdb tcp.telnet.tmp < tcp.telnet
さあ、あとは、このmake_cdbを実行すれば、tcp.telnet から、 tcp.telnet.cdb を作成してくれます。
# ls log/ make_cdb* run* supervise/ tcp.telnet #./make_cdb # ls log/ make_cdb* run* supervise/ tcp.telnet tcp.telnet.cdb
さあ、接続の制御ファイルの準備も出来ました。リンクを張って、再びtelnetデーモンを動かしましょう。
# cd /service # ln -s /var/service/telnet
動作確認。完成
さて、動作が確認できたら完成です。
daemontools。どうでしたか?
いっちばん最初なので、ちょっと大変だったかも知れませんね。
でも、一度出来上がっちゃうと、あとは結構楽ですよ?(設定ファイルも、かなりコピペが効きますし)
最後の仕上げ
さあ、daemontoolsでtelnetがちゃんと動いてくれたら、もうinetdデーモンは用がありません。停止し、かつ、自動起動しないようにしてしまいましょう。
# /etc/init.d/inet stop Stopping INET services: [ OK ] # chkconfig inet off chkconfig --list iptables 0:off 1:off 2:on 3:on 4:on 5:on 6:off portmap 0:off 1:off 2:off 3:off 4:off 5:off 6:off gpm 0:off 1:off 2:on 3:off 4:off 5:off 6:off syslog 0:off 1:off 2:on 3:on 4:on 5:on 6:off keytable 0:off 1:off 2:on 3:on 4:on 5:on 6:off anacron 0:off 1:off 2:on 3:on 4:on 5:on 6:off rawdevices 0:off 1:off 2:off 3:off 4:off 5:off 6:off netfs 0:off 1:off 2:off 3:off 4:off 5:off 6:off network 0:off 1:off 2:on 3:on 4:on 5:on 6:off random 0:off 1:off 2:on 3:on 4:on 5:on 6:off crond 0:off 1:off 2:on 3:on 4:on 5:on 6:off inet 0:off 1:off 2:off 3:off 4:off 5:off 6:off
以上で完成です。お疲れ様でした。