Add Kerberos config

Step one in an AFS cell is getting kerberos working. This does not
provide end-to-end KDC management - the realm still needs to be
created by hand.

Change-Id: I891d784d676ab79e7aca9c883dd9e705a30db6e5
This commit is contained in:
Monty Taylor 2014-10-18 14:56:00 -07:00
parent 849cd8933d
commit d33895f3b1
13 changed files with 533 additions and 0 deletions

63
doc/source/kerberos.rst Normal file
View File

@ -0,0 +1,63 @@
:title: Kerberos
.. _kerberos:
Kerberos
########
Kerberos is a computer network authentication protocol which works on the
basis of 'tickets' to allow nodes communicating over a non-secure network
to prove their identity to one another in a secure manner. It is the basis
for authentication to AFS.
At a Glance
===========
:Hosts:
* kdc*.openstack.org
:Puppet:
* :file:`modules/kerberos`
* :file:`modules/openstack_project/manifests/kdc.pp`
:Projects:
* http://web.mit.edu/kerberos
:Bugs:
* http://bugs.launchpad.net/openstack-ci
* http://krbdev.mit.edu/rt/
:Resources:
* `Kerberos Website <http://web.mit.edu/kerberos>`_
* `KDC Install guide <http://web.mit.edu/kerberos/krb5-devel/doc/admin/install_kdc.html>`_
OpenStack Realm
---------------
OpenStack runs a Kerberos ``Realm`` called ``OPENSTACK.ORG``.
The realm contains a ``Key Distribution Center`` or KDC which is spread
across a master and a slave, as well as an admin server which only runs on the
master. Most of the configuration is in puppet, but initial setup and
the management of user accounts, known as ``principals``, are manual tasks.
Realm Creation
--------------
On the first KDC host, the admin needs to run `krb5_newrealm` by hand. Then
admin principals and host principles need to be set up.
Set up host principals for slave propogation::
# execute kadmin.local then run these commands
addprinc -randkey host/kdc01.openstack.org
addprinc -randkey host/kdc02.openstack.org
ktadd host/kdc01.openstack.org
ktadd host/kdc02.openstack.org
Copy the file `/etc/krb5.keytab` to the second kdc host.
The puppet config sets up slave propogation scripts and cron jobs to run them.
Adding principals
-----------------
To add an admin principal::
# execute kadmin.local then run these commands
addprinc corvus/admin@OPENSTACK.ORG

View File

@ -28,6 +28,7 @@ Major Systems
git
openstackid
storyboard
kerberos
.. NOTE(dhellmann): These projects were not listed above, or in any
other toctree, which breaks the build. It's not clear why they were

View File

@ -649,4 +649,19 @@ node 'single-use-slave' {
}
}
# Node-OS: trusty
node 'kdc01.openstack.org' {
class { 'openstack_project::kdc':
sysadmins => hiera('sysadmins', []),
}
}
# Node-OS: trusty
node 'kdc02.openstack.org' {
class { 'openstack_project::kdc':
sysadmins => hiera('sysadmins', []),
slave => true,
}
}
# vim:sw=2:ts=2:expandtab:textwidth=79

View File

@ -0,0 +1,6 @@
# This file Is the access control list for krb5 administration.
# When this file is edited run /etc/init.d/krb5-admin-server restart to activate
# One common way to set up Kerberos administration is to allow any principal
# ending in /admin is given full administrative rights.
# To enable this, uncomment the following line:
*/admin *

View File

