Red Hat Certified Engineer (RHCE) #17 RHCSA 自動化 4: firewall、SELinux、SSH キー
#16 RHCSA 自動化 3: ストレージ (LVM)、ファイルシステム (NFS) でストレージをプレイブックで構成したなら、今回は RHCSA 自動化の最後の領域である セキュリティ構成 を扱います。firewalld でポートを永続的に許可し、SELinux boolean とファイルコンテキストを調整し、ユーザーアカウントに SSH 公開鍵を配布する作業をすべて Ansible で自動化します。
この 3 つは RHCSA で手で覚えた作業です。RHCSA #12 firewalld と SSH 鍵認証 で firewall-cmd --permanent と ssh-copy-id を扱い、RHCSA #13 SELinux 深掘り で setsebool -P と semanage fcontext、restorecon を覚えました。RHCE は同じ結果を 冪等性のあるプレイブック で作り出す仕事です。
モジュールが属する collection から #
セキュリティ作業に使うモジュールは大半が ansible.posix と community.general collection に入っています。core にデフォルトで含まれていないことがあるので、試験環境でインストールされているかをまず確認します。
| 作業 | モジュール | collection |
|---|---|---|
| firewalld ルール | firewalld | ansible.posix |
| SELinux boolean | seboolean | ansible.posix |
| SELinux モード | selinux | ansible.posix |
| ファイルコンテキスト | sefcontext | community.general |
| SSH 公開鍵の配布 | authorized_key | ansible.builtin |
ansible-doc -l | grep firewalld でモジュールが見えるか確認し、見えなければ ansible-galaxy collection install ansible.posix でインストールします。モジュールの全オプションは、インターネットのない環境で ansible-doc ansible.posix.firewalld で調べる習慣をつけます。
firewalld の自動化 #
RHCSA で firewall-cmd --add-service=http --permanent と --reload でやった作業を ansible.posix.firewalld モジュールに移します。このモジュールの核心は、永続適用と即時適用を別々のオプションで制御する という点です。
| オプション | 意味 |
|---|---|
service または port | 許可対象。サービス名または ポート/プロトコル |
state | enabled で許可、disabled で遮断 |
permanent: true | 永続ルール (reboot 後も維持)。--permanent に該当 |
immediate: true | ランタイムにも即時反映。--reload なしですぐ適用 |
zone | 適用する zone。省略時はデフォルト zone |
--permanent だけを適用すると再起動前までランタイムに反映されないので、試験では permanent: true と immediate: true を一緒に かけるのが安全です。片方だけかけると「今は開いたが再起動すると閉じる」または「再起動後は開くが今は閉じている」といった部分減点になります。
---
- name: Configure firewalld
hosts: webservers
become: true
tasks:
- name: Ensure firewalld is running
ansible.builtin.service:
name: firewalld
state: started
enabled: true
- name: Allow http service permanently and immediately
ansible.posix.firewalld:
service: http
state: enabled
permanent: true
immediate: true
- name: Allow https service
ansible.posix.firewalld:
service: https
state: enabled
permanent: true
immediate: true
- name: Allow custom tcp port 8080
ansible.posix.firewalld:
port: 8080/tcp
state: enabled
permanent: true
immediate: trueservice は /usr/lib/firewalld/services に定義された名前を使い、定義のないポートは port: 8080/tcp 形式で直接開きます。複数のサービスを一度に処理するには loop でまとめても構いません。
- name: Allow multiple services
ansible.posix.firewalld:
service: "{{ item }}"
state: enabled
permanent: true
immediate: true
loop:
- http
- https
- cockpitSELinux の自動化 #
SELinux の作業は 3 つに分かれます。モード設定、boolean トグル、ファイルコンテキスト指定 です。それぞれ別のモジュールを使うので、区別して覚えます。
1) モード設定: selinux モジュール #
ansible.posix.selinux モジュールで enforcing または permissive モードを設定します。state: enforcing がポリシー適用モードで、policy: targeted が標準ポリシーです。
- name: Ensure SELinux is enforcing
ansible.posix.selinux:
state: enforcing
policy: targeteddisabled から enabled に変える場合のように再起動が必要な変更だと、このモジュールは結果に reboot_required を知らせます。その場合は ansible.builtin.reboot task で再起動につなげるパターンが安全です。
2) boolean トグル: seboolean モジュール #
setsebool -P httpd_can_network_connect on でやった作業が ansible.posix.seboolean モジュールです。persistent: true が RHCSA の -P に該当 し、これを抜かすと再起動後に値が初期化されます。
- name: Allow httpd to make network connections
ansible.posix.seboolean:
name: httpd_can_network_connect
state: true
persistent: true| オプション | 意味 |
|---|---|
name | boolean の名前。getsebool -a で確認 |
state | true でオン、false でオフ |
persistent: true | 再起動後も維持。setsebool -P に該当 |
3) ファイルコンテキスト: sefcontext モジュール #
非標準パス (例: /web 配下の Web コンテンツ) を置くと SELinux ラベルが合わず、サービスがアクセスできません。RHCSA では semanage fcontext でポリシーにルールを追加し、restorecon で実際のファイルにラベルを適用しました。
community.general.sefcontext モジュールは ポリシールールの追加だけ を行います。つまり semanage fcontext に該当する作業までしかせず、実際のファイルラベルの適用 (restorecon) は別の task でつなげる必要があります。この 2 つをまとめるのが定石です。
- name: Add fcontext rule for /web
community.general.sefcontext:
target: '/web(/.*)?'
setype: httpd_sys_content_t
state: present
- name: Apply the new context to existing files
ansible.builtin.command:
cmd: restorecon -Rv /websefcontext だけを実行するとポリシーにはルールが入りますが、すでに存在するファイルのラベルは変わりません。そのため command で restorecon を一度回さないと実際のファイルに反映されません。command は毎回 changed として扱われ冪等性が少し崩れますが、試験では restorecon が抜けるほうがはるかに大きい減点なので、一緒に置くことをおすすめします。
SSH 公開鍵の配布 #
RHCSA で ssh-copy-id でやった公開鍵の配布を ansible.builtin.authorized_key モジュールで自動化します。特定のユーザーの ~/.ssh/authorized_keys に公開鍵を冪等に追加するモジュールです。
- name: Deploy public key for deploy user
ansible.builtin.authorized_key:
user: deploy
state: present
key: "{{ lookup('file', 'files/deploy_id_ed25519.pub') }}"| オプション | 意味 |
|---|---|
user | 対象のユーザーアカウント |
key | 登録する公開鍵の文字列。lookup('file', ...) でファイルから読む |
state | present で追加、absent で削除 |
exclusive: true | この鍵だけを残し既存の鍵をすべて削除 |
key は control node に置いた公開鍵ファイルを lookup('file', ...) で読み込む方式がよくあります。複数のユーザーにそれぞれの鍵を配布するには、変数ディクショナリと loop を組み合わせます。
- name: Deploy keys for multiple users
ansible.builtin.authorized_key:
user: "{{ item.name }}"
state: present
key: "{{ lookup('file', item.keyfile) }}"
loop:
- { name: alice, keyfile: files/alice.pub }
- { name: bob, keyfile: files/bob.pub }system role の代替 #
この領域も手でモジュールをかける代わりに、#13 system roles で扱った rhel-system-roles で処理できます。試験で system role を使えと明示されたら必ず role を使い、そうでなければ慣れているほうを選べばよいです。
firewall system role #
redhat.rhel_system_roles.firewall role に変数でルールを宣言します。role の内部が永続適用まで処理するので、オプションを一つ一つ気にする必要が減ります。
- name: Configure firewall via system role
hosts: webservers
become: true
roles:
- redhat.rhel_system_roles.firewall
vars:
firewall:
- service: http
state: enabled
- service: https
state: enabled
- port: 8080/tcp
state: enabledselinux system role #
redhat.rhel_system_roles.selinux role でモードと boolean、ファイルコンテキストを一度に宣言します。role がコンテキストの適用まで一緒に処理するので、restorecon を別に呼ばなくても済みます。
- name: Configure SELinux via system role
hosts: webservers
become: true
roles:
- redhat.rhel_system_roles.selinux
vars:
selinux_state: enforcing
selinux_booleans:
- name: httpd_can_network_connect
state: true
persistent: true
selinux_fcontexts:
- target: '/web(/.*)?'
setype: httpd_sys_content_t
state: present
selinux_restore_dirs:
- /web統合例 #
3 つの領域を 1 つのプレイブックにまとめると、試験のセキュリティ自動化問題に近い形になります。firewalld でポートを開け、SELinux boolean をオンにし、SSH 鍵を配布する流れです。
---
- name: Secure web hosts
hosts: webservers
become: true
tasks:
- name: Open http and https permanently
ansible.posix.firewalld:
service: "{{ item }}"
state: enabled
permanent: true
immediate: true
loop:
- http
- https
- name: Enforce SELinux
ansible.posix.selinux:
state: enforcing
policy: targeted
- name: Enable httpd network boolean
ansible.posix.seboolean:
name: httpd_can_network_connect
state: true
persistent: true
- name: Add fcontext for content dir
community.general.sefcontext:
target: '/web(/.*)?'
setype: httpd_sys_content_t
state: present
- name: Restore context on content dir
ansible.builtin.command:
cmd: restorecon -Rv /web
- name: Deploy admin public key
ansible.builtin.authorized_key:
user: deploy
state: present
key: "{{ lookup('file', 'files/deploy.pub') }}"試験のポイント #
- firewalld は
permanent: trueとimmediate: trueを一緒に かけるのが安全です。片方だけかけると再起動の前後で状態が食い違い、部分減点になります。 - seboolean は
persistent: trueを必ず 入れます。RHCSA のsetsebool -Pに該当し、抜けると再起動後に初期化されます。 - sefcontext はルールの追加だけ を行います。実際のファイルへの適用は
restoreconを別の task でつなげないとラベルが反映されません。 - selinux モジュールは再起動が必要な変更 (disabled から enabled) だと
reboot_requiredを知らせます。必要ならreboottask につなげます。 - authorized_key の
keyはlookup('file', ...)で control node の公開鍵を読み込みます。exclusive: trueは既存の鍵を消すので、意図するときだけ使います。 - モジュールが見えなければ、
ansible-galaxy collection install ansible.posixとcommunity.generalをまず確認します。
まとめ #
この記事で押さえたこと:
- firewalld。
ansible.posix.firewalldで service と port をpermanent: true+immediate: trueで永続許可 - SELinux モード。
ansible.posix.selinuxで enforcing/targeted を設定。必要に応じて再起動 - SELinux boolean。
ansible.posix.sebooleanでトグル。persistent: trueで永続適用 - SELinux コンテキスト。
community.general.sefcontextでルールを追加後restoreconで適用 - SSH 鍵。
ansible.builtin.authorized_keyでユーザーごとの公開鍵を配布 - system role の代替。firewall と selinux role で同じ作業を変数宣言で処理
これで #14 から続いた RHCSA 自動化の 4 編が終わりました。ユーザー・パッケージ、サービス・時刻・ログ、ストレージ、セキュリティまで、RHCSA の手作業をすべてプレイブックに移しました。試験比重の半分を占める領域なので、各モジュールの永続適用オプションを手に覚えることが合格ラインを超える近道です。
次へ: 試験のコツ #
自動化の領域をすべて扱ったので、次は 4 時間を実際にどう運用するかを整理する番です。
#18 試験のコツと時間管理 では、ansible-doc の活用法、冪等性検証の習慣、永続適用の点検チェックリスト、そして時間配分の戦略まで、試験会場ですぐ使える実戦的なコツを整理します。