Red Hat Certified System Administrator (RHCSA) #12: firewalld と SSH 鍵認証

読了 11分

#11 ユーザー/グループ で UID/GID と sudo、ACL、パスワードポリシーでユーザーのセキュリティを固めたなら、今回はシステムの外から入ってくるアクセスを制御する 2 つの軸を扱います。1 つは firewalld でどのポートとサービスを開くかを決めること であり、もう 1 つは SSH 鍵認証でパスワードなしに安全にリモート接続すること です。

どちらの主題も RHCSA の定番です。firewalld は「このサービス (またはポート) を永続的に許可せよ」という形でほぼ毎回出題され、SSH 鍵認証は「このユーザーが鍵でログインできるよう設定せよ」という作業で出ます。そして両方の作業とも 永続適用を抜かすと 0 点 です。firewalld は --permanent を、SSH は権限と sshd の再起動を逃した瞬間に採点スクリプトが失敗します。そのため今回の記事はコマンド 1 つ 1 つを永続適用の観点で整理します。

firewalld とは何か #

RHEL の標準ファイアウォールは firewalld です。内部的には nftables (以前は iptables) を扱いますが、私たちは firewall-cmd というコマンドで抽象化された規則を扱います。firewalld の最大の特徴は zone (領域) という概念です。

zone は「このネットワークトラフィックをどれだけ信頼するか」によってまとめた規則の集合です。同じ 80 番ポートでも、信頼する内部網から入ってくれば許可し、信頼しない外部から入ってくれば塞ぐことができます。よく使う zone は次のとおりです。

zone性格
public標準 zone。信頼しない公開網。明示的に開けたものだけ許可
trustedすべてのトラフィックを許可。完全に信頼する網
drop入ってくるすべてのパケットを応答なしで破棄
block入ってくる接続を拒否 (reject) するが応答は送る
internal / dmz / work用途別の事前定義 zone

RHCSA ではほとんどの場合、標準 zone である public に規則を追加します。ただし「特定の出発地アドレスは別の zone で処理せよ」のような source ベースの問題が出ることがあるので、zone の概念自体は知っておく必要があります。

firewalld の状態確認 #

作業の前に firewalld が動作中か、そしてどの zone が有効かをまず確認します。

# firewalld サービスの状態確認
systemctl status firewalld

# 有効化されていなければ起動し、起動時の自動起動を登録
systemctl enable --now firewalld

# 現在の有効 zone とその zone に紐づくインターフェースを確認
firewall-cmd --get-active-zones

# 標準 zone の確認
firewall-cmd --get-default-zone

--get-active-zones は実際にトラフィックが流れる zone とそこに紐づくインターフェースを見せてくれます。たとえば次のように出力されます。

public
  interfaces: ens160

この出力は ens160 インターフェースで入ってくるトラフィックが public zone の規則に従うという意味です。したがって別途指定がなければ public に規則を入れればよいです。

firewall-cmd でサービス・ポートを開く #

firewalld で何かを許可する方法は大きく 2 つあります。サービス名で開くことポート番号で開くこと です。

サービスで開く #

firewalld はよく知られたサービスのポートを名前でまとめた定義を持っています。http は 80、https は 443、ssh は 22 のように、名前だけ指定すれば該当ポートが開きます。使用可能なサービスの一覧は次で見ます。

# firewalld が知っているサービス名の一覧
firewall-cmd --get-services

サービスを追加するコマンドは次のとおりです。

# public zone に http サービスを許可 (現在のセッションのみに適用。再起動すると消える)
firewall-cmd --add-service=http

このコマンドは 今すぐ は動作しますが、再起動すると消えます。永続適用はあとで別に扱います。

ポートで開く #

標準サービスではない任意のポートを開くには、ポートとプロトコルを直接指定します。

# 8080/tcp ポートを許可 (現在のセッションのみに適用)
firewall-cmd --add-port=8080/tcp

# 範囲での指定も可能 (5900〜5910/tcp)
firewall-cmd --add-port=5900-5910/tcp

--add-port は常に ポート/プロトコル の形式です。プロトコル (tcp または udp) を抜かすとコマンドが失敗するので注意します。

–permanent と –reload: 永続適用の核心 #

ここが RHCSA で最も多く点数を失う地点です。firewalld の規則には 2 つの分離した設定集合 があります。

  • runtime (現在適用): 今メモリに載って動作中の規則。再起動すると消えます。
  • permanent (永続設定): ディスクに保存され再起動後も維持される規則。ただし保存したからといってすぐ適用されるわけではありません。

--permanent なしで --add-service=http だけすると今は開きますが再起動後に閉じます。逆に --permanent だけ付けるとディスクには保存されますが 今すぐは適用されません。そのため両方を満たす標準パターンは次の 2 段階です。

# 1) 永続設定に規則を保存
firewall-cmd --permanent --add-service=http

