Linux で Windows 流 SSO——ドメイン参加不要

Kerberos · SSO · Linux

Linux で Windows 流 SSO——ドメイン参加不要

ドメイン参加はマシンにコンピューターアカウントを与える。ユーザーチケットはそもそもそれを必要としなかった。

ドメイン参加した Windows マシンは社内 Web アプリに黙ってログインする。Kerberos チケット、SPNEGO ハンドシェイク、それで終わり——ログインフォームを見ることは一度もない。問題は、AD が存在すら知らない Linux マシンで同じ芸当ができるかどうかだった。

できる。ドメイン参加はマシンアカウントのためのものだ。ユーザーチケットに必要なのは三つだけ:Kerberos クライアント、5行の設定、そしてパスワード。ここに旅の全体を記す。二度顔から転んだ場所も含めて。

セットアップ

shell
sudo apt install krb5-user

続いて /etc/krb5.conf:

/etc/krb5.conf
[libdefaults]
    default_realm = EXAMPLE.COM
    dns_lookup_kdc = true
    dns_lookup_realm = true
    rdns = false

これだけだ。KDC のアドレスはハードコードしない——AD がドメインコントローラーを DNS に公開しており、クライアントは自力でそれを見つける:

shell
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 における kdcadmin_server の区別は? 消える。どの DC もすべてをこなす。

チケットを取る——そして顔面から転倒 その1

最初の試み:

shell
kinit myuser@example.com

結果:空行。プロンプトもエラーも、何もない。ただこちらを見つめ返すカーソルだけ。Enter を押すとまた別の空行が出た。素晴らしいソフトウェアだ。

問題:@ より後ろはすべて Kerberos のレルムであり、レルムは大文字で書く。 example.com はドメインのように見える——自分のメールアドレスにさえ見える——が、Kerberos にとっては未知のレルムであり、それを伝える代わりにただ……黙り込んだのだ。

修正はほとんど侮辱的なほど単純だ:

shell
kinit myuser
Password:

レルムを完全に省くと、krb5.conf の default_realm が効いてくる。突然、本物の、目に見える Password: プロンプトが現れる——正しいレルムと話していることがこれでわかる。パスワードを入力し(sudo と同様に入力は隠れる)、Enter を押すと:

shell
klist
# Default principal: myuser@EXAMPLE.COM
# krbtgt/EXAMPLE.COM@EXAMPLE.COM   valid ~10h

krbtgt のエントリがあるということは、TGT を保持しているということだ。暗号学的に言えば、これでドメインにログインしたことになる。

kinit がまた誤動作したら、これが実際に何をしているかを正確に見せてくれる——DNS ルックアップ、どの DC に接続しているか、どこで死んでいるか:

shell
KRB5_TRACE=/dev/stdout kinit myuser

顔面から転倒 その2:「Unable to locate package nc」

ポート 88 がそもそも到達可能かを確認したかった。apt install nc——そんなパッケージは無い。Debian/Ubuntu では netcat-openbsd という名前だ。あるいはインストール自体を丸ごと飛ばしてもいい。bash にはネットワーク機能が組み込まれている:

shell
timeout 3 bash -c 'cat < /dev/null > /dev/tcp/dc01.example.com/88' && echo OPEN || echo CLOSED

ブラウザに教え込む

Windows のブラウザはイントラネットゾーンを信頼しているため、自動でネゴシエートする。Linux のブラウザは、そう指示されるまで誰も信頼しない:

Firefoxabout:confignetwork.negotiate-auth.trusted-uris.example.com

Chrome/Chromium/etc/opt/chrome/policies/managed/kerberos.json:

/etc/opt/chrome/policies/managed/kerberos.json
{ "AuthServerAllowlist": "*.example.com" }

curl ——もちろん curl にもできる:

shell
curl --negotiate -u : https://internal-app.example.com/

社内サイトを開く。ログインできる。静かに。ドメインに参加していないマシンで。

非常に満足感がある。

細かい注意点

  • 時計: Kerberos が許容するずれは約5分。NTP を動かし続けること。さもないと何も動かず、エラーもその理由を教えてくれない。
  • FQDN を使うこと: ホスト名はサービスの SPN と一致していなければならない。IP やランダムなエイリアスは NTLM にフォールバックするか失敗する。
  • チケットは期限切れになる (約10時間)。毎日 kinit をやり直すか、k5start、keytab、あるいは sssd + KCM で自動化すること。
まとめ

大文字のレルムを持つ krb5.confkinit myuser → ブラウザの許可リスト。三段階、ドメイン参加ゼロ、そして Windows がずっと裏でやっていたのと同じ静かなチケットダンス。

そして、もし kinit が Password: の代わりに空行で応えてきたら——レルムを確認すること。大文字か、さもなくば無だ。

コメント (0)

まだコメントがありません。最初のコメントを書いてみましょう!

コメントを書く