@ -0,0 +1,123 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: krb5-kpropd
# Required-Start: $local_fs $remote_fs $network $syslog
# Required-Stop: $local_fs $remote_fs $network $syslog
# X-Start-Before: $x-display-manager
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: MIT Kerberos propagation daemon
# Description: Starts, stops, or restarts the MIT kpropd.
### END INIT INFO
# Author: Sam Hartman <hartmans@mit.edu>
# Author: Russ Allbery <rra@debian.org>
#
# Based on the /etc/init.d/skeleton template as found in initscripts version
# 2.86.ds1-15.
PATH=/usr/sbin:/usr/bin:/sbin:/bin
DESC="Kerberos kpropd"
NAME=kpropd
DAEMON=/usr/sbin/$NAME
DAEMON_ARGS=""
SCRIPTNAME=/etc/init.d/krb5-kpropd
# Exit if the package is not installed.
[ -x "$DAEMON" ] || exit 0
# Read configuration if it is present.
[ -r /etc/default/krb5-kpropd ] && . /etc/default/krb5-kpropd
# Get the setting of VERBOSE and other rcS variables.
[ -f /etc/default/rcS ] && . /etc/default/rcS
# Define LSB log functions (requires lsb-base >= 3.0-6).
. /lib/lsb/init-functions
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
do_start_kpropd()
{
start-stop-daemon --start --quiet --startas $DAEMON --name $NAME --test \
> /dev/null || return 1
start-stop-daemon --start --quiet --startas $DAEMON --name $NAME \
-- $DAEMON_ARGS || return 2
}
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
do_stop_kpropd()
{
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
return "$RETVAL"
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start_kpropd
case "$?" in
0|1)
[ "$VERBOSE" != no ] && log_end_msg 0
;;
2)
[ "$VERBOSE" != no ] && log_end_msg 1
;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop_kpropd
case "$?" in
0|1)
[ "$VERBOSE" != no ] && log_progress_msg "krb524d"
;;
2)
[ "$VERBOSE" != no ] && log_end_msg 1
;;
esac
;;
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop_kpropd
case "$?" in
0|1)
do_start_kpropd
case "$?" in
0)
log_end_msg 0
;;
1|2)
log_end_msg 1
;;
esac
;;
*)
log_end_msg 1
;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload|status}" >&2
exit 3
;;
esac
:

View File

@ -0,0 +1,17 @@
class kerberos::client (
$realm,
$kdcs,
$admin_server,
) {
package { 'krb5-user':
ensure => present,
require => File['/etc/krb5.conf'],
}
file { '/etc/krb5.conf':
ensure => present,
replace => true,
content => template('kerberos/krb5.conf.erb'),
}
}

View File

@ -0,0 +1,111 @@
class kerberos::server (
$realm,
$kdcs = [$::fqdn],
$admin_server = [$::fdqn],
$slaves = [],
$slave = false,
) {
include haveged
include ntp
class { 'kerberos::client':
realm => $realm,
kdcs => $kdcs,
admin_server => $admin_server,
}
$packages = [
'krb5-admin-server',
'krb5-kdc',
]
package { $packages:
ensure => present,
}
file { '/etc/krb5kdc/kdc.conf':
ensure => present,
replace => true,
content => template('kerberos/kdc.conf.erb'),
require => Package['krb5-kdc'],
}
file { '/etc/krb5kdc/kpropd.acl':
ensure => present,
replace => true,
content => template('kerberos/kpropd.acl.erb'),
require => Package['krb5-kdc'],
}
file { '/etc/krb5kdc/kadm5.acl':
ensure => present,
replace => true,
source => 'puppet:///modules/kerberos/kadm5.acl',
require => Package['krb5-admin-server'],
}
file { '/var/krb5kdc':
ensure => directory,
}
file { '/etc/init.d/krb5-kpropd':
ensure => present,
replace => true,
source => 'puppet:///modules/kerberos/krb5-kpropd',
require => Package['krb5-admin-server'],
}
file { '/usr/local/bin/run-kprop.sh':
ensure => present,
replace => true,
mode => 0755,
content => template('kerberos/run-kprop.sh.erb'),
require => Package['krb5-admin-server'],
}
if ($slave) {
$run_admin_server = stopped
$run_kadmind = 'false'
$run_kpropd = running
$kprop_cron = absent
} else {
$run_admin_server = running
$run_kadmind = 'true'
$run_kpropd = stopped
$kprop_cron = present
}
# krb5-admin-server generates this, so make sure this runs after we do
# things with krb5-admin-server
file { '/etc/default/krb5-admin-server':
ensure => present,
replace => true,
content => template('kerberos/krb5-admin-server.defaults.erb'),
require => Package['krb5-admin-server'],
}
cron { 'kprop':
ensure => $kprop_cron,
user => 'root',
minute => '*/15',
command => '/usr/local/bin/run-kprop.sh >/dev/null 2>&1',
environment => 'PATH=/usr/bin:/bin:/usr/sbin:/sbin',
}
service { 'krb5-kpropd':
ensure => $run_kpropd,
require => [
File['/etc/init.d/krb5-kpropd'],
Package['krb5-admin-server'],
],
}
service { 'krb5-admin-server':
ensure => $run_admin_server,
subscribe => File['/etc/krb5kdc/kadm5.acl'],
require => [
File['/etc/krb5kdc/kadm5.acl'],
Package['krb5-admin-server'],
],
}
}

