Kerberosで共有フォルダやWebサイトにアクセスするとき、DCは「どのサービス向けのチケットを作るのか」を知る必要があります。そのときに使われる名前がSPN(Service Principal Name、サービスプリンシパル名)です。ふだんは意識しなくても動いていますが、SPNがずれていると「なぜかNTLMになる」「アクセスが拒否される」といったトラブルになります。この記事では、SPNの書き方、登録されている場所、Kerberosの中での使われ方、つまずきやすい場面を順に見ていきます。
- SPNの書き方と、どのアカウントに登録されているのか
- KerberosのチケットとSPNの関係
- SPNの未登録・重複・登録先の間違いで起きることと、確かめ方
SPNとは:サービスに付けた名前
SPNは、ネットワーク上のサービスを1つずつ見分けるための名前です。そしてもう1つ大事な役割があります。SPNは「そのサービスがどのアカウントで動いているか」を結び付けています。DCはSPNを手がかりにアカウントを探し、そのアカウントの鍵でチケットを暗号化します。
宅配便にたとえると、SPNは荷物の宛名です。宛名が正しければ、荷物(チケット)は受取人だけが開けられる箱に入れて届けられます。宛名が登録されていなければ配達できず、宛名が別の人のところに登録されていれば、受取人は箱を開けられません。
SPNは、次のような形で書きます。
| SPNの例 | どのサービスか |
|---|---|
cifs/fs01.corp.example.com | ファイル共有(SMB) |
HOST/fs01.corp.example.com | そのコンピュータの標準的なサービス全般 |
HTTP/web01.corp.example.com | Webサイト(IISなど) |
MSSQLSvc/sql01.corp.example.com:1433 | SQL 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はフォレストの中で一意でなければならないからです。
| サービスの動かし方 | SPNの登録先 |
|---|---|
| Local System や Network Service で動くサービス (ファイル共有など、OSのサービスの多く) | そのサーバのコンピュータアカウント。ドメインに参加したときに HOST/FS01 や HOST/fs01.corp.example.com などが自動で登録される |
| ドメインユーザーやgMSAで動くサービス (Webアプリ、SQL Serverなど) | そのサービスが使うアカウント。製品が自動で登録することもあるが、管理者が登録することも多い |
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も HOST で代わりになるサービスクラスの1つです。ただし、IISのアプリケーションプールをドメインユーザーやgMSAで動かしている場合は、チケットをそのアカウントの鍵で作ってもらう必要があります。そのため、HTTP/web01.corp.example.com のSPNを、そのアカウントに明示的に登録します。
KerberosでのSPNの使われ方
ファイルサーバの共有フォルダを開くときの流れで見てみます。KerberosではPCが最初にDCから「TGT」という入場券を受け取っていて、サービスを使うときはTGTを見せて、そのサービス用の「サービスチケット」をもらいます。SPNが登場するのは、このサービスチケットを頼むところです。
- 利用者が
\\fs01.corp.example.com\shareを開きます。 - PCは、接続先の名前からSPN(
cifs/fs01.corp.example.com)を組み立てます。 - PCはDCに、そのSPNのサービスチケットを頼みます。
- DCはADの中で、そのSPN(またはそれに当たるHOSTのSPN)を持つアカウントを探します。ここでは FS01$ です。
- DCは、FS01$ の鍵で暗号化したサービスチケットを返します。
- PCは、SMBの接続の中でサービスチケットをファイルサーバに渡します。
- ファイルサーバは自分の鍵でチケットを復号します。復号できれば、DCが本物と認めたチケットだと分かります。
ポイントは⑤と⑦です。チケットは、SPNを持っているアカウントの鍵で暗号化されます。そのため、実際にサービスを動かしているアカウントにSPNが付いていないと、サーバはチケットを開けません。
DCとサーバは同じ鍵を持っている
⑤でDCがFS01$の鍵で暗号化し、⑦でFS01が自分の鍵で復号できるのは、DCとFS01が同じ鍵を持っているからです。この鍵は、コンピュータアカウントFS01$のパスワードから作られます。
| だれが | どの鍵を、どこに持っているか |
|---|---|
| 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がない | 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も新しいアカウントに移します。
ファイルサーバを 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」という攻撃です。
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のSPN | cifs や http など多くのサービスクラスの代わりになる |
| Kerberosでの役割 | DCはSPNを持つアカウントの鍵でサービスチケットを暗号化する |
| つまずく場面 | 未登録(NTLMに切り替わる)、重複(失敗)、別のアカウント(サーバが復号できない) |
| セキュリティ | SPNを持つユーザーアカウントはKerberoastingに狙われる。gMSAや長いパスワードで守る |
Kerberosのトラブルを調べるときは、「PCがどのSPNを頼んだか」「そのSPNがどのアカウントに付いているか」「サービスは実際にどのアカウントで動いているか」の3つをそろえて見ると、原因に早くたどり着けます。
- Service principal names(Microsoft Learn)
- Name Formats for Unique SPNs(Microsoft Learn)
- How a Service Registers its SPNs(Microsoft Learn)
- How to configure SPN(Microsoft Learn)
- setspn(Microsoft Learn)
- SPN and UPN uniqueness(Microsoft Learn)
- Kerberos generates KDC_ERR_S_PRINCIPAL_UNKNOWN or KDC_ERR_PRINCIPAL_NOT_UNIQUE error(Microsoft Learn)
- Kerberos Service Principal Name on Wrong Account(Microsoft Learn)
- The KDC encountered duplicate names(KDCのイベント11の例)(Microsoft Learn)
- Kerberos clients allow IPv4 and IPv6 address hostnames in SPNs(Microsoft Learn)
- SMB file server share access is unsuccessful through DNS CNAME alias(Microsoft Learn)
- netdom computername(Microsoft Learn)
- klist(Microsoft Learn)
- Microsoft Defender for Identity classic alerts(Kerberoastingの説明と対策)(Microsoft Learn)
- Group Managed Service Accounts overview(Microsoft Learn)
- Manage group Managed Service Accounts(Microsoft Learn)
- Service accounts(Microsoft Learn)
- Event ID 5722 is logged on your domain controller(コンピュータアカウントのパスワード)(Microsoft Learn)
- Credentials processes in Windows authentication(LSAシークレット)(Microsoft Learn)
- Account Database(パスワードから作った鍵を保存すること)(Microsoft Learn)
- Secure group managed service accounts(Microsoft Learn)
- Delegated Managed Service Accounts overview(Microsoft Learn)
コメント