El otro dia se montó un buen revuelo en la oficina.
Un certificado de nosequien, estaba a punto de caducar y nadie se habia dado cuenta…

¿Pero no está monitorizado?
Fue la pregunta más repetida…

Y no, no lo estaba, nadie nos lo había pedido.

Vale, vamos a monitorizarlo…

Hasta ahora, la manera de monitorizar certificados era accediendo a la uri donde estaba instalado, con un curl, PERO, esta vez no era tan sencillo, se trataba de monitorizar los Certificados instalados en los propios servidores…Windows 🙁

Mi primera pregunta al admin fue – “¿Cómo ves tú la fecha en la que caducan?”
Y el admin contestó lo que me temía – “Mmm…abro la Consola de Certificados y echo un vistazo…”

Acabáramos…ya estamos con las ventanitas…
Bueno, pues me puse a buscar por aquí..[google], por allá [más google]… y BINGO!
Menos mal que existe Powershell <3

Parece que con este comando podemos listar los certificados instalados en la máquina:

PS C:> Get-ChildItem -Path cert:\LocalMachine\


Name : SmartCardRoot
Name : AuthRoot
Name : CA
Name : Trust
Name : Disallowed
Name : SMS
Name : McAfee Trust
Name : My
Name : Root
Name : TrustedPeople
Name : TrustedDevices
Name : Remote Desktop
Name : TrustedPublisher
Name : REQUEST

Si los que quieres ver son los de la carpeta Personal

consola de certificados de Windows

curiosamente, tienes que llamarla con esta ruta:

Get-ChildItem -Path cert:\LocalMachine\My

y ahí ya te salen…

Vale, guay.

Pero…¿Dónde está la fecha de caducidad?

Pues hay que decirle al Get-ChildItem específicamente que te muestre los campos posibles, así que:

Get-ChildItem -Path cert:\LocalMachine\My | fl *

y ahí si que te sale toda la chicha:

OK, entonces la fecha de caducidad está en NotAfter.

Vale, pues ya tenemos todos los datos, no?

Vamos a crear un bucle para comprobar que la fecha de NotAfter, en cada certificado que tengamos en la máquina, dentro de la carpeta Personal, no es menor que un umbral.

Bueno, yo he puesto dos umbrales, el de warning y el de critical y si en algún caso SI cumplen la condición, que se escriba la linea en un fichero ($STATUSFILE_warn o $STATUSFILE_crit), ya que si salimos del loop a la primera de cambio, no seguiría chequeando si hay algún certificado más que cumpla la condición.

Get-ChildItem -Path cert:\LocalMachine\My  | ForEach-Object { 
     $name = $_.Subject 
     $dateExpireDays = $_.NotAfter 
         If ($dateExpireDays -lt $dateDeadline_crit){ 
             $MSG = "CRITICAL: [$name] expires [$dateExpireDays]" 
             Add-Content $STATUSFILE_crit "$MSG" 
         }ElseIf ($dateExpireDays -lt $dateDeadline_warn){ 
             $MSG = "WARNING: [$name] expires [$dateExpireDays]" 
             Add-Content $STATUSFILE_warn "$MSG" 
             } 
       } 
 }

Los umbrales $dateDeadline_crit y $dateDeadline_warn se pueden pasar como parámetro o ponerlos a fuego en el script.

  • exit 2 -> si el fichero $STATUSFILE_crit no es null, ya que eso significaria que tiene alguna linea escrita.
  • exit 1 -> si el fichero $STATUSFILE_warn no es null, misma idea que antes.
  • exit 0 -> when no news, good news 😀

Podeis ver el desarrollo completo en mi repo de GitHub 😉