Habilitar logging de netlogon sólo para eventos de Logon

Si tienes habilitada la auditoría de eventos de logon en tus controladores de dominio probablemente te hayas dado cuenta de que solamente quedan registrados los eventos de Kerberos.

Si tienes un proxy en el que los usuarios se autentican con NTLM usando una cuenta de dominio verás que estos eventos no quedan registrados en el visor de eventos del controlador de dominio. Si embargo, sí quedarían en el propio proxy si este tiene habilitada la auditoría de eventos de logon.

Para poder ver estos inicios de sesión tienes que tener habilitado el debug logging en los controladores de dominio. Habilitar esto es muy fácil y lo indica claramente en este KB de Microsoft. El problema es que si sigues los pasos de este KB vas a ver en el log muchos más eventos de los que seguramente te interesan.

Si solamente quieres que se registren los eventos de Logon tienes que ejecutar el siguiente comando en todos tus controladores de dominio:

nltest /DBFlag:0x20000004

Después de que ejecutes ese comando vas a ver los registros de inicio de sesión en el archivo C:\Windows\Debug\netlogon.log. Este archivo lo puedes enviar a tu sistema de centralización de logs para un posterior analísis.

Para desactivar el registro de estos eventos basta con ejecutar el siguiente comando:

nltest /DBFlag:0x0

Exportar y eliminar OU vacías en Active Directory

Tenemos una implementación de FIM (Forefront Identity Manager) que siempre está haciendo cosas raras.

La última de estas es que debido a un cambio en el ERP fueron creadas cientos de OU vacias en el Active Directory 🙂

Maravilloso…

Afortunadamente, con PowerShell y ActiveRoles fue muy fácil saber cuáles fueron estas OU. Aquí os dejo el script:


$OUS = Get-QADObject -Type organizationalunit -SizeLimit 0

$output = @()

foreach($OU in $OUS) {
$Children = Get-QADObject -SearchRoot $OU -LdapFilter “(!(objectClass=organizationalUnit))” -SizeLimit 1 -WarningAction SilentlyContinue | Measure-Object
$outputObj = “” | select OU,CanonicalName,HasChildren,Level
$outputObj.OU = $OU.Name
$outputObj.CanonicalName = $OU.CanonicalName

if ($Children.Count -ne 0) {
$outputObj.HasChildren = “Yes”
}
else {
$outputObj.HasChildren = “No”
}

$outputObj.Level = $OU.CanonicalName.Split(“/”).Count
$output += $outputObj
}

$output | export-csv -notypeinformation -encoding utf8 -delimiter “;” EmptyOUs.csv

Este nos va a exportar un CSV que luego podemos abrir en Excel. En este se muestra la OU, el nombre canónico de la OU, si tiene hijos que no sean otras OU vacías y el nivel de la OU (siendo la raíz del dominio el nivel 0).

Una vez que tenegamos identificadas las OU vacías, podemos exportar el listado de los nombres canónicos de las OU a borrar y borrarlas con el siguiente comando:

LA SIGUIENTE LINEA ES PELIGROSA, ASEGURATE DE TENER UN BACKUP DEL AD ACTUALIZADO ANTES DE EJECUTARLA

get-content -encoding utf8 MiLista.txt | Remove-QADObject -DeleteTree -Force -Confirm:$false

Algunas GPO son “destructivas”

Vaya título, ¿No?

Esto es simplemente un recordatorio/advertencia para nuevos y no tan nuevos administradores de Windows.

SIEMPRE tenemos que tener en cuenta qué es lo que hace una GPO y a quíen se aplica, y probarla muy bien antes de pasarla a producción, porque sino podemos pasar un mal rato. Sobre todo si no tenemos un control de configuración actualizado 😉

Veamos un ejemplo y el motivo del título de este post:

Eres el administrador del dominio contoso.com (jeje) y tienes 20 servidores en la OU Servidores. Cada uno de estos servidores se utiliza para un software en particular y cada software se ejecuta con su propia cuenta de servicio.

