authnd, un servidor LDAP para personas que están en otro lugar
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 = truenecesita ahora un bloquesamba, o authnd no arranca.- Una persona sin
uidNumber,gidNumberyhomeDirectoryya no es unposixAccount, y un grupo singidNumberya no es unposixGroup, 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 listeningLa 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ón | respuesta | por qué |
|---|---|---|
| nombre vacío, contraseña vacía (RFC 4513 §5.1.1, anónimo) | éxito | dice «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) | unwillingToPerform | nombra 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í | invalidCredentials | los dos casos no se distinguen |
una búsqueda por cualquiera que no sea un reader | insufficientAccessRights | el bind prueba quién es usted; leer a todo el mundo es algo distinto que hay que permitir |
add, delete, modifyDN | unwillingToPerform | no 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.11.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
| Instalarlo | el binario de la versión, la cuenta authnd, la unidad systemd, las actualizaciones |
| De dónde proceden las personas | bloques user y group, una base de datos SQL, otro directorio LDAP |
| Las entradas y el esquema | como qué se publica cada persona y cada grupo, cn=Subschema, los atributos, lo que se descarta o se retiene |
check | releer la configuración antes de reiniciar |
| TLS | ldaps:// o StartTLS, y publish_nt_hash |
| Cambiar una contraseña | ldappasswd, ldapmodify, y por qué siempre se pide la contraseña anterior |
| Un reino Kerberos | la keytab, y a quién se le puede emitir un ticket |
| Un segundo factor | un código de un solo uso al final de la contraseña |
| Un token en el bind | OIDC sobre SASL OAUTHBEARER |
| Ejecutarlo | señ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