Skip to content

MS_ServiceAndTaskAccountIssues

nishi_74322014 edited this page Aug 12, 2026 · 1 revision

サービス・タスク系のアカウント問題

概要

Windowsサービス全般の実行アカウント問題を中心とした
トラブルシュートについて説明します。

  • 通常、Windows サービスの実行アカウントとして
    サービスで使用されるビルトイン システム アカウント
    MS_BuiltInSystemAccount.md)が使用されます。

    • IISでは、「Network Service」を使用します。
    • タスク スケジューラでは、「System」(LocalSystem)を使用します。
  • このため、Windows サービスやタスク スケジューラからの実行では、
    普段意識していない OS や API の認証機構の存在を意識する必要があります。

補足(3 つのビルトイン アカウントの違い): 切り分けの前提として、
この 3 つの差を押さえておきたい。

アカウント ローカル権限 ネットワークでの見え方
LocalSystem 非常に強い(管理者以上) コンピュータ アカウントDOMAIN\HOST$
NetworkService 弱い(Users 相当) コンピュータ アカウント(同上)
LocalService 弱い 匿名(ネットワーク認証できない)

ここで重要なのは、LocalSystem / NetworkService は
ネットワーク越しには「コンピュータ アカウント」として振る舞う
という点である。
「ローカルでは全能なのに、共有フォルダにアクセスできない」という
典型的な症状はこれで説明できる。

なお LocalService はネットワーク上では匿名になるため、
認証が必要なリソースには一切アクセスできない。

実行アカウントの確認方法

以下を参照下さい。

補足(手早い確認手段): コードを書かずに調べるなら次が早い。

whoami /user /groups /priv    ← 実行アカウントと特権を一括表示

サービス側からは、タスク/サービスの中で
whoami /all > C:\temp\who.txt を実行させるのが確実である。
稼働中プロセスなら、タスク マネージャーの[詳細]タブに
「ユーザー名」列を追加しても確認できる。

実行アカウントの指定方法

runasコマンドで実行アカウントを指定する(アンマッチ)

一般的なアカウント

runas コマンドで一時的にほかのユーザー権限でプログラムを実行する事ができますが、
コマンドからパスワードは与えられず、ユーザに入力を求めるダイアログが表示されますので
非対話型のセッションから実行される Windows サービスやタスク スケジューラでは
アンマッチです。

ビルトイン システム アカウント

  • runas コマンドにはサービスで使用されるビルトイン システム アカウントを
    指定できません。
  • 既定で、サービスで使用されるビルトイン システム アカウントが利用されます。

移行メモ(誤字): 元ページの「指定きません」は「指定できません」の脱字である。

Windowsサービスの実行アカウントを指定する

IISやSQL Serverなど

IIS(のワーカ・プロセス)や SQL Serverなど、
専用の設定画面を持ち、ここから設定が可能です。

  • IIS
    • IIS 7.5(のワーカ・プロセス)からは、アプリケーション プール ID が導入され、
      既定で「Network Service」ではなく「DefaultAppPool」(仮想アカウント)が
      使用されます。
Windows Server 2003 Windows Vista
Windows Server 2008
Windows 7/Vista SP2
Windows Server 2008 R2
既定の匿名ユーザーID IUSR_<マシン名> IUSR IUSR
既定のワーカープロセスID NETWORK SERVICE NETWORK SERVICE アプリケーション プール ID
仮想アカウント
ワーカープロセスグループ IIS_WPG IIS_IUSRS IIS_IUSRS
  • アプリケーション プール ID の権限設定をする場合、
    IIS_AppPool\ApplicationPoolName ユーザか、IIS_IUSRS グループに対して
    権限を設定する。

    IIS 7 以降でのアプリケーションプールと権限について調べた - しばやん雑記
    http://blog.shibayan.jp/entry/20150127/1422369253

  • SQL Server

    • SQL Server のサービス開始アカウントは、
      SQL Server 構成マネージャーから変更する
      (サービス コンソールから直接変えると権限が壊れる)。

ASP.NET(偽装)

ASP.NETでは、偽装を使用する事によって、
実行アカウントを指定することもできます。

偽装には、

があります。

匿名アカウントを実行アカウントにする場合は偽装が必要になります。
通常は、IIS(のワーカ・プロセス)の実行アカウントで実行される。

