9 min czytania

gMSA jako konto usługi SQL Servera: wdrożenie krok po kroku

Konto usługi SQL Servera z hasłem, które nigdy nie wygasa i które zna kilka osób, zostaje bez zmian latami, bo zmiana hasła oznacza przestój na każdym serwerze. Jak wdrożyć grupowe zarządzane konto usługi (gMSA): klucz KDS, konto, instalacja na serwerach i zmiana konta w SQL Server Configuration Manager.

Rys. 1. Hasło konta gMSA oblicza i zmienia kontroler domeny, a pobrać je mogą tylko serwery z grupy wskazanej w koncie; żaden administrator go nie zna ani nie wpisuje na serwerach.

Konto usługi SQL Servera założono przy pierwszej instalacji, kilka lat temu, z zaznaczoną opcją „Hasło nigdy nie wygasa”. Hasło zna administrator, który instalował serwer, dwie inne osoby z działu IT i co najmniej jeden były pracownik, a do tego jest zapisane w dokumentacji wdrożenia. Nikt go nie zmienia, bo zmiana oznacza nowe hasło w Active Directory, ręczne wpisanie go w każdej usłudze SQL na każdym serwerze i restart każdej instancji. Usługa pominięta przy zmianie nie wystartuje po najbliższym restarcie serwera i zgłosi błąd 1069 („The service did not start due to a logon failure”).

Grupowe zarządzane konto usługi (gMSA, group Managed Service Account) usuwa ten problem u źródła. Hasło generuje i zmienia kontroler domeny, serwery pobierają je same, a żaden człowiek go nie zna i nigdzie nie wpisuje. Ten wpis prowadzi przez wdrożenie: od klucza głównego KDS, przez utworzenie konta i instalację na serwerach, po zmianę konta instancji w SQL Server Configuration Manager.

Jak działa gMSA

Konto gMSA to obiekt Active Directory zbliżony budową do konta komputera. Hasło oblicza kontroler domeny na podstawie klucza głównego usługi KDS (Key Distribution Service) i atrybutów konta, a domyślnie zmienia je co 30 dni. Interwał można ustawić wyłącznie przy tworzeniu konta, parametrem -ManagedPasswordIntervalInDays. Później atrybut msDS-ManagedPasswordInterval jest tylko do odczytu, a inny interwał wymaga utworzenia nowego konta.

Hasło mogą pobrać tylko podmioty wpisane w atrybucie msDS-GroupMSAMembership, który ustawia parametr -PrincipalsAllowedToRetrieveManagedPassword. Najprościej wskazać w nim grupę komputerów, tu GG-SQL-Hosts z serwerami srv-sql-01 i srv-sql-02. Serwer z tej grupy pobiera z kontrolera domeny bieżące i poprzednie hasło, dlatego zmiana hasła nie wymaga restartu usług.

SQL Server obsługuje gMSA jako konto usługi od wersji 2014, na Windows Server 2012 R2 lub nowszym.

Konto wirtualne, konto domenowe czy gMSA

Instalator SQL Servera domyślnie uruchamia silnik na koncie wirtualnym, na przykład NT SERVICE\MSSQL$CRM. To dobre ustawienie dla pojedynczego serwera, który nie sięga do zasobów sieciowych. W sieci konto wirtualne występuje jako konto komputera, więc uprawnienie do udziału z kopiami dostaje cały serwer ze wszystkimi usługami, a SPN dla własnych nazw instancji trzeba rejestrować na koncie komputera i przenosić razem z instancją.

CechaKonto wirtualneZwykłe konto domenowegMSA
Kto zna hasłonikt, konto nie ma hasłaadministrator, który je ustawił, i każdy, komu je przekazanonikt, hasło oblicza kontroler domeny
Zmiana hasłanie dotyczyręcznie w AD i w każdej usłudze, z restartemautomatycznie, domyślnie co 30 dni, bez restartu
Dostęp do zasobów sieciowychjako konto komputera, np. CORP\srv-sql-01$jako to kontojako CORP\svc-sql$
SPNna koncie komputerana koncie usługina koncie gMSA
Praca na kilku serwerachnie, tożsamość lokalna serwerataktak, na serwerach z grupy GG-SQL-Hosts
Logowanie interaktywneniemożliwemożliwe dla każdego, kto zna hasłoniemożliwe

Klucz główny KDS

Kontrolery domeny potrzebują klucza głównego KDS, zanim zaczną obliczać hasła gMSA. Klucz tworzy się raz na las, na kontrolerze domeny, z uprawnieniami grupy Domain Admins lub Enterprise Admins. Najpierw warto sprawdzić, czy klucz już istnieje, bo mógł powstać przy wdrażaniu innej usługi.

# Sprawdzenie, czy klucz już istnieje
Get-KdsRootKey

# Tylko gdy poprzednie polecenie nic nie zwróciło
Add-KdsRootKey -EffectiveImmediately

