手動ユーザー管理が破綻する理由(そして私がどう対処したか)
深夜にSSHブルートフォース攻撃を受けてから、新しいデプロイの初日から認証を最重要課題として扱うようになった。しかしSSHのセキュリティ強化は実は簡単な部分だった。本当の問題は構造的なものだった:各Linuxサーバーは独自の/etc/passwdを持ち、独自のローカルユーザーがあり、SSHキーはチームメンバーのノートPCに散乱していた。誰かが退職すると、どのサーバーにアカウントがあるか追跡するのに2〜3時間かかり、見落としがないかと不安になることもあった。
その経験から、一元化された認証をきちんと評価するようになった。これらのソリューションを本番環境で運用した後にわかったことをまとめる。
主要なアプローチの比較
中小規模では、現実的な選択肢は3つある:
1. LDAP + PAM(DIYスタック)
OpenLDAPを立ち上げ、pam_ldapとnss_ldapで接続する方法だ。理論上は柔軟だが、実際には苦労が多い。スキーマの移行、レプリケーションの遅延、TLS証明書の期限切れで午後丸ごと潰れることがある。LDAPサーバーの維持に、本来の製品開発よりも多くのエンジニアリング時間を費やしているチームを何度も見てきた。
2. Active Directory(SambaまたはMicrosoft AD)
組織がすでにWindows ADを運用しているなら、sssdとrealmdでLinuxマシンをドメイン参加させる方法はそれなりに機能する。問題はWindowsインフラに縛られる点で、ADはLinuxネイティブのワークフローを念頭に設計されていない。sudoルールやホストベースのアクセス制御には、取ってつけたようなプラグインやグループポリシーのハックが必要になる。
3. FreeIPA
FreeIPAはKerberos、LDAP(389 Directory Server)、DNS、NTP、CAをひとつの統合スタックとして提供する。最初からLinuxとUnix向けに設計されており、後付けではない。Web UIはシンプルで、SSH公開鍵管理が組み込まれており、LDIFファイルを一切触ることなく、sudoポリシーとホストベースのアクセス制御をネイティブでサポートしている。
FreeIPAのメリットとデメリット
FreeIPAが得意なこと
- 統合Kerberos SSO — 一度認証すれば、サービスへのチケットを取得できる。SSH、GSSAPI経由のHTTPなど、パスワードを何度も入力する必要がない。
- HBACルール — どのユーザーがどのホストにアクセスできるかを制限できる。ジュニア開発者はステージングのみ、シニアエンジニアは本番環境へ——ひとつのポリシーで全環境に適用される。
- 一元化されたsudoルール — FreeIPAで一度定義すれば、SSSDが全クライアントに自動的に配布する。20台のマシンに手動で
/etc/sudoersを同期する必要はもうない。 - SSH公開鍵の一元管理 — FreeIPAにキーを保存し、クライアントはSSSD経由で取得する。キーの追加や失効は10秒もかからず、フリート全体に即座に反映される。
- 組み込みCA — サービス証明書の発行と更新を処理する。スタンドアロンCAを運用したり、自己署名証明書をインフラに散乱させるよりずっとクリーンだ。
- Web UI + CLI — 日常的なタスク(ユーザー追加、パスワードリセット、グループメンバーシップ変更)はブラウザから1分以内にできる。
注意すべき点
- リソース要件 — サーバーには最低でも2 vCPUと4 GB RAMを用意すること。月5ドルのVPSでは足りない。
- DNSへの依存 — Kerberosは名前解決に厳格だ。DNSが壊れると認証も壊れる。FreeIPAは独自のDNSゾーンを管理するので助かるが、インストーラーを実行する前にゾーン委任を設計しておくこと。
- 学習コスト — レルム、プリンシパル、キータブ——初めて触れる概念ばかりだ。理解できるまで数時間の予習を見込んでおくこと。
- HAには設計が必要 — FreeIPAサーバーが1台だと単一障害点になる。本番環境では最低1台のレプリカを用意すること。
小規模チームへの推奨構成
5〜50人のチームが10〜100台のLinuxサーバーを管理する場合、以下の構成がシンプルさと耐障害性のバランスが取れている。Linuxサーバー強化チェックリストと組み合わせることで、より堅牢な防御が実現できる:
- FreeIPAプライマリ1台 + レプリカ1台——どちらもプライベートネットワークまたは専用管理VLANに配置
- 全本番マシンを
sssd経由でFreeIPAクライアントとして参加 - 内部DNSはFreeIPAで管理(例:
internal.example.com) - SSHキーはFreeIPAに保存し、動的に取得——
authorized_keysファイルの同期は不要 - 開発、ステージング、本番のアクセスを分けるHBACルール
構築手順
ステップ1:FreeIPAサーバーのインストール
RHEL 9、Rocky Linux 9、またはAlmaLinux 9が最もサポートされている対象だ。何かを実行する前に適切なFQDNを設定すること:
# ホスト名を設定
hostnamectl set-hostname ipa.internal.example.com
# /etc/hostsを更新
echo "192.168.1.10 ipa.internal.example.com ipa" >> /etc/hosts
# インストール
dnf install -y freeipa-server freeipa-server-dns
# インストーラーを実行
ipa-server-install \
--domain=internal.example.com \
--realm=INTERNAL.EXAMPLE.COM \
--ds-password=YourDirManagerPass \
--admin-password=YourAdminPass \
--setup-dns \
--auto-forwarders \
--unattended
インストーラーの完了には5〜10分かかる。結果を確認する:
ipactl status
ステップ2:ユーザーとグループの作成
サーバーが起動したら、ログインして最初のユーザーを作成する。https://ipa.internal.example.comのWeb UIでも問題ないが、スクリプト化にはCLIの方が速い:
# 管理者として認証
kinit admin
# ユーザーを作成
ipa user-add jdoe \
--first=John \
--last=Doe \
[email protected] \
--shell=/bin/bash
# 初期パスワードを設定
ipa passwd jdoe
# グループを作成
ipa group-add devops --desc="DevOpsエンジニア"
# ユーザーをグループに追加
ipa group-add-member devops --users=jdoe
ステップ3:FreeIPAへのSSHキーの保存
初めて見るシステム管理者が最も驚く機能だ。一度キーをアップロードすれば、どこでも使えるようになる:
# ユーザーのSSH公開鍵をアップロード
ipa user-mod jdoe --sshpubkey="$(cat /home/jdoe/.ssh/id_ed25519.pub)"
クライアントマシンのSSSDはログイン時に自動的にキーを取得する。同期するファイルも、cronジョブも、ずれも発生しない。
ステップ4:LinuxクライアントをFreeIPAに参加させる
一元管理下に置きたい各サーバーで以下を実行する:
# クライアントツールをインストール
dnf install -y freeipa-client
# ドメインに参加
ipa-client-install \
--domain=internal.example.com \
--server=ipa.internal.example.com \
--realm=INTERNAL.EXAMPLE.COM \
--principal=admin \
--password=YourAdminPass \
--mkhomedir \
--unattended
参加後は、ローカルアカウントなしで、FreeIPAのユーザーが一元管理された認証情報でそのマシンにSSH接続できるようになる。
ステップ5:HBACルールの設定
新規インストール直後は、全FreeIPAユーザーが全登録ホストにアクセスできる状態になっている。すぐに無効化すること:
# 許可的なデフォルトルールを無効化
ipa hbacrule-disable allow_all
# ルールを作成:devopsグループが本番サーバーにアクセスできる
ipa hbacrule-add allow_devops_prod \
--desc="DevOpsの本番ホストへのアクセス"
ipa hbacrule-add-user allow_devops_prod --groups=devops
ipa hbacrule-add-host allow_devops_prod --hosts=prod-web-01.internal.example.com
ipa hbacrule-add-service allow_devops_prod --hbacsvcs=sshd
# ルールを適用する前にアクセスをシミュレート
ipa hbactest \
--user=jdoe \
--host=prod-web-01.internal.example.com \
--service=sshd
ステップ6:sudoルールの一元化
sudoersのスニペットを手動で配布する必要はもうない。ルールを一度定義すれば、SSSDが伝播を担当する:
# devops用のsudoルールを作成
ipa sudorule-add devops_all_commands \
--desc="DevOpsはrootとして全コマンドを実行可能"
ipa sudorule-add-user devops_all_commands --groups=devops
ipa sudorule-add-host devops_all_commands --hostgroups=ipaservers
ipa sudorule-mod devops_all_commands --cmdcat=all
ipa sudorule-mod devops_all_commands --runasusercat=all
SSSDは次のキャッシュ更新時——通常60秒以内——にこれを反映する。visudoも不要、20台のサーバーにSSH接続する必要もない。
ステップ7:レプリカのセットアップ
本番環境でFreeIPAサーバーを1台だけにすべきではない。2台目のマシンでのレプリカインストールは簡単だ:
# FreeIPAサーバーパッケージをインストール
dnf install -y freeipa-server
# レプリカとして参加
ipa-replica-install \
--setup-ca \
--setup-dns \
--principal=admin \
--admin-password=YourAdminPass
レプリケーションはデフォルトで同期的に行われ、通常1秒以内に落ち着く。プライマリがダウンした場合、クライアントのSSSDは自動的にレプリカにフェイルオーバーする——手動の介入は不要だ。
FreeIPAを本番運用して学んだこと
- HBACルールは必ず
ipa hbactestで事前検証すること。 代替ルールが準備できていない状態でallow_allを無効化して、自分でサーバーからロックアウトされたことがある。シミュレーションコマンドはまさにこのために存在する——必ず使うこと。 - Kerberosチケットの有効期限を監視すること。 デフォルトの有効期間は24時間だ。Kerberos認証に依存する長時間実行ジョブは、チケットが期限切れになると停止する。サービスアカウントには
k5startまたはキータブを使うこと。 - DNSの検証を省略しないこと。
ipa dns-checkを実行し、クライアントを参加させる前に全ての警告を修正すること。DNSの問題はプレッシャーのかかる状況でデバッグが非常に困難な、不可解なKerberosエラーを引き起こす。 - SSSDのオフラインキャッシュをチューニングすること。 FreeIPAサーバーに一時的にアクセスできない場合、SSSDはキャッシュされた認証情報にフォールバックするが、それも期限切れになる。接続が失われる可能性があるマシンの
/etc/sssd/sssd.confにcache_credentials = Trueとkrb5_store_password_if_offline = Trueを設定すること。 - オフボーディングが非常に簡単になる。 コマンド1つで、登録済みの全マシンでユーザーのアクセスを即座に無効化できる:
ipa user-disable jdoe。二段階認証(2FA)と組み合わせれば、この機能だけでFreeIPA全体の導入が正当化されることも多い。