補足(最新化:偽装は ASP.NET Core では使えない): <identity impersonate="true" />
という設定は .NET Framework 版の ASP.NET 固有であり、
ASP.NET Coreには存在しない

ASP.NET Core で同等のことをするには、

  • アプリケーション プールの ID そのものを変える(サーバ信頼モデル相当)
  • Windows 認証 + WindowsIdentity.RunImpersonated()
    区間的に偽装する(ベース クライアント モデル相当)

のいずれかになる。
移行時に見落としやすい非互換点なので注意が要る。

APIを使用した偽装

ASP.NETのように、偽装の機能が実装されている Windows サービスも
有りますが、Win32 API を使用して偽装することもできます(区間的、部分的な偽装)。

タスク スケジューラの実行アカウントを指定する

以下の KB にあるように、タスク スケジューラは実行アカウントを指定して
実行させる事ができます。

  • ユーザー アカウントにパスワードがないとタスク スケジューラでタスクが実行されない

コマンドからは以下の様に設定します。

  • at コマンド(現在は非推奨schtasks を使う)
  • schtasks コマンド

補足(at は廃止された): at コマンドは Windows 8 / Server 2012 以降
非推奨となり、現在の OS では実質使えない。
schtasks か、PowerShellScheduledTasks モジュール
New-ScheduledTask / Register-ScheduledTask)を使う。

パスワードを保存したくない場合は、
グループ管理サービス アカウント(gMSA) を使うと
パスワード管理を Active Directory 側に任せられる。
30 日ごとに AD が自動でパスワードを変更するため、
「サービス アカウントのパスワード有効期限切れで夜間バッチが止まる」
という定番の事故を防げる。

ネットワークの問題

ネットワーク間認証

  • サービスで使用されるビルトイン システム アカウントを使用すると
    ネットワーク間で認証できません。

  • サービスで使用されるビルトイン システム アカウントは
    ADのグループに入れる事ができないので AD 環境下でも NG です。

  • このため、一般的に匿名アクセスを許可する以外、ネットワーク間の認証には

    の何れかを使用する必要があります。

WORKGROUP 環境で利用。

Active Directory環境で利用。

  • コンピュータ・アカウント
    AD 環境下の場合、サービスで使用されるビルトイン システム アカウントを
    使用する場合、コンピュータ・アカウントのアクセス許可を
    リソースに付与するだけでも良い。
  • 仮想アカウント
    AD 環境下の場合、仮想アカウントは自動的に管理され、
    ドメイン環境でネットワークにアクセスすることができる。

移行メモ(補足): 「ビルトイン システム アカウントは AD のグループに
入れられない」という記述は、ローカルの擬似アカウントであることに由来する。
ただし前述のとおり、LocalSystem / NetworkService は
ネットワーク越しにはコンピュータ アカウントDOMAIN\HOST$)として
認証される。
このコンピュータ アカウントは AD のオブジェクトなので、
グループに入れることができる
実務では「Domain Computers ではなく、
専用のグループを作ってサーバのコンピュータ アカウントを入れ、
そのグループに共有フォルダの権限を与える」という設計が使われる。

net use(WNetAddConnection)

リモート・コマンドの問題

  • RSH(rshsvc サービス)や
  • PowerShell(WinRM サービス)で

リモート・コマンドを実行する場合、
リモートでコマンドを実行する際の実行アカウントを考慮する必要があります。

RSH

rshsvc.exe は、渡されたシェルを実行しますが、シェルの実行アカウントは、
サービスで使用されるビルトイン システム アカウントである
LocalSystem となるようです。

補足: RSH(rshsvc)は暗号化されないうえ、
Windows Server 2012 以降は同梱されていない。
現在は PowerShell Remoting(WinRM)か
SSH(Windows 標準の OpenSSH)を使う。

WinRM

WinRM サービスは、渡された PowerShell を実行しますが、
PowerShell の実行アカウントは、サービスで使用されるビルトイン システム
アカウントである Network Service となるようです。

しかし、WinRM サービスは実行時に Credential を渡す事で実行アカウントを指定でき、
また、色々設定を行う事によって WinRM ではダブルホップも可能であるようです。

PsExec

RSH(rshsvc サービス)など、上記の実行アカウントで
実行できないコマンドをリモート実行したい場合、PsExec が利用できる。

  • リモート・コンピュータ上でプログラムを実行する(PsExec編) - @IT
    http://www.atmarkit.co.jp/fwin2k/win2ktips/1416psexec/psexec.html
    • ローカル・アカウントと同じ資格情報で偽装しリモート・タスクを実行する。
      ただし、この偽装アカウントはダブルホップ問題を持つため
      適切な設定が無いとリモート・タスク上のネットワーク・アクセス時の
      認証等に失敗する。
    • リモートで実行するときのアカウントを指定できる。
    • System アカウントでプログラムを実行するよう指定できる。

ダブルホップ

ローカルの実行アカウントを引き継いでリモートアクセスする場合に知っておきたい
「ダブルホップ」については
ベース クライアント セキュリティ モデル
→「委任」を参照。

補足(ダブルホップの回避策): WinRM でのダブルホップ問題には、
主に次の 3 つの解がある。セキュリティ強度の順に並べると次のとおり。

方式 内容 評価
リソースベースの制約付き委任 (RBCD) 委任先のリソース側で許可を設定 推奨。範囲を絞れる
制約付き委任(Kerberos) 委任元のサーバに委任先サービスを列挙 可。設定が AD 管理者側
CredSSP 資格情報そのものを転送 非推奨。転送先が侵害されると資格情報が漏れる

-Authentication CredSSP は手軽なため多用されがちだが、
平文相当の資格情報を相手に渡すことになる。
本番環境では RBCD を検討したい。

その他の問題

コンピューター スタートアップ スクリプトの実行アカウント

スタートアップ スクリプトは LocalSystem アカウントとして実行されるらしい。

補足: グループ ポリシーのスクリプトは、
割り当て先で実行アカウントが変わる。

種別 実行アカウント タイミング
コンピューターの構成(スタートアップ / シャットダウン) LocalSystem OS 起動時 / 停止時
ユーザーの構成(ログオン / ログオフ) そのユーザー ログオン時 / ログオフ時

「管理者権限が要る処理はコンピューターの構成に置く」のが原則である。

Windowsサービスの偽装スレッドからEXE起動をした場合

また、ASP.NETなどの偽装スレッドから EXE 起動をした場合、
EXE が偽装スレッドの実行アカウントで実行されない問題があります。

Win32 API

  • Microsoft ASP.NET で偽装ユーザーの
    コンテキストで実行されるプロセスを生成する方法。

    偽装ユーザーのコンテキストで実行されるプロセスを起動するのには、
    System.Diagnostics.Process.Start メソッドを使用できません。

  • 偽装スレッドの実行アカウントで EXE を起動する場合は、
    DuplicateTokenExCreateProcessAsUser 関数を使用し、
    独自に、ユーザ権限を割り当てる必要があるようです。

補足(なぜ Process.Start では引き継がれないのか): 偽装は
スレッドに付くトークン(impersonation token)であり、
CreateProcessプロセスのプライマリ トークンを継承する。
つまり、偽装しているスレッドから起動しても、
子プロセスはサービス本体のアカウントで動く。

だから DuplicateTokenEx で偽装トークンを
プライマリ トークンに複製してから CreateProcessAsUser に渡す
という手順が必要になる。この理屈を知っていると迷いにくい。

注意点

以下の点に注意が必要のようです。

  • ASP.NET 偽装や、ImpersonateValidUser の偽装レベルは
    SecurityImpersonation なので、これに合わせる必要がある。

  • 独自偽装の、偽装レベルは、どちらでも良いが、双方を合わせる必要がある。

    • SecurityImpersonation
    • SecurityDelegation
  • 実行アカウントには、以下の設定が必要になる。

    • 「プロセス レベル トークンの置き換え」セキュリティ・ポリシー
      このセキュリティ設定は、ある Windows サービスから別の Windows サービスを
      開始するために、CreateProcessAsUser() Win32 API を呼び出せる
      ユーザ アカウントを決定します。
      このユーザー権利を使用するプロセスの 1 つがタスク スケジューラです。
      • 既定値: Network Service、LocalSystem
  • 参考情報

事例


Tags: 移行, あるある, Windows, アカウント, セキュリティ, 障害対応, デバッグ

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally