Problém expirace hesla v RDP prostředí s NLA autentizací

(MS Windows Server 2012 R2)

Na Windows serverech v RDP prostředí s vynucenou NLA autentizací (Network Level Authentication) resp. CredSSP protokolem (Credential Security Support Provider) nelze u klientů mimo doménu provést změnu hesla pomocí aplikace Mstsc.exe (Připojení ke vzdálené ploše). 
Tato situace je pro uživatele nepříjemná, protože nezmění-li si heslo včas sami, po expiraci hesla se do systému již nepřihlásí.

Standardní řešení

  1. zobrazovat výzvu (bublinu) s informací o blížící se expiraci hesla viz https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/interactive-logon-prompt-user-to-change-password-before-expiration 
  2. zprovoznit "RD Web" roli na serveru a umožnit tak uživateli změnu hesla pomocí webové služby viz https://docs.microsoft.com/en-us/windows-server/remote/remote-desktop-services/rds-rdweb-gateway-ha

Výzva bohužel nevyžaduje akci uživatele, tudíž bývá mnohdy opomíjena a uvádí postup pomocí zkratky CTRL+ALT+END, která neplatí např. u Linuxových klientů. V případě služby RD Web je třeba uživatele předem informovat a distribuovat mu zástupce resp. URL adresu.

Vlastní řešení - zpráva pomocí PowerShell skriptu

Protože výše uvedená řešení nepovažuji za ideální, připravil jsem PowerShell skript, který zobrazí uživateli zprávu s informací o expiraci hesla a vyžaduje akci. Po kliknutí na ANO se zobrazí tzv. GINA obrazovka (CTRL+ALT+DEL).

Skript načítá informace uložené v AD (Active Directory). Zjišťuje počet dní od poslední změny hesla (hodnota PasswordLastSet v účtu uživatele) a porovnává s hodnotou MaxPasswordAge v Password Policy převedenou na dny. Pokud do expirace hesla zbývá počet dnů v rozsahu 0 - $MsgDays, je uživateli zobrazena zpráva. Z Password Policy se ještě načte informace o minimální délce hesla (MinPasswordLength) a počtu posledních hesel, která nelze použít (PasswordHistoryCount).

Zprovoznění skriptu

Na RDP servery je třeba nainstalovat PowerShell modul activedirectory a v AD nad objektem Password Policy (System -> Password Settings Container -> Policy) nastavit uživatelům právo Read pro potřebné vlastnosti (MinPasswordLength, PasswordHistoryCount, MaxPasswordAge) + Read permissions

Ve skriptu stačí definovat 2 proměnné:

  • $PassPolicyName = název Password Policy v AD
  • $MsgDays = počet dní pro zobrazení zprávy před expirací hesla

Skript je nutné spouštět pod účtem uživatele po přihlášení a načtení Plochy, např. v GPO zde:
User Configuration -> Policies -> Administrative Templates -> System -> Logon: "Run these programs at user logon"

Skript

##############################################################################
# The name of the password policy
# (Users need permission to read the properties of this policy.)
$PassPolicyName = "Password_Policy_name"

# Number of days to display the message (before the password expires)
$MsgDays = 14
##############################################################################

# Import ActiveDirectory PS module
import-module activedirectory

# Date the password was last set.
$PassLastSetDate = [DateTime](get-aduser $env:UserName -properties passwordlastset | % passwordlastset)  
# Today date
$Today = [DateTime](Get-Date)
# Number of days since the last password was set.
$PassLastSetDays = (New-TimeSpan -Start $PassLastSetDate -End $Today).Days
# Get the properties of the password policy
$PassPolicy = (Get-ADFineGrainedPasswordPolicy -Filter {name -like $PassPolicyName} -Properties MinPasswordLength, PasswordHistoryCount, MaxPasswordAge)
# Maximum password age (days) 
$MaxPassDays = $PassPolicy.MaxPasswordAge.Days
# Minimum password length
$MinPassLength = $PassPolicy.MinPasswordLength
# Number of remembered passwords
$PassHistCount = $PassPolicy.PasswordHistoryCount
# Remaining days of password validity
$RemainingDays = ($MaxPassDays - $PassLastSetDays)

# Display message only the X last days ($MsgDays) before the password expires
if ( ($RemainingDays -ge 0) -and ($RemainingDays -le $MsgDays) ) 
{   
    # Text string for the remaining days
    switch ($RemainingDays)
    {
        {$_ -eq 1} { $MsgRemDaysText = "den" }
        { ($_ -gt 1) -and ($_ -lt 5) } { $MsgRemDaysText = "dny" }
        Default {
            $MsgRemDaysText = "dní"
        }
    }
    
    # MessageBox settings
    Add-Type -AssemblyName PresentationCore, PresentationFramework
    $MsgTitle = "ZMĚNA HESLA"
    $MsgBody = "Vaše heslo vyprší za $RemainingDays $MsgRemDaysText. Chcete-li heslo změnit, klikněte na ANO`na zvolte 'Změnit heslo'.`n`nMin. délka hesla: $MinPassLength (znaků)`nPočet posledních hesel, která nelze použít: $PassHistCount"
    $MsgIcon = [System.Windows.MessageBoxImage]::Asterisk
    $MsgButtonType = [System.Windows.MessageBoxButton]::YesNo
    
    # MessageBox result
    $MsgResult = [System.Windows.MessageBox]::Show($MsgBody,$MsgTitle,$MsgButtonType,$MsgIcon)
    
    # If the answer ($MsgResult) = YES
    if ( $MsgResult -eq 6 ) {

        # Send CTRL+ALT+DEL command 
        (New-Object -COM Shell.Application).WindowsSecurity()    
          
    }
}

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.