Saltar al contenido

authnd, un servidor LDAP para personas que están en otro lugar

Un directorio LDAP, y opcionalmente un reino Kerberos, sobre personas guardadas en un archivo de configuración, una base de datos SQL u otro directorio.

Las personas de un sitio ya están en una base de datos, un archivo u otro directorio. Lo que quiere autenticarlas habla LDAP. authnd es la fachada: hace binds y búsquedas sobre los orígenes de go-authn/directory, así que lo que guarda una base de datos puede leerlo cualquier cosa que sepa consultar un directorio. Go puro, CGO_ENABLED=0, un solo binario. Estas páginas describen la v0.11.1, cuyas entradas siguen los esquemas estándar y superan el esquema que sirve en cn=Subschema, con go-authn/ldap v0.8.0 y go-authn/directory v0.14.0 por debajo; lo que está verificado y lo que no figura en la página de estado.

Actualizar desde la v0.10.x

  • publish_nt_hash = true necesita ahora un bloque samba, o authnd no arranca.
  • Una persona sin uidNumber, gidNumber y homeDirectory ya no es un posixAccount, y un grupo sin gidNumber ya no es un posixGroup, así que un consumidor que filtra por esas clases ve menos entradas: consulte las entradas.
  • Un bloque users "ldap" lee por defecto más del directorio que tiene detrás: consulte personas.

authnd check con el nuevo binario dice las tres cosas antes del reinicio.

authnd --config /etc/authnd      # serve
authnd check /etc/authnd         # say what would be served, without listening

La configuración más pequeña

listen  = "127.0.0.1:3893"            # the default
base_dn = "dc=example,dc=org"         # required

reader "cn=reader,dc=example,dc=org" { password_file = "/etc/authnd/reader.pw" }

user "alice" { password_file = "/etc/authnd/passwords/alice.pw" }

group "staff" { members = ["alice"] }

Las personas se publican como uid=<name>,ou=people,<base_dn>, y los grupos como cn=<name>,ou=groups,<base_dn>. Lo que es cada entrada se deduce de lo que dio su origen: una persona es un account, o un inetOrgPerson cuando hay un sn, y un posixAccount solo con uidNumber, gidNumber y homeDirectory; toda persona es un uidObject. Un grupo es un posixGroup (con memberUid) cuando tiene un gidNumber, si no un groupOfNames (con DN en member), o un organizationalRole cuando además está vacío. sshPublicKey se añade cuando la persona tiene claves, y sambaNTPassword cuando publish_nt_hash lo indica y se puede dar un SID. Cada entrada supera el esquema servido en cn=Subschema antes de publicarse: consulte las entradas y el esquema. Hasta la v0.10.2, toda persona era un posixAccount y todo grupo un posixGroup, tuvieran lo que tuvieran.

--config (-c) admite un archivo o un directorio y puede repetirse; un directorio equivale a todos los archivos .hcl que contiene, leídos por orden de nombre y fusionados en una sola configuración. Una configuración sin base_dn, o sin nadie dentro, no arranca.

Quién puede hacer un bind, y quién puede leer

A un servidor LDAP se le pide que pruebe quiénes son las personas, así que sus rechazos son el diseño. Estas son las respuestas del binario de la versión v0.10.0 al propio cliente de OpenLDAP:

$ ldapwhoami -x -H ldap://127.0.0.1:3893 -D uid=alice,ou=people,dc=example,dc=org -y alice.pwin
dn:uid=alice,ou=people,dc=example,dc=org

$ ldapwhoami -x -H ldap://127.0.0.1:3893 -D uid=alice,ou=people,dc=example,dc=org -y wrong.pwin
ldap_bind: Invalid credentials (49)

$ ldapwhoami -x -H ldap://127.0.0.1:3893 -D uid=alice,ou=people,dc=example,dc=org -w ''
ldap_bind: Server is unwilling to perform (53)
	additional info: an unauthenticated bind proves nothing, and this server does not accept one

