インストール直後に絶対やるべき作業と設定

第1回 インストール直後に絶対やるべき作業と設定

正しく管理されていないLinuxにセキュリティなどないに等しい。しかし、どこから手をつければよいかすら分からない人も多いだろう。本連載ではLinuxのセキュリティ対策をインストール時点からファイアウォールやIDSの構築、ログ管理まで解説していく。

終わらないセキュリティ対策の世界

 Linuxは現在、インターネットサーバOSとして注目されています。特に初期コストを抑えてネットワークを構築したい場合にLinuxは有効ですが、適切なセキュリティ対策が施されずに公開され、クラッキングなどの被害に遭っているところも多々見受けられます。

 インターネットの世界には、クラッカーと呼ばれる悪質なネット利用者もいますし、最近では彼らが開発した(?)ワームにも注意する必要があります。万が一これらのえじきとなった場合、Webページを改ざんされたり踏み台にされて人様に迷惑をかけてしまうかもしれません。企業としてはイメージダウンにつながってしまうのではないでしょうか?

 セキュリティ対策のポイントは、構築するサーバの役割や目的で変わってきます。とはいえ、ある程度普遍性を持った原則は存在します。

 上記のことをセキュリティ対策のポイントとしてとらえてもらい、その具体的な対策方法として本連載を参考にしていただければと思います。

 また、セキュリティ対策というのは一度行って終わりというものではありません。それを維持していくことも重要なセキュリティ対策といえます。これらについても触れていきたいと思います。

 これから、Linuxに関するセキュリティ対策をさまざまな面から紹介していきます。今回は、まず各種セキュリティ対策の大前提となるホストベースのセキュリティについて解説したいと思います。

OSインストール時の注意点

 セキュリティ対策は、OSをインストールするところから始まっています。のちのちの運用を考えるならば、インストールにも十分注意しておきましょう。

 ここでは、OSにRed Hat Linux 7.1Jを使用すると仮定して話を進めていきます。しかし、ほかのディストリビューションでも考え方は同じです。

インストールは必要最小限の構成で

 OSは、できる限り必要最小限の構成でインストールしましょう。何でもインストールしてしまうと、それだけ不具合のあるパッケージをインストールしてしまう可能性が高くなってしまいます。「使わないものはインストールしない」ことが重要です。

 主要なLinuxディストリビューションは、インストールするパッケージを細かく選択することができます。Red Hat Linux 7.1Jの場合は、インストール方法で[カスタムシステム]を選択すれば、パッケージを細かく選択できます。しかし、この方法でインストールするには多少知識を必要とするので、今回は[サーバシステム]を選択したいと思います。また、インストール過程で「シャドウパスワード」「MD5暗号化アルゴリズム」を有効にすることを忘れないでください。

パッケージを最新版にアップデート

 Red Hat Linux 7.1Jでもすでに不具合が発見され、修正版が公開されているパッケージもあります。OSのインストール後、以下のサイトを参考にしてパッケージを必ず最新版にアップデートします。また、運用を開始した後も常に最新の状態を保つ必要があります。

http://www.redhat.com/support/errata/rh71-errata-security.html

 では、実際の管理方法を紹介します。まず、修正版が出ているパッケージが自分のホストにインストールされているかどうかを確認します。

# rpm -qv パッケージ名

 不具合のあるパッケージがインストールされているようであれば、必ずアップデートしましょう。

# rpm -Fvh パッケージ名

 原則的には、この-Fvhオプションを使用します。これは、古いバージョンがインストールされていたときのみアップデートします。

# rpm -Uvh パッケージ名

 上記の-Fvhオプションではアップデートできないものもあります。そのときは-Uvhオプションを使います。このオプションは、古いバージョンがインストールされているとアップデートし、入っていない場合は新規インストールを行ってしまいます。従って、不要なパッケージをインストールしてしまう可能性があるので気を付けましょう。

