RHELにおけるfirewalldとSELinuxによるセキュリティ保護

Red Hat Enterprise LinuxBeginner
オンラインで実践に進む

はじめに

この実験では、SELinuxポリシーとファイアウォールルールを管理することで、Red Hat Enterprise Linux (RHEL) 上のApache Webサーバー (httpd) を保護する方法を学びます。httpdが標準以外のポートでリッスンするように構成し、そのような構成に対してSELinuxとファイアウォールシステムがどのようにセキュリティを管理するかを調査する実践的なシナリオに取り組みます。この演習を通じて、RHEL環境における一般的なセキュリティ管理タスクの実践的な経験を積むことができます。

まず、httpdサービスをカスタムポートで実行するように構成し、SELinuxの強制下でどのように動作するかを観察します。次に、semanageコマンドを使用してSELinuxのポートラベルを理解・管理し、適切なセキュリティコンプライアンスを確保します。その後、firewall-cmdを使用して、システムのファイアウォールでこのカスタムポートを開放します。最後に、Webサーバーにアクセスできることを確認し、セキュリティ構成が正しく適用されていることを検証します。

httpdをカスタムポートで構成し、SELinuxコンテキストを理解する

このステップでは、Apache Webサーバー (httpd) を標準以外のポートで実行するように構成し、SELinuxがどのようにポートアクセスを管理するかを理解します。ポート8081を使用し、サービスが一部の構成で正常に起動する場合でも、SELinuxのポート管理について調査します。

必要なパッケージ (httpdpolicycoreutils-python-utilsfirewalld) はセットアップフェーズですでにインストールされています。policycoreutils-python-utilsパッケージは、後のステップで使用するsemanageコマンドを提供します。

まず、デフォルトのhttpd構成を変更して、標準以外のポートである8081でリッスンするようにします。httpdのメイン構成ファイルは/etc/httpd/conf/httpd.confにあります。nanoエディタを使用してリッスンポートを変更します。

sudo nano /etc/httpd/conf/httpd.conf

nanoエディタ内で矢印キーを使用して下にスクロールし、Listen 80という行を見つけます。この行を以下のように変更します。

Listen 8081

ファイルを保存してnanoを終了するには、Ctrl+Xを押し、変更を確定するためにYを押し、最後にEnterを押してファイルに書き込みます。

構成が変更されたので、httpdサービスを起動してみましょう。このコンテナ化された環境ではsystemctlは使用できないため、httpdデーモンを直接起動します。

セットアップフェーズですでにデフォルトのSSLバーチャルホストが無効になっているため、このプレーンHTTPの実験は、無関係な証明書ファイルのエラーなしで開始できます。

sudo /usr/sbin/httpd

サーバーの完全修飾ドメイン名に関する警告メッセージが表示される場合がありますが、これは正常であり無視して構いません。

AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::216:3eff:fe02:1a1e%eth0. Set the 'ServerName' directive globally to suppress this message

httpdプロセスを確認して、サービスが実行されているか検証しましょう。

ps aux | grep httpd

複数のhttpdプロセスが実行されているのが確認できるはずです。これはWebサーバーが正常に起動したことを示しています。

root        4813  0.0  0.2  23364  7736 ?        Ss   09:32   0:00 /usr/sbin/httpd
apache      4814  0.0  0.1  23020  5092 ?        S    09:32   0:00 /usr/sbin/httpd
apache      4815  0.0  0.4 1441064 14620 ?       Sl   09:32   0:00 /usr/sbin/httpd
apache      4816  0.0  0.5 1441064 18736 ?       Sl   09:32   0:00 /usr/sbin/httpd
apache      4837  0.0  0.4 1572200 16872 ?       Sl   09:32   0:00 /usr/sbin/httpd
labex       4996  0.0  0.0   6408  2176 pts/3    S+   09:32   0:00 grep --color=auto httpd

起動中に何が起こったかを確認するために、httpdのエラーログも確認してみましょう。

sudo tail /var/log/httpd/error_log

