第3章 Apache HTTP Server

Apache HTTP Server Project ページより抜粋:
原文: "The Apache HTTP Server Project is an effort to develop and maintain an open-source HTTP server for modern operating systems including UNIX and Windows NT. The goal of this project is to provide a secure, efficient and extensible server that provides HTTP services in sync with the current HTTP standards". (訳文: Apache HTTP Server Project は、 UNIX や Windows NT など新しいオペレーティングシステム向けのオープンソース HTTP サーバーの開発および保守に取り組んでいます。 現在の HTTP 標準に適合する HTTP サービスを提供し、 安全かつ効率的で拡張性のあるサーバーを実現していくことを目標としています。)[5]
Red Hat Enterprise Linux では、 Apache HTTP Server は httpd パッケージで提供されています。 httpd パッケージがインストールされているか確認する場合は、 rpm -q httpd を実行します。Apache HTTP Server を使用する予定にも関わらず、このパッケージがインストールされていない場合は、root ユーザーになり次のコマンドを実行してパッケージのインストールを行ないます。
yum install httpd

3.1. Apache HTTP Server と SELinux

SELinux を有効にすると、Apache HTTP Server (httpd) はデフォルトで制限のあるサービスとして実行されます。制限のあるプロセスはそのプロセス自体のドメインで実行され、 他の制限のあるプロセスとは分離されます。 制限のあるプロセスが攻撃を受けると、 SELinux ポリシー設定に応じて、 攻撃側がリソースにアクセスして加えることができる被害は限定されます。 次の例では、 httpd プロセス自体のドメイン内で実行しているプロセスを示します。 httpdsetroubleshootsetroubleshoot-serverpolicycoreutils-python の各パッケージがインストールされていることを前提とします。
  1. getenforce を実行して SELinux が enforcing モードで実行しているか確認します。
    $ getenforce
    Enforcing
    
    SELinux が enforcing モードで実行している場合は、 getenforce コマンドを実行すると Enforcing が返されます。
  2. root ユーザーになり service httpd start を実行し、 httpd を起動します。
    # service httpd start
    Starting httpd:                                            [  OK  ]
    
  3. ps -eZ | grep httpd を実行して httpd プロセスを表示します。
    $ ps -eZ | grep httpd
    unconfined_u:system_r:httpd_t:s0 2850 ?        00:00:00 httpd
    unconfined_u:system_r:httpd_t:s0 2852 ?        00:00:00 httpd
    unconfined_u:system_r:httpd_t:s0 2853 ?        00:00:00 httpd
    unconfined_u:system_r:httpd_t:s0 2854 ?        00:00:00 httpd
    unconfined_u:system_r:httpd_t:s0 2855 ?        00:00:00 httpd
    unconfined_u:system_r:httpd_t:s0 2856 ?        00:00:00 httpd
    unconfined_u:system_r:httpd_t:s0 2857 ?        00:00:00 httpd
    unconfined_u:system_r:httpd_t:s0 2858 ?        00:00:00 httpd
    unconfined_u:system_r:httpd_t:s0 2859 ?        00:00:00 httpd
    
    httpd プロセスに関連する SELinux コンテキストは unconfined_u:system_r:httpd_t:s0 です。 コンテキストの末尾から 2 番目の部分、 httpd_t がタイプになります。 プロセスのドメインやファイルのタイプを定義するのがタイプです。 この例の場合、 httpd プロセスは httpd_t ドメインで実行されています。
