本稿の内容を検証する場合は、必ず影響を及ぼさない限られた環境下で行って下さい。また、本稿を利用した行為による問題に関しましては、筆者および株式会社アットマーク・アイティは一切責任を負いかねます。ご了承ください。
「第2回 ソフトウェアの現状確認とアップグレード」までの内容を実施することで、現行サービスのセキュリティを向上させることができた。今回からは、それらのサービスをよりセキュアにするための手法を紹介していく。
特定サービスの利用制限
稼働中のサービスの中には、特定ユーザーのみに限定してサービスを提供したい場合がある。特に、telnet、ftpなどのメンテナンス系のサービスは、通常であれば当該サーバの関係者が利用できればよいので、それ以外、つまり部外者からのアクセスは制限するのが望ましい。
接続元によるアクセス制限
UNIXサーバでサービスの利用制限を行う方法の1つとして、接続元(IPアドレス)によるアクセス制限がよく知られているが、それを実現するためには、上位(よりインターネット側)のルータやファイアウォール、もしくは対象サーバ上で実施する必要がある。
本稿では、後者の対象サーバ上でアクセス制限を実施する方法を、アクセス制御ツールのTCP Wrapperを用いて説明する。
ファイアウォールがあれば十分?
最近の主流としては、接続元によるアクセス制限を上位のファイアウォールなどで行う傾向にある。そのメリットとしては、ネットワーク全体に対するアクセス制御ポリシーを一元管理できること、そして何より対象ホストへの不要なサービスに対する攻撃を到達する前に遮断できるということが挙げられる。そのため、ファイアウォールでさえ防いでいれば、TCP Wrapperなどのような対象サーバ自身で行うアクセス制限は、一見すると必要ないように思える。
しかし、対象サーバのセキュリティをさらに向上させたいのであれば、対象サーバ自身でのアクセス制限の実施も併せて行うことをお勧めする。その理由としては、例えば内部の別のサーバが侵入された時のことを考えてみるとよいだろう。侵入したサーバを踏台として利用された場合、上位のファイアウォールによるアクセス制限は、全く意味をなさなくなってしまう。対象サーバ上でアクセス制限を行うと、たとえ同一ネットワーク上からのアクセスであっても制限できるため、更なる2次被害を防ぐことが可能だ。
inetd + TCP Wrapperの組合せ
既存のUNIXの多くが、メンテナンス系のサービスを提供する場合はinetdを用いる。しかし、元来inetd自身にはアクセス制限の機能は付いていないため、その部分はTCP Wrapperで補うのが慣例となっていた。本稿でもそれに従いinetdとTCP Wrapperの組合せを紹介する。
しかし、inetdには接続受け付けの上限を設定できないなど、DoSに弱いという問題も存在するため(一部バージョンでは可能なものもある)、最近では、それらすべての機能を併せ持ったxinetdや(ucspi-tcp に含まれる)tcpserverが利用される傾向にある。本稿では既存のサービスに極力影響を与えないようにするためinetd + TCP Wrapperの組合せを説明するが、サーバの新規導入などを考えている場合は、xinetdやtcpserverの使用も検討するとよいだろう。
TCP Wrapperとは?
TCP Wrapperは、SATANやPostfixでもおなじみのWietse Venema氏が作成したアクセス制御ツールで、UNIXサーバのセキュリティを向上させるための定番ツールとして古くから利用されている。もともとはinetdにアクセス制御と通信ログを持たせることを目的*1に利用されていたが、最近ではライブラリ(libwrap)を取り込むことで、そのほかのサービスでも利用されるようになった。
inetdの拡張版であるxinetdは、自身にアクセス制御の機能が備わっているため、TCP Wrapperを別途準備する必要はない。
主な特徴
- TCP、UDPサービスのアクセス制御
各サービスに対するアクセス制御を、ホスト名、IPアドレス、ネットワークアドレス単位で実現可能。また、相手がidentサービスを利用している条件下でユーザー認証も行える。
- 既存のアプリケーションを改変することなく導入可能
稼働中の既存のアプリケーションを改変することなく、アクセス制限を導入することが可能。また、取り外しも容易。
- 合致したルールに応じてアクション(コマンド)を実行
各種コマンドを用いることで、接続元の身元確認、メールによる通知、バナーメッセージの表示を行える。
- ホスト名スプーフィング(なりすまし)の検出
ホスト名からIPアドレス(正引き)、IPアドレスからホスト名(逆引き)の名前解決を行うことで、スプーフィング(なりすまし)を検出、または拒否する。
- 設定の妥当性チェックとシミュレーションの実施
TCP Wrapper付属のコマンドtcpdchkおよびtcpdmatchを利用することで、設定の妥当性およびアクセス制限のシミュレーションを実施可能。
TCP Wrapperのインストール
インストール前に
TCP Wrapperは、多くのUNIXに標準でインストールされている。そのため、TCP Wrapperをインストールする前に、すでにインストールされていないかどうかを確かめる必要がある。もし、インストール済みの場合は、次の設定に進もう。
各種パッケージであれば前回紹介した手法でインストール済みかどうかをチェックすればよい。そうでなければ、lddコマンドや/etc/inetd.confファイルをチェックすることで確認できる。
例:/etc/inetd.conf をチェック
% grep tcpd /etc/inetd.conf ftp stream tcp6 nowait root /usr/sbin/tcpd in.ftpd telnet stream tcp6 nowait root /usr/sbin/tcpd in.telnetd
上記では、ftpdおよびtelnetd起動時に、tcpd(TCP Wrapperプログラム)が呼び出される。
例:lddコマンドで確認
% ldd /usr/sbin/inetd /usr/sbin/inetd: -lwrap.0 => /usr/lib/libwrap.so.0 -lutil.6 => /usr/lib/libutil.so.6 -lipsec.2 => /usr/lib/libipsec.so.2 -lc.12 => /usr/lib/libc.so.12
libwrap.soが動的に呼び出されるのが分かる。
また、inetdに限らず、最近ではライブラリ(libwrap)を取り込むことで、そのほかのデーモンプログラムでも利用されている。例えばOpenSSHの場合は、configure実行時に--with-tcp-wrappersを指定することで、TCP Wrapperの機能を取り込むことが可能だ。
% ldd /usr/sbin/sshd /usr/sbin/sshd: …… 途中省略 …… -lwrap.0 => /usr/lib/libwrap.so.0 -lskey.1 => /usr/lib/libskey.so.1 -lc.12 => /usr/lib/libc.so.12
TCP Wrapperのインストール
確認の結果、TCP Wrapperがインストールされていない場合は、ソースコードもしくはパッケージをダウンロードする。バージョンは、ここでは最新の7.6を使用する。
なお、IPv6対応サービスのアクセス制限も行いたい場合は、IPv6対応版(tcp_wrappers_7.6-ipv6.2.tar.gz)の方を選ぶ必要がある。
ファイルをダウンロードしたら、最初にファイルの整合性チェックを必ず行うこと。特にTCP Wrapperの場合は、以前バックドア付きで配布されたことがあったので注意が必要だ。
※参考
CERT Advisory CA-99-01-Trojan-TCP-Wrappers:http://www.cert.org/advisories/CA-1999-01.html
ファイルの整合性チェックを無事にクリアできたら、実際にインストールを行う。パッケージの場合は、各種パッケージの手順に沿ってインストールすればよい。ソースコードからインストールする場合は、以下の手順で実施する。
% tar zxvf tcp_wrappers_7.6.tar.gz % cd tcp_wrappers_7.6 % vi Makefile
コメント部(先頭が#)に、各OS別に有効にすべき設定値が明記されているので、それを参考にしながら編集する。例えば、Solaris 8の場合は以下のとおり編集する。なお、コンパイラはgcc(GNU cc)を用いる。
変更前:
変更後:
また、Solaris 8など、IPv6サービスを有効にしている場合は、IPV6 = -DHAVE_IPV6を忘れずに有効にしておく。
変更前:#IPV6 = -DHAVE_IPV6
変更後:IPV6 = -DHAVE_IPV6
さらに後述のコマンド実行(spawn)など、hosts_options(5)の機能を使いたい場合は、STYLE = -DPROCESS_OPTIONSも有効にする必要がある。
変更前:#STYLE = -DPROCESS_OPTIONS
変更後:STYLE = -DPROCESS_OPTIONS
makeの際に、該当するアーキテクチャを引数で指定する。例えば、Solaris 8の場合はsunos5を指定する。
% make sunos5
コンパイルが正常に終了すると、tcpd、tchdchk、tcpdmatchというバイナリプログラムが生成されるので、それを変数REAL_DAEMON_DIRで指定した場所にコピーする。また、必要に応じて、safe_fingerコマンド*2や付属のマニュアル類もコピーするとよい。
# cp tcpd tcpdchk tcpdmatch /usr/sbin # chown root /usr/sbin/tcpd /usr/sbin/tcpdchk /usr/sbin/tcpmatch # chmod 555 /usr/sbin/tcpd /usr/sbin/tcpdchk /usr/sbin/tcpmatch
後述のコマンド実行(spawn)で、接続元の情報を得る場合に必要となる。
後は/etc/inetd.confを編集して、サービス起動時にtcpdが呼び出されるようにする。例えば telnet の場合は以下のとおりに変更する(libwrap読み込み型の場合は不要)。
編集前:telnet stream tcp nowait root /usr/sbin/in.telnetd in.telnetd
編集後:telnet stream tcp nowait root/usr/sbin/tcpd in.telnetd
Copyright © ITmedia, Inc. All Rights Reserved.