Para que una cuenta de AD pueda iniciar sesión como servicio se le deben dar privilegios de Logon as service utilizando secpol.msc o gpedit.msc (esto ya estaba hecho para cada uno de estos 20 servidores).

Debido a necesidades de negocio tienes que agregar un servidor adicional para otro software que también se va a ejecutar con una cuenta de servicio. Como acabas de aprender sobre GPO, decides hacer una GPO para asignar los privilegios de iniciar sesión como servicio a la cuenta del software en cuestión y aplicarla a la OU de Servidores y así te evitas configurar el servidor localmente.

Excelente, ¿No?

Pues no, muy mal, te acabas de cargar la configuración de los otros 20 servidores y seguramente en un par de horas tendrás a media empresa quejándose de que las aplicaciones no funcionan. ¡Mas te vale que sepas que cuenta de servicio tenía privilegios de iniciar sesión como servicio en cúal servidor!

¿Qué ha salido mal? Resulta que algunas políticas de grupo son “destructivas”, con esto quiero decir que reemplazan lo que ya estaba configurado. No hacen un concatenado o “merge” de las opciones configuradas y por eso debes saber muy bien lo que estas hacen antes de pasarlas a producción.

Otros casos en los que tienes que tener mucho cuidado de no sobreescribir cosas que ya estaban definidas:

  • Definiendo grupos de seguridad locales -> Puedes quitarle permisos a usuarios que ya estaban definidos. Es mejor que uses GPP.
  • Excepciones del proxy configuradas en Internet Explorer -> Puedes dejar sin acceso a sistemas web a muchos usuarios

¿Cómo se pudo haber evitado lo de arriba? La solución más sencilla sería crear un grupo de Cuentas de servicio y agregar todas las cuentas de servicio definidas en cada uno de los servidores y DESPUES configurar la GPO, dándole permisos de Logon as service a este grupo.

Así que ya sabes, ojito con las GPO que defines.

Crear Directorio Personal/Carpeta Particular (Home Directory) con Powershell

Seguimos migrando el servidor de ficheros…

Esta vez toca mover los directorios personales (carpeta particular en AD) de todos los usuarios al nuevo servidor.

Ir usuario a usuario cambiando este directorio es muy tedioso, por lo que una vez más vamos a usar PowerShell para terminar mas rápido.

Lo primero que tenemos que hacer es crear los directorios en el nuevo servidor para después mover los datos. Una de las cosas que hay que tener cuenta al mover estos directorios personales de cada usuario es que solo ese usuario (y los administradores del servidor) deben tener acceso a estos. Cuando este directorio se asigna desde la interfaz de administración de Active Directory esta se encarga de asignar los permisos requeridos, pero cuando lo haces directamente desde el servidor de ficheros los permisos se deben cambiar manualmente.

Afortunadamente, los de Scripting Guy de Microsoft crearon una serie de posts donde explican como hacer esto a través de PowerShell, el problema es que el código que está en la parte 3 de la serie, que debería hacer todas estas tareas, tiene varios bugs.

Desde aquí te puedes decargar ese código corregido y convertido en una funcion (Create-HomeDirectory). Recuerda cambiar los valores de HomeDrive, UserRoot y Domain por los valores que correspondan para tu entorno.

Para usar la función solo tienes que ejecutar Create-HomeDirectory NombreUsuario.

Una vez que esten creados todos los directorios con los permisos correspondientes en el nuevo servidor solo queda mover los datos con Cortar y Pegar, Robocopy o cualquier otra herramienta.

A Active Directory no le importa si tu nombre es Jose o José

Hoy fue uno de esos días que se viven una vez cada 10 años, ¡Hoy el usuario tuvo la razón!

Ya lo se, parece increíble, pero es la verdad.

Tenemos una aplicación que coge los atributos de un usuario del Active Directory y después los usa para conectarse a diferentes servicios. Esta funciona perfectamente para todos los usuarios excepto para José. Cuando José se intenta conectar a uno de los servicios estos siempre dan un error de autenticación (usuario o contraseña erroneos) y fallan.

Después de estar varios días mirando logs finalmente dimos con el problema… La aplicación se intenta autenticar utilizando el usuario Josñ. ¡Un aplauso para los desarrolladores que no soportan Unicode!

El usuario nos comentaba que él podía hacer que la aplicación funcionase si utilizaba el usuario Jose en vez de José y, por supuesto, nosotros no le creímos. ¿Como va a ser lo mismo conectarse con un usuario que con otro? ¿Tendría dos usuarios en el Active Directory?

Para nuestra sorpresa, no había otro usuario y la aplicación si que funcionaba al iniciar sesión con el usuario Jose. Lo curioso es que cuando revisabamos los logs aparecía que el usuario que se conectaba era José.

Después de investigar un rato conseguimos el siguiente artículo de Microsoft que confirmaba lo que decía el usuario. Cuando te intentas conectar al Active Directory con un usuario que tiene acentos o simbolos diacríticos en el nombre (sAMAccountName) se hace una conversión a “símbolos simples” para facilitar el inicio de sesión con interfaces que no soportan estos caracteres. Bien de parte de Microsoft, muy mal de parte de los desarrolladores.

Así que ahí está… Todos los días se aprende algo nuevo.

Autodiscover con dominio SMTP compartido

Paciencia y foco, este post es un poco denso 😀

Fusiones, adquisiciones o simple colaboración entre empresas de una misma corporación… Si eres administrador del servicio de correo de tu empresa (por vocación o por enmarronamiento) y has vivido alguno de los momentos que menciono antes, seguramente te ha tocado pasar por una situación llamada “Split SMTP domain” o “Shared SMTP address space”.

Un dominio SMTP compartido, como su nombre lo indica, es un mismo dominio SMTP que es compartido por varias organizaciones o sistemas de correo. Esto quiere decir que, por ejemplo, para el dominio midominio.com, puede haber buzones de correo en los servidores de la organización Alfa o en los servidores de la organización Beta.

Cuando una persona envía desde internet un correo a empleado@midominio.com, este es recibido por los servidores de la organización Alfa, si este buzón se encuentra en sus servidores el correo se entrega localmente, de lo contrario es reenviado a la organización Beta. Fácil, ¿No?

El problema, como siempre, está en los detalles. Desde hace varias versiones de Exchange, Lync y Outlook existe algo llamado Autodiscover, que no es más que un mecanismo para encontrar información de autoconfiguración de dispositivos, disponibilidad de personas y localización de servidores sin necesidad de introducir manualmente los parametros de estos servidores. Tener el Autodiscover funcionando de forma correcta es bastante complicado, requiere configuración de los servidores de CAS, certificados de confianza, cambios en el DNS, publicación de SCP en AD, una pata de conejo y extracto de mandragora, entre otras cosas.

Con un poco de esfuerzo, se puede configurar el Autodiscover para que funcione correctamente en una organización de Exchange. Pero, ¿Qué pasa si tengo un dominio SMTP compartido? No hay problema, en Exchange se puede utilizar el atributo ExternalEmailAddress (llamado targetAddress en el AD). Este atributo nos indica, en el caso de Autodiscover, a que dominio debemos recurrir para buscar los parametros de configuración de un buzón.

Por ejemplo, en la organización Alfa tengo los dominios alfa.com y omega.com y en la organización Beta tengo los dominios beta.com y omega.com. Cuando intento configurar mi Outlook a través de Autodiscover para el buzón boli@omega.com primero me conecto a autodiscover.omega.com, que está alojado en la organización Alfa, el Exchange de esta organizacón ve que el usuario boli@omega.com tiene un ExternalEmailAddress de boli@beta.com, y redirige el cliente de Outlook a autodiscover.beta.com. Outlook se conecta a autodiscover.beta.com y obtiene todos los parámetros necesarios para configurar correctamente este buzón. MAGIA

Si todo fuese tan fácil no estaría escribiendo esta entrada…

¿Qué pasa si no tengo relación de confianza entre los dominios de AD de ambas organizaciones? En este caso Autodiscover no va a funcionar para los usuarios de una de las dos organizaciones. ¿Por qué? La razón es muy sencilla, cuando te conectas con el usuario boli@omega.com a autodiscover.omega.com este primer servidor que está en la organización Alfa te pide que te autentiques con usuario y contraseña. ¿Pero como me autentico si mi usuario no existe en la organizacion Alfa? EXACTO, no puedes, por lo que Autodiscover no va a funcionar para ti. Y con esto vendran popups constantes en Lync y Outlook. Si tienes Lync 2013 puedes evitar estos popups con este hack, pero si tienes Lync 2010 no puedes hacer nada.

Así que ya sabes, si te piden que compartas un dominio SMTP entre varias organizaciones de Exchange, trata, en la medida de lo posible, de tener una relación de confianza entre las mismas. De lo contrario puedes tener problemas tanto con el Lync como con Outlook.

Convertir SID en Base64 a String con Powershell

Si exportas los datos del Active Directory usando LDIFDE te darás cuenta de que algunos campos vienen en formato Base64. Por lo general esto no es un problema, ya que estos se pueden decodificar usando cualquier herramienta de las muchas que hay en la web para este propósito. Sin embargo, en el caso del SID, si intentas pasar de Base64 a String verás que la salida esta compuesta de un montón de caracteres extraños.

Para pasar esto al formato que todos conocemos de S-1-5-***** puedes utilizar el siguiente script:

$sidBase64 = "AQUAAAAAAAUVAAAAPXj3WXwxNhGBjE3aTQQAAA=="

$sid = [System.Convert]::FromBase64String($sidBase64)

$nuevoSid = New-Object System.Security.Principal.SecurityIdentifier($sid, 0)

$nuevoSid.ToString()

sid

Referencia

Incluir manager al exportar un listado de usuarios

Un requisito muy común a la hora de exportar un listado de usuarios del Active Directory es incluir el manager o responsable de una persona dentro del listado.

Hacer esto con PowerShell es muy sencillo, utilizando nuestro viejo ActiveRoles podemos ejecutar el siguiente comando:

Get-QADUser | Select-Object Name,Department,Title,Manager,Company

¿Problema? El comando nos devuelve todos los datos, pero el manager viene con su Distinguished Name (DN: CN=El Jefe,OU=Mi OU,DC=MiDominio,DC=Root). Esto puede que sea correcto, pero no nos es de mucha utilidad a la hora de pasarle la información al auditor que necesita este listado para ayer por la mañana 🙂 .

Para solucionar este detalle podemos hacer dos cosas, decirle al auditor que es “eche e o que hai”, con lo que seguramente te mirará con mala cara y luego se chivará con el jefe, o entregarle un listado en condiciones. Para esto último tenemos que usar las propiedades calculadas de la siguiente forma:

Get-QADUser | Select-Object Name,Department,Title,@{Expression={(Get-QADUser $_.Manager).Name};Label="Manager"},Company

Listo, puedes entregarle la información la información al auditor y seguir tomándote el café mientras le cuentas a tus compis lo mal que lo ha hecho Lenovo con todo el rollo de Superfish.

Active Directory, el atributo pwdLastSet y cómo extender tiempo de expiración de una contraseña

Hoy quiero hablar un poco sobre el atributo pwdLastSet y su importancia.

Este es uno de esos atributos que no se suele mirar mucho, pero que puede ser de mucha utilidad si se sabe usar.

Cada vez que cambiamos nuestra contraseña en Active Directory se modifica este atributo y se guarda el Time Stamp correspondiente a la fecha/hora de ese momento. Este valor solo puede ser asignado por SYSTEM, por lo que las únicas formas de cambiarlo son:

  1. Cambiando la contraseña
  2. Marcando la casilla el “El usuario debe cambiar la contraseña en el siguiente inicio de sesión”

Si pedimos que el usuario cambie contraseña en el próximo inicio de sesión el sistema cambia el valor de este atributo a 0.