パッケージに含まれないアプリケーションのインストール

 公開するサービスによって使用するアプリケーションは変わります。これらのアプリケーションについては、OS付属のものをインストールしないことを勧めます。理由は、常に最新バージョンをインストールしていただきたいからです。面倒かもしれませんが、最新のソースファイルをダウンロードして、これをコンパイルしてインストールしてください。

不要なサービスの停止

 システム要件に関係のないサービスは停止しましょう。サービスによっては、起動しているだけで危険なものもあります。ここでいう「危険なサービス」とは、脆弱性を持ったアプリケーションだけを指しているわけではありません。第三者に対し、不用意に情報を提示してしまうようなサービスも含まれます。万一、アプリケーションに不具合があっても、サービスを停止していればリモートからのバッファオーバーフロー攻撃などのえじきにならずに済みますし、情報の漏えいなども回避できます。

停止すべき「不要なサービス」

 Red Hat Linux 7.1Jには、/usr/sbin/setupコマンドがあります。このコマンドを用いて、不要なサービスがOS起動時にサービスを開始しないように設定を変更します。

 [サーバシステム]でインストールした直後のRed Hat Linux 7.1Jでは、以下のものが不要なサービスと考えられます。

 設定が終了したらOSを再起動します。OS起動後、netstatコマンドを用いて不要なサービスが起動していないか確認しましょう。

$ netstat -an

デーモンの起動について

 デーモンには、単独で起動するものと、「スーパーデーモン」と呼ばれるinetdを介して起動するものがあります。

 Red Hat Linux 7.1Jではsetupコマンドで簡単に設定できますが、すべてのディストリビューションで使えるわけではありません。そこで、OS起動時に提供されるサービスについて簡単ではありますが説明しておきます。ほかのディストリビューションを使用している方はこちらを参考にしてください。

単独で起動するデーモンの起動と停止

 単独で起動するデーモンは、プロセスとして常駐し、自分自身でポートを監視します。これをデーモンモード(standaloneモード)といいます。

 Linuxは、起動時に/etc/rc.d/rc1.d〜rc6.d内にある起動スクリプトを読み込みます。rc1.d〜rc6.dのどのディレクトリを使うかは、そのシステムのデフォルトのランレベルによって変わってきます。デフォルトランレベルの情報は、/etc/inittabファイルにあり、以下の方法で確認できます。

# more /etc/inittab

id:3:initdefault:

 moreコマンドなどで/etc/inittabを表示させると、このような記述があると思います。この「3」の部分がrc1.d〜rc6.dの数字部分に当たり、ランレベル3ということになります。つまり、この場合は/etc/rc.d/rc3.dにある起動スクリプトで、ファイル名が「S」で始まるものが起動されます。

 この中にも不要なサービスがありますので、inetd経由で起動される不要なサービスと同様、OS起動時に起動されないようにしましょう。以下のように、ファイル名を変えるだけでも起動されなくなります。

# mv /etc/rc.d/rc3.d/S20pcmcia /etc/rc.d/rc3.d/.S20pcmcia

 ここまで終わったら、一度OSを再起動してみましょう。起動後、まだ不要なサービスが動いているのであれば、再度確認して起動しないように設定を変更しましょう。

inetd経由で起動されるデーモン

 inetdは、1つのプロセスで複数のポートを監視しています。inetdで監視しているサービスに対してアクセスがあったとき、それに対応するデーモンを起動します(inetd自体は単独で起動します)。FTPデーモン(ftpd)をinetd経由で起動している場合、接続要求があるまでプロセスは上がっていません。これはpsコマンドで確認できます。

# ps -aux | grep ftpd
root       689  0.0  1.0  1664  508 pts/0    S    01:37   0:00 grep ftpd

 FTP接続した後でpsコマンドを実行してみましょう。

# ps -aux | grep ftpd
admin      692  0.9  2.6  2008 1264 ?        S    01:41   0:00 ftpd: 192.168.0.1

