2005/05/14
履歴:
これらのサーバには時折いたずらの telnet や ssh ボートへのアクセスがある。現在の所、これらは単なるいたずらに留まっており、現実的な脅威ではないが、対策をとることにした。
#!/bin/rc ifs=! r=`{cat $3/remote} {ip=$r(1)} if(test -e /sys/log/okip/$ip) exec /bin/ip/telnetd $* echo Login rejected
/rc/bin/service/tcp23 の内容
ディレクトリ /sys/log/okip にアクセスを許可する IP アドレスと同名のファイルを作成しておく。例えば 164.46.240.3 に許可する場合にはファイル 164.46.240.3 を /sys/log/okip に作成しておくのである。クライアントからの作成は POP3 によって行う。POP3 認証に成功した場合には、成功した IP アドレスを /sys/log/okip に登録する*。
ifs=! r=`{cat $3/remote} {ip=$r(1)}によって分かるので* $ip と同名のファイルが存在する場合にだけ
exec /bin/ip/telnetd $*を実行する。ここでは telnet ポートを例に説明したが、他のポートに対しても同様にやって行ける。
/net/tcp/90のような情報が渡される。/net/tcp/ に続く 90 はコネクション番号である。従って
cat $3/remoteの内容は
cat /net/tcp/90/remoteで得られるもの、例えば
164.46.240.3!18617と同じものである。
'164.46.240.3#32'のようなファイルを生成する。'#32' が付いているのは、ratfs はこのディレクトリに smtp.conf の内容を反映させるからだ。例えば smtp.conf に 164.46.240/24 からの転送要求には答えてよいよと書いてあれば ratfs は
'164.46.240.0#24'を作成すると言った具合である。ファイル名が複雑になるのは、このディレクトリがリレーの可否をも決定しているからである。プロバイダーが NAT を使用していれば、IP アドレスが共有されているので、POP3 before smtp の信頼性を落とすことになる。
Plan 9 の smtpd は esmtp をサポートしている。つまり、パスワード認証によってリレーの可否を決定できる。この方法であれば不正リレーを正しくカットできる。
また smtpd の -g オプションはなかなか旨く働いている。ratfs に頼らなくても筆者の環境では SPAM メールは適正レベルにまで落ちている。
による。従って Plan9 パスワードが使われる全てのポートに IP による保護を掛ければ pop3 パスワードと Plan 9 パスワードが同時に漏れない限り侵入が困難である。もちろん bootes には pop3 パスワードは必要ないし、与えない方が良い。
enableaddr(); if(readmbox(box) < 0) exits(nil); syslog(0, "pop3", "OK %s", peeraddr); //Kenar return sendok("mailbox is %s", box); }これで pop3 は認証が成功した IP のログを
ar Apr 12 15:56:18 OK 202.250.160.166のように /sys/log/pop3 に残す。/sys/log/pop3 は作成しておく。
#!/bin/rc ifs=! r=`{cat $3/remote} {ip=$r(1)} if(! nodos $ip 110){ echo '-ERR Busy' exit } /$cputype/bin/upas/pop3 a=`{tail -1 /sys/log/pop3} if(! ~ $a(6) $ip) exit if(test -e /sys/log/okip/$ip) rm /sys/log/okip/$ip touch /sys/log/okip/$ip
/rc/bin/service/tcp110 の内容
nodos のソースは後にまた解説するが、このプログラムは nodos の引数で与えた IP と同一の IP から多数の同時アクセスが発生している場合にエラー終了する。もう一つの引数(110) は nodos のログファイルにポート番号を残すために使われている。
ディレクトリ /sys/log/okip の許可ビットは
d-rwx-wx-wx /sys/log/okipとしておく。
このディレクトリは本当はシステムユーザの悪態から保護されるべきである。しかし先に述べた許可ビットでは保護されない。この問題は、pop3 を none ではない仮想ユーザとして実行すれば解決できる。
このディレクトリの有効期間が過ぎたファイルは定期的に cron によって削除されるべきである。
筆者のサーバでは secstore、 fossil への不正アクセスは未だ観測されないものの Plan 9 では重要なポートである。他方 aquarela には不正アクセスが多発し、しかも aquarela は 0.5 版に留まっているように十分な強度を持っていないように思える。
これらにパッチを当てるのは避けたい。以下の方法を採用すればパッチ当ては避けられる。
#!/bin/rc # # usage: relay from_addr to_addr # # Log is put into /sys/log/relay # Incomming call is relayed if and only if # it is allowed by /sys/log/okip/* # switch($#*){ case 1 ifs='! ' r=`{cat $net/remote} l=`{cat $net/local}{i=$r(1) p=$l(2)} # $i is remote ip # $p is local port logit -l relay $p $i if(test -e /sys/log/okip/$i) exec connect -v $1 |[2] logit -l relay echo Rejected case 2 exec aux/listen1 $1 /bin/relay $2 }
relay の内容
relay の引数 from_addr と to_addr は
tcp!ホスト名!ポート名の形式で与える。
このスクリプトの中での
$netは
/net/tcp/90のような値をとる。この環境変数は listen1 が与えている。$net は listen での $3 に相当する。
logit はログを採るためのプログラムで、使い方は
logit -l logname [message ...]である。ログ情報は logit の引数からでも標準入力からでも与える事ができる。この件に関しては後に解説する。
relay に現れる connect は con と似ているのだが、con のようによけいな事をしない。純粋に標準入出力を指定されたアドレスに転送しているだけである。con にそのようなオプションがあれば connect を持つ必要は無いのだが今の所は無い。
connect の使い方は
connect [-v] addrである。-v フラグはメッセージを標準エラーに出力する。connect に関しても後に解説する。
relay のログが欲しくなるのは最初だけかもしれない。ログが不要なら
#!/bin/rc # # usage: relay from_addr to_addr # # Log is put into /sys/log/relay # Incomming call is relayed if and only if # it is allowed by /sys/log/okip/* # switch($#*){ case 1 ifs='! ' r=`{cat $net/remote} l=`{cat $net/local}{i=$r(1) p=$l(2)} # $i is remote ip # $p is local port if(test -e /sys/log/okip/$i) exec connect $1 echo Rejected case 2 exec aux/listen1 $1 /bin/relay $2 }
ログを採らない relay の内容
と変更すればよいであろう。
従って認証サーバ hera で
auth/secstored -s tcp!127.0.0.1!secstore relay tcp!hera!secstore tcp!127.0.0.1!secstore &を実行する。
relay 'tcp!*!secstore' tcp!127.0.0.1!secstore &としてはならない。なぜなら tcp!*!secstore は tcp!127.0.0.1!secstore をも受け取る。従って悲惨な結果に終わるかもしれない。
一つは hera のサービスを il プロトコルに限定し、ar で
relay tcp!ar!9fs il!hera!9fs &を実行しておく事。CPU サーバなどは il プロトコルで hera にマウントすることになる*。
二つ目は tcp!hera!9fs はファイアーウォールの後ろに隠し、ar で
relay tcp!ar!9fs tcp!hera!9fs &を実行しておく事。
前者の方が厳重であるが。何れにせよ、大学の外のクライアントからは
9fs arでマウントできる。
bootargs=ilを指定しておいた方が良いであろう。
もっとも筆者は Windows を使わないので aquarela もまた使わない。relay の実験は行っていないので、悪しからず。
「9fs のリレー」で述べた事は次のように行う事もできる。
term% mntgen term% srv -e 'rx ar connect il!hera!9fs' foo /n/foo post... term% ls /n/foo /n/foo/386 ... /n/foo/mnt /n/foo/n /n/foo/power /n/foo/rc /n/foo/sparc /n/foo/sparc64 /n/foo/sys /n/foo/tmp /n/foo/update /n/foo/usr term%これは筆者の家庭の Plan 9 端末から CPU サーバに rx によってアクセスし、その標準入出力を /srv/foo に繋げ、それをマウントしている。srv のこの使い方は Pipe に載っているので参考にして頂きたい。