Mimo nazwy przełącznika -EffectiveImmediately Microsoft zaleca odczekać 10 godzin, zanim pierwsze konto zacznie być używane. Klucz musi się zreplikować na wszystkie kontrolery domeny, a serwer, który zwróci się o hasło do kontrolera jeszcze bez klucza, nie dostanie go. Utworzenie klucza potwierdza zdarzenie 4004 w dzienniku operacyjnym usługi KdsSvc. W laboratorium z jednym kontrolerem można ustawić datę wejścia w życie 10 godzin wstecz (-EffectiveTime ((Get-Date).AddHours(-10))); w środowisku produkcyjnym nie należy tego robić.

Grupa serwerów i konto gMSA

Konto tworzy się poleceniem New-ADServiceAccount, które domyślnie umieszcza je w kontenerze Managed Service Accounts. Parametr -DNSHostName jest wymagany dla konta grupowego i zwykle zawiera nazwę konta w domenie. Parametr -KerberosEncryptionType ogranicza szyfrowanie biletów do AES, zgodnie z zaleceniem Microsoftu dla kont zarządzanych.

# Grupa komputerów, które mogą pobrać hasło konta
New-ADGroup -Name GG-SQL-Hosts -GroupScope Global -GroupCategory Security
Add-ADGroupMember -Identity GG-SQL-Hosts -Members 'srv-sql-01$', 'srv-sql-02$'