inetd経由で起動されるデーモンの停止方法

 inetd経由で開始されるサービスの多くは停止してしまっても問題ありません。しかしながら、どのサービスを停止していいのか理解せずに行うと、システムが思いどおりに稼働しなくなってしまうことがあるかもしれません。そこで、inetd経由で開始される代表的なサービスの内容とその停止方法について簡単に説明します。

 inetdの設定はxinetdと違い、/etc/inetd.confという1つのファイルに記述されています(xinetdではサービスごとにファイルが存在します)。サービスの停止方法は以下の手順で行います。

・/etc/inetd.confファイルのバックアップを取る

# cp /etc/inetd.conf /etc/inetd.conf.bak

・エディタを用いて、停止したいサービスの行頭に「#」を付けることで無効化する

telnet  stream  tcp     nowait  root    /usr/sbin/tcpd  in.telnetd
#telnet  stream  tcp     nowait  root    /usr/sbin/tcpd  in.telnetd
telnetを停止する場合

・設定の変更を反映する。inetdのPIDを調べ、「kill -HUP」する

# ps -aux | grep inetd
root         529  0.0  0.2  1160  224 ?        S    Apr14   0:00 inetd
hogehoge   27663  0.1  0.6  1456  632 pts/0    T    16:11   0:00 less /etc/inetd.conf
hogehoge   27666  8.0  0.5  1664  508 pts/0    S    16:14   0:00 grep inetd
# kill -HUP 529
実行例。kill -HUPするPIDは環境によって異なる

 inetd経由で以下のサービスが起動されますが、これらは停止してもよいものです。ディストリビューションによって違いがあると思いますが、参考にしてください。

xinetdについて

 inetdの後継として、「xinetd」が注目されています。Red Hat Linuxでは、バージョン7.0からinetdではなくxinetdが採用されています。セキュリティの面から考えてみても、今後はxinetdに移行していくものと思います。inetdとxinetdの違いについて簡単ではありますが説明させていただきます。

 inetdとxinetdでは設定ファイルのフォーマットがまったく違うため、そのままでは使えません。inetdでは、TCP_Wrapperを用いなければアクセスコントロールをかけることができません。これに対し、xinetdは設定ファイルの記述でアクセスコントロールをかけることが可能です()。つまり、機能的には、

inetd + TCP_Wrapper = xinetd

と考えていただいても構いません。さらに、xinetdはアクセスコントロールだけでなく、もっと多くの実装を備えています。TCPだけでなく、UDPのアクセスコントロールもできます。このように、xinetdはinetd + TCP_Wrapperより優れているといえます。

注:xinetdでもTCP_Wrapperはサポートされているので利用することはできます。

 ほかにも、inetd経由でデーモンを起動するユーザーはrootである必要があったのですが、xinetdではその必要がありません。xinetdではアプリケーション専用のアカウントを作成し、そのアカウントの権限でデーモンを起動できます。これにより、バッファオーバーフロー攻撃でシェルを実行されてしまっても、そのアカウントの権限のみであるのためroot権限の必要なファイルの書き換えなどはできません。

 inetdやxinetd経由で起動されるサービスはすべて停止しても問題はありません。telnetであれば、sshなど代わりになるプログラムがあります。よって、必要がなければinetdおよびxinetd経由で起動される全サービスを停止し、inetdあるいはxinetd自体も停止してしまうことをお勧めします

編注:inetd+TCP_Wrapperおよびxinetdの設定については、今後取り上げる予定です。

コラム:xinetdの設定フィル
 inetd.confをxinetd.confファイルにコンバートする「xconv.pl」というツールがすでに出ています。Debian/GNU Linuxでは、aptコマンドを用いてxinetdをインストールすると、inetd.confをxinetd.confへコンバートしてくれます。

 xconv.plでコンバートした場合、Red Hat Linux 7.1Jのデフォルトのxinetdの設定とは形式がやや異なります。Red Hat Linux 7.1Jでは、/etc/xinetd.d以下にサービスごとにファイルが作成されます。xconv.plが作成するxinetd.confは、inetd.confと同じように1つのファイルに各サービスの設定が記述されます


