Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addition of configuration and initialization of a MIT (Kerberos) KDC #322

Closed
wants to merge 2 commits into from

Conversation

beargiles
Copy link

This patch adds the configuration and initialization of a MIT(Kerberos) KDC. It is 90% complete but the final bit requires thought by the upstream maintainer.

The changes fall into three broad categories.

The items with a modest impact that can easily be integrated into stable.

  1. Creation of the /etc/krb5.conf, /etc/krb5kdc/kdc.conf, and /etc/krb5kdc/kadm5.conf files configured to refer to the OpenLDAP server.

  2. Addition of kerberos.schema to the list of default schemas, plus modest changes to the bootstrap ldif files for tasks like adding an index on krbPrincipalName.

  3. Addition of krb5-admin-server as a Debian dependency.

The items that should only be performed conditionally.

  1. Creation of three bootstrap/ldif/custom files that create a few entries, modify the ACLs, then delete the entries so kdb5-ldap-util can run as usual later. I put them in ldif/custom since they also define two ou but it maybe better to put them into a new directory (ldif/krb5) and delete the ou as well. Creation of the ou can be deferred until the script mentioned below. This is required since we want the ACLs to limit access to the KDC information since it contains sensitive information but we can't change the ACLs on a running server.

  2. Stashing the ldap admin password for use by the kdc and kadmin servers. This is really iffy since the password is unencrypted.

The items that can only be performed once the LDAP server is running

I don't know if there's an easy way to run scripts once the LDAP server is running - for now I'm just creating a script in /usr/local/bin/01-kdc.sh that does the following tasks:

  1. (create the ou currently created in ldif/custom/01-groups.ldif?)

  2. Run kdb5-ldap-util to populate the LDAP database with the required KDC entries.

  3. Start the krb5-kdc and krb5-admin-server servers.

beargiles and others added 2 commits May 7, 2019 16:03
Added kerberos.schema

Tweaked assets/config/bootstrap/ldif to add a few kerberos attributes

Added assets/config/bootstrap/ldif/custom to tweak a few more - need to decide on final resolution of this.

Added configuration of /etc/krb5.conf and /etc/krb5kdc/kdc.conf

Create script to finish initialization of system.

Added dependency on krb5-admin-server - if nothing else provides kadmin.local to create principals that can be used with kadmin externally.

Added EXPOSE 88 750 to Dockerfile

Added script to initialize KDC entries once the LDAP server is up.

Updated documentation
@darth-veitcher
Copy link

I'm really interested in getting kerberos working so thanks for this. Would appreciate some docs/instructions for getting this pulled together and working 👍

@beargiles
Copy link
Author

beargiles commented May 9, 2019

I'm primarily focused on Hadoop (Cloudera Hadoop) at the moment but I know that quite a few other servers also support Kerberos authentication.

Recap - Kerberos is a three-party protocol between the client, the server, and a central authority (KDC). Microsoft's Active Directory also uses Kerberos under the covers so if you understand it you're most of the way there.

Kerberos principals have one of thee forms:

  • name@REALM
  • name/svc@REALM
  • svc/hostname@REALM

The first two are for users - the first is valid for any service but kadmin (admin), the second is only valid for the specific service (e.g., bgiles/hdfs). The final form is used by servers, e.g. 172.27.17.4/hdfs.

Users typically use passwords for authentication. They get a 'ticket' by running 'kinit username'.

Servers typically use 'keytab' files for authentication. Servers can load them programmatically or with 'kinit -k file.keytab username'. Users can also use keytabs but it's less common.

Advanced configurations allow authentication using digital certificates or smart cards. That has no effect other than how you get your ticket.

You can list your current kerberos ticket with 'klist'. You can logout with 'kdestroy'.