# Konto gMSA; interwał zmiany hasła można ustawić tylko teraz
New-ADServiceAccount -Name svc-sql -DNSHostName svc-sql.corp.example.com `
    -PrincipalsAllowedToRetrieveManagedPassword GG-SQL-Hosts `
    -ManagedPasswordIntervalInDays 30 `
    -KerberosEncryptionType AES128, AES256

Kolejny serwer SQL dodaje się do grupy GG-SQL-Hosts, a nie do samego konta. Polecenie Set-ADServiceAccount z parametrem -PrincipalsAllowedToRetrieveManagedPassword ustawia listę uprawnionych od nowa, więc łatwo nim przypadkiem odebrać dostęp działającym serwerom.

Instalacja i test na serwerze

Na każdym serwerze SQL potrzebny jest moduł ActiveDirectory dla PowerShella. Polecenie Install-ADServiceAccount sprawdza, czy serwer może korzystać z konta, i przygotowuje je lokalnie, a w przypadku gMSA buforuje konto na serwerze. Wymaga sesji PowerShella uruchomionej jako administrator.

# Moduł ActiveDirectory dla PowerShella
Install-WindowsFeature RSAT-AD-PowerShell

Install-ADServiceAccount -Identity svc-sql
Test-ADServiceAccount -Identity svc-sql

Test-ADServiceAccount zwraca True, gdy serwer może pobrać hasło i uwierzytelnić się kontem. Wynik False ma zwykle jedną z trzech przyczyn: serwer nie należy do grupy GG-SQL-Hosts albo jeszcze o tym nie wie, klucz KDS nie dotarł do kontrolera domeny, z którym rozmawia serwer, albo serwer nie obsługuje typów szyfrowania wymaganych przez konto.

Zmiana konta w SQL Server Configuration Manager

Konto instancji zmienia się w SQL Server Configuration Manager. W SQL Server 2025 otwiera go polecenie SQLServerManager17.msc, w starszych wersjach plik z odpowiednio niższym numerem. W węźle SQL Server Services trzeba otworzyć właściwości usługi SQL Server (CRM), przejść na zakładkę Log On i wpisać konto ze znakiem dolara na końcu, zostawiając puste pola hasła:

SQL Server Services > SQL Server (CRM) > Properties > Log On
  This account
    Account Name:      CORP\svc-sql$
    Password:          (puste)
    Confirm password:  (puste)

Po zatwierdzeniu Configuration Manager proponuje restart usługi. Nowe konto działa dopiero po nim, a na czas restartu bazy instancji są niedostępne. To jedyny przestój w całym wdrożeniu, dlatego zmianę planuje się w oknie serwisowym, a kolejne zmiany hasła odbywają się już bez restartów. Tak samo zmienia się konto usługi SQL Server Agent, przy czym Microsoft zaleca osobne konta dla różnych usług SQL Servera, więc Agent może dostać własne konto albo zostać na koncie wirtualnym.

Przystawki Usługi (services.msc) nie należy do tego używać: Microsoft zaleca zmieniać konto i hasło usług SQL Servera wyłącznie jego narzędziami. Configuration Manager oprócz nazwy konta aktualizuje lokalny magazyn zabezpieczeń Windows, który chroni klucz główny usługi (service master key) silnika bazy danych. Przystawka Usługi zmienia tylko nazwę konta, a skutki wychodzą później, na przykład jako błąd „A required privilege is not held by the client” w krokach zadań Agenta. Uprawnienia do plików i rejestru instancji instalator nadaje identyfikatorowi usługi NT SERVICE\MSSQL$CRM (per-service SID), a nie kontu, więc po zmianie konta nie trzeba ich poprawiać.

Przed przełączeniem trzeba przenieść na nowe konto wszystko, co było nadane staremu: uprawnienia do udziałów sieciowych, na przykład udziału z kopiami (kopie bez SQL Agenta opisuje szósta część przewodnika), loginy starego konta na innych instancjach i ustawienia delegacji. SPN trzeba usunąć ze starego konta i zarejestrować na CORP\svc-sql$; polecenia i kolejność opisuje druga część przewodnika. Stare konto wyłącza się dopiero po sprawdzeniu, że żadna usługa z niego nie korzysta, a usuwa po okresie obserwacji.

Jedno konto dla wszystkich instancji czy kilka

Wspólne konto svc-sql dla instancji CRM, ERP i HR na obu serwerach jest najprostsze. SPN wszystkich instancji leżą na jednym koncie, delegację konfiguruje się raz, a przeniesienie instancji ze srv-sql-01 na srv-sql-02 sprowadza się do zmiany rekordu DNS, bez zmian w SPN i uprawnieniach.

Ceną jest zasięg skutków przejęcia. Każdy proces działający jako SYSTEM na dowolnym serwerze z grupy GG-SQL-Hosts może pobrać hasło konta, bo dokładnie w ten sposób pobiera je sam system. Atakujący, który przejmie jedną instancję, na przykład przez xp_cmdshell, działa w sieci jako CORP\svc-sql$, czyli z dostępem do udziałów wszystkich instancji, z ich delegacją i z loginami nadanymi temu kontu na innych serwerach.

Praktyczna zasada: jedno konto na grupę instancji o podobnej wrażliwości danych i tych samych administratorach. Instancja z danymi kadrowymi, tu HR, powinna dostać osobne konto gMSA. Osobne konto tylko częściowo ogranicza skutki przejęcia innej instancji na tym samym serwerze. Proces instancji nie działa jako SYSTEM, więc nie pobierze wprost hasła cudzego konta, ale konta usług SQL Servera mają uprawnienie do personifikacji (SeImpersonatePrivilege), które często pozwala podnieść uprawnienia do poziomu systemu. Pełną izolację daje dopiero osobny serwer i osobna grupa uprawnionych komputerów.

Sprawdź u siebie

Klucze główne KDS w lesie, polecenie do uruchomienia na kontrolerze domeny. Dobry wynik to co najmniej jeden klucz z EffectiveTime przesuniętym o co najmniej 10 godzin w przeszłość. Pusty wynik oznacza, że w lesie nie ma jeszcze kont gMSA, a data w przyszłości, że klucz jeszcze nie obowiązuje.

Get-KdsRootKey | Select-Object KeyId, CreationTime, EffectiveTime

Kto może pobrać hasło konta, z jakim interwałem jest zmieniane, jakie szyfrowanie obsługuje konto i kiedy hasło zmieniło się ostatnio. Dobry wynik to wyłącznie grupa GG-SQL-Hosts w PrincipalsAllowedToRetrieveManagedPassword, wartość 30 (albo świadomie wybrany interwał), 24 w msDS-SupportedEncryptionTypes (AES128 i AES256) oraz PasswordLastSet nie starsze niż mniej więcej jeden interwał. Konta użytkowników albo grupa Domain Computers na liście uprawnionych to zły wynik: hasło może wtedy pobrać ktoś spoza serwerów SQL.

Get-ADServiceAccount -Identity svc-sql -Properties PrincipalsAllowedToRetrieveManagedPassword, 'msDS-ManagedPasswordInterval', 'msDS-SupportedEncryptionTypes', PasswordLastSet |
    Select-Object Name, PrincipalsAllowedToRetrieveManagedPassword, 'msDS-ManagedPasswordInterval', 'msDS-SupportedEncryptionTypes', PasswordLastSet

Dostęp serwera do konta, na każdym serwerze SQL osobno. Dobry wynik to True i grupa GG-SQL-Hosts na liście grup komputera. False przy obecności serwera w grupie oznacza zwykle stary bilet Kerberos, opisany w ramce o członkostwie, a brak grupy na liście oznacza, że serwera nikt do niej nie dodał.

Test-ADServiceAccount -Identity svc-sql

# Grupy, do których należy konto tego komputera
Get-ADComputer -Identity $env:COMPUTERNAME | Get-ADPrincipalGroupMembership | Select-Object Name

Konta, na których działają usługi SQL Servera na serwerze. Dobry wynik to CORP\svc-sql$ w StartName usług MSSQL$… i Running w State. Konto osoby, stare konto usługi albo LocalSystem wskazuje usługę, której jeszcze nie przełączono.

Get-CimInstance -ClassName Win32_Service -Filter "Name LIKE 'MSSQL%' OR Name LIKE 'SQLAgent%'" |
    Select-Object Name, StartName, State