service telnet
{
        disable = yes
        flags           = REUSE
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/sbin/in.telnetd
        log_on_failure  += USERID
}
Red Hat Linux 7.1Jのxinetdの設定(/etc/xinetd.d/telnet)

service telnet
{
        socket_type     = stream
        protocol        = tcp
        wait            = no
        user            = telnetd
        group           = telnetd
        server          = /usr/sbin/in.telnetd
}
Debian/GNU Linuxでinetd.confからxinetd.confにコンバートした設定(/etc/xinetd.conf)

 両者の設定内容は違いますが、フォーマットに変わりはありません。また、inetd.confとは明らかにフォーマットが違うことが分かります。

ユーザーとアカウントの管理および認証方式

アカウントおよびパスワードの管理

 ここで重要なことは、不要なアカウントを作成しないようにすることです。管理者が1人であれば、当然1つで十分です。管理者が変わったときなどは、すぐに前管理者のアカウントを削除し、rootのパスワードも変更しましょう。当然のことながら推測されてしまいそうな簡単なパスワードを設定するようなことは絶対にやめましょう。

 また、アプリケーションを起動するための専用のユーザーを作ることがあるかと思います。SMTPサービスを提供するのに最近使われるようになってきたqmailでは、専用のユーザーとグループを作る必要があります。このアカウントの作成に際してuseraddコマンドを使うのは問題ないのですが、必ずsオプションを指定して/bin/falseなどにするようにしましょう。

# /usr/sbin/useradd -u 10001 -g 10002 -s /bin/false hoge

 sオプションを指定しないと勝手に「/bin/bash」にされて、何らかの原因(セキュリティホールなど)によりこのアカウントでログインされるとシェルを起動してしまいます。sオプションで/bin/falseのようにシェルを架空のものにしておけば、このアカウントでログインを許してしまったとしてもシェルが起動できないため、コマンドが実行される恐れはありません()。

注:これでも、直接シェルが起動されてしまうようなバッファオーバーフロー系の攻撃にはあまり意味を持ちません。ただし、デーモンをrootで起動するよりは安全といえます。

シャドウパスワード

 /etc/passwdファイルは、恐らく以下のような記述になっているものと思います。

hoge:x:1000:1000:hoge:/home/hoge:/bin/bash

 コロン(:)で区切られたフィールドは、それぞれ以下のような意味を持っています。

アカウント名:暗号化されたパスワード:ユーザーID:グループID:フルネーム:ホームディレクトリ:シェル

 「暗号化されたパスワード」を格納する2つ目のフィールドは「x」になっていると思います。これは、シャドウパスワードが有効になっているからです。最近のディストリビューションでは、インストール時にこの機能を有効にするか聞かれるのでぜひ有効にしましょう。シャドウパスワードが有効になっていると、/etc/passwdのパスワードフィールドは上記のように「x」に置き換わり、暗号化されたパスワードはrootしか見ることのできない/etc/shadowファイルに記録されます

 シャドウパスワードを無効にした場合、暗号化されたパスワードはだれでも読むことができる/etc/passwdに保存されます。パスワードがだれにでも見られるようになっていると、パスワードクラッキングソフトを使って簡単にパスワードを推測されてしまいます。

MD5暗号化パスワード

 この機能もシャドウパスワードと同じく、インストール時に使用するかどうかを聞かれます。Linuxでは、この機能を有効にしなくてもcrypt()によりパスワードを暗号化します。

 UNIXの場合、デフォルトの暗号化アルゴリズムはDESが使われていますが、DESには入力文字列長に8文字という制限があります。しかし、MD5ではこの制限がなくなります。つまり、8文字以上のパスワードを設定できるようになります。当然ながら、文字数が多ければそれだけ暗号化パスワードを解読するのが困難になります。

 この機能を生かすためにも、8文字以上のパスワードを設定しましょう)。

