RHEL で firewalld と SELinux を使用したセキュリティ強化

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

はじめに

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

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

カスタムポートでの httpd 設定と SELinux コンテキストの理解

このステップでは、Apache ウェブサーバー (httpd) を非標準ポートで実行するように設定し、SELinux がポートアクセスをどのように管理するかを学びます。ポート 8081 を使用し、一部の構成でサービスが正常に起動した場合でも、SELinux ポート管理について調べます。

必要なパッケージ (httpd, policycoreutils-python-utils, および firewalld) は、セットアップフェーズですでにインストールされています。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 デーモンを直接起動します。

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 プロセスが実行されているはずです。これは、ウェブサーバーが正常に起動したことを示しています。

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 の拒否がないか確認しましょう。

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

結果がない場合、SELinux は httpd サービスがポート 8081 にバインドすることをブロックしませんでした。これは、次の理由が考えられます。

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

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

getenforce

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

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

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

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

sudo semanage port -l | grep http

出力には、いくつかのポートタイプが表示されます。標準のウェブサーバーにとって最も関連性の高いものは 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 は、80443 などの標準 HTTP/HTTPS ポートに割り当てられています。SELinux ポリシーは、httpd_t タイプ (ウェブサーバー) を持つプロセスが、http_port_t でラベル付けされた任意のポートにバインドすることを許可します。ポート 8081 がすでにこのリストにあるかどうかを確認しましょう。

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

  • -a オプションは「追加」を意味します。
  • -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 プロセスが引き続き表示されるはずです。これは、ウェブサーバーが適切な 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 でウェブサーバーへの外部接続を許可するようにシステムのファイアウォールを構成します。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 を使用して、コマンドラインからウェブサーバーへのアクセスをテストしましょう。このコマンドは、ポート 8081localhost に接続しようとします。

curl http://localhost:8081

テストページの HTML コンテンツが表示されるはずです。これは、ウェブサーバーがローカルでアクセス可能であることを意味します。これは、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 デーモンを開始したことを確認し、初期化されるまでしばらく待ちます。

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 サーバーポートへのアクセスの検証

この最終ステップでは、行ったすべての変更により、ウェブサーバーがローカルアクセスと外部アクセスの両方に対して適切に構成されていることを確認します。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. 接続性を検証します。

まとめ

この実験では、カスタムポートでウェブサーバーを構成し、SELinux セキュリティポリシーを管理する方法を学びました。Apache ウェブサーバー (httpd)、policycoreutils-python-utils、および firewalld パッケージが事前にインストールされている状態で、SELinux ポート管理とファイアウォール構成の理解に焦点を当てました。httpd.conf ファイルを変更して、ウェブサーバーのリッスンポートを非標準ポートである 8081 に変更しました。

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