# 2) 永続設定を runtime に読み込み直して今も適用
firewall-cmd --reload

--reload は permanent 設定全体を runtime に再適用します。この 1 行を抜かすと「今はできないのに再起動するとできる」という妙な状態になります。採点スクリプトが再起動なしで検査すると失敗することがあるので、--permanent で保存したあと必ず --reload する習慣をつけます。

落とし穴: –permanent を抜かすミス #

試験で時間に追われると、つい次のように打ちます。

# よくあるミス。runtime のみに適用され再起動後に消える
firewall-cmd --add-service=https

このコマンドは出力が success なので成功したように見えます。しかし再起動すると規則が消えるので採点では 0 点です。「firewall で何かを許可せよ」という問題を見たら 反射的に --permanent を先に思い浮かべる のが安全です。安全な標準手順は次のとおりです。

# 永続 + 即時適用を 1 セットで
firewall-cmd --permanent --add-service=https
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --reload

規則の確認: –list-all #

作業後は必ず結果を確認します。zone に実際に適用された規則を一目で見るコマンドが --list-all です。

# 標準 zone (通常 public) の runtime 規則全体を確認
firewall-cmd --list-all

# 特定の zone を指定して確認
firewall-cmd --zone=public --list-all

出力は次のようになります。

public (active)
  target: default
  interfaces: ens160
  sources:
  services: ssh dhcpv6-client http https
  ports: 8080/tcp
  ...

ここで servicesports の行を見て、意図した規則が入ったか確認します。注意すべき点は --list-all が基本的に runtime を見せる ということです。永続設定がきちんと保存されたかまで確認するには --permanent を一緒に付けます。

# 永続設定に保存された規則を確認
firewall-cmd --permanent --list-all

runtime と permanent が両方とも意図どおりに出れば、その作業は完全に終わったということです。

rich rule: 細かい規則を 1 行で #

単純な許可を超えて「特定の出発地から来た特定のサービスだけ許可」のように条件を細かくかけるのが rich rule です。RHCSA で深くは問われませんが、1 行の形は覚えておくと便利です。

# 192.168.10.0/24 の範囲から来る http だけ永続許可
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.10.0/24" service name="http" accept'
firewall-cmd --reload

rich rule も他の規則と同じく --permanent--reload が必要です。登録された rich rule は次で確認します。

firewall-cmd --list-rich-rules

source で zone を指定する #

zone にインターフェースの代わりに 出発地アドレスを紐づける こともできます。「このアドレスから来るトラフィックはより信頼する zone で処理せよ」のような問題に使います。

# 192.168.20.0/24 の範囲を trusted zone に紐づけて永続適用
firewall-cmd --permanent --zone=trusted --add-source=192.168.20.0/24
firewall-cmd --reload

# 結果確認。trusted zone の sources 行に範囲が現れる
firewall-cmd --zone=trusted --list-all

こうすると該当範囲から来るトラフィックは public ではなく trusted zone の規則に従います。source を追加するとその zone が active zone の一覧に現れるので、--get-active-zones でも確認できます。

SSH 鍵認証 #

ここからは 2 つ目の軸です。SSH 鍵認証はパスワードの代わりに 鍵ペア (公開鍵 + 秘密鍵) で身元を証明する方式です。秘密鍵はクライアントが持っており、公開鍵をサーバーに登録しておけばパスワードなしでログインできます。パスワード推測攻撃に強く自動化に有利なので実務の標準です。

流れは 3 段階です。鍵を作り (ssh-keygen)、サーバーに公開鍵を登録し (ssh-copy-id)、権限を合わせます。

1) 鍵ペアの生成: ssh-keygen #

クライアント (接続する側) で鍵ペアを作ります。

# RSA 鍵ペアを生成 (標準の場所 ~/.ssh/ に保存)
ssh-keygen

# オプションを明示する形。タイプとコメントを指定
ssh-keygen -t rsa -b 4096 -C "user@workstation"

ssh-keygen を実行すると保存場所 (~/.ssh/id_rsa) と passphrase を尋ねます。標準値で進めると 2 つのファイルができます。

ファイル役割
~/.ssh/id_rsa秘密鍵。絶対に外部に露出してはいけない
~/.ssh/id_rsa.pub公開鍵。サーバーに登録するファイル

passphrase は秘密鍵自体にかける追加のパスワードです。セキュリティには良いですが、試験でパスワードなしの自動ログインを要求するなら passphrase を空にしておきます。

2) 公開鍵の登録: ssh-copy-id #

作った公開鍵をサーバーに登録する最も簡単な方法が ssh-copy-id です。このコマンドは公開鍵をサーバーの ~/.ssh/authorized_keys に追加し、権限まで自動で合わせてくれます。

# サーバーの user アカウントに公開鍵を登録 (このとき一度はパスワードで認証)
ssh-copy-id user@server