注:MD5だからといって、DESよりパスワードクラックからの脅威が大きく軽減されるわけではありません。MD5で暗号化しても、8文字以下のパスワードを設定してしまえばDESと差はありません。

rootになれるユーザーの制限

 デフォルトの設定では、suコマンドを実行してパスワード認証をクリアすればだれでもrootになれます。これはセキュリティ上好ましくありません。そこで、suコマンドでrootになれるアカウントを制限するように設定します。

 まず、/etc/login.defsファイルの編集が必要です。このファイルを開いたら、以下の1行を追加します。

SU_WHEEL_ONLY        yes

 次に/etc/groupファイルのwheelの行を修正します。ここでは、例としてrootになれるアカウント名を「user」に限定することにします。もし、user以外のアカウントにもrootになることを許可するのであれば、カンマで区切って列挙します。

wheel:x:10:root,user

 さらに、上記の設定を有効にするため/etc/pam.d/suファイルに以下の行を追加します。

auth    required    /lib/security/pam_wheel.so use_uid group=wheel

 これで、suコマンドでrootになれるアカウントはuserのみとなります。

rootアカウントでのリモートログインの不許可

 リモートからLinuxマシンのメンテナンスを行うときは、ssh以外使わないようにします。しかし、sshのデフォルト設定はrootアカウントでのログインを許可してしまいます。そこで、rootアカウントでは直接ログインできないようにsshの設定ファイルを変更します。こうすることで、sshによる認証とsuコマンドによる認証の2段階を経なければrootになれないようになり、セキュリティを強化できます。

 まず、/etc/ssh/sshd_configファイルをviを使って変更します。

# vi /etc/ssh/sshd_config

 このファイルの18行目あたりに以下のような記述があります。

PermitRootLogin yes

 これを無効にするため「yes」を「no」に変更して、

PermitRootLogin no

設定ファイルの変更を反映させるためにsshデーモンをreloadします。

# /etc/rc.d/init.d/sshd reload

 reloadしたら、正しく機能するか確認してみましょう。

# ssh -l root localhost
root@loclahost's password:

 設定が反映されると、正しいパスワードを入力してもrootアカウントではログインできません。

PAMについて

 ここでPAMPluggable Authentication Modules)についてもお話ししておく必要があるでしょう。PAMを一言でいうと、認証方式を一括管理しているプログラムです。以前はアプリケーションごとに何種類もの認証方式があり、その認証方式の変更には再コンパイルが必要でした。しかし、PAMを用いることで、認証方式の変更のみであればPAMの設定ファイルを編集するだけで済むようになります。最近のディストリビューションであればPAMに対応しています。

 Red Hat Linux 7.1Jの場合、PAMの設定ファイルは/etc/pam.dディレクトリに、プログラムごとに用意されています。

chfs ftp login passwd rexec rsh sshd sudo
chsh kbdrate other ppp rlogin smtp su system-auth

 これらがすべて必要というわけではありません。例えば、/etc/pam.dディレクトリの中にrlogin用の設定ファイルがあります。現在の設定では、このサービスは停止していると思いますが、これが提供されていると仮定してみます。この状態でloginで接続要求があると、Linuxは以下のような動作をします。

 つまり、/etc/pam.dディレクトリに該当するサービス用のファイルが用意されていなければ、うっかり不要なサービスを提供していたとしても接続を拒否できるというわけです。よって、危険なサービスに関する設定ファイルについてはファイル名を変更してしまいましょう。ここでいう危険なサービスとは、rshrexecrloginの3つになります。

# mv rsh .rsh
# mv rexec .rexec
# mv rlogin .rlogin

 このように、mvコマンドを利用してドットファイルにしてしまいましょう。