KRB5.CONF(5)
β¨ NAME β¨
okay so bestie, krb5.conf is literally the configuration file for Kerberos 5. π And this manual page? It's KRB5.CONF(5) β we're just folding that name in right here, no cap. β¨
πΈ SYNOPSIS πΈ
#include <krb5.h>
π DESCRIPTION π
The krb5.conf file is where you specify a bunch of configuration parameters for the Kerberos 5 library, and also for some programs. It's giving main character energy for your Kerberos setup, fr fr. π
The file is made of one or more sections, and each section has a bunch of bindings. The value of each binding can be either a string or a list of other bindings. The grammar looks like this:
file:
/* empty */
sections
includes
sections:
section sections
section
section:
'[' section_name ']' bindings
section_name:
STRING
bindings:
binding bindings
binding
binding:
name '=' STRING
name '=' '{' bindings '}'
name:
STRING
includes:
'include' path
'includedir' path
path: STRING
A STRING is just one or more non-whitespace characters. Simple as that. π
Files and directories can be included by absolute path. If you include a directory, all files in that directory get included as if each file had been included separately. But only files whose names consist of alphanumeric, hyphen, and underscore are included, though they may also end in .conf. So like, don't name your files with spaces or emoji, bestie. π
STRINGs that are specified later in this man-page use the following notation:
booleanβ values can be eitheryes/trueorno/false.timeβ values can be a list of year, month, day, hour, min, second. Example:1 month 2 days 30 min. If no unit is given, seconds is assumed.etypesβ valid encryption types are:des-cbc-crc,des-cbc-md4,des-cbc-md5,des3-cbc-sha1,arcfour-hmac-md5,aes128-cts-hmac-sha1-96, andaes256-cts-hmac-sha1-96.addressβ an address can be either a IPv4 or a IPv6 address.
Currently recognised sections and bindings are:
[appdefaults]
Specifies the default values to be used for Kerberos applications. You can specify defaults per application, realm, or a combination of these. The preference order is:
- application realm option
- application option
- realm option
- option
The supported options are:
forwardable = booleanβ When obtaining initial credentials, make the credentials forwardable. (slay, now they can travel π )proxiable = booleanβ When obtaining initial credentials, make the credentials proxiable.no-addresses = booleanβ When obtaining initial credentials, request them for an empty set of addresses, making the tickets valid from any address.ticket_lifetime = timeβ Default ticket lifetime.renew_lifetime = timeβ Default renewable ticket lifetime.encrypt = booleanβ Use encryption, when available.forward = booleanβ Forward credentials to remote host (forrsh(1),telnet(1), etc).historical_anon_pkinit = booleanβ Enable legacy anonymous pkinit command-line syntax. With this option set to true, thekinit(1) --anonymouscommand with no principal argument specified will request an anonymous pkinit ticket from the default realm. If a principal argument is specified, it is used as an explicit realm name for anonymous pkinit even without an@prefix.
[libdefaults]
default_realm = REALMβ Default realm to use, this is also known as your βlocal realmβ. The default is the result ofkrb5_get_host_realm(local hostname).allow_weak_crypto = booleanβ are weak crypto algorithms allowed to be used, among others, DES is considered weak.clockskew = timeβ Maximum time differential (in seconds) allowed when comparing times. Default is 300 seconds (five minutes).kdc_timeout = timeβ Maximum time to wait for a reply from the kdc, default is 3 seconds.capathβ This is deprecated, see the capaths section below. (not me using deprecated stuff π)
capath = {
destination-realm = next-hop-realm
...
}
default_cc_type = cctypeβ sets the default credentials type.default_cc_name = ccnameβ the default credentials cache name. If you want to change the type only usedefault_cc_type. The string can contain variables that are expanded on runtime. The only supported variable currently is%{uid}which expands to the current user id.default_etypes = etypes ...β A list of default encryption types to use. (Default: all enctypes ifallow_weak_crypto = TRUE, else all enctypes except single DES enctypes.)default_as_etypes = etypes ...β A list of default encryption types to use in AS requests. (Default: the value ofdefault_etypes.)default_tgs_etypes = etypes ...β A list of default encryption types to use in TGS requests. (Default: the value ofdefault_etypes.)default_etypes_des = etypes ...β A list of default encryption types to use when requesting a DES credential.default_keytab_name = keytabβ The keytab to use if no other is specified, default is βFILE:/etc/krb5.keytabβ.dns_lookup_kdc = booleanβ Use DNS SRV records to lookup KDC services location.dns_lookup_realm = booleanβ Use DNS TXT records to lookup domain to realm mappings.kdc_timesync = booleanβ Try to keep track of the time differential between the local machine and the KDC, and then compensate for that when issuing requests.max_retries = numberβ The max number of times to try to contact each KDC.large_msg_size = numberβ The threshold where protocols with tiny maximum message sizes are not considered usable to send messages to the KDC.ticket_lifetime = timeβ Default ticket lifetime.renew_lifetime = timeβ Default renewable ticket lifetime.forwardable = booleanβ When obtaining initial credentials, make the credentials forwardable. This option is also valid in the[realms]section.proxiable = booleanβ When obtaining initial credentials, make the credentials proxiable. This option is also valid in the[realms]section.verify_ap_req_nofail = booleanβ If enabled, failure to verify credentials against a local key is a fatal error. The application has to be able to read the corresponding service key for this to work. Some applications, likesu(1), enable this option unconditionally.warn_pwexpire = timeβ How soon to warn for expiring password. Default is seven days.http_proxy = proxy-specβ A HTTP-proxy to use when talking to the KDC via HTTP.dns_proxy = proxy-specβ Enable using DNS via HTTP.extra_addresses = address ...β A list of addresses to get tickets for along with all local addresses.time_format = stringβ How to print time strings in logs, this string is passed tostrftime(3).date_format = stringβ How to print date strings in logs, this string is passed tostrftime(3).log_utc = booleanβ Write log-entries using UTC instead of your local time zone.scan_interfaces = booleanβ Scan all network interfaces for addresses, as opposed to simply using the address associated with the system's host name.fcache_version = intβ Use file credential cache format version specified.fcc-mit-ticketflags = booleanβ Use MIT compatible format for file credential cache. It's the fieldticketflagsthat is stored in reverse bit order for older than Heimdal 0.7. Setting this flag toTRUEmakes it store the MIT way, this is default for Heimdal 0.7.check-rd-req-serverβ If set to "ignore", the framework will ignore any of the server input tokrb5_rd_req(3), this is very useful when the GSS-API server input the wrong server name into thegss_accept_sec_contextcall.k5login_directory= directory β a whole alternate location for user.k5loginfiles. It's here purely for MIT krb5 config-file compatibility, bestie, so if you're migrating, your old file still vibes. β¨k5login_authoritative= boolean β if this is true, then when a principal isn't found in k5login files,krb5_userok(3)will not fall back on principal-to-username mapping. Also just MIT krb5 compatibility. π«Άkuserok= rule ... β this is the main character setting the wholekrb5_userok(3)behaviour. Give it multiple values andkrb5_userok(3)evaluates them in order until one succeeds, or all of them fail. π Rules come from plugins, and three built-in plugins are described right below. Default:USER-K5LOGIN SIMPLE DENY.kuserok=DENYβ if this gets evaluated,krb5_userok(3)denies access to the given username no matter what the principal name is. Periodt, no exceptions. πkuserok=SIMPLEβ if this gets evaluated,krb5_userok(3)uses principal-to-username mapping (peepauth_to_localbelow π). If the principal maps to the requested username, access is allowed. Slay.kuserok=SYSTEM-K5LOGIN[:directory]β if this gets evaluated,krb5_userok(3)uses k5login files named after the luser argument tokrb5_userok(3), living in the given directory or in/etc/k5login.d/. K5login files are text files, one principal name per line, and principals appearing in a user's k5login file are permitted access to that user's account. π
Heads up bestie: this rule performs no ownership checks and no permissions checks on k5login files. Proper ownership and permissions/ACLs are expected because the k5login location is a system location. It's giving "trust me bro" and that's on you. π
kuserok=USER-K5LOGINβ if this gets evaluated,krb5_userok(3)uses~luser/.k5loginand~luser/.k5login.d/*. User k5login files and directories must be owned by the user and must not have world or group write permissions. πΈ
aname2lname-text-db= filename β the named file has to be a sorted (increasing order, no chaos) text file where every line is an unparsed principal name, optionally followed by whitespace and a username. Theaname2lnamefunction binary-searches this file when it's configured, looking for lines matching the given principal name. Found it? Then the given username gets used β or, if the username is missing, an error comes back. If the file doesn't exist, or no matching line turns up, then other plugins get to run. πfcache_strict_checkingβ strict checking inFILEcredential caches, so that owner, no-symlink and permissions are all correct. Vibe check for your ccache, basically. π₯name_canon_rules= rules β one or more service principal name canonicalization rules. Each rule is one or more tokens separated by colon (':'). Currently these rules are used only for hostname canonicalization β usually when getting a service ticket, from a ccache or a TGS, but also when acquiring GSS initiator credentials from a keytab. You can use them to implement DNS-resolver-style search lists without actually having to use DNS. β¨
NOTE: Name canonicalization rules are an experimental feature. π§ͺ
The first token is a rule type, one of: as-is, qualify, or nss.
Any remaining tokens must be options tokens: use_fast (use FAST to protect TGS exchanges; currently not supported), use_dnssec (use DNSSEC to protect hostname lookups; currently not supported), ccache_only , use_referrals, no_referrals, lookup_realm, mindots=N, maxdots=N, order=N, domain= domain, realm= realm, match_domain= domain, and match_realm= realm.
When trying to obtain a service ticket for a host-based service principal name, name canonicalization rules get applied to that name in the order given, one by one, until one succeeds (a service ticket is obtained), or all of them fail. Same deal when acquiring GSS initiator credentials from a keytab, and when comparing a non-canonical GSS name to a canonical one. π¦
For each rule the system checks that the hostname has at least mindots periods (if given) in it, at most maxdots periods (if given), that the hostname ends in the given match_domain (if given), and that the realm of the principal matches the match_realm (if given).
as-isrules leave the hostname unmodified but may set a realm.qualifyrules qualify the hostname with the given domain and also may set the realm.- The
nssrule uses the system resolver to look up the host's canonical name and is usually not secure. Note that using thenssrule type implies having to have principal aliases in the HDB (though not necessarily in keytabs). β οΈ
The empty realm denotes "ask the client's realm's TGS". The empty realm may be set as well as matched. π
The order in which rules are applied goes like this: first all the rules with explicit order, then all other rules in the order in which they appear. If any two rules have the same explicit order, their order of appearance in krb5.conf breaks the tie. Explicitly specifying order can be useful where tools read and write the configuration file without preserving parameter order. (Not me side-eyeing tools that scramble my config π.)
Malformed rules are ignored.
allow_hierarchical_capaths= boolean β when validating cross-realm transit paths, absent any explicit capath from the client realm to the server realm, this allows a hierarchical transit path via the common ancestor domain of the two realms. Defaults totrue. Note: absent an explicit setting, hierarchical capaths are always used by the KDC when generating a referral to a destination with which there is no direct trust. π
πΈ [domain_realm] πΈ
This one is a list of mappings from DNS domain to Kerberos realm. Each binding in this section looks like:
domain = realm
The domain can be either a full name of a host or a trailing component. In the trailing-component case, the domain-string should start with a period. The trailing component only matches hosts that are in the same domain, ie .example.com matches foo.example.com, but not foo.test.example.com. π―
The realm may be the token dns_locate, in which case the actual realm will be determined using DNS (independently of the setting of the dns_lookup_realm option). π¦
π [realms] π
REALM = {
kdc=[service/]host[:port]β specifies a list of kdcs for this realm. If the optional port is absent, the default value for thekerberos/udp,kerberos/tcp, andhttp/tcpport (depending on service) will be used. The kdcs will be used in the order that they are specified. π
The optional service specifies over what medium the kdc should be contacted. Possible services are udp, tcp, and http. Http can also be written as http://. Default service is udp and tcp. β¨
admin_server=host[:port]β specifies the admin server for this realm, where all the modifications to the database are performed. The main character desk where the edits happen. πkpasswd_server=host[:port]β points to the server where all the password changes are performed. If there's no such entry, the kpasswd port on theadmin_serverhost will be tried. π«Άtgs_require_subkeyβ a boolean variable that defaults tofalse. Old DCEsecd(pre 1.1) might need this to betrue. Ancient lore, but okay. π§auth_to_local_names= {principal_name = usernameβ you drop an actual principal name here and it gets mapped to the given username, but only if the REALM is a default realm. that's the whole vibe. πauth_to_local = HEIMDAL_DEFAULTβ use the Heimdal default principal-to-username mapping. Applies to principals from the REALM if and only if REALM is a default realm.auth_to_local = DEFAULTβ use the MIT default principal-to-username mapping. Applies to principals from the REALM if and only if REALM is a default realm.auth_to_local = DB:/path/to/db.txtβ do a binary search of the given DB. bestie the DB has requirements: it must be a flat-text file sorted in the"C"locale, and each record is a line (separated by eitherLForCRLF) made of a principal name, then whitespace, then a username. Applies to principals from the REALM if and only if REALM is a default realm.auth_to_local = DB:/path/to/dbβ use the given DB, but only if there's a plugin for it. Applies to principals from the REALM if and only if REALM is a default realm.auth_to_local = RULE:...β use the given rule, if there's a plugin for it. Applies to principals from the REALM if and only if REALM is a default realm.auth_to_local = NONEβ no extra principal-to-username mapping happens. π heads up though:auth_to_local_namesand any precedingauth_to_localrules still take precedence, so this isn't a "delete everything" button.
π¦ [capaths] π¦
client-realm = {
server-realm = hop-realm ...
}
server-realm = hop-realm ...β okay so this one does two jobs at once, no cap:- The first listed hop-realm tells a client which realm it should hit up in order to eventually get credentials for a service in the server-realm. π°οΈ
- It also tells the KDC (and other servers) which realms are allowed in a multi-hop traversal from client-realm to server-realm.
And for the second job specifically β the order of the realms doesn't matter. Only the client case cares about ordering. π
πΈ [logging] πΈ
entity = destinationβ says that entity should use the given destination for logging. Wanna know all the defined destinations? go peek at thekrb5_openlog(3)manual page, it's all listed there. π
π [kdc] π
database = {
dbname = [DATBASETYPE:]DATABASENAME
realm = REALM
mkey_file = FILENAME
acl_file = PA FILENAME
log_file = FILENAME
log-max-size = number
}
dbname = [DATBASETYPE:]DATABASENAMEβ use this database for this realm. TheDATABASETYPEshould be one of'lmdb','db3','db1','db','sqlite', or'ldap'. Wanna know how to actually configure the different database backends? the info documentation has the tea. βrealm = REALMβ says which realm is gonna be stored in this database. If realm isn't set, it gets used as the default database, and there can only be one entry that doesn't have a realm stanza. one. that's it. π«Άmkey_file = FILENAMEβ use this keytab file for the master key of this database. If you don't specify it,DATABASENAME.mkeygets used instead.acl_file = PA FILENAMEβ use this file for the ACL list of this database.log_file = FILENAMEβ use this file as the log of changes made to the database. This file is used byipropd-masterfor propagating changes to slaves. It's also used bykadmindandkadmin(when used with the-loption), and by all applications usinglibkadm5with the local backend, for two-phase commit functionality. Slaves use it too. Setting this to/dev/nulldisables two-phase commit and incremental propagation. Andiprop-logis your bestie for showing the contents of this log file. β¨log-max-size = numberβ when the log reaches this size (in bytes), the log gets truncated, saving some entries and keeping the latest version number so incremental propagation isn't disrupted. If it's set to a negative value, automatic log truncation gets disabled. Defaults to52428800(50MB).max-request = SIZEβ maximum size of a kdc request.require-preauth = BOOLβ if set, pre-authentication is required.ports = list of portsβ list of ports the kdc should listen to.addresses = list of interfacesβ list of addresses the kdc should bind to.enable-http = BOOLβ should the kdc answer kdc-requests over http?tgt-use-strongest-session-key = BOOLβ if this isTRUEthen the KDC will prefer the strongest key from the client's AS-REQ or TGS-REQ enctype list for the ticket session key that is supported by the KDC and the target principal when the target principal is a krbtgt principal. Else it'll prefer the first key from the client's AS-REQ enctype list that's also supported by the KDC and the target principal. Defaults toFALSE.svc-use-strongest-session-key = BOOLβ liketgt-use-strongest-session-key, but it applies to the session key enctype of tickets for services other than krbtgt principals. Defaults toFALSE.preauth-use-strongest-session-key = BOOLβ ifTRUEthen it selects the strongest possible enctype from the client's AS-REQ forPA-ETYPE-INFO2(i.e., for password-based pre-authentication). Else it picks the first supported enctype from the client's AS-REQ. Defaults toFALSE.use-strongest-server-key = BOOLβ ifTRUEthen the KDC picks, for the ticket encrypted part's key, the first supported enctype from the target service principal's hdb entry's current keyset. Else the KDC picks the first supported enctype from the target service principal's hdb entry's current keyset. Defaults toTRUE. π« (yes bestie, both branches really do say the same thing up there β I'm just the messenger, not the author.)check-ticket-addresses = BOOLβ verify the addresses in the tickets used in tgs requests.allow-null-ticket-addresses = BOOLβ allow address-less tickets.allow-anonymous = BOOLβ if the kdc is allowed to hand out anonymous tickets.historical_anon_realm = booleanβ enables pre-7.0 non-RFC-comformant KDC behavior. With this option set totrue, the client realm in anonymous pkinit AS replies will be the requested realm, rather than the RFC-conformantWELLKNOWN:ANONYMOUSrealm. π¨ This can have a security impact on servers that expect to grant access to anonymous-but-authenticated-to-the-KDC users of the realm in question: they would also grant access to unauthenticated anonymous users. As such, it is not recommended to set this option totrue. like, genuinely, don't. πencode_as_rep_as_tgs_rep = BOOLβ encode as-rep as tgs-rep to be compatible with mistakes older DCE secd did. πkdc_warn_pwexpire = TIMEβ the time before expiration that the user should be warned that her password is about to expire.logging = Loggingβ what type of logging the kdc should use. See also[logging]/kdc. π
still in the [kdc] energy bestie, we're not done yet β more LDAP and kx509 lore incoming π
hdb-ldap-structural-objectstructural object β if you're using the LDAP backend to stash principals, this is the structural object it grabs when it creates stuff and when it reads stuff back. default value?account. no notes.hdb-ldap-create-basecreation dn β this is the dn that gets appended to the principal when it's making entries. default value is the search dn, slay.enable-digest = BOOLβ should the kdc answer digest requests, or should it be mysterious and unbothered? default isFALSE.digests_allowed = list of digestsβ tells you which digests the kdc will actually reply to. default isntlm-v2.kx509_ca = fileβ points at the PEM credentials for the kx509 certification authority. πrequire_initial_kca_tickets = booleanβ says whether tickets for thekca_serviceservice principal have to be INITIAL. you can set this per-realm or globally, your choice bestie. defaults to true for the global setting.kx509_include_pkinit_san = booleanβ if it's true, then the kx509 client principal's name and realm get tucked into anid-pkinit-sancertificate extension. settable per-realm or globally. defaults to true for the global setting.kx509_template = fileβ the PEM file with a template for the certs that'll be issued. you can interpolate these variables in the subject name using${variable}syntax:principal-nameβ the full name of the kx509 client principal.principal-name-without-realmβ the full name of the kx509 client principal, but minus the realm name.principal-name-realmβ the name of the client principal's realm.
heads up bestie: thekx509,kx509_template,kx509_include_pkinit_san, andrequire_initial_kca_ticketsparameters can also be set on a per-realm basis. the more u know β¨
π [kadmin] π
password_lifetime = timeβ if a principal already has its password set for expiration, this is how long it stays valid after a change. the clock starts ticking β³default_keys = keytypes...β for every entry indefault_keys, it tries to parse it as a sequence ofetype:salttype:saltsyntax, like this lil thing:
[(des|des3|etype):](pw-salt|afs3-salt)[:string]
if etype is omitted, that means everything. and if string is omitted, that means the default salt string (for that principal and encryption type). also there are extra special values of keytypes:
v5β the Kerberos 5 saltpw-salt
default_key_rules = {globing-rule = keytypes...β a globbing rule that matches a principal, and when it's true, it uses the keytypes as specified, same format as[kadmin]default_keys.
}prune-key-history = BOOLβ when it's adding keys to the key history, it drops keys that are too old to match unexpired tickets (based on the principal's maximum ticket lifetime). β οΈ real talk: if the KDC keystore gets compromised later, traffic that was protected with the discarded older keys may stay protected. also this keeps the HDB records for principals with key history from growing without bound, which is honestly a vibe. the default (backwards compatible) value is"false".use_v4_salt = BOOLβ when it's true, it's literally the same as
default_keys = des3:pw-salt v4
and it's only left in for backwards compatibility. it's giving legacy, not giving main character π«
π [password_quality] π
go check the Password quality assurance in the info documentation for more deets, bestie. but here's the lineup:
check_library = library-nameβ library name that contains the passwordcheck_functioncheck_function = function-nameβ function name for checking passwords incheck_librarypolicy_libraries = library1 ... libraryNβ list of libraries that can do password policy checkspolicies = policy1 ... policyNβ list of policy names to apply to the password. builtin policies include, among others,minimum-length,character-class,external-check.
β¨ ENVIRONMENT β¨
KRB5_CONFIGβ points to the configuration file to read. that's it. that's the whole env var. iconic behavior honestly π
πΈ FILES πΈ
/etc/krb5.confβ configuration file for Kerberos 5.
π EXAMPLES π
okay here's a whole mood board of a config, look at her go:
[libdefaults]
default_realm = FOO.SE
name_canon_rules = as-is:realm=FOO.SE
name_canon_rules = qualify:domain=foo.se:realm=FOO.SE
name_canon_rules = qualify:domain=bar.se:realm=FOO.SE
name_canon_rules = nss
[domain_realm]
.foo.se = FOO.SE
.bar.se = FOO.SE
[realms]
FOO.SE = {
kdc = kerberos.foo.se
default_domain = foo.se
}
[logging]
kdc = FILE:/var/heimdal/kdc.log
kdc = SYSLOG:INFO
default = SYSLOG:INFO:USER
[kadmin]
default_key_rules = {
*/ppp@* = arcfour-hmac-md5:pw-salt
}
π©Ί DIAGNOSTICS π©Ί
so here's the tea π β because krb5.conf gets read and parsed by the krb5 library, programs don't really get a lot of opportunities to report parsing errors in any useful format. to help with that whole situation, there's a program called verify_krb5_conf that reads krb5.conf and tries to emit useful diagnostics from parsing errors.
but ngl, this program has no way of knowing what options are actually used, so it cannot warn you about unknown or misspelled ones. it's doing its best, bestie. be nice to her π
π SEE ALSO π
and that's the whole page, bestie, we ate and left no crumbs π β¨ this one's from HEIMDAL, dated May 4, 2005, and it lives at KRB5.CONF(5) β go configure something gorgeous π¦ππ
π¦ where this page comes from
- debian trixie: heimdal-docs 7.8.git20221117.28daf24+dfsg-9+deb13u1 Β· BSD-3-Clause
- ubuntu questing: heimdal-docs 7.8.git20221117.28daf24+dfsg-9ubuntu1
- ubuntu resolute: heimdal-docs 7.8.git20221117.28daf24+dfsg-11ubuntu1 Β· BSD-3-Clause
- ubuntu stonking: heimdal-docs 7.8.git20240113.1b4565a+dfsg-2ubuntu1 Β· BSD-3-Clause
- Copyright (c) 1999 - 2005 Kungliga Tekniska HΓΆgskolan
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms