Сбой EventLog.SourceExists на Windows Server 2019
Я тестирую приложение ASP.NET на Windows Server 2019 с.Net Framework 4.7.2. Приложение IIS настроено для олицетворения пользователя, который НЕ имеет прав администратора.
Приложение вызывает EventLog.SourceExists
проверить, существует ли источник журнала событий, прежде чем пытаться создать новый источник. Я понимаю, что этот метод требует административных привилегий для поиска в существующих журналах событий источника [1]. Еще один способ сделать это, я явно дать своим пользователям разрешения на чтение раздела реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog
и все дети.
Это работает в версиях до Windows Server 2019 (2016, 2012 R2, 2018).
При тестировании это же приложение не работает на Windows Server 2019 за исключением.
Источник не найден, но не удалось найти некоторые или все журналы событий. Недоступные журналы: состояние.
При запуске procmon я вижу, что доступ запрещен при попытке открыть раздел реестра для журнала событий "Состояние" HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\State
Раздел реестра "Состояние" является новым для Windows Server 2019. Он также защищен - он принадлежит SYSTEM, а администраторы ограничены только для чтения. Я получаю Отказ в доступе, когда пытаюсь дать моему пользователю права на чтение. В результате мое приложение, работающее от имени пользователя без прав администратора, перестало работать с Inaccessible logs: State
при вызове EventLog.SourceExists.
Я понимаю, что могу взять на себя ответственность за State
ключ реестра и добавить мой пользователь. Однако, прежде чем я сделаю это, я хотел бы узнать, знает ли кто-нибудь об этом новом ключе реестра (журнал событий) в Windows Server 2019.
Благодарю.
0 ответов
Основная причина:
У куста State в дереве HKLM\SYSTEM\CCS\Services\EventLog странная конфигурация безопасности. Из-за этого любое приложение, пытающееся перечислить Источники событий, в конечном итоге обнаружит исключение "Доступ запрещен" и завершит работу.
Разрешения по умолчанию:
- СИСТЕМА (полный контроль)
- EventLog (полный контроль)
- Администраторы (читать ключ)
Они НЕ наследуются, как, например, для улья "Безопасность". Напротив, второй новый куст с именем "Параметры" наследует разрешения.
Перечисления обычно выполняются в Приложениях следующим образом:
[System.Diagnostics.EventLog]::SourceExists("Source Name")
Даже когда вы пытаетесь выполнить перечисление с помощью PowerShell, вы получите сообщение "Доступ запрещен"
PS C:\> (gci -Recurse HKLM:\System\CurrentControlSet\services\eventlog).Name
Хотя я не знаю, что именно делает улей "Состояние" (Microsoft не дает подробностей об этом), я нашел способ исправить это.
Решение:
интерактивное решение с использованием РЕГРЕДИТА:
a) запустите REGEDIT как SYSTEM с помощью PSexec и b) с помощью пользовательского интерфейса REGEDIT предоставьте разрешения на чтение кусту State для IIS_IUSRS или любой произвольной учетной записи, с которой работает ваша служба или пул приложений IIS.
скриптовый подход с использованием PowerShell:
а) запустите PowerShell как СИСТЕМУ с помощью 'PSexec' и б) с помощью командлетов 'Get-ACL' / 'Set-ACL' предоставьте разрешения на чтение кусту 'State' для IIS_IUSRS или любой произвольной учетной записи, которую выполняет ваша служба или пул приложений IIS. с
Запуск приложения от имени пользователя SYSTEM лучше всего достигается с помощью PSexec, который можно бесплатно загрузить с сайта Microsoft SysInternals (https://docs.microsoft.com/en-us/sysinternals/downloads/psexec)
PS C:\> PSexec.exe -accepteula -d -i -s powershell.exe
Это открывает окно PowerShell, работающее как NT AUTHORITY\System. Отсюда используйте REGEDIT, чтобы изменить разрешения для вашей учетной записи пользователя службы или пользователя пула приложений IIS в кусте "Состояние". В качестве альтернативы можно использовать командлеты Get-ACL / Set-ACL, чтобы сделать то же самое по сценарию. Разрешения на "чтение ключа" достаточно; нет необходимости в "полном контроле".
PS C:\> $hive = HKLM:\System\CurrentControlSet\services\eventlog\state; $acl = Get-ACL $hive; $rule = New-Object System.Security.AccessControl.RegistryAccessRule ("IIS_IUSRS","ReadKey","ContainerInherit","None","Allow"); $acl.SetAccessRule($rule); $acl |Set-ACL $hive
Теперь ваше приложение должно иметь возможность как перечислять все источники событий на компьютере, на котором оно выполняется, так и создавать источник событий, если перечисление его не находит.