Difference between revisions of "Kerberos"

From ArchWiki
Jump to navigation Jump to search
m (→‎Server: link krb5.conf documentation)
(Add DisableAuthNegotiateCnameLookup plolicy information to make Chromium working)
 
(30 intermediate revisions by 12 users not shown)
Line 1: Line 1:
 
[[Category:Networking]]
 
[[Category:Networking]]
 +
[[Category:Authentication]]
 
[[ja:Kerberos]]
 
[[ja:Kerberos]]
 
{{Related articles start}}
 
{{Related articles start}}
Line 5: Line 6:
 
{{Related articles end}}
 
{{Related articles end}}
  
[[Wikipedia:Kerberos_(protocol)|Kerberos]] is a network authentication system. See [https://web.mit.edu/kerberos/krb5-1.12/doc/admin/index.html krb5 documentation].
+
[[Wikipedia:Kerberos_(protocol)|Kerberos]] is a network authentication system. See [https://web.mit.edu/kerberos/krb5-latest/doc/ krb5 documentation].
  
== Server ==
+
== Installation ==
  
Install the {{Pkg|krb5}} package, if it is not already installed, and configure it to your needs. For example:
+
[[Install]] the {{Pkg|krb5}} package on your clients and server.
 +
 
 +
It is '''highly''' recommended to use a [[time synchronization]] daemon to keep client/server clocks in sync.
 +
 
 +
If hostname resolution has not been configured, you can manually add your clients and server to the {{man|5|hosts}} file of each machine. Note that the FQDN (myclient.example.com) must be the first hostname after the IP address in the hosts file.
 +
 
 +
== Server configuration ==
 +
=== Domain creation ===
 +
Edit {{ic|/etc/krb5.conf}} to configure your domain:
  
 
{{hc|/etc/krb5.conf|<nowiki>
 
{{hc|/etc/krb5.conf|<nowiki>
 
[libdefaults]
 
[libdefaults]
 
     default_realm = EXAMPLE.COM
 
     default_realm = EXAMPLE.COM
    permitted_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 camellia256-cts-cmac camellia128-cts-cmac
 
  
 
[realms]
 
[realms]
 
     EXAMPLE.COM = {
 
     EXAMPLE.COM = {
 
         admin_server = kerberos.example.com
 
         admin_server = kerberos.example.com
         supported_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 camellia256-cts-cmac camellia128-cts-cmac
+
         # use "kdc = ..." if the kerberos SRV records aren't in DNS (see Advanced section)
 +
        kdc = kerberos.example.com
 +
        # This breaks krb4 compatibility but increases security
 +
        default_principal_flags = +preauth
 
     }
 
     }
  
 
[domain_realm]
 
[domain_realm]
     example.com = EXAMPLE.COM
+
     example.com = EXAMPLE.COM
 
     .example.com = EXAMPLE.COM
 
     .example.com = EXAMPLE.COM
  
Line 32: Line 43:
 
</nowiki>}}
 
</nowiki>}}
 
This file's format is described in the MIT Kerberos [https://web.mit.edu/kerberos/krb5-1.12/doc/admin/conf_files/krb5_conf.html documentation]
 
This file's format is described in the MIT Kerberos [https://web.mit.edu/kerberos/krb5-1.12/doc/admin/conf_files/krb5_conf.html documentation]
 
Add DNS records:
 
{{hc|db.example.com|
 
kerberos          A  1.2.3.4
 
_kerberos          TXT "EXAMPLE.COM"
 
_kerberos._udp    SRV 0 0  88 kerberos.example.com.
 
_kerberos-adm._udp SRV 0 0 750 kerberos.example.com.
 
}}
 
 
Do not forget reverse DNS.
 
 
{{Accuracy|krb5 documentation says tcp is used on both, though mine is not listening for tcp on 750.}}
 
 
Add ALLOW rules to your firewall for both tcp and udp on ports 88 and 750.
 
  
 
Create the database:
 
Create the database:
# krb5_util -r EXAMPLE.COM create -s
+
{{hc|# kdb5_util -r EXAMPLE.COM create -s|<nowiki>
 +
Loading random data                                                           
 +
Initializing database '/var/lib/krb5kdc/principal' for realm 'EXAMPLE.COM',                 
 +
master key name 'K/M@EXAMPLE.COM'
 +
You will be prompted for the database Master Password.                         
 +
It is important that you NOT FORGET this password.                             
 +
Enter KDC database master key: ***
 +
Re-enter KDC database master key to verify: ***
 +
</nowiki>}}
  
Enable and start the krb5-kdc service.
+
Finally, enable and start the Kerberos services:
 +
# systemctl enable --now krb5-kdc krb5-kadmind
  
Start kadmin, using the local root user instead of kerberos authentication:
+
=== Add principals ===
 +
Start the Kerberos administration tool, using local authentication
 
{{hc|# kadmin.local|Authenticating as principal root/admin@EXAMPLE.COM with password.
 
{{hc|# kadmin.local|Authenticating as principal root/admin@EXAMPLE.COM with password.
 
kadmin.local:}}
 
kadmin.local:}}
  
=== Basic Commands ===
+
Add a user principal to the Kerberos database:
Add a human principal (user):
+
{{hc|kadmin.local: addprinc myuser@EXAMPLE.COM|<nowiki>
{{hc|kadmin.local: add_principal myuser@EXAMPLE.COM|<nowiki>
 
 
WARNING: no policy specified for myuser@EXAMPLE.COM; defaulting to no policy
 
WARNING: no policy specified for myuser@EXAMPLE.COM; defaulting to no policy
 
Enter password for principal "myuser@EXAMPLE.COM": ***
 
Enter password for principal "myuser@EXAMPLE.COM": ***
Line 65: Line 71:
 
</nowiki>}}
 
</nowiki>}}
  
Add a service principal:
+
Add the KDC principal to the Kerberos database:
{{bc|kadmin.local: add_principal -randkey nfs/someserver.example.com@EXAMPLE.COM}}
+
{{hc|kadmin.local: addprinc -randkey host/kerberos.example.com|<nowiki>
 +
WARNING: no policy specified for host/kerberos.example.com@EXAMPLE.COM; defaulting to no policy
 +
Principal "host/kerberos.example.com@EXAMPLE.COM" created.
 +
</nowiki>}}
 +
 
 +
Finally, Add the KDC principal to the server's keytab:
 +
{{hc|kadmin.local: ktadd host/kerberos.example.com|<nowiki>
 +
Entry for principal host/kerberos.example.com with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
 +
Entry for principal host/kerberos.example.com with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
 +
</nowiki>}}
 +
 
 +
Quit the Kerberos administration tool:
 +
 
 +
kadmin.local: quit
 +
 
 +
You should now be able to get a Kerberos ticket:
 +
{{hc|$ kinit|<nowiki>
 +
Password for myuser@EXAMPLE.COM: ***
 +
</nowiki>}}
 +
{{hc|$ klist|<nowiki>
 +
Ticket cache: FILE:/tmp/krb5cc_1000
 +
Default principal: myuser@EXAMPLE.COM
 +
 
 +
Valid starting      Expires              Service principal
 +
08/30/2017 14:26:09  08/31/2017 14:26:09  krbtgt/EXAMPLE.COM@EXAMPLE.COM
 +
</nowiki>}}
 +
 
 +
=== Firewall ===
 +
Add ALLOW rules to your firewall for any applicable ports/protocols:
 +
* 88, TCP and UDP for Kerberos v5
 +
* 749, TCP and UDP for kadmin if you plan to configure it
 +
* 750, TCP and UDP for Kerberos v4 if you need backwards compatibility
 +
 
 +
=== DNS records ===
 +
This isn't necessary if you specify the kerberos and kadmin server in each machine's krb5.conf
 +
{{hc|db.example.com|
 +
kerberos.example.com.          A    1.2.3.4
 +
_kerberos.example.com.          TXT  "EXAMPLE.COM"
 +
_kerberos._udp.example.com.    SRV  0 0  88 kerberos.example.com.
 +
_kerberos-adm._udp.example.com. SRV  0 0 749 kerberos.example.com.
 +
}}
 +
Do not forget reverse DNS.
 +
 
 +
 
 +
== Client configuration ==
 +
Edit the client's {{ic|/etc/krb5.conf}} to match your server's configuration. You can copy this file from the server, or just set the required realm information.
 +
 
 +
=== Testing ===
 +
You should now be able to get a Kerberos ticket on the client:
 +
{{hc|$ kinit|<nowiki>
 +
Password for myuser@EXAMPLE.COM: ***
 +
</nowiki>}}
 +
{{hc|$ klist|<nowiki>
 +
Ticket cache: FILE:/tmp/krb5cc_1000
 +
Default principal: myuser@EXAMPLE.COM
 +
 
 +
Valid starting      Expires              Service principal
 +
08/30/2017 15:36:10  08/31/2017 15:36:10  krbtgt/EXAMPLE.COM@EXAMPLE.COM
 +
</nowiki>}}
 +
 
 +
 
 +
== Configuring kadmin ==
 +
You'll need /etc/krb5.conf configured on the kadmin client, and the server's firewall configured for kadmin.
  
 
=== Configuring kadmin ACL ===
 
=== Configuring kadmin ACL ===
Line 99: Line 167:
  
 
Restart the kdc and kadmin daemons:
 
Restart the kdc and kadmin daemons:
{{bc|sudo systemctl restart krb5-kdc krb5-kadmin}}
+
{{bc|sudo systemctl restart krb5-kdc krb5-kadmind}}
  
 
You can now use kadmin as your own user, authenticating with kerberos:
 
You can now use kadmin as your own user, authenticating with kerberos:
Line 108: Line 176:
 
kadmin:
 
kadmin:
 
</nowiki>}}
 