pwdLastSet1

Si tenemos aplicada una política que pide que los usuarios cambien de contraseña a cada X días el sistema lo que hace es calcular si la contraseña está caducada en base a este atributo, restándole el valor al Time Stamp del momento en el que iniciamos sesión y convirtiendo este valor a días.

Teniendo en cuenta esto útlimo, aquí va el tip:

Supongamos tenemos una política que pide cambio cada 30 días, ahora imagina la siguiente situación.

El CEO se va de vacaciones cuando han pasado 29 días desde que cambió la contraseña. Al día siguiente te llama de emergencia porque el móvil no le sincroniza el correo o no se puede conectar a la VPN corporativa. ¿Cómo hacemos para extenderle el tiempo de caducidad de la contraseña sin cambiarla?

Tenemos tres posibilidades:

  1. Te da su contraseña y le das a cambiar contraseña poniendo la misma que tenía, violando seguramente la política de seguridad de la empresa.
  2. Editamos la cuenta del usuario marcando la casilla “La contraseña nunca expira”, violando nuevamente la política de seguridad.
  3. Le extiendes el tiempo de caducidad a la contraseña actual.

¿Cómo hacemos esto último? Muy facil, hay un tercer posible valor que le podemos asignar al atributo pwdLastSet. Si colocamos el valor -1 utilizando el editor de atributos del ADUC (Active Directory Users and Computers) el sistema convierte este número al Time Stamp actual, dándole a la contraseña otros 30 días de vigencia.

Un punto importante es que no le podemos asignar el valor -1 directamente. Primero hay que asignarle 0, guardar y salir de la cuenta, enterar nuevamente y cambiar el valor a -1. Esto lo podemos hacer más rápidamente con el siguiente script de Powershell.


$cuenta = "usuario del CEO"
Set-QADUser -Identity $cuenta -ObjectAttributes @{pwdLastSet='0'}
Set-QADUser -Identity $cuenta -ObjectAttributes @{pwdLastSet='-1'}

Referencia

Administrar Active Directory con PowerShell y ActiveRoles Management Shell

La administración de Active Directory se ha hecho más sencilla con el paso de los años, se ha pasado por la interfaz ADUC (Active Directory Users and Computers), herramientas de línea de comando, el Centro de administración de Active Directory y en los últimos años los Snap-ins de PowerShell. Las interfaces gráficas son muy útiles para tareas puntulaes, tales como cambiar el nombre de un usuario, bloquear y desbloquear cuentas o mover PCs de una OU a otra. Sin embargo, para trabajos en lote es mejor utilizar scripts de PowerShell. El Snap-in de Active Directory incluído en las herramientas de RSAT de Windows 7 están bien, pero en mi opinión tiene fallos que dificultan su utilización. No quiero entrar en detalle, pero uno de estos fallos es que no muestra los Time Stamps de algunos campos en un formato legible y estos campos se utilizan mucho en los scripts.

Un sustituto de este Snap-in es el ActiveRoles Managemente Shell ofrecido de forma gratuita por DELL (antes Quest) desde hace algunos años. Lo puedes descargar desde aquí.

Algunos ejemplos de scripts que se pueden ejecutar con esta herramienta son los siguientes:

  • Listar usuarios con su última fecha de logon (la diferencia entre LastLogon y LastLogonTimeStamp para el próximo post)
    Get-QADUser -IncludedProperties LastLogonTimeStamp | Select-Object Name,ParentContainer,LastLogonTimeStamp
  • Listar usuarios deshabilitados
    Get-QADUser -Disabled:$true
  • Deshabilitar todas las cuentas de equipo que estén inactivas
    Get-QADComputer -Inactive | Disable-QADComputer
  • Exportar todos los usuarios de la OU Administración a un CSV delimitado por punto y coma
    Get-QADUser -SearchRoot "chorbo.es/Administracion" | Export-Csv -NoTypeInformation -Encoding UTF8 -Delimiter ";" UsuariosAdministracion.csv