Por Luke Orellana

La seguridad es ahora más exigente que nunca en TI. No solo estamos obligados a jugar al juego del gato y el ratón con interminables parches de vulnerabilidades de seguridad, sino que también estamos obligados a mantener nuestra infraestructura dentro de ciertas pautas de cumplimiento normativo. Ya sea para aprobar una auditoría financiera o de salud, siempre hay restricciones de seguridad que deben implementarse para pasar estas inspecciones con éxito. Si alguna vez se te ha asignado la tarea de implementar rotaciones recurrentes de contraseñas, estoy seguro de que puede comprender los dolores de cabeza que causará tener una solución distinta para cada sistema. Afortunadamente, podemos usar PowerCLI para realizar los cambios de contraseña en ESXi en cuestión de minutos. En este post, te mostraré cómo.

Cambio de raíz en varios hosts desde la consola

Primero, veamoss cómo cambiar inmediatamente las contraseñas de raíz de todos los hosts desde la consola de PowerShell. Es algo muy útil si un empleado TI o alguien que hubiese tenido acceso a todas las contraseñas abandona la empresa o es despedido. En estos casos, es obligatorio un cambio de contraseña en todos los sistemas. Para comenzar, asegúrate de que sea cual sea el punto final desde el que esté ejecutando los comandos, el módulo PowerCLI está instalado. Si no lo está, ejecuta el siguiente comando en una consola de administración de PowerShell:

Install-Module -Name VMware.PowerCLI

Una vez que el módulo PowerCLI está instalado, la parte dura ha terminado. Iniciaremos una conexión a ESXi usando el cmdlet Connect-VIServer y especificaremos la dirección de vCenter con el parámetro -Server:

Connect-VIServer -server "192.168.0.7"

Te pedirá las credenciales de inicio de sesión de vCenter, introduce las adecuadas y selecciona Aceptar:

changing passwords using PowerShell

Ahora queremos ver una lista de todos los hosts en los que cambiaremos la contraseña de Raíz. Escribe la siguiente sintaxis para ver una lista de todos los hosts ESXi en vCenter:

 Get-VMhost  -Name * 

Vamos a crear las variables de contraseña para la nueva credencial y nuestra credencial raíz actual. Como se muestra en la imagen siguiente, escribe el nombre de usuario como «root» y luego establece la nueva contraseña que desees:

$NewPassword = Get-Credential

$CurrentPassword = Get-Credential

Ahora usaremos el cmdlet Set-VMHostAccount para cambiar la contraseña de root de todos nuestros hosts a nuestra variable $NewPassword:

ForEach($name in (Get-VMhost -name * ).name) { Connect-viserver -server $name -Credential $CurrentPassword -NotDefault; Set-VMHostAccount -server $name -UserAccount root -Password $NewPassword.GetNetworkCredential().Password}

Ya tenemos una conexión establecida entre cada host ESXi y seguidamente se cambia la contraseña:

Automatizando las rotaciones de contraseña ESXi

Ahora vamos a dar un paso más. Hace un tiempo, creé un artículo sobre cómo comenzar a automatizar KeePass. Usaremos el módulo KeePass PowerShell para almacenar nuestra contraseña ESXi y crear una tarea programada para ir rotando nuestras contraseñas ESXi y actualizar la base de datos KeePass. He creado una base de datos KeePass con la siguiente estructura de carpetas.

Nota: la secuencia de comandos que compartiré se basará en que los nombres de los títulos son «ESXi» y «VCenter», así como la ubicación de estas entradas en la raíz de la carpeta ESXi DB. Siempre puedes editar el script para cambiar las ubicaciones de las carpetas y los nombres de los títulos:

KeePass

Ahora debo crear un archivo de contraseña encriptado. Esto me permitirá almacenar de forma segura la contraseña de la base de datos KeePass en un recurso compartido de red y hacer que mi tarea programada se ejecute como una cuenta que tenga acceso a ese recurso compartido. Para configurar esto solo tenemos que ejecutar la siguiente sintaxis:

$Key = New-Object Byte[] 32
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($Key)
$Key | out-file "C:\Scripts\ESXi Pass Rotate\aes.key" 

A continuación, tenemos que crear nuestro archivo de contraseña. Escribe la siguiente sintaxis cuando se te soliciten las credenciales, introduce tu contraseña en la base de datos KeePass. El campo de nombre de usuario no importará:

(get-credential).Password | ConvertFrom-SecureString -key (get-content "C:\Scripts\ESXi Pass Rotate\aes.key") | set-content "C:\Scripts\ESXi Pass Rotate\password.txt"

Ahora debemos instalar los módulos de KeePass Powershell para manipular KeePass. Abre una consola de administración de PowerShell y escribe lo siguiente:

 install-module -name PoShKeePass 

Ahora, guarda el código en un archivo .ps1. He escrito un script que cogerá nuestra clave de contraseña, nuestro archivo de contraseñas y la base de datos de KeePass, rotará automáticamente las contraseñas en los hosts ESXi y guardará la nueva contraseña en KeePass:

[CmdletBinding()]
param(
    [Parameter(Mandatory=$True)]
    [String]$KeePassDB,
 
    [Parameter(Mandatory=$True)]
    [String]$Vcenter,
 
    [Parameter(Mandatory=$True,ParameterSetName="PassFile")]
    [String]$PasswordFile,
 
    [Parameter(Mandatory=$True,ParameterSetName="PassKey")]
    [String]$Passwordkey
 
    )