このコマンドを一度実行したあとからはパスワードなしで鍵でログインできます。

# 鍵認証で接続。パスワードを尋ねなければ成功
ssh user@server

3) 手動登録と権限: authorized_keys #

ssh-copy-id を使えない環境なら公開鍵を直接 authorized_keys に入れなければなりません。このとき 権限を正確に合わせること が核心です。SSH は権限が緩いとセキュリティ上、鍵認証を拒否します。

# サーバーで対象ユーザーとして作業すると仮定
mkdir -p ~/.ssh
chmod 700 ~/.ssh

# 公開鍵の内容を authorized_keys に追加
cat id_rsa.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

権限の規則は覚えておくのがよいです。

対象権限
~/.ssh ディレクトリ700 (drwx——)
~/.ssh/authorized_keys ファイル600 (-rw——-)
ホームディレクトリ自体グループ・その他に書き込み権限なし

所有者も重要です。ユーザーの .ssh ディレクトリとその中のファイルは該当ユーザーの所有でなければなりません。root で他のユーザーの鍵を作ったなら chown -R user:user /home/user/.ssh で所有権を合わせます。鍵認証ができないときに最もよくある原因が 権限と所有権 なので、できなければここから点検します。SELinux がオンのシステムではコンテキストも影響を与えますが、これは #13 SELinux 深掘りrestorecon で扱います。

4) パスワード認証を切る (sshd 設定) #

鍵認証を強制してパスワードログインを塞ぐには sshd 設定を変えます。核心は次の 1 行です。

# /etc/ssh/sshd_config または /etc/ssh/sshd_config.d/*.conf で設定
PasswordAuthentication no

RHEL 9 では /etc/ssh/sshd_config.d/ 配下の drop-in ファイルがメイン設定より優先する場合が多いので、そちらに同じキーがあるかも確認します。設定を変えたあとは sshd を再起動しないと適用されません。

# 設定の適用のために sshd を再起動
systemctl restart sshd

注意すべき点は、パスワード認証を切る前に 鍵認証が実際に動作するかをまず確認する ことです。鍵ができない状態でパスワードまで塞ぐと、自分自身がログインできない状況が生まれます。

試験ポイント #

  • firewalld の作業は --permanent で保存し --reload で適用する 2 段階が 1 セットです。1 つでも抜けると失点します。
  • 「firewall で許可せよ」という問題を見たら反射的に --permanent を思い浮かべます。runtime のみ適用すると再起動後に消えて 0 点です。
  • サービスは --add-service=名前、ポートは --add-port=ポート/プロトコル の形式です。ポートにはプロトコル (tcp/udp) を必ず付けます。
  • 作業後は firewall-cmd --list-all で runtime を、firewall-cmd --permanent --list-all で永続設定を両方とも確認します。
  • 有効 zone とインターフェースは --get-active-zones で、出発地ベースの zone 指定は --add-source で処理します。
  • SSH 鍵認証は ssh-keygen で作り ssh-copy-id で登録する流れが最も速いです。
  • 手動登録時は権限が核心です。~/.ssh700authorized_keys600、所有者は該当ユーザーでなければなりません。
  • パスワード認証を切るには PasswordAuthentication no のあと systemctl restart sshd まで実行しないと適用されません。切る前に鍵ログインができるかをまず確認します。

まとめ #

この記事で押さえたこと:

  • firewalld。zone で信頼水準を分け、firewall-cmd でサービス・ポートを許可します。
  • 永続適用--permanent で保存し --reload で即時適用する 2 段階が必須です。
  • 確認--get-active-zones で有効 zone を、--list-all で適用された規則を確認します。
  • 細かい規則。rich rule で出発地・サービスの条件をかけ、--add-source で zone を指定します。
  • SSH 鍵認証ssh-keygenssh-copy-id の流れ、手動登録時は 700/600 の権限と所有権を合わせます。
  • パスワード遮断PasswordAuthentication no のあと sshd を再起動。鍵ログインを先に検証します。

firewalld と SSH 鍵認証はコマンド自体は難しくありませんが、永続適用と権限という落とし穴が点数を分けます。両方の作業とも「再起動後も維持されるか」と「権限が正確か」を最後に自問する習慣で締めくくります。

次へ: SELinux 深掘り #

ファイアウォールと SSH で外部アクセスを制御したなら、システム内部でプロセスが何をできるのかを制御するのが SELinux です。RHCSA で最も厄介とされる領域ですが、パターンを知れば点数源になります。

#13 SELinux 深掘り: contexts、booleans、troubleshooting (audit2allow) では、ファイルコンテキストを扱う semanage fcontextrestorecon、動作をトグルする boolean、そして拒否ログを読んでポリシーを作る audit2allow まで、直接打ちながら SELinux のトラブルシューティングを整理します。

X