Linux で Windows 流 SSO——ドメイン参加不要
ドメイン参加はマシンにコンピューターアカウントを与える。ユーザーチケットはそもそもそれを必要としなかった。
ドメイン参加した Windows マシンは社内 Web アプリに黙ってログインする。Kerberos チケット、SPNEGO ハンドシェイク、それで終わり——ログインフォームを見ることは一度もない。問題は、AD が存在すら知らない Linux マシンで同じ芸当ができるかどうかだった。
できる。ドメイン参加はマシンアカウントのためのものだ。ユーザーチケットに必要なのは三つだけ:Kerberos クライアント、5行の設定、そしてパスワード。ここに旅の全体を記す。二度顔から転んだ場所も含めて。
セットアップ
sudo apt install krb5-user
続いて /etc/krb5.conf:
[libdefaults]
default_realm = EXAMPLE.COM
dns_lookup_kdc = true
dns_lookup_realm = true
rdns = falseこれだけだ。KDC のアドレスはハードコードしない——AD がドメインコントローラーを DNS に公開しており、クライアントは自力でそれを見つける:
dig +short SRV _kerberos._tcp.example.com # 0 100 88 dc01.example.com. # 0 100 88 dc02.example.com.
(社内 DNS のみ。パブリックリゾルバーは何も知らない。VPN 上では、Kerberos を疑う前に resolvectl status を確認すること。)
おまけの AD 知識:どの DC も同時に KDC であり、パスワードサーバーであり、admin/LDAP エンドポイントでもある。MIT-Kerberos における kdc と admin_server の区別は? 消える。どの DC もすべてをこなす。
チケットを取る——そして顔面から転倒 その1
最初の試み:
kinit myuser@example.com
結果:空行。プロンプトもエラーも、何もない。ただこちらを見つめ返すカーソルだけ。Enter を押すとまた別の空行が出た。素晴らしいソフトウェアだ。
問題:@ より後ろはすべて Kerberos のレルムであり、レルムは大文字で書く。 example.com はドメインのように見える——自分のメールアドレスにさえ見える——が、Kerberos にとっては未知のレルムであり、それを伝える代わりにただ……黙り込んだのだ。
修正はほとんど侮辱的なほど単純だ:
kinit myuser Password:
レルムを完全に省くと、krb5.conf の default_realm が効いてくる。突然、本物の、目に見える Password: プロンプトが現れる——正しいレルムと話していることがこれでわかる。パスワードを入力し(sudo と同様に入力は隠れる)、Enter を押すと:
klist # Default principal: myuser@EXAMPLE.COM # krbtgt/EXAMPLE.COM@EXAMPLE.COM valid ~10h
krbtgt のエントリがあるということは、TGT を保持しているということだ。暗号学的に言えば、これでドメインにログインしたことになる。
kinit がまた誤動作したら、これが実際に何をしているかを正確に見せてくれる——DNS ルックアップ、どの DC に接続しているか、どこで死んでいるか:
KRB5_TRACE=/dev/stdout kinit myuser
顔面から転倒 その2:「Unable to locate package nc」
ポート 88 がそもそも到達可能かを確認したかった。apt install nc——そんなパッケージは無い。Debian/Ubuntu では netcat-openbsd という名前だ。あるいはインストール自体を丸ごと飛ばしてもいい。bash にはネットワーク機能が組み込まれている:
timeout 3 bash -c 'cat < /dev/null > /dev/tcp/dc01.example.com/88' && echo OPEN || echo CLOSED
ブラウザに教え込む
Windows のブラウザはイントラネットゾーンを信頼しているため、自動でネゴシエートする。Linux のブラウザは、そう指示されるまで誰も信頼しない:
Firefox — about:config → network.negotiate-auth.trusted-uris → .example.com
Chrome/Chromium — /etc/opt/chrome/policies/managed/kerberos.json:
{ "AuthServerAllowlist": "*.example.com" }curl ——もちろん curl にもできる:
curl --negotiate -u : https://internal-app.example.com/
社内サイトを開く。ログインできる。静かに。ドメインに参加していないマシンで。
非常に満足感がある。
細かい注意点
- 時計: Kerberos が許容するずれは約5分。NTP を動かし続けること。さもないと何も動かず、エラーもその理由を教えてくれない。
- FQDN を使うこと: ホスト名はサービスの SPN と一致していなければならない。IP やランダムなエイリアスは NTLM にフォールバックするか失敗する。
- チケットは期限切れになる (約10時間)。毎日 kinit をやり直すか、
k5start、keytab、あるいは sssd + KCM で自動化すること。
大文字のレルムを持つ krb5.conf → kinit myuser → ブラウザの許可リスト。三段階、ドメイン参加ゼロ、そして Windows がずっと裏でやっていたのと同じ静かなチケットダンス。
そして、もし kinit が Password: の代わりに空行で応えてきたら——レルムを確認すること。大文字か、さもなくば無だ。