Begin{
        
        #Retrive KeePass Password if -Passwordfile parameter is used
        if($PasswordFile -and $Passwordkey)
        {
            $KeePassPW = Get-Content $PasswordFile | ConvertTo-SecureString -Key (Get-Content $Passwordkey)
        }
 
        
        #Get current passwords for VCenter and ESXi
        New-KeePassDatabaseConfiguration -DatabaseProfileName 'ESXiAutoRotate' -DatabasePath $KeePassDB -UseMasterKey
        Try
        {
            
            $CurrentESxiPassword = (Get-KeePassEntry -DatabaseProfileName 'ESXiAutoRotate' -Title "ESXi" -WithCredential -MasterKey $KeePassPW ).password
            $currentVCenterPassword = (Get-KeePassEntry -DatabaseProfileName 'ESXiAutoRotate' -Title "VCenter" -WithCredential -MasterKey $KeePassPW ).password
            $currentVCenterUsername =(Get-KeePassEntry -DatabaseProfileName 'ESXiAutoRotate' -Title "VCenter" -WithCredential -MasterKey $KeePassPW ).username
            $VcenterCredential = New-Object System.Management.Automation.PsCredential($currentVCenterUsername,$currentVCenterPassword)
            $CurrentESXiCredential = New-Object System.Management.Automation.PsCredential("root",$CurrentESxiPassword)
        }
        Catch
        {
            
            Write-error -Message "Unable to retrieve credentials from $KeePassDB"  
        }
 
        #Get the date for ESXi Password Title
        $timestamp = Get-Date -Format o | foreach {$_ -replace ":", "."}
}
 
Process{
        
        #Autogenerate new credentials and create new entry in keepass
        New-KeePassEntry -DatabaseProfileName 'ESXiAutoRotate' -KeePassEntryGroupPath "ESXI DB" -Title "ESXi-New" -Notes "New auto rotate password on $timestamp" -UserName "root" -KeePassPassword $(New-KeePassPassword -UpperCase -LowerCase -Digits -SpecialCharacters -Length10)  -MasterKey $KeePasspw | Out-Null -ErrorAction SilentlyContinue
        $NewESxiPassword = (Get-KeePassEntry -DatabaseProfileName 'ESXiAutoRotate' -Title "ESXi-New" -WithCredential -MasterKey $KeePassPW )
 
 
        #If new password is able to be generated, continue with password changes on ESXi environment
        if($NewESxiPassword)
        {
            #Get Connection to VCenter
            Connect-VIServer -Server $Vcenter -Credential $VcenterCredential
            
            #Change Password for all ESXi Hosts in VCenter
            ForEach($name in (Get-VMhost -name * ).name)
            {
            
                Connect-viserver -server $name -Credential $CurrentESXiCredential -NotDefault; Set-VMHostAccount -server $name -UserAccount root -Password $NewESxiPassword.Credential.GetNetworkCredential().password
            }
 
        }
        Else
        {
 
            Write-Error -Message "There was an issue with creating the new ESXi password"
            
        }
 
}
End {
    
    #clean up keepass
    Update-KeePassEntry -Title 'ESXi-Old' -KeePassEntry (Get-KeePassEntry -DatabaseProfileName 'ESXiAutoRotate' -Title "ESXi" -WithCredential -MasterKey $KeePassPW ) -DatabaseProfileName 'ESXiAutoRotate' -MasterKey $KeePassPW -KeePassEntryGroupPath "ESXI DB" -Force
    Update-KeePassEntry -Title 'ESXi' -KeePassEntry $NewESxiPassword -DatabaseProfileName 'ESXiAutoRotate' -MasterKey $KeePassPW -KeePassEntryGroupPath "ESXI DB" -Force
    Remove-KeePassDatabaseConfiguration -DatabaseProfileName 'ESXiAutoRotate' -Confirm:$false
} 

Tengo todos mis archivos requeridos en una carpeta en C:\Scripts\ESXi Pass Rotate”:

Para ejecutar el script, simplemente abre una consola de PowerShell y ejecuta la siguiente sintaxis completando la ubicación correcta de cada archivo según sea necesario:

powershell -file "C:\Scripts\AutoRotatePassword.ps1" -keepassdb "C:\Scripts\ESXi Pass Rotate\ESXi DB.kdbx" -vcenter "192.168.0.7" -passwordfile "C:\Scripts\ESXi Pass Rotate\password.txt" -passwordkey "C:\Scripts\ESXi Pass Rotate\aes.key"

Una completada la secuencia de comandos, podemos ver que nuestra nueva contraseña se ha introducido en KeePass, y al probar nuestros hosts ESXi, podemos ver que la nueva contraseña funciona:

Este script se puede ejecutar con el Programador de tareas para realizar rotaciones de contraseñas mensuales automáticas, si es necesario. Además, recomiendo agregar algunos «checks» y «logs» más en el script para garantizar que un host ESXi que tenga un problema con el cambio de contraseña quede resaltado para que puedas solventarlo. Lo último que deseas es tener que recuperar la contraseña raíz en el host porque la contraseña se ha eliminado de KeePass. La posibilidad de combinar los cambios automáticos de contraseña de ESXi con KeePass te muestra el poder real de los módulos PowerShell en situaciones como esta.

¿Lo ves útil? ¿Algo que te gustaría añadir? Házmelo saber debajo en los comentarios.

¡Gracias por leer!