-
Notifications
You must be signed in to change notification settings - Fork 0
MS_ServiceAndTaskAccountIssues
- 戻る(サービス・タスク系のいろいろ)
- サービス・タスク系のアカウント問題
- Windowsサービス
- アカウント
Windowsサービス全般の実行アカウント問題を中心とした
トラブルシュートについて説明します。
-
通常、Windows サービスの実行アカウントとして
サービスで使用されるビルトイン システム アカウント
(MS_BuiltInSystemAccount.md)が使用されます。- IISでは、「Network Service」を使用します。
- タスク スケジューラでは、「System」(LocalSystem)を使用します。
-
このため、Windows サービスやタスク スケジューラからの実行では、
普段意識していない OS や API の認証機構の存在を意識する必要があります。
補足(3 つのビルトイン アカウントの違い): 切り分けの前提として、
この 3 つの差を押さえておきたい。
アカウント ローカル権限 ネットワークでの見え方 LocalSystem 非常に強い(管理者以上) コンピュータ アカウント( DOMAIN\HOST$)NetworkService 弱い(Users 相当) コンピュータ アカウント(同上) LocalService 弱い 匿名(ネットワーク認証できない) ここで重要なのは、LocalSystem / NetworkService は
ネットワーク越しには「コンピュータ アカウント」として振る舞うという点である。
「ローカルでは全能なのに、共有フォルダにアクセスできない」という
典型的な症状はこれで説明できる。なお LocalService はネットワーク上では匿名になるため、
認証が必要なリソースには一切アクセスできない。
以下を参照下さい。
- @IT:.NET TIPS ユーザーのセキュリティ権限を確認するには?(基本編)
http://www.atmarkit.co.jp/fdotnet/dotnettips/346rolebasesec1/rolebasesec1.html
補足(手早い確認手段): コードを書かずに調べるなら次が早い。
whoami /user /groups /priv ← 実行アカウントと特権を一括表示サービス側からは、タスク/サービスの中で
whoami /all > C:\temp\who.txtを実行させるのが確実である。
稼働中プロセスなら、タスク マネージャーの[詳細]タブに
「ユーザー名」列を追加しても確認できる。
runas コマンドで一時的にほかのユーザー権限でプログラムを実行する事ができますが、
コマンドからパスワードは与えられず、ユーザに入力を求めるダイアログが表示されますので
非対話型のセッションから実行される Windows サービスやタスク スケジューラでは
アンマッチです。
-
runasコマンドにはサービスで使用されるビルトイン システム アカウントを
指定できません。 - 既定で、サービスで使用されるビルトイン システム アカウントが利用されます。
移行メモ(誤字): 元ページの「指定きません」は「指定できません」の脱字である。
IIS(のワーカ・プロセス)や SQL Serverなど、
専用の設定画面を持ち、ここから設定が可能です。
-
IIS
- IIS 7.5(のワーカ・プロセス)からは、アプリケーション プール ID が導入され、
既定で「Network Service」ではなく「DefaultAppPool」(仮想アカウント)が
使用されます。
- IIS 7.5(のワーカ・プロセス)からは、アプリケーション プール ID が導入され、
| 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では、偽装を使用する事によって、
実行アカウントを指定することもできます。
偽装には、
-
特定のアカウントに偽装する。
-
Windows サービスにアクセスしてきたユーザの認証アカウントに偽装する。
があります。
匿名アカウントを実行アカウントにする場合は偽装が必要になります。
通常は、IIS(のワーカ・プロセス)の実行アカウントで実行される。
補足(最新化:偽装は ASP.NET Core では使えない):
<identity impersonate="true" />
という設定は .NET Framework 版の ASP.NET 固有であり、
ASP.NET Coreには存在しない。ASP.NET Core で同等のことをするには、
- アプリケーション プールの ID そのものを変える(サーバ信頼モデル相当)
- Windows 認証 +
WindowsIdentity.RunImpersonated()で
区間的に偽装する(ベース クライアント モデル相当)のいずれかになる。
移行時に見落としやすい非互換点なので注意が要る。
ASP.NETのように、偽装の機能が実装されている Windows サービスも
有りますが、Win32 API を使用して偽装することもできます(区間的、部分的な偽装)。
- 参考
- コード内で認証中のユーザーを偽装する
- コード内で特定のユーザーを偽装する
-
Open棟梁の IdentityImpersonation.ImpersonateValidUser + UndoImpersonation メソッド
- 区間偽装のサンプル(
OTR_IntervalImpersonationSample.md)
- 区間偽装のサンプル(
以下の KB にあるように、タスク スケジューラは実行アカウントを指定して
実行させる事ができます。
- ユーザー アカウントにパスワードがないとタスク スケジューラでタスクが実行されない
コマンドからは以下の様に設定します。
-
atコマンド(現在は非推奨。schtasksを使う) -
schtasksコマンド
補足(
atは廃止された):atコマンドは Windows 8 / Server 2012 以降
非推奨となり、現在の OS では実質使えない。
schtasksか、PowerShellのScheduledTasksモジュール
(New-ScheduledTask/Register-ScheduledTask)を使う。パスワードを保存したくない場合は、
グループ管理サービス アカウント(gMSA) を使うと
パスワード管理を Active Directory 側に任せられる。
30 日ごとに AD が自動でパスワードを変更するため、
「サービス アカウントのパスワード有効期限切れで夜間バッチが止まる」
という定番の事故を防げる。
-
サービスで使用されるビルトイン システム アカウントを使用すると
ネットワーク間で認証できません。 -
サービスで使用されるビルトイン システム アカウントは
ADのグループに入れる事ができないので AD 環境下でも NG です。 -
このため、一般的に匿名アクセスを許可する以外、ネットワーク間の認証には
- ミラーアカウント
- ドメイン アカウント
-
net use(WNetAddConnection)
の何れかを使用する必要があります。
WORKGROUP 環境で利用。
Active Directory環境で利用。
- コンピュータ・アカウント
AD 環境下の場合、サービスで使用されるビルトイン システム アカウントを
使用する場合、コンピュータ・アカウントのアクセス許可を
リソースに付与するだけでも良い。 - 仮想アカウント
AD 環境下の場合、仮想アカウントは自動的に管理され、
ドメイン環境でネットワークにアクセスすることができる。
移行メモ(補足): 「ビルトイン システム アカウントは AD のグループに
入れられない」という記述は、ローカルの擬似アカウントであることに由来する。
ただし前述のとおり、LocalSystem / NetworkService は
ネットワーク越しにはコンピュータ アカウント(DOMAIN\HOST$)として
認証される。
このコンピュータ アカウントは AD のオブジェクトなので、
グループに入れることができる。
実務では「Domain Computersではなく、
専用のグループを作ってサーバのコンピュータ アカウントを入れ、
そのグループに共有フォルダの権限を与える」という設計が使われる。
-
net use(WNetAddConnection)
WORKGROUP 環境・Active Directory環境でも利用可能。 - 詳細はサービス・タスク系のいろいろを参照。
- RSH(rshsvc サービス)や
- PowerShell(WinRM サービス)で
リモート・コマンドを実行する場合、
リモートでコマンドを実行する際の実行アカウントを考慮する必要があります。
rshsvc.exe は、渡されたシェルを実行しますが、シェルの実行アカウントは、
サービスで使用されるビルトイン システム アカウントである
LocalSystem となるようです。
補足: RSH(rshsvc)は暗号化されないうえ、
Windows Server 2012 以降は同梱されていない。
現在は PowerShell Remoting(WinRM)か
SSH(Windows 標準の OpenSSH)を使う。
WinRM サービスは、渡された PowerShell を実行しますが、
PowerShell の実行アカウントは、サービスで使用されるビルトイン システム
アカウントである Network Service となるようです。
しかし、WinRM サービスは実行時に Credential を渡す事で実行アカウントを指定でき、
また、色々設定を行う事によって WinRM ではダブルホップも可能であるようです。
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 アカウントとして実行されるらしい。
- コンピューター スタートアップ スクリプトを割り当てる
https://learn.microsoft.com/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc770556(v=ws.11)
補足: グループ ポリシーのスクリプトは、
割り当て先で実行アカウントが変わる。
種別 実行アカウント タイミング コンピューターの構成(スタートアップ / シャットダウン) LocalSystem OS 起動時 / 停止時 ユーザーの構成(ログオン / ログオフ) そのユーザー ログオン時 / ログオフ時 「管理者権限が要る処理はコンピューターの構成に置く」のが原則である。
また、ASP.NETなどの偽装スレッドから EXE 起動をした場合、
EXE が偽装スレッドの実行アカウントで実行されない問題があります。
-
Microsoft ASP.NET で偽装ユーザーの
コンテキストで実行されるプロセスを生成する方法。偽装ユーザーのコンテキストで実行されるプロセスを起動するのには、
System.Diagnostics.Process.Startメソッドを使用できません。 -
偽装スレッドの実行アカウントで EXE を起動する場合は、
DuplicateTokenEx→CreateProcessAsUser関数を使用し、
独自に、ユーザ権限を割り当てる必要があるようです。
補足(なぜ
Process.Startでは引き継がれないのか): 偽装は
スレッドに付くトークン(impersonation token)であり、
CreateProcessはプロセスのプライマリ トークンを継承する。
つまり、偽装しているスレッドから起動しても、
子プロセスはサービス本体のアカウントで動く。だから
DuplicateTokenExで偽装トークンを
プライマリ トークンに複製してからCreateProcessAsUserに渡す
という手順が必要になる。この理屈を知っていると迷いにくい。
以下の点に注意が必要のようです。
-
ASP.NET 偽装や、
ImpersonateValidUserの偽装レベルは
SecurityImpersonationなので、これに合わせる必要がある。 -
独自偽装の、偽装レベルは、どちらでも良いが、双方を合わせる必要がある。
SecurityImpersonationSecurityDelegation
-
実行アカウントには、以下の設定が必要になる。
- 「プロセス レベル トークンの置き換え」セキュリティ・ポリシー
このセキュリティ設定は、ある Windows サービスから別の Windows サービスを
開始するために、CreateProcessAsUser()Win32 API を呼び出せる
ユーザ アカウントを決定します。
このユーザー権利を使用するプロセスの 1 つがタスク スケジューラです。- 既定値: Network Service、LocalSystem
- 「プロセス レベル トークンの置き換え」セキュリティ・ポリシー
-
参考情報
- CreateProcessAsUser(すなのかたまり)
http://msmania.wordpress.com/tag/createprocessasuser/ - Open棟梁の IdentityImpersonation.CreateProcessAsImpersonationUser メソッド
- CreateProcessAsUser(すなのかたまり)
Tags: 移行, あるある, Windows, アカウント, セキュリティ, 障害対応, デバッグ
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。