View File

@ -0,0 +1,16 @@
[kdcdefaults]
kdc_ports = 750,88
[realms]
<%= @realm %> = {
database_name = /var/lib/krb5kdc/principal
admin_keytab = FILE:/etc/krb5kdc/kadm5.keytab
acl_file = /etc/krb5kdc/kadm5.acl
key_stash_file = /etc/krb5kdc/stash
kdc_ports = 750,88
max_life = 10h 0m 0s
max_renewable_life = 7d 0h 0m 0s
master_key_type = aes256-cts
supported_enctypes = aes256-cts:normal
default_principal_flags = +preauth
}

View File

@ -0,0 +1,3 @@
<% @kdcs.each do |kdc| -%>
host/<%= kdc %>@<%= @realm %>
<% end -%>

View File

@ -0,0 +1,2 @@
# Managed by puppet
RUN_KADMIND=<%= @run_kadmind %>

View File

@ -0,0 +1,146 @@
[libdefaults]
default_realm = <%= @realm %>
# The following krb5.conf variables are only for MIT Kerberos.
krb4_config = /etc/krb.conf
krb4_realms = /etc/krb.realms
kdc_timesync = 1
ccache_type = 4
forwardable = true
proxiable = true
# The following encryption type specification will be used by MIT Kerberos
# if uncommented. In general, the defaults in the MIT Kerberos code are
# correct and overriding these specifications only serves to disable new
# encryption types as they are added, creating interoperability problems.
#
# Thie only time when you might need to uncomment these lines and change
# the enctypes is if you have local software that will break on ticket
# caches containing ticket encryption types it doesn't know about (such as
# old versions of Sun Java).
# default_tgs_enctypes = des3-hmac-sha1
# default_tkt_enctypes = des3-hmac-sha1
# permitted_enctypes = des3-hmac-sha1
# The following libdefaults parameters are only for Heimdal Kerberos.
v4_instance_resolve = false
v4_name_convert = {
host = {
rcmd = host
ftp = ftp
}
plain = {
something = something-else
}
}
fcc-mit-ticketflags = true
[realms]
ATHENA.MIT.EDU = {
kdc = kerberos.mit.edu:88
kdc = kerberos-1.mit.edu:88
kdc = kerberos-2.mit.edu:88
admin_server = kerberos.mit.edu
default_domain = mit.edu
}
MEDIA-LAB.MIT.EDU = {
kdc = kerberos.media.mit.edu
admin_server = kerberos.media.mit.edu
}
ZONE.MIT.EDU = {
kdc = casio.mit.edu
kdc = seiko.mit.edu
admin_server = casio.mit.edu
}
MOOF.MIT.EDU = {
kdc = three-headed-dogcow.mit.edu:88
kdc = three-headed-dogcow-1.mit.edu:88
admin_server = three-headed-dogcow.mit.edu
}
CSAIL.MIT.EDU = {
kdc = kerberos-1.csail.mit.edu
kdc = kerberos-2.csail.mit.edu
admin_server = kerberos.csail.mit.edu
default_domain = csail.mit.edu
krb524_server = krb524.csail.mit.edu
}
IHTFP.ORG = {
kdc = kerberos.ihtfp.org
admin_server = kerberos.ihtfp.org
}
GNU.ORG = {
kdc = kerberos.gnu.org
kdc = kerberos-2.gnu.org
kdc = kerberos-3.gnu.org
admin_server = kerberos.gnu.org
}
1TS.ORG = {
kdc = kerberos.1ts.org
admin_server = kerberos.1ts.org
}
GRATUITOUS.ORG = {
kdc = kerberos.gratuitous.org
admin_server = kerberos.gratuitous.org
}
DOOMCOM.ORG = {
kdc = kerberos.doomcom.org
admin_server = kerberos.doomcom.org
}
ANDREW.CMU.EDU = {
kdc = kerberos.andrew.cmu.edu
kdc = kerberos2.andrew.cmu.edu
kdc = kerberos3.andrew.cmu.edu
admin_server = kerberos.andrew.cmu.edu
default_domain = andrew.cmu.edu
}
CS.CMU.EDU = {
kdc = kerberos.cs.cmu.edu
kdc = kerberos-2.srv.cs.cmu.edu
admin_server = kerberos.cs.cmu.edu
}
DEMENTIA.ORG = {
kdc = kerberos.dementix.org
kdc = kerberos2.dementix.org
admin_server = kerberos.dementix.org
}
stanford.edu = {
kdc = krb5auth1.stanford.edu
kdc = krb5auth2.stanford.edu
kdc = krb5auth3.stanford.edu
master_kdc = krb5auth1.stanford.edu
admin_server = krb5-admin.stanford.edu
default_domain = stanford.edu
}
UTORONTO.CA = {
kdc = kerberos1.utoronto.ca
kdc = kerberos2.utoronto.ca
kdc = kerberos3.utoronto.ca
admin_server = kerberos1.utoronto.ca
default_domain = utoronto.ca
}
<%= @realm %> = {
<% @kdcs.each do |kdc| -%>
kdc = <%= kdc %>
<% end -%>
admin_server = <%= admin_server %>
default_domain = <%= @realm.downcase %>
}
[domain_realm]
.mit.edu = ATHENA.MIT.EDU
mit.edu = ATHENA.MIT.EDU
.media.mit.edu = MEDIA-LAB.MIT.EDU
media.mit.edu = MEDIA-LAB.MIT.EDU
.csail.mit.edu = CSAIL.MIT.EDU
csail.mit.edu = CSAIL.MIT.EDU
.whoi.edu = ATHENA.MIT.EDU
whoi.edu = ATHENA.MIT.EDU
.stanford.edu = stanford.edu
.slac.stanford.edu = SLAC.STANFORD.EDU
.toronto.edu = UTORONTO.CA
.utoronto.ca = UTORONTO.CA
[login]
krb4_convert = true
krb4_get_tickets = false

View File

@ -0,0 +1,7 @@
#!/bin/sh
kdclist = "<% @slaves.each do |slave| -%><%= slave %> <% end -%>"
kdb5_util dump /var/krb5kdc/slave_datatrans
for kdc in $kdclist
do
kprop -f /var/krb5kdc/slave_datatrans $kdc
done

View File

@ -0,0 +1,23 @@
# kerberos kdc servers
class openstack_project::kdc (
$slave = false,
$sysadmins = [],
) {
class { 'openstack_project::server':
iptables_public_tcp_ports => [88,464,749,754],
iptables_public_udp_ports => [88,464,749],
sysadmins => $sysadmins
}
class { 'kerberos::server':
realm => 'OPENSTACK.ORG',
kdcs => [
'kdc01.openstack.org',
'kdc02.openstack.org',
],
admin_server => 'kdc.openstack.org',
slaves => [
'kdc02.openstack.org',
],
slave => $slave,
}
}