【図解】SPNとは?Kerberosがサービスを見分ける名前を初心者向けに解説

Kerberosで共有フォルダやWebサイトにアクセスするとき、DCは「どのサービス向けのチケットを作るのか」を知る必要があります。そのときに使われる名前がSPN(Service Principal Name、サービスプリンシパル名)です。ふだんは意識しなくても動いていますが、SPNがずれていると「なぜかNTLMになる」「アクセスが拒否される」といったトラブルになります。この記事では、SPNの書き方、登録されている場所、Kerberosの中での使われ方、つまずきやすい場面を順に見ていきます。

この記事でわかること
  1. SPNの書き方と、どのアカウントに登録されているのか
  2. KerberosのチケットとSPNの関係
  3. SPNの未登録・重複・登録先の間違いで起きることと、確かめ方

SPNとは:サービスに付けた名前

SPNは、ネットワーク上のサービスを1つずつ見分けるための名前です。そしてもう1つ大事な役割があります。SPNは「そのサービスがどのアカウントで動いているか」を結び付けています。DCはSPNを手がかりにアカウントを探し、そのアカウントの鍵でチケットを暗号化します。

宅配便にたとえると、SPNは荷物の宛名です。宛名が正しければ、荷物(チケット)は受取人だけが開けられる箱に入れて届けられます。宛名が登録されていなければ配達できず、宛名が別の人のところに登録されていれば、受取人は箱を開けられません。

SPNは、次のような形で書きます。

SPNの書き方MSSQLSvcサービスクラスサービスの種類/sql01.corp.example.comホスト名どのコンピュータか:1433ポート(省略可)同じホストに複数あるとき基本の形は「サービスクラス/ホスト名」。ポートや、サービス名(4つ目の要素)は同じホストに同じ種類のサービスが複数あるときなど、区別が必要なときだけ付ける
図1 SPNの書き方。「サービスクラス/ホスト名」が基本で、必要なときだけポートなどを付ける
SPNの例どのサービスか
cifs/fs01.corp.example.comファイル共有(SMB)
HOST/fs01.corp.example.comそのコンピュータの標準的なサービス全般
HTTP/web01.corp.example.comWebサイト(IISなど)
MSSQLSvc/sql01.corp.example.com:1433SQL Server(TCP 1433)
TERMSRV/rds01.corp.example.comリモートデスクトップ
ldap/dc01.corp.example.comドメインコントローラのLDAP

ホスト名には、FQDN(fs01.corp.example.com)とNetBIOS名(FS01)のどちらも使えます。そのため、1つのサービスに両方の形でSPNを登録しておくのが一般的です。WindowsのSPNは大文字と小文字を区別しません(Linuxなど、区別するシステムもあります)。

SPNはどこに登録されているのか

SPNは、Active Directoryのアカウントの servicePrincipalName という属性に入っています。1つのアカウントに複数のSPNを登録できますが、同じSPNを複数のアカウントに登録することはできません。SPNはフォレストの中で一意でなければならないからです。

Active Directory各アカウントの servicePrincipalName 属性コンピュータアカウントFS01$(ファイルサーバ)HOST/FS01HOST/fs01.corp.example.com…(ドメイン参加で自動登録)cifs などは HOST が代わりになるサービス用のアカウントsvc-web(Webアプリの実行アカウント)HTTP/web01HTTP/web01.corp.example.com…(管理者が登録)ドメインユーザーやgMSAで動くサービス
図2 SPNの登録先。コンピュータアカウントと、サービス用のアカウントの例
サービスの動かし方SPNの登録先
Local System や Network Service で動くサービス
(ファイル共有など、OSのサービスの多く)
そのサーバのコンピュータアカウント。ドメインに参加したときに HOST/FS01 や HOST/fs01.corp.example.com などが自動で登録される
ドメインユーザーやgMSAで動くサービス
(Webアプリ、SQL Serverなど)
そのサービスが使うアカウント。製品が自動で登録することもあるが、管理者が登録することも多い
gMSAとは

gMSA(group Managed Service Account、グループ管理サービスアカウント)は、サービスを動かすために用意されたActive Directoryのアカウントの種類です。ふつうのユーザーアカウントをサービス用に使うと、管理者がパスワードを決めて、各サーバのサービスの設定に入力し、変えるときは全部のサーバで入れ直す必要があります。gMSAでは、このパスワードの管理をWindowsが引き受けます。

  • パスワードはDCが計算して管理し、許可したサーバだけがDCから自動で受け取る。管理者はパスワードを知らなくてよい
  • パスワードは240バイトのランダムな値で、既定では30日ごとに自動で変わる
  • 複数のサーバで同じgMSAを使えるので、負荷分散した複数台のWebサーバを1つのアカウントで動かせる
  • 作るときにSPNも一緒に登録できる。アカウント名の最後には $ が付く(例:CORP\gmsa-web$)