httpd_t などの制限ドメイン内で実行しているプロセスがファイルや他のプロセス、システムなどとどのように交信するのかをSELinux ポリシーで定義します。httpd からアクセスができるよう、ファイルには適切なラベルを付けなければなりません。たとえば、httpd_sys_content_t タイプのラベルが付いたファイルの場合、httpd からはこのファイルの読み取りは可能ですが書き込みはできません。この場合、Linux (DAC) のパーミッションで書き込みのアクセスが許可されていても書き込みを行なうことはできません。特定の動作を許可する場合、たとえば、スクリプトによるネットワークへのアクセスを許可する、httpd による NFS や CIFS ファイルシステムへのアクセスを許可する、httpd による CGI (Common Gateway Interface) スクリプトの実行を許可するなどの場合には、Boolean をオンにする必要があります。
httpd が TCP ポート 80、443、488、8008、8009、8443 以外のポートでリッスンするよう /etc/httpd/conf/httpd.conf を設定する場合は、semanage port コマンドを使って SELinux ポリシー設定に新しいポート番号を追加する必要があります。以下では、まだ SELinux ポリシー設定で httpd 用には定義されていないポートでリッスンするよう httpd を設定した結果、httpd の起動に失敗する例を示します。また、httpd がポリシーにまだ定義されていない非標準のポートで正しくリッスンするよう SELinux システムを設定する方法についても示します。httpd パッケージがインストールされていることを前提としています。各コマンドは root ユーザーで実行してください。
  1. service httpd status を実行して httpd が実行中ではないことを確認します。
    # service httpd status
    httpd is stopped
    
    出力が上記と異なる場合は、 service httpd stop を実行してプロセスを停止します。
    # service httpd stop
    Stopping httpd:                                            [  OK  ]
    
  2. semanage port -l | grep -w http_port_t を実行して、 SELinux で httpd にリッスンを許可しているポートを表示させます。
    # semanage port -l | grep -w http_port_t
    http_port_t                    tcp      80, 443, 488, 8008, 8009, 8443
    
  3. root ユーザーで /etc/httpd/conf/httpd.conf を編集、Listen オプションを設定します。SELinux ポリシー設定では httpd 用にまだ設定が行なわれていないポートをこのオプションに記述します。この例では、 ポート 12345 でリッスンするよう httpd を設定しています。
    # Change this to Listen on specific IP addresses as shown below to 
    # prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
    #
    #Listen 12.34.56.78:80
    Listen 127.0.0.1:12345
    
  4. service httpd start を実行して httpd を起動します。
    # service httpd start
    Starting httpd: (13)Permission denied: make_sock: could not bind to address 127.0.0.1:12345
    no listening sockets available, shutting down
    Unable to open logs					   [FAILED]
    
    以下のような SELinux 拒否がログ記録されます。
    setroubleshoot: SELinux is preventing the httpd (httpd_t) from binding to port 12345. For complete SELinux messages. run sealert -l f18bca99-db64-4c16-9719-1db89f0d8c77
    
  5. httpd によるポート 12345 のリッスンを SELinux で許可させるには、 以下の例で使用している次のコマンドが必要になります。
    # semanage port -a -t http_port_t -p tcp 12345
    
  6. もう一度 service httpd start を実行して、 httpd を起動させ新しいポートをリッスンするようにします。
    # service httpd start
    Starting httpd:						   [  OK  ]
    
  7. httpd による非標準ポート (この例では TCP 12345) でのリッスンを許可する SELinux 設定が完了しました。これで、httpd がこのポートで正常に起動するようになります。
  8. httpd が確かに TCP ポート 12345 でリッスンし通信を行なっているか確認するには、 そのポートに telnet 接続を開き HTTP GET コマンドを以下のように発行します。
    # telnet localhost 12345
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    GET / HTTP/1.0
    
    HTTP/1.1 200 OK
    Date: Wed, 02 Dec 2009 14:36:34 GMT
    Server: Apache/2.2.13 (Red Hat)
    Accept-Ranges: bytes
    Content-Length: 3985
    Content-Type: text/html; charset=UTF-8
    [...continues...]
    


[5] Apache HTTP Server Project ページの "The Number One HTTP Server On The Internet" セクションより抜粋: http://httpd.apache.org/。 著作権 © 2009 The Apache Software Foundation (2010年 7月 7日に閲覧)