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 git
openstackid openstackid
storyboard storyboard
kerberos
.. NOTE(dhellmann): These projects were not listed above, or in any .. NOTE(dhellmann): These projects were not listed above, or in any
other toctree, which breaks the build. It's not clear why they were 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 # 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,
}
}