使うには、ドメインに「KDSルートキー」を一度作っておく必要があります。また、フェールオーバークラスターのサービスそのものなど、gMSAに対応していないものもあります。

コンピュータアカウントには、cifs/… のSPNが見当たらないことがよくあります。これは、HOST のSPNが cifs、http、rpcss、schedule など多くのサービスクラスの代わりになるためです。cifs/fs01.corp.example.com のチケットを頼まれたDCは、HOST/fs01.corp.example.com を持つ FS01$ を見つけて、そのアカウント向けのチケットを作ります。

HTTPのSPNには注意

HTTPも HOST で代わりになるサービスクラスの1つです。ただし、IISのアプリケーションプールをドメインユーザーやgMSAで動かしている場合は、チケットをそのアカウントの鍵で作ってもらう必要があります。そのため、HTTP/web01.corp.example.com のSPNを、そのアカウントに明示的に登録します。

KerberosでのSPNの使われ方

ファイルサーバの共有フォルダを開くときの流れで見てみます。KerberosではPCが最初にDCから「TGT」という入場券を受け取っていて、サービスを使うときはTGTを見せて、そのサービス用の「サービスチケット」をもらいます。SPNが登場するのは、このサービスチケットを頼むところです。

PCuser01DC(KDC)FS01ファイルサーバ① \\fs01.corp.example.com\share を開く② SPN を組み立てる:cifs/fs01.corp.example.com③ このSPNのチケットをくださいTGSのリクエスト(TGTを添えて)④ ADを検索 → HOST/fs01… を持つ FS01$ が該当⑤ FS01$ の鍵で暗号化したサービスチケット⑥ サービスチケットを渡すSMBのSession Setupの中⑦ 自分の鍵で復号できた → 本物
図3 KerberosでのSPNの使われ方。DCはSPNを手がかりに、どのアカウントの鍵でチケットを作るかを決める
  1. 利用者が \\fs01.corp.example.com\share を開きます。
  2. PCは、接続先の名前からSPN(cifs/fs01.corp.example.com)を組み立てます。
  3. PCはDCに、そのSPNのサービスチケットを頼みます。
  4. DCはADの中で、そのSPN(またはそれに当たるHOSTのSPN)を持つアカウントを探します。ここでは FS01$ です。
  5. DCは、FS01$ の鍵で暗号化したサービスチケットを返します。
  6. PCは、SMBの接続の中でサービスチケットをファイルサーバに渡します。
  7. ファイルサーバは自分の鍵でチケットを復号します。復号できれば、DCが本物と認めたチケットだと分かります。

ポイントは⑤と⑦です。チケットは、SPNを持っているアカウントの鍵で暗号化されます。そのため、実際にサービスを動かしているアカウントにSPNが付いていないと、サーバはチケットを開けません。

DCとサーバは同じ鍵を持っている

⑤でDCがFS01$の鍵で暗号化し、⑦でFS01が自分の鍵で復号できるのは、DCとFS01が同じ鍵を持っているからです。この鍵は、コンピュータアカウントFS01$のパスワードから作られます。

利用者のPCDCFS01LSASSのメモリuser01 の鍵サインインのときにパスワードから作るFS01$ の鍵は持たないADのデータベースuser01 の鍵FS01$ の鍵svc-web の鍵 …LSAシークレットFS01$ の鍵同じ鍵ドメイン参加で決め、30日ごとに自動で更新サービスチケット(cifs/fs01…)は FS01$ の鍵で暗号化開けられるのは DC と FS01 だけ。PC は中身を読めず、そのまま運ぶ
図4 だれがどの鍵を持っているか。サービスチケットを開けられるのは、DCとそのサービスのアカウントだけ
だれがどの鍵を、どこに持っているか
DCドメインのすべてのアカウント(ユーザー、コンピュータ、サービス用)の鍵を、ADのデータベースに持っている。保存しているのはパスワードそのものではなく、パスワードから作った鍵
ファイルサーバ(FS01)自分のコンピュータアカウントFS01$のパスワードを、LSAシークレットという保護された場所に持っている。ドメインに参加したときにFS01とドメインの間で決めたもので、既定では30日ごとにFS01が自動で変え、そのたびにDCにも書き込む
サービス用のアカウントで動くサーバサービスの設定に入力したパスワード(gMSAならDCから受け取ったパスワード)を持っている
利用者のPCサインインしたユーザーのパスワードから作った鍵は持っているが、FS01$の鍵は持っていない。そのため、サービスチケットの中身は読めず、そのまま運ぶだけ

