inetd から起動される TCP サービス (ftp, telnet 等) のアクセスを制限し、リクエストをログに記録します。
ソースを入手します。
archive: | tcp_wrappers-7.6.tar.gz | |
os release: | Solaris 8 (IA-32) |
アーカイブを展開します。
% pwd |
Makefile を書き換えてコンパイルします。以下の3行を加えます。
REAL_DAEMON_DIR=/usr/sbin |
qmail で使用する可能性があるので -DPROCESS_OPTIONS を有効にしています。
コンパイルします。
% pwd |
実行可能ファイルが5個作成されます。
-rwxr-xr-x 1 tachi staff 10724 12月 12日 21:58 safe_finger |
root になり、作成されたバイナリファイルを手動でインストールします。
# mkdir -p /usr/local/sbin |
バイナリファイルを配置するディレクトリを作成し、バイナリファイルを mv してパーミッションと所有者、グループを変更しています。
マニュアルをインストールします。
# cd /usr/local/man |
man コマンドで参照できるように環境変数 MANPATH に /usr/local/man を加えておきます。
例えば csh だと以下のようにします ($HOME/.cshrc に記述します)。
% setenv MANPATH /usr/local/man:$MANPATH |
inetd (Internet services daemon) は、/etc/inet/inetd.conf ファイルの設定にしたがってサービスを起動します。起動するプログラムを tcpd に変更することでアクセスの制限を実現します。inetd の子プロセスとして tcpd が起動し、tcpd は /etc/hosts.allow と /etc/hosts.deny を参照してリクエストの可否を判断します。
inetd.conf を書き換え、起動されるサーバプログラムを tcpd に置き換えます。
ftp stream tcp nowait root /usr/sbin/in.ftpd in.ftpd |
Makefile 中で定義した、REAL_DAEMON_DIR=/usr/sbin 以外のディレクトリに存在するサーバプログラムを tcpd で置き換える場合は、引数の指定でプログラム名を絶対パスで記述します。
imap stream tcp nowait root /usr/local/libexec/imapd imapd |
ついでに permission を変更しておきます (policy に依存すると思います)。
# chmod go-r /etc/inet/inetd.conf |
tcpd によるアクセスコントロールは /etc/hosts.allow と /etc/hosts.deny の2つのファイルの検索によって決定します。最初に hosts.allow の検索を行い、これと一致する場合アクセスを許可します。hosts.allow と一致しない場合は hosts.deny の検索を行い、これと一致する場合はアクセスを拒否します。hosts.deny とも一致しない (つまり両方に一致しない) 場合はアクセスを許可します。
以下に /etc/hosts.deny と /etc/hosts.allow の例を挙げます。
# cat /etc/hosts.deny |
# cat /etc/hosts.allow |
この場合は hosts.deny ですべてを拒否しておいて、許可する address をサービス毎に hosts.allow で許可しています。テスト用にひとつのローカルアドレスをアクセス拒否しています。
記述の書式は以下です。
daemon_list : client_list [ : shell_command ] |
それぞれの list element は comma か blank で区切ります。daemon_list には以下の wildcard が使用でき、client_list には host 名と、以下の address, pattern, wildcard が使用できます。
wildcards | notes |
---|---|
ALL | すべて (のサービス or host) に match します |
LOCAL | dot (.) を含まない名前の host に match します |
UNKNOWN | 名前か address が不明な host に match します |
NKOWN | 名前と address が引ける host に match します |
PARANOID | 名前が address に一致しない host に match します |
operators | notes |
EXCEPT | a EXCEPT b と記述するとき、b 以外の a に match します |
patterns | notes |
一致するドメイン名の host に match します | |
数値が address に一致する host に match します | |
@ で始まる文字列 | nis の netgroup として扱います |
n.n.n.n/m.m.m.m | net/mask の pair と解釈します address の bit 幅と、mask 値でマスクしたネットワークアドレス番号の両方が一致する host に match します |
/etc/hosts.allow, /etc/hosts.deny の2つも permission を変更しておきます。
# chmod 600 /etc/hosts.allow /etc/hosts.deny |
/etc/inetd/inetd.conf, /etc/hosts.allow, /etc/hosts.deny の編集のあとで tcpdchk を実行します。
error が出力される場合はファイルを修正し、error (と warning ) が出力されないように設定します。
ちなみに上の例だと下のように warning が出力されます。
# /usr/local/sbin/tcpdchk |
つぎに、tcpdmatch でいくつかのパターンを match してみます。これは policy に従った設定がされているか確認するためのもの (oracle: 預言) ですので、重要なパターンを確認すれば問題ないと思います。
# /usr/local/sbin/tcpdmatch in.telnetd 192.168.5.45 |
実際にアクセス制御を開始するために inetd を再起動します。
# ps -ef | grep inetd |
実際に他の host からリクエストし、アクセス制限を確認します。
ちょっと淋しいので、アクセスを拒否するときにメッセージ (banner) を表示するようにしてみます。
banner 用ディレクトリ (例えば /etc/banners) を作成し、Banners.Makefile を cp します。
# mkdir /etc/banners |
banner 用ディレクトリに prototype という名前のファイルを作成し、表示するメッセージを記述します。
# cat /etc/banners/prototype |
shell command で使用できる expansion を以下に挙げます。
expansions | notes |
---|---|
%a | client の address を展開します。 |
%A | server の address を展開します。 |
%c | client の情報 (可能であれば user@host) を展開します。 |
%d | サービスプログラム名を展開します。 |
%h | client の hostname (あるいは address) を展開します。 |
%H | server の hostname (あるいは address) を展開します。 |
%n | client の hostname (あるいは "unknown" か "paranoid") を展開します。 |
%N | server の hostname (あるいは "unknown" か "paranoid") を展開します。 |
%p | サービスプログラムのプロセスIDを展開します。 |
%s | server の情報 (可能であれば daemon@host) を展開します。 |
%u | client username (あるいは "unknown") を展開します。 |
%% | % いっこです。 |
つぎに banner 表示用のコマンドを作成します。
# pwd |
banner は /etc/hosts.allow と /etc/hosts.deny の rule ひとつひとつに割り当てることが可能です。それぞれの rule に対してディレクトリを用意し、banner 表示プログラムを置きます。ここでは、アクセスを拒否する場合のディレクトリ (/etc/banners/refuse) を用意し、ファイルを cp します。
# pwd |
/etc/hosts.deny ファイルを編集して、アクセス拒否時の banner ディレクトリを指定します。
# cat /etc/hosts.deny |
アクセスを拒否する場合、banner が表示されるようになります。