$ ldapsearch -x -LLL -H ldap://127.0.0.1:3893 -D uid=alice,ou=people,dc=example,dc=org -y alice.pwin -b dc=example,dc=org '(uid=alice)'
Insufficient access (50)
Additional information: only a reader may search
peticiónrespuestapor qué
nombre vacío, contraseña vacía (RFC 4513 §5.1.1, anónimo)éxitodice «no soy nadie», lo cual es cierto, y un cliente lo envía antes de haber descubierto nada
un nombre y una contraseña vacía (§5.1.2, no autenticado)unwillingToPerformnombra a alguien y no prueba nada; §5.1.2 pide exactamente este código. invalidCredentials le diría a la persona que su contraseña era incorrecta
una contraseña incorrecta, o un nombre que nadie tiene aquíinvalidCredentialslos dos casos no se distinguen
una búsqueda por cualquiera que no sea un readerinsufficientAccessRightsel bind prueba quién es usted; leer a todo el mundo es algo distinto que hay que permitir
add, delete, modifyDNunwillingToPerformno hay ningún manejador conectado para ellas; la única escritura es la contraseña de la propia persona

Un reader es una cuenta de servicio con un DN de bind y password o password_file; un reader sin ninguno de los dos se rechaza al arrancar (a reader that proves nothing is anonymous search with extra steps). Sin ningún reader, nada puede buscar, y check lo dice.

El root DSE se responde a un cliente anónimo, como exige el descubrimiento:

$ ldapsearch -x -LLL -H ldap://127.0.0.1:3893 -s base -b '' '+' '*'
dn:
objectClass: top
objectClass: OpenLDAProotDSE
supportedLDAPVersion: 3
namingContexts: dc=example,dc=org
supportedExtension: 1.3.6.1.4.1.4203.1.11.3
supportedExtension: 1.3.6.1.4.1.4203.1.11.1
supportedControl: 1.2.840.113556.1.4.319
supportedControl: 1.3.6.1.1.13.1
supportedControl: 1.3.6.1.1.13.2
supportedFeatures: 1.3.6.1.4.1.4203.1.5.1
supportedFeatures: 1.3.6.1.4.1.4203.1.5.3
subschemaSubentry: cn=Subschema
vendorName: go-authn/authnd
vendorVersion: v0.11.1

1.3.6.1.4.1.4203.1.11.1 es la operación de modificación de contraseña del RFC 3062. subschemaSubentry nombra el esquema, que también se responde a un cliente anónimo. supportedSASLMechanisms: OAUTHBEARER solo aparece con un bloque oidc.

Por dónde seguir

Instalarloel binario de la versión, la cuenta authnd, la unidad systemd, las actualizaciones
De dónde proceden las personasbloques user y group, una base de datos SQL, otro directorio LDAP
Las entradas y el esquemacomo qué se publica cada persona y cada grupo, cn=Subschema, los atributos, lo que se descarta o se retiene
checkreleer la configuración antes de reiniciar
TLSldaps:// o StartTLS, y publish_nt_hash
Cambiar una contraseñaldappasswd, ldapmodify, y por qué siempre se pide la contraseña anterior
Un reino Kerberosla keytab, y a quién se le puede emitir un ticket
Un segundo factorun código de un solo uso al final de la contraseña
Un token en el bindOIDC sobre SASL OAUTHBEARER
Ejecutarloseñales, reinicios, lo que registra, cómo saber que está en marcha

Sobre las transcripciones

Cada línea de arranque, el root DSE y las líneas --version los imprimió el binario de la versión v0.11.1 (authnd-darwin-arm64, go version -m: mod github.com/go-authn/authnd v0.11.1, vcs.modified=false), igual que cualquier otro comando que aparece en la misma transcripción que una línea de arranque. La v0.11.1 no cambia nada más que esa línea. Cada tabla de check, las entradas releídas con ldapsearch, cn=Subschema y los rechazos de samba los imprimió el binario de la versión v0.11.0 (mod github.com/go-authn/authnd v0.11.0, vcs.modified=false). También los rechazos de configuración de estas páginas, que la v0.11.0 imprimió byte a byte como lo había hecho la v0.10.0. Los demás binds, kinit, cambios de contraseña e intercambios de tokens los imprimió el binario de la versión v0.10.0 y no se volvieron a ejecutar, porque ni las notas de versión de la v0.11.0 ni las de la v0.11.1 cambian ninguno de ellos. Todos los pidieron los clientes OpenLDAP y Heimdal que incluye macOS, en 127.0.0.1 en puertos sin privilegios, en un directorio temporal bajo /tmp. Por eso las configuraciones que hay detrás nombran los archivos con rutas relativas como etc/authnd/passwords/alice.pw, y por eso los archivos de contraseña tienen nombres como alice.pwin. Las rutas /etc/authnd de los ejemplos son las que usa un servidor instalado.

Creada el por tannevaled

Modificada el por tannevaled