つまり、サービスチケットを開けられるのは、鍵を知っているDCと、SPNを持つアカウントで動いているサーバの2者だけです。サーバがチケットを開けられたということは、そのチケットを作ったのが鍵を知っている本物のDCだという証明になります。SPNが別のアカウントに付いていると、DCはそちらの鍵でチケットを作ってしまい、サーバは開けられなくなります。

どのSPNを使うかは、接続先として指定した名前で決まります。\\192.168.1.10\share のようにIPアドレスで開いた場合、Windowsは既定ではKerberosを試さず、NTLMを使います。Kerberosで認証させたいときは、ホスト名(できればFQDN)で接続します。

SPNでつまずく3つの場面

SPNのトラブルは、大きく3つに分けられます。

SPNがない登録されていないSPNが2つある重複しているSPNが別の場所違うアカウントに付いているcifs/fs01 … 見つからないKDC_ERR_S_PRINCIPAL_UNKNOWNNTLMに切り替わる(NTLMを止めていれば アクセスできない)同じSPNが2つのアカウントにFS01$FS02$どちらの鍵で作ればよいか分からない認証が失敗するKDCのイベント11などsvc-old の鍵で暗号化されているFS01 は復号できないアクセスが拒否されるKRB_AP_ERR_MODIFIED
図5 SPNでつまずく3つの場面
状態何が起きるか直し方
SPNがないDCがアカウントを見つけられず、KDC_ERR_S_PRINCIPAL_UNKNOWN になる。多くの場合はNTLMに切り替わって動くので、気づきにくいサービスを動かしているアカウントにSPNを登録する
SPNが重複している同じSPNが複数のアカウントにあり、DCがどちらの鍵を使えばよいか決められない。KDC_ERR_PRINCIPAL_NOT_UNIQUE になり、DCのシステムログにKDCのイベントID 11が記録される正しいアカウント以外からSPNを削除する
SPNが別のアカウントに付いているDCは、SPNを持つ(間違った)アカウントの鍵でチケットを作る。サーバはそれを復号できず、アクセスが拒否される。サーバ側にKerberosのイベントID 4(KRB_AP_ERR_MODIFIED)が記録される間違ったアカウントからSPNを削除し、正しいアカウントに登録し直す

3つ目は、サービスの実行アカウントを変えたときによく起きます。たとえば、SQL Serverの実行アカウントをドメインユーザーからgMSAに変えたのに、SPNが前のアカウントに残っていると、このパターンになります。実行アカウントを変えたら、SPNも新しいアカウントに移します。

別名(CNAME)でアクセスするとき

ファイルサーバを files.corp.example.com のような別名で使いたいとき、DNSのCNAMEレコードだけを作ると、別名のSPNがないなどの理由でアクセスできないことがあります。Microsoftは、CNAMEではなく netdom computername で別名(代替のコンピュータ名)を付ける方法を勧めています。netdomで別名を付けると、別名の HOST のSPNも登録され、SMBサーバもその名前での接続を受け付けるようになります。

SPNの登録とセキュリティ

SPNを書き込めるのは、既定ではDomain Adminsなどの管理者だけです。例外として、コンピュータは自分のホスト名を使ったSPN(「サービスクラス/自分のDNS名」の形)を、自分のコンピュータアカウントに登録できます。Local Systemで動くサービスがSPNを自動で登録できるのはこのためです。管理者以外に登録を任せたいときは、「servicePrincipalName の検証された書き込み」の権限を委任します。

SPNを登録するときは、setspn -A ではなく setspn -S を使います。-S は、同じSPNがほかのアカウントにないことを確かめてから登録します。なお、Windows Server 2012 R2以降のDCは、重複するSPNの登録そのものを拒否します。

もう1つ知っておきたいのが、SPNを持つアカウントを狙う「Kerberoasting」という攻撃です。

ドメインユーザー(乗っ取られたPC)DC(KDC)① SPNの一覧を調べ、チケットを要求② サービスチケットsvc-web のパスワードから作った鍵で暗号化③ 持ち帰ったチケットを手元で総当たりし、パスワードを割り出す(Kerberoasting)・チケットの要求そのものは、どのドメインユーザーにもできる正規の操作・狙われるのは、人が決めた短いパスワードのユーザーアカウントにSPNが付いている場合・対策:長く複雑なパスワード、gMSA(パスワードを自動で長くランダムにする)への置き換え
図6 Kerberoastingのしくみ。SPNを持つユーザーアカウントのパスワードが弱いと、手元で割り出される

