本校では、iij-pppにNAT(Network Address Translator) のパッチをあてて、ダイヤルアップでもLAN上のどのマシンからでもインターネットに出ていけるようにしています。
※参考ところが、ダイヤルアップとはいえ、グローバルなIPアドレスを使っている以上、外部から不正に侵入される危険性はあるわけです。(図1参照)
NAT on iij-ppp
On Demand Dialup IP[目次]
※こういう場合、huck あるいは hucker という言葉が一般に通用していますが、cruck あるいは attack というのが正確です。プロバイダから割り振られる IP アドレスは電話をかけて回線をつなげる度に違います。しかし、その範囲は限られたもので、何度もつなげていると、中には同じアドレスが割り振られていることもあります( ppp で show ipcp してみるとわかる)。
<図1>
Foreign-host | ||||
Server |
inetd (アクセス制限 無し) ↓ telnetd |
LAN | ||
そこで……許可されたホスト以外から telnet, ftp, finger, rlogin, POP などでのアクセスを制限するプログラム tcp_wrapper ( tcpd ) を入れることにしました。(図2参照)
tcpd は inetd と telnetd etc. の間に入り、アクセスを許可されたホストからのものかどうかチェックして、その後のプロセスを立ち上げます。
これだと、不正なアクセスを拒否するばかりでなく、もし不正なアドレスがあった場合、どこからアタックをかけられたか知らせてくれます。
<図2>
Foreign-host | ||||
Server |
inetd ↓
tcpd ↓ telnetd |
LAN | ||
NG! | ||||
OK! |
可能性は低いとはいえ、安全策を講じておくにしくはありませんね。
設定
インストールは ports から行いました。2.2.1R の CD には tcp_wrappers_7.4.tar.gz が収録されています。
/usr/ports/security/tcp_wrapper の下で make install を実行するだけです。
この後で、各種の設定にはいるわけですが、ここで注意しなければならないことがあります。
ports でインストールすると、README とは違ったディレクトリ設定になるのです。具体的には、アクセスを許可 or 拒否するホストの情報を、ディフォルトでは
/etc/hosts.allowに書くことになっていますが、ports でだと、
/etc/hosts.deny
/usr/local/etc/hosts.allowに書き込むように、Makefile ではなっています。
/usr/local/etc/hosts.deny
tcp_wrapper を動かすには /etc/inetd.conf を書き換えます。
ftp, telnet, rlogin, pop3 を制限してみます。それらの行を以下のように書き換えました。
#ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l
ftp stream tcp nowait root /usr/local/libexec/tcpd ftpd -l
#telnet stream tcp nowait root /usr/libexec/telnetd telnetd
telnet stream tcp nowait root /usr/local/libexec/tcpd telnetd
#login stream tcp nowait root /usr/libexec/rlogind rlogind
login stream tcp nowait root /usr/local/libexec/tcpd rlogind#pop3 stream tcp nowait root /usr/local/libexec/popper popper
pop3 stream tcp nowait root /usr/local/libexec/tcpd popper
次に、/usr/local/etc/hosts.allow と /usr/local/etc/hosts.deny を次のようにします。※注意!もし、popper を ports からインストールしてあれば、そのバイナリの置き場が tcpd の想定している場所と違っていますので、以下のようにしてリンクしておきましょう。
# cd /usr/libexec # ln -s /usr/local/libexec/popper
/usr/local/etc/hosts.allow最初の「ALL」は制限するデーモンの名前を書くのですが、これだと /etc/inetd で tcpd をかましてある全てのものが対象になります。次の「ALL」あるいは IP アドレスは拒否、あるいは許可するホストの情報です。IP アドレスではなく、ドメインでも書き込めます。ALL: 192.168.0./usr/local/etc/hosts.denyALL: ALL
man 5 hosts_accessしてください。
不正アクセスの知らせをメールで受け取るには
もし、許可していないホスト以外から不正にアクセスがあった場合、/var/log/messages に
というようなログが残ります。Sep 25 12:54:53 white telnetd[252]: refused connect from bad.host Sep 25 12:55:02 white telnetd[256]: refused connect from bad.host
man 5 hosts_access によると /usr/local/etc/hosts.deny 等で
daemon_list : client_list [ : shell_command ]の書式で書けばいいとあるのですが、この shell_command のところにどう書くかが問題 になります。
--------------------------- hosts.deny --------------------------------- ALL EXCEPT fingerd: ALL: spawn = (/usr/local/bin/safe_finger -l @%h | \ /usr/bin/mail -s %d-%h root) & ALL: ALL: spawn = (/usr/bin/mail -s %d-%h root) & ------------------------------------------------------------------------man 5 hosts_access に出ている例には spawn = の表現が抜けてますね。(man 5 hosts_options にはちょっとだけ書かれています。)
※自白注意すべきは、2つあって、このことを発見したのは私ではなく、ある人がソースを読んでいて気が付きました。私はそれを教えてもらっただけ……(^-^ゞ
私にはソースを読む力なんてありませんからねえ……(^-^ゞ
これらのファイルの記述ミスとかは、実験してみて messages を見てもいいのですが、効率が悪いので
# /usr/local/sbin/tcpdchkとやって、警告がなければ OK です。
これで、不正アクセスをすると以下のようなメールが届きます。
From daemon Fri Sep 26 11:11:24 1997 Date: Fri, 26 Sep 1997 11:11:24 +0900 (JST) From: Charlie RootTo: root Subject: telnetd-badhost [badhost] Login name: hoge In real life: hoge hoge Directory: /home/hoge Shell: /bin/tcsh On since Sep 26 09:39:54 on ttyp0 from host_name No Plan.
これで、安心ですね\(^0^)/
※参考許可するホストに関しては、domain name よりも IP アドレスの列挙の方がより頑丈だそうです。
ALL: 10.0.0.0/255.255.255.0 10.0.1.100hosts.allow でこうすると 10.0.0.0 から 10.0.0.254 までの client と 10.0.1.100 が入れます。ネットワーク表現をうまく使えるといいですね。
name を使わない方がいいのは DNS サーバーをだまして入る事が不可能ではないからです。古いバージョンの DNS を参照するとだまされやすいので。
tcp_wrapper に付属するツール
上記で使った
もそうですが、tcp_wrapper を make すると、いくつかのバイナリができています。
- tcpdchk(hosts.allow, hosts.deny の記述をチェック)
- safe_finger(不正アクセス者を逆探知)
許可ルールの確認に便利なコマンドです。
(1)アクセスが許される例
(2)アクセスが許されない例# /usr/local/sbin/tcpdmatch ftpd goodhost client: hostname goodhost client: address xxx.yyy.zzz.aaa server: process ftpd matched: /usr/local/etc/hosts.allow line 1 access: granted
こうすると、実際にそのマシンに入らずにルールの正当性の確認ができます。どのルールで、OK なのか NG なのかも確認できます。# /usr/local/sbin/tcpdmatch ftpd badhost client: hostname badhost client: address ppp.qqq.rrr.sss server: process ftpd matched: /usr/local/etc/hosts.deny line 2 option: spawn (/usr/local/bin/safe_finger -l @badhost | /usr/bin/mail -s ftpd-badhost root) & access: denied