В прошлой статье «Меньше администраторов всем» я рассказывал о принципах работы без прав администратора ― в частности, о технологии Just Enough Administration (JEA). Этот механизм хоть и гибкий, но сложный в настройке, и в ряде ситуаций можно обойтись и без него.
Например, если в бухгалтерии используется регулярно обновляемое ПО, то совершенно не обязательно выдавать права администратора, использовать сторонние решения вроде AdminLink и тем более обновлять руками. Есть другие варианты.
Временное членство в группах
В Windows 2016 появился такой механизм, как PAM ― Privileged Access Management или система управления привилегированным доступом. Подробнее про PAM можно почитать в документации Microsoft Privileged Access Management for Active Directory Domain Services. Одним из его инструментов является возможность включать пользователя в группу на определенное время.
Для включения PAM необходимо выполнить следующую команду:
Enable-ADOptionalFeature "Privileged Access Management Feature" -Scope ForestOrConfigurationSet -Target corp.domain.com
И подтвердить включение опции в домене.
Включаем PAM.
Проверить, что опция включена можно командой:
Get-ADOptionalFeature -filter {name -like "Privileged*"}
Проверка, что PAM включен.
Теперь можно задавать время членства пользователя в группе. Например, дадим пользователю Vasya.Pupkin право управления аккаунтами в домене, включив его в группу «Операторы учета» (Account Operators):
$Time = New-TimeSpan -Minutes 15
Add-ADGroupMember -Identity "Операторы учета" -Members Vasya.Pupkin -MemberTimeToLive $Time
Проверить оставшееся время жизни пользователя в группе можно командой:
Get-ADGroup "Операторы учета" -Property member –ShowMemberTimeToLive
Проверяем пользователей в группе.
Время жизни в секундах отображается в атрибуте TTL. В моем случае значение <TTL=849> означает, что пользователю Vasya.Pupkin осталось «жить» в группе 849 секунд.
При необходимости скрипт добавления пользователя в группу можно установить в планировщик. И тогда сотрудники техподдержки смогут создавать новых пользователей в заданное время: например, только по утрам. Если, конечно, создание новых пользователей еще не автоматизировано.
К сожалению, не все еще в полной мере наслаждаются новыми возможностями Windows 2016. Но можно обойтись и без них.
Меня зовут Георгий, и я параноик
Действительно, зачем включать какие-то новые возможности, если можно добавить аккаунт в группу, а потом удалить аккаунт из группы. Такой способ неудобен для временного предоставления полномочий сотрудникам, зато вполне подходит для собственной работы, если вы, соблюдая все заветы ИБ, не работаете под пользователем с административными правами.
Предположим, что нам надо перезапустить сервер 1С: Предприятия. Если у вас есть права, это довольно легко сделать такой командой:
Invoke-Command -ComputerName servername -ScriptBlock {
Restart-Service "1C:Enterprise 8.3 Server Agent"
}
Но я не работаю с административными правами, поэтому создал отдельного пользователя admin-zhora, который входит в группу server-admins. В свою очередь эта группа при помощи механизма Restricted Groups добавлена в локальные администраторы серверов. Поэтому мой скрипт выглядит так:
$Credential = Get-Credential
Invoke-Command-ComputerName servername -Credential $Credential -ScriptBlock {
Restart-Service "1C:Enterprise 8.3 Server Agent"
}
Запрос учетных данных при запуске скрипта.
И я забочусь о безопасности ― вдруг кто-то украдет учетные данные пользователя. Поэтому дорабатываю скрипт: добавляю включение пользователя в группу и удаление пользователя из группы:
Add-ADGroupMember -Identity server-admins -Members admin-zhora
...
Remove-ADGroupMember -Identity server-admins -Members admin-zhora –Confirm:$False
Теперь стало безопаснее. Но это не точно.
Добавим еще безопасности моему скрипту: каждый раз будем менять пароль пользователя admin-zhora на случайный, чтобы не беспокоиться о его компрометации. Для этого я возьму модуль New-SWRandomPassword.ps1, опубликованный на портале Script Center, и с его помощью напишу следующую функцию:
#requires -Modules New-SWRandomPassword
function Reset-InvokePassword {
param
(
[Parameter(Mandatory=$true)]
[string]$UserName
)
$NewSecurePassword = ConvertTo-SecureString -String (New-SWRandomPassword -MinPasswordLength 14 -MaxPasswordLength 14) -AsPlainText -Force
try
{
Set-ADAccountPassword -Identity $UserName -NewPassword $NewSecurePassword -Reset -Confirm:$False -ErrorAction Stop
}
catch
{
Write-Output "Could not change password"
$ErrorMessage = $_.Exception.Message
$ErrorMessage
break
}
New-Object System.Management.Automation.PsCredential($UserName,$NewSecurePassword)
}
На выходе этой функции я получаю новые учетные данные в формате Credential, которые могу передавать другим командлетам. Добавим в изначальный скрипт смену пароля до выполнения основной команды и после него. Итоговый скрипт будет таким:
#requires -Modules Reset-InvokePassword
Add-ADGroupMember -Identity server-admins -Members admin-zhora -Verbose
$Credential = Reset-InvokePassword -Username admin-zhora
Invoke-Command -ComputerName servername -Credential $Credential -ScriptBlock {
Restart-Service "1C:Enterprise 8.3 Server Agent" -Verbose
}
Reset-InvokePassword -Username admin-zhora | Out-Null
Remove-ADGroupMember -Identity server-admins -Members admin-zhora -Confirm:$False -Verbose
Вот теперь достаточно безопасно, и еще и пароль не запрашивает.
Внимательный читатель отметит, что моей учетной записи нужно дать права на управление группой и пользователем, чтобы менять пароль и членство в группе. Что ж, в этом примере я готов пойти на риск, но в реальной практике для таких команд предпочитаю JEA.
Если сравнивать JEA с sudo, требующей предварительной настройки и выдачи прав, то механизм добавления-удаления в группы больше напоминает su и больше подходит для разовых, а не регулярных задач.