"REALM" is now traditionally the domain name in capital letters. Kerberos realms actually predate domain names! (IIRC Kerberos came out from MIT in the late 70s or early 80s, domain names weren't introduced until the 90s).

Kerberos users on the KDC are created with 'kadmin' or 'kadmin.local'. The latter can only be executed on the same machine as the KDC (hence .local) and does not require additional authentication beyond being run as root. It is how you create the initial administrative users.

Administrative users have a svc of 'admin'. For instance I define both

(careful sites will assign different 'policies' to these accounts. E.g., the first account might be valid for 1 day before a refresh, the second account might only be valid for 10 minutes.)

Once you have administrative users you can run 'kadmin' from any system with the /etc/krb5.conf file copied from the KDC. You can easily support multiple realms, just edit the file.

You create accounts for users and servers with kadmin:

  • kadmin addprinc -pw user (or kadmin ank ...)

  • kadmin addprinc -randkey svc/hostname

  • kadmin ktadd -k /tmp/server.keytab -norandkey srv/hostname

You need to add @realm unless you have a default realm specified in /etc/krb5.conf.

I mentioned above I'm using this with Hadoop. It creates a monstrous number of Kerberos accounts so you'll want to use the wizard for it.

For something like a PostgreSQL server I think the service name is 'postgres', not 'postgresql', so the server principal name would be something like:

  postgres/db.example.com@EXAMPLE.COM

and you would add this entry to pg_hba.conf

  host  all  all  all  gss  krb_realm=EXAMPLE.COM

and a user bob@EXAMPLE.COM would be mapped to PostgreSQL user 'bob@EXAMPLE.COM'. That can be pretty annoying it's convenient, but slightly less secure, to add 'include_realm=0' and the kerberos principal will be mapped to just 'bob'.

A better approach is to add a 'map=mapfile' option that contains a mapping from Kerberos principal to PostgreSQL account.

Other servers are similar. You'll sometimes see explicit configuration like this, you'll sometimes see 'local_rules' that operate behind the scenes.

@beargiles
Copy link
Author

I forgot add that Kerberos and GSS or GSS-API can be treated as synonymous. The latter is actually a generalization that supports additional authentication mechanisms. Old software might still be using Kerberos-specific libraries but anything remotely recent will use the more general GSS libraries. If you see both, e.g., both 'kerb' and 'gss', always go with GSS.

SPENGO is a Microsoft variant. You probably won't encounter it outside of the context of a web browser connecting to a web site that requires Kerberos authentication. (There's an ancient Apache mod_kerberos module but it's very broken, from a security perspective, unless it's been changed.)

@beargiles
Copy link
Author

beargiles commented May 9, 2019

Finally - one point that's often overlooked. Kerberos is an authentication protocol. It does not encrypt the data. You still need to turn on a privacy protocol like TLS. People often over look this, including me, since you'll always see both protocols offered and some servers will transparently turn on TLS if you specify Kerberos authentication. However you must double check whether every server you use does this!

Strict sites will require both Kerberos authentication (which always provides mutual authentication) AND TLS mutual authentication (which requires both a 'keystore' and a 'truststore', or at least a shared CA cert on both sites.)

This is one reason why a KDC backed by LDAP is so attractive. LDAP also supports userCertificate and cACertificate attributes. It is very reasonable use a process where:

  1. the other party connects via Kerberos.
  2. you get their Kerberos Principal from the connection and use it to look up their LDAP entry.
  3. you get their userCertificate from their LDAP entry.
  4. after verifying the certificate you use it to establish the TLS session with mutual authentication.

If you produce your own certs (locally, via Let's Encrypt, or via a paid service) you can use the same value for the LDAP entry and the "Subject" of the digital certificate. This is possible since they're from the same RFC family - LDAP is X.500 and Digital Certificates are X.509. This lets you easily go from LDAP to digital cert (LDAP lookup) OR from a digital cert to everything in LDAP (use the 'Subject' DN).

@jwheeler91
Copy link

Is there anything that can bee done to help with this pull request? I'd like to set up Kerberos with LDAP but would like to use docker. I'll probably build your fork for now, but keen to use the original image rather than a feature fork.

@beargiles
Copy link
Author

beargiles commented Jul 2, 2019 via email

@BertrandGouny
Copy link
Member

BertrandGouny commented Jul 7, 2019

Hello,
thanks for the PR ! Would be great to have it as on option. And be sure that it don't changed any existing db or config if user don't want it :)

@@ -0,0 +1,43 @@
[logging]
default = FILE:/var/log/krb5libs.log
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to log to stdout to have those logs directly with docker logs


By default the MIT KDC is configured but the actual LDAP entries required are not created.
That requires the user to call /usr/local/bin/01-kdc.sh. (We should find a way
to call this automatically if 'ENABLE_KDC'? is set.)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ENABLE_KERBEROS ? as in startup.sh

@tsmethurst
Copy link

Also interested in this PR, any movement?

@BertrandGouny BertrandGouny deleted the branch osixia:stable February 19, 2021 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants