きなこもち.net

.NET Framework × UiPath,Orchestrator × Azure × AWS × Angularなどの忘備録

.NET core × Windows Service × 作成から、設定変更まで

この記事の目的

この記事は、
Windows Serviceの作成から、設定変更までの手順をまとめること
を目的としています。

本題

Windows Serviceの作成(開発)

.NET Core でWindows Serviceを作ります。
今回は、特別中身のあるWindows Serviceが必要ではないので、
WorkerServiceプロジェクトのテンプレートをそのまま利用します。
codeburst.io
tech.guitarrapc.com

Windows Serviceの作成(Service登録)

SC.exeを使って、Windows Serviceを登録します。
https://support.microsoft.com/ja-jp/help/251192/how-to-create-a-windows-service-by-using-sc-exe

説明:
レジストリおよびサービス データベースのサービス エントリを作成します。
使用法:
sc <サーバー> create [サービス名] [binPath= ] <オプション1> <オプション2>...

オプション:
注意: オプション名には等号が含まれています。
等号と値の間にはスペースが必要です。
type=
(既定 = own)
start=
(既定 = demand)
error=
(既定 = normal)
binPath= <.exe ファイルへの BinaryPathName>
group=
tag=
depend= <依存関係 (スラッシュ (/) で区切ります)>
obj=
(既定 = LocalSystem)
DisplayName= <表示名>
password= <パスワード>

実際には、こんな感じでコマンドを実行しました。
<dir>は、Exeファイルの絶対パスで置換します。
なお、実行するときには、管理者権限でコマンドプロンプトを開いてから実行します。

sc.exe kinakomotitti binPath=<dir>\WorkerService1.exe

Windows Serviceのセキュリティ設定変更

作成したサービスのセキュリティ設定を確認すると、こうなっていました(一部改行しています。)

C:\WINDOWS\system32>sc sdshow kinakomotitti

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)
   (A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)
   (A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)
S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

うわぁ。。って感じの出力結果ですね。
なので、読み取り方をメモしておきます。。。

*詳しい読み取り方は、以下のブログにとても分かりやすくまとめられていました。
taeisheauton4programming.blogspot.com
stakiran.hatenablog.com

C:\WINDOWS\system32>sc sdshow kinakomotitti 
  → cmdでコマンド実行。
↓ D:はDACL
D:(A;;CC LC SW RP WP DT LO CR RC;;;SY) 
  → (許可;;いろいろ;;Local System)
   (A;;CC DC LC SW RP WP DT LO CR SD RC WD WO;;;BA) 
  → (許可;;いろいろ;;ビルトイン (ローカル) の Administrators)
   (A;;CC LC SW LO CR RC;;;IU) 
  → (許可;;いろいろ;;対話型ログオン ユーザー)
   (A;;CCLCSWLOCRRC;;;SU) 
  → (許可;;いろいろ;;Service Logon User)

↓ S:はSACL
S:(AU;FA;CC  DC  LC  SW  RP  WP  DT  LO  CR  SD  RC  WD  WO;;;WD) 
  →こっちは省略

上記から、「Administratorsグループのユーザーに対して、「CC DC LC SW RP WP DT LO CR SD RC WD WO」の権限は付与されている」ことが読み取れます。*CCとかDCとかは、公式でまとまっている表(下図)を参考に読み取ります。ここでは、RPとWPがサービスの開始、停止権限ということだけ把握しておきます。

f:id:kinakomotitti:20200412222748p:plain
アクセス許可の文字列

とりあえずStartしてみようとしたところ、失敗したエビデンスが以下の通りです。

C:\>sc start kinakomotitti
[SC] StartService: OpenService FAILED 5:

アクセスが拒否されました。


毎回管理者権限のコマンドプロンプトを起動するのは嫌なので、
Administratorsだけではなく、今のユーザー自身に対して、直接権限を付与してみました。
特定のユーザーに権限を与えるには、そのユーザーのSIDを指定する必要があります。
Whoamiコマンドで調べられるので、その結果をもとに、権限を付与したところが↓です。

C:\WINDOWS\system32>whoami /user -> UserのSIDを取得する

USER INFORMATION
----------------

ユーザー名            SID
===================== ============================================
domain\UserName S-1-9-99-ここの値

C:\WINDOWS\system32>sc sdset kinakomotitti D:(A;;CCLCSWRPWPDTLOCRRC;;;S-1-9-99-ここの値)
(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD) <- もともとの権限も一緒に設定する。

[SC] SetServiceObjectSecurity SUCCESS


ここまでやると、管理者権限で開いたコマンドプロンプトを使わなくても、
サービスをStart/Stopすることができるようになりました(∩´∀`)∩ワーイ