サーバーが正常に動作していることを示す通常の起動メッセージが表示されるはずです。

[Tue Jun 17 09:32:46.374275 2025] [core:notice] [pid 4812:tid 4812] SELinux policy enabled; httpd running as context system_u:system_r:unconfined_service_t:s0
[Tue Jun 17 09:32:46.377265 2025] [suexec:notice] [pid 4812:tid 4812] AH01232: suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Tue Jun 17 09:32:46.394284 2025] [lbmethod_heartbeat:notice] [pid 4813:tid 4813] AH02282: No slotmem from mod_heartmonitor
[Tue Jun 17 09:32:46.399433 2025] [mpm_event:notice] [pid 4813:tid 4813] AH00489: Apache/2.4.62 (Red Hat Enterprise Linux) configured -- resuming normal operations
[Tue Jun 17 09:32:46.399458 2025] [core:notice] [pid 4813:tid 4813] AH00094: Command line: '/usr/sbin/httpd'

興味深いことに、httpdサービスはSELinuxの問題なしに起動しました。監査ログにSELinuxの拒否(denials)があったかどうかを確認してみましょう。

sudo grep AVC /var/log/audit/audit.log | grep httpd

結果がない場合、SELinuxがhttpdサービスのポート8081へのバインドをブロックしなかったことを意味します。これは以下の理由が考えられます。

  1. 一部の構成では、ポート8081がデフォルトでHTTPサービスに対してすでに許可されている可能性がある
  2. httpdプロセスが制限なし(unconfined)コンテキストで実行されている可能性がある
  3. ポート8081がすでにSELinuxポリシーで定義されている可能性がある

現在のSELinuxモードを確認してみましょう。

getenforce

SELinuxが「Enforcing(強制)」モードになっていることがわかります。これはポリシーが積極的に適用されていることを意味します。httpdが正常に起動したという事実は、ポート8081がすでに適切なSELinuxラベルを持っているか、ログメッセージに示されているようにサービスが制限なしコンテキストで実行されていることを示しています。この学習演習の目的のため、次のステップに進み、SELinuxのポート管理を調査して適切な構成を確保します。

semanageを使用したSELinuxポートラベルの理解と管理

このステップでは、semanageコマンドを使用してSELinuxのポートラベルを管理する方法を学びます。現在httpdサービスがポート8081で実行されていますが、セキュリティとコンプライアンスを確保するために、SELinuxのポートポリシーを適切に構成する方法を理解することが重要です。現在のポート構成を調査し、カスタムポートに正しいSELinuxタイプを明示的に割り当てる方法を学びます。

まず、Webサーバーポートに適したSELinuxタイプを見つける必要があります。semanage port -lコマンドは、SELinuxが認識しているすべてのポート定義をリスト表示します。この出力をgrepにパイプして、httpに関連するタイプを見つけることができます。

sudo semanage port -l | grep http

出力にはいくつかのポートタイプが表示されます。標準的なWebサーバーにとって最も関連性が高いのはhttp_port_tです。

http_cache_port_t              tcp      8080, 8118, 8123, 10001-10010
http_cache_port_t              udp      3130
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t            tcp      5988
pegasus_https_port_t           tcp      5989

ご覧のとおり、http_port_tは80や443のような標準的なHTTP/HTTPSポートに割り当てられています。SELinuxポリシーでは、httpd_tタイプ(Webサーバー)を持つプロセスが、http_port_tとラベル付けされた任意のポートにバインドすることを許可しています。ポート8081がすでにこのリストにあるか確認してみましょう。

ポート8081が現在http_port_tの下にリストされていないことに注意してください。ただし、一部のRHEL構成では、このポートがすでにSELinuxポリシーで定義されている場合があります。semanage port -aコマンドを使用して、適切なSELinuxコンプライアンスのために明示的に追加してみましょう。

  • -aオプションは「追加(add)」を意味します。
  • -t http_port_tオプションは、割り当てるタイプを指定します。
  • -p tcpオプションは、プロトコルを指定します。
sudo semanage port -a -t http_port_t -p tcp 8081

「Port tcp/8081 already defined, modifying instead(ポートtcp/8081はすでに定義されています。代わりに変更します)」というメッセージが表示される場合があります。これは、ポートがすでに構成されていたことを意味します。これが、前のステップでhttpdが正常に起動した理由です。現在の構成を検証するために、http_port_tの定義を再度リスト表示します。

sudo semanage port -l | grep '^http_port_t'

これで、ポート8081がリストに含まれているはずです。

http_port_t                    tcp      8081, 80, 81, 443, 488, 8008, 8009, 8443, 9000

SELinuxポリシーが明示的に更新されたことで、ポート8081は正式にHTTPポートとして認識されました。httpdサービスは問題なく実行され続け、適切なSELinuxコンプライアンスが確保されました。

プロセスがまだ実行されていることを確認しましょう。

ps aux | grep httpd

複数のhttpdプロセスが引き続き表示されるはずであり、Webサーバーが適切なSELinuxポートラベルで正常に実行されていることを示しています。

root        4813  0.0  0.2  23364  7736 ?        Ss   09:32   0:00 /usr/sbin/httpd
apache      4814  0.0  0.1  23020  5092 ?        S    09:32   0:00 /usr/sbin/httpd
apache      4815  0.0  0.4 1441064 14620 ?       Sl   09:32   0:00 /usr/sbin/httpd
apache      4816  0.0  0.5 1441064 18736 ?       Sl   09:32   0:00 /usr/sbin/httpd
apache      4837  0.0  0.4 1572200 16872 ?       Sl   09:32   0:00 /usr/sbin/httpd
labex       5215  0.0  0.0   6408  2176 pts/3    S+   09:33   0:00 grep --color=auto httpd

httpdサービスがポート8081で実行されることを明示的に許可するようにSELinuxポリシーを正常に構成し、適切なセキュリティコンプライアンスを確保しました。

firewall-cmdを使用してファイアウォールでカスタムポートを開放する

このステップでは、カスタムポート8081でWebサーバーへの外部接続を許可するようにシステムのファイアウォールを構成します。SELinuxポリシーの変更によりhttpdサービスは正しく実行されていますが、ネットワークトラフィックルールを管理するfirewalldサービスは、デフォルトではこの標準以外のポートへの着信リクエストをブロックしている可能性が高いです。

firewalldパッケージはセットアップフェーズですでにインストールされています。ただし、まずfirewalldサービスを開始する必要があります。現在のステータスを確認し、必要に応じて開始しましょう。

sudo firewall-cmd --list-all

「FirewallD is not running(FirewallDは実行されていません)」と表示された場合は、firewalldデーモンを開始する必要があります。このコンテナ環境では、firewalldデーモンを直接開始します。末尾の&はプロセスをバックグラウンドで実行します。

sudo /usr/sbin/firewalld &

サービスが初期化されるまで少し待ち、実行されていることを確認します。

sudo firewall-cmd --list-all

これで、デフォルトゾーン (public) の現在のファイアウォール構成が表示されるはずです。

curlを使用してコマンドラインからWebサーバーへのアクセスをテストしてみましょう。このコマンドは、ポート8081でlocalhostへの接続を試みます。

curl http://localhost:8081

テストページのHTMLコンテンツが表示されるはずです。これはWebサーバーがローカルでアクセス可能であることを意味します。firewalldは通常デフォルトでlocalhostのトラフィックを許可するため、これは想定通りです。

ただし、外部アクセスと適切なセキュリティ構成のためには、カスタムポート用にファイアウォールを適切に構成する必要があります。localhost接続は通常ファイアウォールルールに関係なく機能しますが、他のマシンからの外部接続は、適切なファイアウォール構成がないとブロックされます。

まず、デフォルトゾーン (public) の現在のルールを検査します。

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources:
  services: cockpit dhcpv6-client ssh
  ports:
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

