Solaris のセキュリティ設定

Solaris 階層に戻る  |  ホームに戻る

この文書について

インストール直後の Solaris は、 いろいろな点でセキュリティホールを含んでいるので、 パッチを当てたり、設定を変更するなどして穴を埋める必要がある。 ファイアウォールの導入、ネットワーク構成の見直しなど、 セキュリティを高めるには様々なレイヤでの対処が必要だが、この文書では、 単一ホストレベルでセキュリティを高める工夫に限定して論じることとする。

具体的には、以下のような対処を行うと良い。

  1. Recommended patch の適用
  2. 不必要なサービスを停止
  3. TCP Wrappers によるアクセス制限
  4. リモートログインの ssh 化
  5. ipfilter によるホストファイアウォール化
  6. そのほか、細かな Tips
  7. アプリケーションレイヤでの設定

アプリケーションレイヤでの対処は各アプリケーションごとに異なり、 膨大な量に達するのでここでは扱わない。各種アプリケーションの ドキュメント類をあたって欲しい。

なお、これ以降、この文書は一部を除き Solaris 9 (SPARC/Intel) を対象としている。

1. Recommended patch の適用

Recommended patch は SunSolve または SunSite Japan から入手できる。

システムをシングルユーザモードで起動して (init 1 や S では終了できないデーモンが存在するので) 以下の手順でパッチを適用する。

# unzip 9_Recommended.zip
# cd 9_Recommended
# ./install_cluster
(略)
Are you ready to continue with install? [y/n]: y

Solaris を公開サーバとして運用する場合、最低でもその時点で最新の Recommended Patch を適用しておくことが必須である。

2. 不必要なサービスを停止

どのようなサービスも潜在的な脆弱性を持っているので、 各サーバにとって本質的なサービス以外のネットワークサービスは、 停止しておくべきである。 たとえば、メールサーバではメールサービスのみを動かして、 その他のサービスは止めておく必要がある。

