Ein Kerberos-Realm für dieselben Personen
kerberos {
realm = "EXAMPLE.ORG" # required, upper case
keytab = "/etc/authnd/krb5.keytab" # required; must hold krbtgt/EXAMPLE.ORG
listen = "127.0.0.1:88" # the default; UDP and TCP both
lifetime = "10h" # the default, MIT's
}Ein kerberos-Block macht authnd zusätzlich zum Verzeichnis zu einem KDC, über
go-authn/kdc: Denselben Personen werden Tickets
ausgestellt, statt dass sie nur nachgeschlagen werden. Er antwortet über UDP und TCP an
derselben Adresse, verlangt Pre-Authentication per verschlüsseltem Zeitstempel und stellt
ausschließlich aes256-cts-hmac-sha1-96-Tickets aus. lifetime ist eine Go-Dauer
("10h", "90m"). Verzeichnis und Realm sind gleichrangig: Hält eines von beiden an, hält der
Prozess an, denn ein Server, der weiter LDAP beantwortet, nachdem sein KDC gestorben ist, sähe
für alles, was kein Kerberos spricht, gesund aus.
Beim Start abgelehnt:
$ authnd check cases/realm-lower.hcl
authnd: kerberos: realm "example.org" is not upper case: clients uppercase the realm they derive from a domain, and would then ask for a realm this server does not answer forund ebenso ein Realm ohne Namen, ohne Keytab, eine Adresse, die sich nicht parsen lässt, eine
lifetime, die Go nicht lesen kann, und ein kerberos-Block neben einem mfa-Block (siehe
unten).
Der Keytab
Der Keytab enthält den Schlüssel, mit dem authnd seine eigenen Tickets signiert –
krbtgt/REALM@REALM –, und einen Schlüssel je Dienst, für den es Tickets ausstellt. Es ist
dieselbe Datei, die diese Dienste lesen. Das krbtgt-Passwort wird nie wieder eingegeben, also
machen Sie es zufällig. Mit MITs ktutil (Paket krb5-user unter Debian und Ubuntu; dieses
Rezept ist das aus docs/install.md und wurde für diese Seiten nicht ausgeführt):
printf 'addent -password -p krbtgt/EXAMPLE.ORG@EXAMPLE.ORG -k 1 -e aes256-cts-hmac-sha1-96\n%s\nwkt /tmp/krb5.keytab\nquit\n' \
"$(head -c 32 /dev/urandom | base64)" | ktutil
sudo install -o root -g authnd -m 0640 /tmp/krb5.keytab /etc/authnd/krb5.keytab
rm /tmp/krb5.keytabFügen Sie den Schlüssel eines Dienstes auf dieselbe Weise hinzu
(-p nfs/files.example.org@EXAMPLE.ORG), und geben Sie diesem Dienst denselben Schlüssel in
seinem eigenen Keytab. Unter macOS schreibt Heimdals
ktutil -k <file> add -r -p <principal> -V 1 -e aes256-cts-hmac-sha1-96
einen zufälligen Schlüssel ganz ohne Passwort. In jedem Fall lesen Sie den Keytab vor dem Start
zurück (klist -k mit MIT, ktutil -k <file> list mit Heimdal):
$ ktutil -k etc/authnd/krb5.keytab list
etc/authnd/krb5.keytab:
Vno Type Principal Aliases
1 aes256-cts-hmac-sha1-96 krbtgt/EXAMPLE.ORG@EXAMPLE.ORG Ein Keytab ohne krbtgt/REALM wird von check und beim Start abgelehnt; siehe
check.
Der Keytab wird einmal gelesen, beim Start: Ihn zu ersetzen erfordert einen Neustart.
Wem ein Ticket ausgestellt werden kann
Ein KDC muss die Pre-Authentication des Clients mit dem langfristigen Schlüssel der Person
entschlüsseln, braucht also das Passwort der Person, nicht nur eine Möglichkeit, eines
zu prüfen. check sagt, wer ein Ticket bekommen kann und wer nicht, mit dem Grund:
$ authnd check realm
ldap://127.0.0.1:3893, base dc=example,dc=org
USER FROM CAN PROVE PUBLISHED AS WITH
alice the configuration file a password account, uidObject uid
bob the configuration file an NT hash account, uidObject uid
dora a sqlite database a password account, uidObject uid
eli a sqlite database an NT hash account, uidObject uid
GROUP MEMBERS PUBLISHED AS
staff alice and bob groupOfNames
alice has no uidNumber, gidNumber or homeDirectory: not a posixAccount, published as account, uidObject
bob has no uidNumber, gidNumber or homeDirectory: not a posixAccount, published as account, uidObject
dora has no uidNumber, gidNumber or homeDirectory: not a posixAccount, published as account, uidObject
eli has no uidNumber, gidNumber or homeDirectory: not a posixAccount, published as account, uidObject
group staff has no gidNumber: not a posixGroup, published as a groupOfNames (member DNs, no memberUid)
realm EXAMPLE.ORG on 127.0.0.1:18388 (udp and tcp), keytab etc/authnd/krb5.keytab
can be issued a ticket: alice and dora
CANNOT, whatever they type: bob and eli
a KDC must decrypt the pre-authentication with the person's key
bob and eli: an NT hash is only the RC4-HMAC key (RFC 4757), and this realm issues aes256-cts-hmac-sha1-96 alone, whose key is derived from the password itself
a bind carries a password
bob and eli cannot bind with a password: their sources hold only what an SMB server needs (an NT hash), which a bind cannot be checked against
no reader is declared: nothing may search, and binds are not affected
sambaNTPassword is not published, so nothing here can authenticate an SMB session (NTLMv2 needs the password or its MD4, and a bind cannot answer it)
this configuration can be served| die Quelle hat | ein Ticket |
|---|---|
ein Passwort (password, password_file, eine SQL-Passwortspalte) | ja |
| nur einen NT-Hash | nein: Er ist der RC4-HMAC-Schlüssel, und dieser Realm stellt nur AES aus |
nur eine Passwortprüfung (ein users "ldap"-Verzeichnis hinter diesem) | nein: Eine Quelle, die ein Passwort nur verifiziert, kann keinen Schlüssel erzeugen |
Bei einem Verzeichnis hinter diesem lautet die letzte Zeile des Realm-Teils
alice, bob, dora and eli: the source only verifies a password, so it cannot produce any key.
Das ist strukturell und keine Frage der Konfiguration, und es in check zu finden ist besser,
als es von jemandem zu erfahren, dessen kinit behauptet, das richtige Passwort sei falsch.
kinit dagegen
Eine krb5.conf, die diesen KDC nennt. ⛔ Bei MIT Kerberos stehen die geschweiften Klammern auf
eigenen Zeilen: Sein Parser ignoriert stillschweigend einen Realm, der in einer Zeile
geschrieben ist.
[libdefaults]
default_realm = EXAMPLE.ORG
dns_lookup_kdc = false
[realms]
EXAMPLE.ORG = {
kdc = 127.0.0.1:18388
}Dieselbe Konfiguration, bereitgestellt und befragt von Heimdals kinit unter macOS
(--password-file liest das Passwort aus einer Datei):
$ authnd --config realm
ldap on 127.0.0.1:3893, serving 4 people from the configuration file, then a sqlite database
realm EXAMPLE.ORG on 127.0.0.1:18388 (udp and tcp)
$ kinit --password-file=alice.pwin alice@EXAMPLE.ORG
$ klist
Credentials cache: FILE:ccache
Principal: alice@EXAMPLE.ORG
Issued Expires Principal
Oct 18 16:10:19 2026 Oct 19 02:10:19 2026 krbtgt/EXAMPLE.ORG@EXAMPLE.ORG
$ kinit --password-file=wrong.pwin alice@EXAMPLE.ORG
kinit: Password incorrect
$ kinit --password-file=bob.pwin bob@EXAMPLE.ORG
kinit: krb5_get_init_creds: Error from KDC: this realm holds no Kerberos key for that principal
$ kinit --password-file=dora.pwin zed@EXAMPLE.ORG
kinit: krb5_get_init_creds: Error from KDC: no such principal in this realmDas Ticket gilt die standardmäßigen zehn Stunden. bob hat das Passwort eingegeben, aus dem sein NT-Hash berechnet wurde, und wird trotzdem abgelehnt: Der Realm hat keinen Schlüssel für dieses Konto. Der KDC schreibt, was er abgelehnt hat, mit dem Kerberos-Fehlercode, in seine Ausgabe:
kerberos: refused krbtgt/EXAMPLE.ORG: pre-authentication required (code 25)
kerberos: refused krbtgt/EXAMPLE.ORG: pre-authentication required (code 25)
kerberos: the timestamp does not decrypt (client etype 18, our key type 18): error decrypting: integrity verification failed
kerberos: refused krbtgt/EXAMPLE.ORG: pre-authentication does not decrypt (code 24)
kerberos: refused krbtgt/EXAMPLE.ORG: this realm holds no Kerberos key for that principal (code 9)
kerberos: refused krbtgt/EXAMPLE.ORG: no such principal in this realm (code 6)Pre-authentication required ist die normale erste Runde eines kinit: Der Client fragt ohne
Pre-Authentication, erfährt, dass sie erforderlich ist, und fragt dann mit ihr erneut. Das
erfolgreiche kinit von alice hinterlässt nur diese Zeile.
Der Realm verrät, welche Namen existieren; das Verzeichnis nicht
Ein LDAP-Bind für einen Namen, den niemand hat, wird mit invalidCredentials beantwortet,
genau wie ein falsches Passwort. Der KDC antwortet no such principal in this realm
(KDC_ERR_C_PRINCIPAL_UNKNOWN, Code 6), wie es Kerberos-KDCs tun. Mit einem kerberos-Block
an einer Adresse, die andere erreichen können, ist die Liste der Namen daher so erratbar wie
bei jedem KDC; listen ist standardmäßig Loopback.
Ein über LDAP geändertes Passwort
Der KDC liest dieselben Personen, die das Verzeichnis bereitstellt, daher erreicht ein
über LDAP geändertes Passwort den Realm sofort – das
alte funktioniert für kinit in dem Moment nicht mehr, in dem es für einen Bind nicht mehr
funktioniert:
$ ldappasswd -x -H ldap://127.0.0.1:3893 -D uid=alice,ou=people,dc=example,dc=org -y alice.pwin -t alice.pwin -T alice.new
$ kinit --password-file=alice.pwin alice@EXAMPLE.ORG
kinit: Password incorrect
$ kinit --password-file=alice.new alice@EXAMPLE.ORG
$Nicht neben einem mfa-Block
$ authnd check cases/krb-mfa.hcl
authnd: kerberos and mfa together: the mfa block asks every bind for a password AND a code, and a kinit carries only the password -- this KDC has no second-factor pre-authentication, so a realm here would accept one factor where the mfa block demands two. Remove one of the blocksDie Pre-Authentication per verschlüsseltem Zeitstempel aus RFC 4120 ist allein mit dem Passwort
verschlüsselt. Ein zweiter Faktor braucht OTP-Pre-Authentication (RFC 6560) innerhalb von FAST
(RFC 6113), was dieser KDC nicht implementiert. Ein Realm hier würde den Personen, für die der
mfa-Block zwei Faktoren verlangt, Tickets auf einen Faktor
hin aushändigen, und ein Ticket öffnet alles, was ein Bind öffnet – also fällt die Wahl
geschlossen aus: das eine oder das andere.
Ports
88 ist privilegiert. Unter der mitgelieferten Unit deckt CAP_NET_BIND_SERVICE ihn ab; ein
Server, der als gewöhnlicher Benutzer läuft, braucht einen hohen Port, wie oben, und eine
krb5.conf, die ihn nennt.
Erstellt am von tannevaled
Geändert am von tannevaled