次に、ポート8081でのTCPトラフィックを許可する新しいルールを追加します。このコマンドを実行する前に、firewalldが実行されていることを確認してください。

  • --add-port=8081/tcpは、開放するポートとプロトコルを指定します。
  • --permanentは、再起動やファイアウォールのリロード後もルールが保持されるようにします。
sudo firewall-cmd --permanent --add-port=8081/tcp

「FirewallD is not running」と表示された場合は、前のステップでfirewalldデーモンを開始したことを確認し、初期化されるまで少し待ってください。

firewalldが正しく実行されていれば、コマンドはsuccessを返すはずです。

success

永続的なルールは、リロードされるまでアクティブなファイアウォール構成には適用されません。新しいルールを適用するためにファイアウォールをリロードしましょう。

sudo firewall-cmd --reload

このコマンドもsuccessを返すはずです。

success

ルールを再度リスト表示して、ポートが開放されたことを確認しましょう。

sudo firewall-cmd --list-all

ports:セクションに8081/tcpが表示されているはずです。

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources:
  services: cockpit dhcpv6-client ssh
  ports: 8081/tcp
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

ファイアウォールの構成が完了しました。最後のステップは、Webサーバーにアクセスできるかテストすることです。

標準およびカスタムWebサーバーポートへのアクセスを検証する

この最後のステップでは、行ったすべての変更によって、Webサーバーがローカルおよび外部アクセスの両方に対して適切に構成されていることを検証します。SELinuxポリシーを構成し、ファイアウォールで必要なポートを開放しました。次に、構成を確認するために包括的なテストを実行します。

まず、接続したときにカスタムメッセージが表示されるように、簡単なテストページを作成しましょう。httpdのデフォルトのドキュメントルートは/var/www/htmlです。そのディレクトリにindex.htmlファイルを作成します。この場所に書き込むにはsudo権限が必要です。

echo "Success! Web server on custom port 8081 is working." | sudo tee /var/www/html/index.html

このコマンドは、成功メッセージをindex.htmlファイルに配置します。ここではteeコマンドを使用しています。これは、パイプを使用しながらsudo権限が必要なファイルに書き込むことができるためです。確認として、ターミナルにメッセージがエコーされるはずです。

Success! Web server on custom port 8081 is working.

演習を完了するために、標準のHTTPポート80へのアクセスを試みて、対照的な結果を示しましょう。サーバーは8081でのみリッスンするように構成されているため、このリクエストは失敗するはずです。

curl http://localhost:80

予想通り、そのポートでリッスンしているサービスがないため、接続は拒否されます。

curl: (7) Failed to connect to localhost port 80: Connection refused

これにより、サーバーが構成したカスタムポートでのみ実行されていることが確認できました。この実験を通じて、RHEL上のサービスに関する重要なトラブルシューティングワークフローを学びました。

  1. サービスの状態とログを確認する。
  2. 監査ログでSELinuxの拒否を調査する。
  3. semanageを使用してSELinuxポリシーを修正する。
  4. firewall-cmdを使用してファイアウォールルールを構成する。
  5. 接続性を検証する。

まとめ

この実験では、カスタムポートでWebサーバーを構成し、SELinuxセキュリティポリシーを管理する方法を学びました。Apache Webサーバー (httpd)、policycoreutils-python-utilsfirewalldパッケージがプリインストールされた環境で、SELinuxのポート管理とファイアウォール構成の理解に焦点を当てました。httpd.confファイルを変更して、Webサーバーのリッスンポートを標準以外のポート8081に変更しました。

ポート8081がすでにSELinuxポリシーで適切に構成されていたため、httpdサービスがカスタムポートで正常に起動したことを発見しました。これは、SELinuxのポート管理を調査し、適切なポートラベルを維持するためにsemanageがどのように機能するかを理解する機会となりました。また、firewall-cmdを使用してファイアウォールルールを管理し、セキュリティコンプライアンスとアクセシビリティの両方を確保する方法も学びました。httpdは制限なしコンテキストで実行されていましたが、この実験は本番環境における適切なSELinuxおよびファイアウォール構成の重要性を示しました。