</nowiki>}}
 +
 +
 +
== Service principals and keytabs ==
 +
First, ensure you've configured krb5.conf on all involved machines.
 +
 +
A kerberos principal has three components, formatted as `primary/instance@REALM`. For user principals, the primary is your username and the instance is omitted or is a role (eg. "admin"): `myuser@EXAMPLE.COM` or `myuser/admin@EXAMPLE.COM`. For hosts, the primary is "host" and the instance is the server FQDN: `host/myserver.example.com@EXAMPLE.COM`. For services, the primary is the service abbreviation and the instance is the FQDN: `nfs/myserver.example.com@EXAMPLE.COM`.
 +
The realm can often be omitted, the local computer's default realm is usually assumed.
 +
 +
=== With remote kadmin ===
 +
This is the easier method, but requires you to have configured [[#Configuring kadmin|kadmin]].
 +
 +
Open kadmin as root (so we can write the keytab) on the client, authenticating with your admin principal:
 +
{{hc|client# kadmin -p myuser/admin|<nowiki>
 +
Authenticating as principal myuser/admin with password.
 +
Password for myuser/admin@EXAMPLE.COM:
 +
kadmin:
 +
</nowiki>}}
 +
 +
Add a principal for any services you will be using, eg. "host" for SSH authentication or "nfs" for NFS:
 +
{{hc|kadmin: addprinc -randkey host/kbclient.example.com|<nowiki>
 +
WARNING: no policy specified for host/kbclient.example.com@EXAMPLE.COM; defaulting to no policy
 +
Principal "host/kbclient.example.com@EXAMPLE.COM" created.</nowiki>}}
 +
 +
Save each key to the local keytab:
 +
{{hc|kadmin: ktadd host/kbclient.example.com|<nowiki>
 +
Entry for principal host/kbclient.example.com with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
 +
Entry for principal host/kbclient.example.com with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
 +
</nowiki>}}
 +
 +
=== Without remote kadmin ===
 +
 +
Start kadmin on the Kerberos server, using either unix or kerberos authentication:
 +
{{hc|# kadmin.local|<nowiki>
 +
Authenticating as principal root/admin@EXAMPLE.COM with password.
 +
kadmin.local:
 +
</nowiki>}}
 +
 +
Add a principal for any services you will be using, eg. "host" for SSH authentication or "nfs" for NFS:
 +
{{hc|kadmin.local: addprinc -randkey host/kbclient.example.com|<nowiki>
 +
WARNING: no policy specified for host/kbclient.example.com@EXAMPLE.COM; defaulting to no policy
 +
Principal "host/kbclient.example.com@EXAMPLE.COM" created.
 +
</nowiki>}}
 +
 +
Save each key to a new keytab to be transferred to the client:
 +
{{hc|kadmin.local: ktadd -k kbclient.keytab host/kbclient.example.com|<nowiki>
 +
Entry for principal host/kbclient.example.com with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
 +
Entry for principal host/kbclient.example.com with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
 +
</nowiki>}}
 +
 +
Finally, copy {{ic|kbclient.keytab}} from the server to the client using SCP or similar, then put it in place with correct permissions:
 +
{{bc|<nowiki># install -b -o root -g root -m 600 kbclient.keytab /etc/krb5.keytab</nowiki>}}
 +
 +
Finally, delete kbclient.keytab from the server and client.
 +
 +
 +
== Cross-Realm Trust ==
 +
 +
Set up a second server as shown above, then create the cross-realm principal on both KDCs. Cross-realm principals must be created with strong passwords, not {{ic|-randkey}}, and the same password must be used on both KDCs. The principal must have the same key version number (kvno) in both KDCs.
 +
 +
To grant EXAMPLE.COM principals access to EXAMPLE.ORG resources, you would use the following principal:
 +
kadmin# addprinc krbtgt/EXAMPLE.ORG@EXAMPLE.COM
 +
The {{ic|[capaths]}} section of {{ic|krb5.conf}} can be used to further control cross-realm trust relationships.
  
 
== SSH Authentication ==
 
== SSH Authentication ==
  
Make sure both your [[SSH]] server and client configurations include this line, then restart the server:
+
Use the instructions in [[#Service principals and keytabs|Service principals and keytabs]] to create a principal for the "host" service for both client and server, then put the client's keys in the client's keytab and the server's keys in the server's keytab.
{{bc|GSSAPIAuthentication yes}}
 
  
Generate a service principal:
+
Modify your [[SSH]] server configuration to enable GSSAPI authentication:
{{bc|kadmin.local:  add_principal -randkey host/someserver.example.com@EXAMPLE.COM}}
+
{{hc|/etc/ssh/sshd_config|<nowiki>
 +
# GSSAPI Options
 +
GSSAPIAuthentication yes
 +
GSSAPICleanupCredentials yes
 +
</nowiki>}}
  
Generate the keytab for the server:
+
And modify your client configuration to send GSSAPI requests:
{{bc|kadmin.local:  ktadd -keytab /root/someserver.krb5.keytab}}
+
{{hc|/etc/ssh/ssh_config|<nowiki>
{{bc|<nowiki># scp kerberos.example.com:/root/someserver.krb5.keytab /etc/krb5.keytab
+
Host *
# chmod 600 /etc/krb5.keytab</nowiki>}}
+
  GSSAPIAuthentication yes
 +
  GSSAPIDelegateCredentials yes
 +
</nowiki>}}
  
Get a ticket-granting ticket on the ssh client:
+
Get a ticket-granting ticket on the client before using ssh:
 
{{hc|$ kinit myuser@EXAMPLE.COM|Password for myuser@EXAMPLE.COM: ***}}
 
{{hc|$ kinit myuser@EXAMPLE.COM|Password for myuser@EXAMPLE.COM: ***}}
  
Debug with:
+
Pass the -v option to ssh to watch what's happening:
{{bc|$ ssh someserver.example.com -v}}
+
{{hc|$ ssh sshserver.example.com -v|<nowiki>
 +
debug1: Authentications that can continue: publickey,gssapi-with-mic,password
 +
debug1: Next authentication method: gssapi-with-mic
 +
debug1: Delegating credentials
 +
debug1: Delegating credentials
 +
debug1: Authentication succeeded (gssapi-with-mic).
 +
Authenticated to sshserver.example.com ([192.168.100.136]:22).
 +
debug1: channel 0: new [client-session]
 +
debug1: Requesting no-more-sessions@openssh.com
 +
debug1: Entering interactive session.
 +
debug1: pledge: network
 +
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
 +
Last login: Wed Aug 30 15:52:41 2017 from 192.168.100.1
 +
</nowiki>}}
 +
 
 +
And you should now see a host ticket on the client:
 +
{{hc|client$ klist|<nowiki>
 +
Ticket cache: FILE:/tmp/krb5cc_1000
 +
Default principal: myuser@EXAMPLE.COM
 +
 
 +
Valid starting      Expires              Service principal
 +
08/30/2017 15:37:40  08/31/2017 15:37:40  krbtgt/EXAMPLE.COM@EXAMPLE.COM
 +
08/30/2017 15:53:04  08/31/2017 15:37:40  host/sshserver.example.com@EXAMPLE.COM
 +
</nowiki>}}
 +
 
 +
=== Authorize other principals ===
 +
 
 +
To allow a different kerberos principal to authenticate to a user account, add the principal name to the target account's {{ic|.k5login}} file. For example, to allow {{ic|robert@EXAMPLE.COM}} to SSH to alice's account:
 +
{{hc|/home/alice/.k5login|<nowiki>
 +
robert@EXAMPLE.COM
 +
</nowiki>}}
 +
 
 +
== NFS Security ==
 +
 
 +
First, configure your [[NFS#Server|NFS server]] server. Also see [[NFS Troubleshooting]].
 +
Configuring a [[time synchronization]] daemon on both the clients and the server is strongly recommended. Clock drift will cause this to break, and the error message will not be helpful.
 +
 
 +
Use the instructions in [[#Service principals and keytabs|Service principals and keytabs]] to create a principal for the "nfs" service for both client and server, then put the client's keys in the client's keytab and the server's keys in the server's keytab.
 +
 
 +
=== NFS Server ===
 +
 
 +
Add a Kerberos export option:
 +
* sec=krb5 uses kerberos for authentication only, and transmits the data unauthenticated and unencrypted.
 +
* sec=krb5i uses kerberos for authentication and integrity checking, but still transmits data unencrypted.
 +
* sec=krb5p uses kerberos for authentication and encryption.
 +
{{hc|/etc/exports|<nowiki>
 +
/srv/export *(rw,async,no_subtree_check,no_root_squash,sec=krb5p)
 +
</nowiki>}}
 +
 
 +
And reload the exports:
 +
# exportfs -arv
 +
 
 +
=== NFS Client ===
 +
Mount the exported directory:
 +
# mount nfsserver:/srv/export /mnt/
 +
You can add -vv for verbose information, and may need -t nfs4 and -o sec=krb5p or your chosen security option.
 +
 
 +
Check that it worked with the {{ic|mount}} command:
 +
{{hc|mount {{!}} grep krb5|<nowiki>
 +
nfsserver:/srv/export on /mnt type nfs4 (rw,relatime,vers=4.1,rsize=131072,wsize=131072,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=krb5,clientaddr=192.168.100.139,local_lock=none,addr=192.168.100.136)
 +
</nowiki>}}
 +
 
 +
== Browsers ==
 +
Some browsers have support for Kerberos protocol but disable it by default. Here are the instructions how to enable it:
 +
 
 +
=== Chromium ===
 +
Chromium needs to be run with a command line parameter that specifies a list of sites where Kerberos authentication is allowed. The easiest way is to add persistent flag to the config file:
 +
 
 +
{{hc|/etc/chromium/policies/managed/test_policy.json|<nowiki>
 +
{
 +
  "AuthServerWhitelist": "*.mycompany.com",
 +
  "DisableAuthNegotiateCnameLookup": true
 +
}
 +
</nowiki>}}
 +
 
 +
=== Firefox ===
 +
To configure Firefox with trusted sites visit {{ic|about:config}} and set {{ic|network.negotiate-auth.trusted-uris}} property to FOO.COM (Note: for Firefox there is no "*."; for Chrome, there is).
 +
 
 +
== Troubleshooting ==
 +
 
 +
=== Cannot set GSSAPI authentication names ===
 +
 
 +
Cannot set GSSAPI authentication names, aborting
 +
 
 +
Your realm is missing either the {{ic|kadmin/admin}} or {{ic|kadmin/changepw}} principal.
 +
 
 +
For clients, invalid arguments/options may happen on first setup if rpc-gssd is not loaded. Loading it is usually acomplished by [[enabling]] and [[starting]] {{ic|nfs-client.target}}, but after first setup this target will need a [[restart]].
 +
 
 +
== See also ==
 +
* [https://www.certdepot.net/rhel7-configure-kerberos-kdc/  RHEL7: Configure a Kerberos KDC]
 +
* [https://www.certdepot.net/rhel7-configure-system-authenticate-using-kerberos/ RHEL7: Configure a system to authenticate using Kerberos]

Latest revision as of 22:04, 9 December 2019

Kerberos is a network authentication system. See krb5 documentation.

Installation

Install the krb5 package on your clients and server.

It is highly recommended to use a time synchronization daemon to keep client/server clocks in sync.

If hostname resolution has not been configured, you can manually add your clients and server to the hosts(5) file of each machine. Note that the FQDN (myclient.example.com) must be the first hostname after the IP address in the hosts file.

Server configuration

Domain creation

Edit /etc/krb5.conf to configure your domain:

/etc/krb5.conf
[libdefaults]
    default_realm = EXAMPLE.COM

[realms]
    EXAMPLE.COM = {
        admin_server = kerberos.example.com
        # use "kdc = ..." if the kerberos SRV records aren't in DNS (see Advanced section)
        kdc = kerberos.example.com
        # This breaks krb4 compatibility but increases security
        default_principal_flags = +preauth
    }

[domain_realm]
    example.com  = EXAMPLE.COM
    .example.com = EXAMPLE.COM

[logging]
    kdc          = SYSLOG:NOTICE
    admin_server = SYSLOG:NOTICE
    default      = SYSLOG:NOTICE

This file's format is described in the MIT Kerberos documentation

Create the database:

# kdb5_util -r EXAMPLE.COM create -s
Loading random data                                                             
Initializing database '/var/lib/krb5kdc/principal' for realm 'EXAMPLE.COM',                  
master key name 'K/M@EXAMPLE.COM'
You will be prompted for the database Master Password.                          
It is important that you NOT FORGET this password.                              
Enter KDC database master key: ***
Re-enter KDC database master key to verify: ***

Finally, enable and start the Kerberos services:

# systemctl enable --now krb5-kdc krb5-kadmind

Add principals

Start the Kerberos administration tool, using local authentication

# kadmin.local
Authenticating as principal root/admin@EXAMPLE.COM with password.
kadmin.local:

Add a user principal to the Kerberos database:

kadmin.local: addprinc myuser@EXAMPLE.COM
WARNING: no policy specified for myuser@EXAMPLE.COM; defaulting to no policy
Enter password for principal "myuser@EXAMPLE.COM": ***
Re-enter password for principal "myuser@EXAMPLE.COM": ***
Principal "myuser@EXAMPLE.COM" created.

Add the KDC principal to the Kerberos database:

kadmin.local: addprinc -randkey host/kerberos.example.com
WARNING: no policy specified for host/kerberos.example.com@EXAMPLE.COM; defaulting to no policy
Principal "host/kerberos.example.com@EXAMPLE.COM" created.

Finally, Add the KDC principal to the server's keytab:

kadmin.local: ktadd host/kerberos.example.com
Entry for principal host/kerberos.example.com with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/kerberos.example.com with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.

Quit the Kerberos administration tool:

kadmin.local: quit

You should now be able to get a Kerberos ticket:

$ kinit
Password for myuser@EXAMPLE.COM: ***
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: myuser@EXAMPLE.COM

Valid starting       Expires              Service principal
08/30/2017 14:26:09  08/31/2017 14:26:09  krbtgt/EXAMPLE.COM@EXAMPLE.COM

Firewall

Add ALLOW rules to your firewall for any applicable ports/protocols:

  • 88, TCP and UDP for Kerberos v5
  • 749, TCP and UDP for kadmin if you plan to configure it
  • 750, TCP and UDP for Kerberos v4 if you need backwards compatibility

DNS records

This isn't necessary if you specify the kerberos and kadmin server in each machine's krb5.conf

db.example.com
kerberos.example.com.           A     1.2.3.4
_kerberos.example.com.          TXT   "EXAMPLE.COM"
_kerberos._udp.example.com.     SRV   0 0  88 kerberos.example.com.
_kerberos-adm._udp.example.com. SRV   0 0 749 kerberos.example.com.

Do not forget reverse DNS.


Client configuration

Edit the client's /etc/krb5.conf to match your server's configuration. You can copy this file from the server, or just set the required realm information.

Testing

You should now be able to get a Kerberos ticket on the client:

$ kinit
Password for myuser@EXAMPLE.COM: ***
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: myuser@EXAMPLE.COM

Valid starting       Expires              Service principal
08/30/2017 15:36:10  08/31/2017 15:36:10  krbtgt/EXAMPLE.COM@EXAMPLE.COM


Configuring kadmin

You'll need /etc/krb5.conf configured on the kadmin client, and the server's firewall configured for kadmin.

Configuring kadmin ACL

Create a principal for administration:

kadmin.local:  add_principal myuser/admin@EXAMPLE.COM
WARNING: no policy specified for myuser/admin@EXAMPLE.COM; defaulting to no policy
Enter password for principal "myuser/admin@EXAMPLE.COM": ***
Re-enter password for principal "myuser/admin@EXAMPLE.COM": ***
Principal "myuser/admin@EXAMPLE.COM" created.

Add the user to the kadmin ACL file:

/var/lib/krb5kdc/kadm5.acl
myuser/admin@EXAMPLE.COM *

This file's format is described in the MIT Kerberos documentation

Configure kdc.conf:

/var/lib/krb5kdc/kdc.conf
[kdcdefaults]
    kdc_ports = 750,88

[realms]
    EXAMPLE.COM = {
        database_name = /var/lib/krb5kdc/principal
        acl_file = /var/lib/krb5kdc/kadm5.acl
        key_stash_file = /var/lib/krb5kdc/.k5.EXAMPLE.COM
        kdc_ports = 750,88
        max_life = 10h 0m 0s
        max_renewable_life = 7d 0h 0m 0s
    }

This file's format is described in the MIT Kerberos documentation

Restart the kdc and kadmin daemons:

sudo systemctl restart krb5-kdc krb5-kadmind

You can now use kadmin as your own user, authenticating with kerberos:

$ kadmin
Authenticating as principal myuser/admin@EXAMPLE.COM with password.
Password for myuser/admin@EXAMPLE.COM: ***
kadmin:


Service principals and keytabs

First, ensure you've configured krb5.conf on all involved machines.

A kerberos principal has three components, formatted as `primary/instance@REALM`. For user principals, the primary is your username and the instance is omitted or is a role (eg. "admin"): `myuser@EXAMPLE.COM` or `myuser/admin@EXAMPLE.COM`. For hosts, the primary is "host" and the instance is the server FQDN: `host/myserver.example.com@EXAMPLE.COM`. For services, the primary is the service abbreviation and the instance is the FQDN: `nfs/myserver.example.com@EXAMPLE.COM`. The realm can often be omitted, the local computer's default realm is usually assumed.

With remote kadmin

This is the easier method, but requires you to have configured kadmin.

Open kadmin as root (so we can write the keytab) on the client, authenticating with your admin principal:

client# kadmin -p myuser/admin
Authenticating as principal myuser/admin with password.
Password for myuser/admin@EXAMPLE.COM:
kadmin:

Add a principal for any services you will be using, eg. "host" for SSH authentication or "nfs" for NFS:

kadmin: addprinc -randkey host/kbclient.example.com
WARNING: no policy specified for host/kbclient.example.com@EXAMPLE.COM; defaulting to no policy
Principal "host/kbclient.example.com@EXAMPLE.COM" created.

Save each key to the local keytab:

kadmin: ktadd host/kbclient.example.com
Entry for principal host/kbclient.example.com with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/kbclient.example.com with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.

Without remote kadmin

Start kadmin on the Kerberos server, using either unix or kerberos authentication:

# kadmin.local
Authenticating as principal root/admin@EXAMPLE.COM with password.
kadmin.local:

Add a principal for any services you will be using, eg. "host" for SSH authentication or "nfs" for NFS:

kadmin.local: addprinc -randkey host/kbclient.example.com
WARNING: no policy specified for host/kbclient.example.com@EXAMPLE.COM; defaulting to no policy
Principal "host/kbclient.example.com@EXAMPLE.COM" created.

Save each key to a new keytab to be transferred to the client:

kadmin.local: ktadd -k kbclient.keytab host/kbclient.example.com
Entry for principal host/kbclient.example.com with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/kbclient.example.com with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.

Finally, copy kbclient.keytab from the server to the client using SCP or similar, then put it in place with correct permissions:

# install -b -o root -g root -m 600 kbclient.keytab /etc/krb5.keytab

Finally, delete kbclient.keytab from the server and client.


Cross-Realm Trust

Set up a second server as shown above, then create the cross-realm principal on both KDCs. Cross-realm principals must be created with strong passwords, not -randkey, and the same password must be used on both KDCs. The principal must have the same key version number (kvno) in both KDCs.

To grant EXAMPLE.COM principals access to EXAMPLE.ORG resources, you would use the following principal:

kadmin# addprinc krbtgt/EXAMPLE.ORG@EXAMPLE.COM

The [capaths] section of krb5.conf can be used to further control cross-realm trust relationships.

SSH Authentication

Use the instructions in Service principals and keytabs to create a principal for the "host" service for both client and server, then put the client's keys in the client's keytab and the server's keys in the server's keytab.

Modify your SSH server configuration to enable GSSAPI authentication:

/etc/ssh/sshd_config
# GSSAPI Options
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes

And modify your client configuration to send GSSAPI requests:

/etc/ssh/ssh_config
Host *
  GSSAPIAuthentication yes
  GSSAPIDelegateCredentials yes

Get a ticket-granting ticket on the client before using ssh:

$ kinit myuser@EXAMPLE.COM
Password for myuser@EXAMPLE.COM: ***

Pass the -v option to ssh to watch what's happening:

$ ssh sshserver.example.com -v
debug1: Authentications that can continue: publickey,gssapi-with-mic,password
debug1: Next authentication method: gssapi-with-mic
debug1: Delegating credentials
debug1: Delegating credentials
debug1: Authentication succeeded (gssapi-with-mic).
Authenticated to sshserver.example.com ([192.168.100.136]:22).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: network
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
Last login: Wed Aug 30 15:52:41 2017 from 192.168.100.1

And you should now see a host ticket on the client:

client$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: myuser@EXAMPLE.COM

Valid starting       Expires              Service principal
08/30/2017 15:37:40  08/31/2017 15:37:40  krbtgt/EXAMPLE.COM@EXAMPLE.COM
08/30/2017 15:53:04  08/31/2017 15:37:40  host/sshserver.example.com@EXAMPLE.COM

Authorize other principals

To allow a different kerberos principal to authenticate to a user account, add the principal name to the target account's .k5login file. For example, to allow robert@EXAMPLE.COM to SSH to alice's account:

/home/alice/.k5login
robert@EXAMPLE.COM

NFS Security

First, configure your NFS server server. Also see NFS Troubleshooting. Configuring a time synchronization daemon on both the clients and the server is strongly recommended. Clock drift will cause this to break, and the error message will not be helpful.

Use the instructions in Service principals and keytabs to create a principal for the "nfs" service for both client and server, then put the client's keys in the client's keytab and the server's keys in the server's keytab.

NFS Server

Add a Kerberos export option:

  • sec=krb5 uses kerberos for authentication only, and transmits the data unauthenticated and unencrypted.
  • sec=krb5i uses kerberos for authentication and integrity checking, but still transmits data unencrypted.
  • sec=krb5p uses kerberos for authentication and encryption.
/etc/exports
/srv/export *(rw,async,no_subtree_check,no_root_squash,sec=krb5p)

And reload the exports:

# exportfs -arv

NFS Client

Mount the exported directory:

# mount nfsserver:/srv/export /mnt/

You can add -vv for verbose information, and may need -t nfs4 and -o sec=krb5p or your chosen security option.

Check that it worked with the mount command:

mount | grep krb5
nfsserver:/srv/export on /mnt type nfs4 (rw,relatime,vers=4.1,rsize=131072,wsize=131072,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=krb5,clientaddr=192.168.100.139,local_lock=none,addr=192.168.100.136)

Browsers

Some browsers have support for Kerberos protocol but disable it by default. Here are the instructions how to enable it:

Chromium

Chromium needs to be run with a command line parameter that specifies a list of sites where Kerberos authentication is allowed. The easiest way is to add persistent flag to the config file:

/etc/chromium/policies/managed/test_policy.json
{
  "AuthServerWhitelist": "*.mycompany.com",
  "DisableAuthNegotiateCnameLookup": true
}

Firefox

To configure Firefox with trusted sites visit about:config and set network.negotiate-auth.trusted-uris property to FOO.COM (Note: for Firefox there is no "*."; for Chrome, there is).

Troubleshooting

Cannot set GSSAPI authentication names

Cannot set GSSAPI authentication names, aborting

Your realm is missing either the kadmin/admin or kadmin/changepw principal.

For clients, invalid arguments/options may happen on first setup if rpc-gssd is not loaded. Loading it is usually acomplished by enabling and starting nfs-client.target, but after first setup this target will need a restart.

See also