Solaris では、ネットワークサービスは /etc/rc?.d/* のスクリプトから 起動されるものと、inetd (インターネットスーパーサーバ) から間接的に 起動されるものがある。それぞれについて、停止すべく対処を施す。

/etc/rc?.d 以下の起動スクリプト

停止すべきサービスとして、以下のものが挙げられる。

以上は、X を動作させる必要のあるマシン (具体的には、FireWall-1 マシン) でのリストである。それ以外のサーバでは、さらに加えて以下のサービスを 停止すべきである。

スクリプトを無効化するためには、大文字 S プラス数字二桁で始まら 「ない」名前に変更すれば良い。 ファイル名の先頭に _ (アンダースコア) を付けるなどが一般的である。

# cd /etc/rc2.d
# mv S71rpc _S71rpc

inetd によって起動するデーモン

基本的に、以下のサービスを停止すべきである。 /etc/inet/inetd.conf を編集して、以下の行をコメントアウト (行頭に # を付加) することで無効化できる。

rc スクリプトと同様、以上は CDE を動かしたいマシンでの設定である。 それ以外のサーバでは、さらに以下のサービスを停止する。

サービスを止める対処を行ったあと、システムを再起動する。

3. TCP Wrappers によるアクセス制限

ネットワークサービスの中には、TCP Wrapper を利用して、 クライアントの IP アドレスによるアクセスコントロールを行えるものがある。 inetd 経由で起動される tcp 系サービス (ftp、telnet など)、 libwrap を組み込んだもの (ssh、sendmail など) である。

telnet、ftp といった危険なプロトコルを使用する場合は、 最低でもこの対処を行っておいた方が良い。

TCP Wrappers 7.6 のインストール方法については 「フリーソフトウェアのコンパイル」内 tcp_wrappers の項を参照のこと。 インストールが完了したら /etc/hosts.allow というファイルを作成して、編集する。 これは、TCP Wrappers によって走査される最初のファイルで、 ルールにマッチしたパケットは通過を許可される。

# vi /etc/hosts.allow

hosts.allow ファイルの例を以下に示す。ルータでのパケットフィルタリングや ファイアウォールのポリシー作成と同じように、パケットごとにルールを 走査して、最初にマッチしたルールが適用される。 記法は、「サービス : ソース IP アドレス」となる。詳細は hosts_access(5) を参照。

# 試験の時は次行のコメントをはずしてパケットが通るかどうか確認する
#ALL : ALL

# sendmail に関してはラッパーをかけない
sendmail : ALL

# ssh のアクセスは内部からのみ
sshd : 172.16.0.0/255.255.0.0

# ftp のアクセスは内部からのみ
in.ftpd : 172.16.0.0/255.255.0.0

# 自分自身との通信はすべて許可
ALL : 127.0.0.1,172.16.0.13

次に、hosts.allow の後に評価されるファイルとして、hosts.deny を作成する。 こちらにマッチしたパケットは reject される。 内容は、ALL : ALL というルールにしておく。 これで、hosts.allow にマッチしなかったパケットはすべて拒否される。

さらに、inetd 経由で起動するプログラム (ftpd、telnetd) に関しては、 inetd.conf を編集して、tcpd 経由で起動されるよう変更する必要がある。

# vi /etc/inetd.conf

以下、ftp と telnet サービスを TCP Wrappers 経由にする例を示す。

ftp    stream  tcp6    nowait  root    /usr/sbin/in.ftpd       in.ftpd
telnet stream  tcp6    nowait  root    /usr/sbin/in.telnetd    in.telnetd

↑このようになっている部分を、↓このように変更する。

ftp    stream  tcp6    nowait  root    /usr/local/bin/tcpd     in.ftpd
telnet stream  tcp6    nowait  root    /usr/local/bin/tcpd     in.telnetd

注: Solaris 7 までは tcp6 ではなく tcp となっている。

変更を行ったら、inetd プロセスに HUP シグナルを送るか、システムを 再起動すれば完了である。

4. リモートログインの ssh 化

rsh や rlogin などのいわゆる r 系コマンドに加え、 telnet や ftp はログインパスワードが平文のままネットワークを流れる点で 致命的にセキュリティを破壊するため、できるだけ使用しないことが望ましい。 そこで、代替手段としての ssh が必要となる。

Solaris 9 では、ssh が標準添付されるようになったため、 改めてインストールする必要はない。

Solaris 8 以前の場合、フリーの ssh 実装である OpenSSH をインストールする。 やり方は「フリーソフトウェアのコンパイル」内 ssh の項を参照。

使い方は、rsh/rlogin コマンドと同じである。 sshd の動作しているホストに対して、% ssh sshhost ls と実行すればリモートで ls が実行されるし、 % slogin sshhost とすればリモートログインできる。

5. ipfilter によるホストファイアウォール化

いわゆるルータ/ファイアウォールマシンだけでなく、 インターネットサーバにおいてもパケットフィルタリングをかけて ホストレベルのセキュリティを高めることができる。 例えば、Web サーバホストでは TCP 80 番宛て以外のパケットを すべてフィルタリングすれば、より安全になる。

Solaris でパケットフィルタリングを行いたいとき、 よく使われるフリーソフトウェアが IP Filter (ipf) である。

IP Filter は BSD系 OS、IRIX などでも動作するクロスプラットフォームな プログラムであるため、文献が多いことが利点である。 また、カーネルモジュールとしてパケットを処理できるため、 ユーザアプリケーションでフィルタリングするよりも安全性が高い (ユーザアプリケーションでは、そのプロセスを kill されたら終りである)。 ルールを入出力にグループ分けでき、入出力デバイスの特定ができることも 特徴である。

短所としては、ファーストマッチルールではないためルールが理解しにくい (ファーストマッチ的に書く方法もある) 点があげられる。

IP Filter はルータマシンにインストールしたときに NAT を行う機能も 持っているのだが、今回は単なるサーバホストにインストールするので NAT については扱わない。

1. インストール

使用したコンパイラは gcc-3.0.4 である。SPARC 64bit カーネルを利用している場合は、64bit コードを吐けるコンパイラが 必要になるので、gcc を sparcv9-sun-solaris2.8 オプションつきで ビルドしておく。

まずは tarball を取得・展開する。

$ tar xzf ip-fil3.4.25.tar.gz
$ cd ip_fil3.4.25

Solaris/IA ではここで以下のパッチを当てないとコンパイルに失敗するかも しれない。

$ gpatch -p1 < ../ip-fil3.4.25-sol.patch
$ make solaris
$ su
Password:
# cd SunOS5
# make package

これで "ipf" (64bit 版ならば ipf と ipfx の2つ) という名前のパッケージが作成され、自動的にインストールされる。 削除したい場合は、pkgrm コマンドを使用すればよい。 ここでデバイスファイルを作り直すため、システムを再起動する。

実行ファイル、マニュアルなどは /opt/ipf の下にインストールされる。 setenv MANPATH /opt/ipf/man:$MANPATH として、man を熟読すべきである。

2. ルールの設定

IP Filter のルール設定は /etc/opt/ipf/ipf.conf を編集して行う。 その書式については、ipf(8) を参照のこと。 まずは、すべてのパケットを通過させるルールを作って動作を確認する。

# vi /etc/opt/ipf/ipf.conf

pass in quick all
pass out quick all

キーワード quick は、そのルールにマッチした時点でパケット検査を終える ために付ける。すべてのルールに quick を付ければファーストマッチルールの ファイアウォールと同じように扱える。

この状態でパケットが通ることを確認したあと、最初のルールを コメントアウトして、徐々にルールを追加していく。 /opt/ipf/bin/mkfilters コマンドで作られるサンプルのルールファイルをベースにすると良い。 ルールを編集したら、ipf を再起動する。

# /etc/init.d/ipfboot reload
Set 1 now inactive

比較的緩めのポリシーの例を 設定例1にて示す。 入力ルールを group 100、出力ルールを group 200 としてグループ分けしている。

といったポリシーである。家庭内サーバ兼デスクトップユースの Solaris マシンでは、この程度に緩いポリシーにしておいた方が良い。

しかし上述の例では、DMZ に置く公開サーバのポリシーとしては弱すぎる。 厳しめのルールファイル例を 設定例2に示す。 このルールのポリシーは Web サーバ兼 NTP サーバのためのものである。

返りパケットのみを許可するには、キーワード keep state を使う。 この場合、入力と出力でグループ分けする意味があまり無いので (in のグループ内のルールで出力パケットが許可される)、 あえてグループ分けを行っていない。 (註)

TCP DNS query を閉じていることや ICMP を閉じていることで 何かトラブルが起きるかも知れないが、 その場合は徐々に必要な部分だけ開けていくことで対処する。

※ グループ分けと keep state

グループ分けして入力/出力パケットを区別する書き方と、 keep state を使う書き方にはそれぞれ長短がある。

グループ分けすると、

keep state を使うと、

それぞれの得失を勘案してルールを書くべきである。

6. そのほか、細かな Tips

1. root のリモートログイン禁止

Solaris のデフォルトでは、リモートからの root ログインを禁止している。 このデフォルト設定を変更しないようにするべきである。 設定の場所は、/etc/default/login の中の、

CONSOLE=/dev/console

という行である。 もしこの行にコメント記号 (#) が付いている場合は消去しておく。

2. ndd パラメタの設定

ndd はネットワークインターフェイスのパラメタを指定するコマンドで、 これによって危険なパケットを通すことをある程度防ぐことができる。 /etc/init.d/inetinit の最後に、

# ルータでないホストでは明示的に IP フォワーディングを無効にする
/usr/sbin/ndd -set /dev/ip ip_forwarding 0
# ルータホストで IP スプーフィングをチェックする
#/usr/sbin/ndd -set /dev/ip ip_strict_dst_multihoming 1
# リダイレクトパケットを無視
/usr/sbin/ndd -set /dev/ip ip_ignore_redirect 1
# リダイレクトパケットを投げない
/usr/sbin/ndd -set /dev/ip ip_send_redirects 0
# ブロードキャストを転送しない
/usr/sbin/ndd -set /dev/ip ip_forward_directed_broadcasts 0
# ブロードキャスト ICMP に応答しない
/usr/sbin/ndd -set /dev/ip ip_respond_to_echo_broadcast 0
/usr/sbin/ndd -set /dev/ip ip_respond_to_timestamp_broadcast 0
/usr/sbin/ndd -set /dev/ip ip_respond_to_address_mask_broadcast 0
# ユニキャストの timestamp 要求にも応答しない
/usr/sbin/ndd -set /dev/ip ip_respond_to_timestamp 0
# ソースルーティングパケットを転送しない
/usr/sbin/ndd -set /dev/ip ip_forward_src_routed 0
# IP ルーティングキャッシュの有効時間を短くする
# (Solaris 7 までは ip_ire_flush_interval)
/usr/sbin/ndd -set /dev/ip ip_ire_arp_interval 60000
# ARP キャッシュの有効時間を短くする
/usr/sbin/ndd -set /dev/arp arp_cleanup_interval 60000
# SYN flood 攻撃への対処: 接続キューサイズを増やす
/usr/sbin/ndd -set /dev/tcp tcp_conn_req_max_q0 4096
# SYN flood 攻撃への対処: 確立できる接続数を増やす
/usr/sbin/ndd -set /dev/tcp tcp_conn_req_max_q 1024

などと加えると良い。また、/etc/init.d/inetinit の中で使用されるパラメタ TCP_STRONG_ISS が /etc/default/inetinit の中で指定されているので、 この値を 2 にしておく。

TCP_STRONG_ISS=2

こうしておくことで、TCP の初期シーケンス番号が予測されにくくなる。

3. /etc/system パラメタの設定

/etc/system ファイルはカーネルのパラメタを設定するファイルである。 これに、

set noexec_user_stack = 1
set noexec_user_stack_log = 1

と書くことで、ユーザプロセスのスタック上での実行を禁止することができる。 この設定により、いわゆるバッファオーバーフローエラーを突いた攻撃を ある程度防ぐことができる。

また、攻撃者はクラッシュダンプしたアプリケーションの core ファイルから情報を引き出すことがあるため、 core を出力させないためのパラメタも指定しておくと良い。

set sys:coredumpsize = 0

4. nscd キャッシュの無効化

nscd (ネームサービスキャッシュデーモン) は、 DNS や NIS の検索結果をキャッシュするデーモンであるが、 常に脆弱性が指摘され、またキャッシュがあることによる不都合も多いので、 無効化する方が良い。

そのためには、/etc/nscd.conf に、

enable-cache hosts no
enable-cache passwd no
enable-cache group no

の3行を加える。これで bind と nis のキャッシュが無効になる。

5. ログを取る

ログを取っておくことは重要である。 ここでは syslogd の機能を使って簡単に取れるログの例を2つ紹介する。

1つ目は、デフォルトの syslog.conf ではコメントアウトされている /var/log/authlog を有効化することである。 /etc/syslog.conf の22行目の先頭の # 記号を外して、syslogd を再起動する。

# vi /etc/syslog.conf

#auth.notice                     ifdef(`LOGHOST', /var/log/authlog, @loghost)
↑先頭のコメント記号を外す

# pkill -HUP syslogd

これで、連続5回ログインに失敗すると、/var/log/authlog に記録されるようになる。

2つ目は、3章で扱った IP Filter のログである。 IP Filter はファシリティ local0 で syslogd にメッセージを渡すので、 以下のような記述を /etc/syslog.conf に加えれば記録が取れる。

local0.info                     ifdef(`LOGHOST', /var/log/ipf.log, @loghost)

"local0.info" と "ifdef" の間は TAB 文字でなければならない。 IP Filter のログは、 ポートスキャンを受けたりすると際限無く膨れ上がるので、 サイズの管理に気をつけること。

7. 参考文献

Solaris 階層に戻る  |  ホームに戻る

Copyright (C) 2001-2004
Last modified: Wed Aug 16 16:52:41 JST 2006
You are the 134628 th visitor.