SPNを持つアカウントのサービスチケットは、どのドメインユーザーでも要求できます。チケットは、そのアカウントのパスワードから作った鍵で暗号化されています。攻撃者はチケットを持ち帰り、DCに気づかれない手元のコンピュータでパスワードの総当たりをします。コンピュータアカウントやgMSAのパスワードは長くランダムなので現実的には割り出せませんが、人が決めた短いパスワードのユーザーアカウントは危険です。

対策内容
gMSAに置き換えるパスワードは240バイトのランダムな値で、30日ごとにWindowsが自動で変える(くわしくは前の「gMSAとは」を参照)
長く複雑なパスワードにするgMSAを使えないサービスのユーザーアカウントは、長いパスワードにする
不要なSPNを消す使っていないサービスのSPNがユーザーアカウントに残っていないか確かめる

Windows Server 2025では、従来のサービスアカウントから移行できるdMSA(delegated Managed Service Account)という種類のアカウントも追加されています。

確認に使うコマンド

SPNは setspn で確かめます。setspnは管理者として開いたコマンドプロンプトで実行します(AD DSの役割か、RSATのADツールが必要です)。

管理用PC(コマンドプロンプト・管理者):コンピュータアカウントに登録されているSPNを表示する

setspn -L FS01

管理用PC(コマンドプロンプト・管理者):サービス用のアカウントに登録されているSPNを表示する

setspn -L CORP\svc-web

管理用PC(コマンドプロンプト・管理者):指定したSPNを持つアカウントを探す

setspn -Q HTTP/web01.corp.example.com

管理用PC(コマンドプロンプト・管理者):ドメインの中で重複しているSPNを探す

setspn -X

管理用PC(コマンドプロンプト・管理者):重複がないことを確かめてからSPNを登録する

setspn -S HTTP/web01.corp.example.com CORP\svc-web

管理用PC(コマンドプロンプト・管理者):間違って登録したSPNを削除する

setspn -D HTTP/web01.corp.example.com CORP\svc-old

管理用PC(PowerShell・管理者):SPNを登録したgMSAを作る(WebServers グループのサーバだけがパスワードを受け取れる)

New-ADServiceAccount -Name gmsa-web -DNSHostName gmsa-web.corp.example.com -PrincipalsAllowedToRetrieveManagedPassword WebServers -ServicePrincipalNames "HTTP/web01.corp.example.com","HTTP/web01"

管理用PC(コマンドプロンプト・管理者):gMSAに登録されているSPNを表示する(名前の最後に $ を付ける)

setspn -L CORP\gmsa-web$

PC(コマンドプロンプト):指定したSPNのサービスチケットをDCに要求する

klist get cifs/fs01.corp.example.com

PC(コマンドプロンプト):手元のKerberosのチケットを削除する(SPNを直したあと、取り直させるため)

klist purge

ファイルサーバ(コマンドプロンプト・管理者):別名を付ける

netdom computername fs01.corp.example.com /add:files.corp.example.com

ファイルサーバ(コマンドプロンプト・管理者):それぞれの名前にDNSレコードとSPNがあるかを確かめる

netdom computername fs01.corp.example.com /verify

klist get でチケットを取れれば、そのSPNはDCに登録されています。取れなければ、エラーの内容からSPNがないのか重複しているのかを切り分けられます。SPNを直したあとは、PCに古いチケットが残っていることがあるので、klist purge してから試し直します。

まとめ

項目ポイント
SPNとはサービスを見分ける名前で、そのサービスを動かすアカウントと結び付いている
書き方「サービスクラス/ホスト名」が基本。必要なときだけポートなどを付ける
登録先ADのアカウントの servicePrincipalName 属性。フォレストの中で一意
HOSTのSPNcifs や http など多くのサービスクラスの代わりになる
Kerberosでの役割DCはSPNを持つアカウントの鍵でサービスチケットを暗号化する
つまずく場面未登録(NTLMに切り替わる)、重複(失敗)、別のアカウント(サーバが復号できない)
セキュリティSPNを持つユーザーアカウントはKerberoastingに狙われる。gMSAや長いパスワードで守る

Kerberosのトラブルを調べるときは、「PCがどのSPNを頼んだか」「そのSPNがどのアカウントに付いているか」「サービスは実際にどのアカウントで動いているか」の3つをそろえて見ると、原因に早くたどり着けます。

参考にした資料

コメント