diff --git a/README.md b/README.md index 6f2d8c4..4d3bfa9 100644 --- a/README.md +++ b/README.md @@ -41,28 +41,15 @@ NCSA allows `createhost` principals for projects. This allows for two automated In order to support this, you need to request a `createhost` principal keytab for your project, then assign the base64 encoding of the keytab file to `profile_system_auth::kerberos::createhostkeytab` and the first part of the principal's username to `profile_system_auth::kerberos::createhostuser` parameters. NCSA staff can request a `createhost` principal by emailing service@ncsa.illinois.edu. They will provide you a principal username and either the keytab file for that user or a BASE64 encoding of that keytab. -## Reference +The same sort of approach can be done if using Active Directory (AD) to create a computer object for your host and save its keytab locally. This can be configured by specifying the following paraters: + +``` +profile_system_auth::kerberos::ad_computers_ou # AD OU FOR COMPUTER OBJECTS +profile_system_auth::kerberos::ad_createhostkeytab # BASE64 ENCODING OF KRB5 CREATEHOST KEYTAB FILE +profile_system_auth::kerberos::ad_createhostuser # AD CREATEHOST USER +profile_system_auth::kerberos::ad_domain # AD DOMAIN +``` -### class profile_system_auth::config ( -- String $authselect_profile, -- Boolean $enable_mkhomedir, -- String $oddjobd_mkhomedir_conf, -- $removed_pkgs, -- Array[ String[1] ] $required_pkgs, -- Boolean $use_authconfig, -### class profile_system_auth::kerberos ( -- Hash $cfg_file_settings, # cfg files and their contents -- Optional[ String ] $createhostkeytab, # BASE64 ENCODING OF KRB5 CREATEHOST KEYTAB FILE -- Optional[ String ] $createhostuser, # CREATEHOST USER -- Hash $crons, -- Hash $files_remove_setuid, -- Array[ String[1] ] $required_pkgs, # DEFAULT SET VIA MODULE DATA -- Optional[ Array[ String[1] ] ] $root_k5login_principals, # PRINCIPALS WITH ROOT PRIVILEGES -### class profile_system_auth::ldap ( -- String $ldap_conf, # ldap.conf file contents -- Array[ String[1] ] $required_pkgs, # DEFAULT SET VIA MODULE DATA -### class profile_system_auth::su ( -- Boolean $disable_su, -- String $su_path, +## Reference [REFERENCE.md](REFERENCE.md) diff --git a/REFERENCE.md b/REFERENCE.md index 5fb1ba8..351249e 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -109,6 +109,10 @@ include profile_system_auth::kerberos The following parameters are available in the `profile_system_auth::kerberos` class: +* [`ad_computers_ou`](#-profile_system_auth--kerberos--ad_computers_ou) +* [`ad_createhostkeytab`](#-profile_system_auth--kerberos--ad_createhostkeytab) +* [`ad_createhostuser`](#-profile_system_auth--kerberos--ad_createhostuser) +* [`ad_domain`](#-profile_system_auth--kerberos--ad_domain) * [`cfg_file_settings`](#-profile_system_auth--kerberos--cfg_file_settings) * [`createhostkeytab`](#-profile_system_auth--kerberos--createhostkeytab) * [`createhostuser`](#-profile_system_auth--kerberos--createhostuser) @@ -118,6 +122,30 @@ The following parameters are available in the `profile_system_auth::kerberos` cl * [`required_pkgs`](#-profile_system_auth--kerberos--required_pkgs) * [`root_k5login_principals`](#-profile_system_auth--kerberos--root_k5login_principals) +##### `ad_computers_ou` + +Data type: `Optional[String]` + +Optional String of AD OU where computer objects should be created + +##### `ad_createhostkeytab` + +Data type: `Optional[String]` + +Optional String of base64 encoding of AD krb5 createhost keytab file + +##### `ad_createhostuser` + +Data type: `Optional[String]` + +Optional String of user with permissions to create host in AD + +##### `ad_domain` + +Data type: `Optional[String]` + +Optional String of the Active Directory domain that the computer should join + ##### `cfg_file_settings` Data type: `Hash` diff --git a/data/common.yaml b/data/common.yaml index 93e2bdb..788d4fc 100644 --- a/data/common.yaml +++ b/data/common.yaml @@ -27,6 +27,12 @@ profile_system_auth::config::oddjobd_mkhomedir_conf: | profile_system_auth::config::pam_config: {} + +profile_system_auth::kerberos::ad_computers_ou: null +profile_system_auth::kerberos::ad_createhostkeytab: null +profile_system_auth::kerberos::ad_createhostuser: null +profile_system_auth::kerberos::ad_domain: null + profile_system_auth::kerberos::cfg_file_settings: /etc/krb5.conf: | # This file is managed by Puppet. diff --git a/data/os/RedHat.yaml b/data/os/RedHat.yaml index 3919725..33a462c 100644 --- a/data/os/RedHat.yaml +++ b/data/os/RedHat.yaml @@ -10,6 +10,7 @@ profile_system_auth::config::use_authconfig: false profile_system_auth::kerberos::files_remove_setuid: "/usr/bin/ksu": {} profile_system_auth::kerberos::required_pkgs: + - "adcli" - "krb5-libs" - "krb5-workstation" profile_system_auth::ldap::ldap_conf: | diff --git a/lib/facter/is_joined_ad_domain.rb b/lib/facter/is_joined_ad_domain.rb new file mode 100644 index 0000000..3bdc395 --- /dev/null +++ b/lib/facter/is_joined_ad_domain.rb @@ -0,0 +1,8 @@ +Facter.add('kerberos_keytab_domains') do + setcode do + command = "klist -kte 2>&1 | grep $(hostname) | awk -F\\@ '{ print $2 }' | awk '{ print $1 }' | uniq" + result = Facter::Core::Execution.execute(command) + domains = result.split("\n").uniq + domains.join(',') + end +end diff --git a/manifests/kerberos.pp b/manifests/kerberos.pp index a15a86f..8d190ed 100644 --- a/manifests/kerberos.pp +++ b/manifests/kerberos.pp @@ -2,6 +2,18 @@ # # @summary Basic kerberos client setup, with optional host principal management # +# @param ad_computers_ou +# Optional String of AD OU where computer objects should be created +# +# @param ad_createhostkeytab +# Optional String of base64 encoding of AD krb5 createhost keytab file +# +# @param ad_createhostuser +# Optional String of user with permissions to create host in AD +# +# @param ad_domain +# Optional String of the Active Directory domain that the computer should join +# # @param cfg_file_settings # Hash of file resource parameters for various config files # @@ -30,12 +42,16 @@ # include profile_system_auth::kerberos # class profile_system_auth::kerberos ( - Hash $cfg_file_settings, # cfg files and their contents + Optional[String] $ad_computers_ou, # AD OU FOR COMPUTER OBJECTS + Optional[String] $ad_createhostkeytab, # BASE64 ENCODING OF KRB5 CREATEHOST KEYTAB FILE + Optional[String] $ad_createhostuser, # AD CREATEHOST USER + Optional[String] $ad_domain, # AD DOMAIN + Hash $cfg_file_settings, # cfg files and their contents Optional[String] $createhostkeytab, # BASE64 ENCODING OF KRB5 CREATEHOST KEYTAB FILE Optional[String] $createhostuser, # CREATEHOST USER - Hash $crons, - Boolean $enable, - Hash $files_remove_setuid, + Hash $crons, + Boolean $enable, + Hash $files_remove_setuid, Array[String[1]] $required_pkgs, # DEFAULT SET VIA MODULE DATA Optional[Array[String[1]]] $root_k5login_principals, # PRINCIPALS WITH ROOT PRIVILEGES ) { @@ -80,11 +96,12 @@ } } + # KERBEROS HOST PRINCIPAL CREATION if ( $createhostkeytab and $createhostuser ) { # CREATE KEYS AND SETUP RENEWAL file { '/root/createhostkeytab.sh': ensure => file, - mode => '0700', + mode => '0500', source => "puppet:///modules/${module_name}/root/createhostkeytab.sh", } ## THIS MIGHT NEED TO BE SMARTER TO ALLOW FOR MULTIPLE HOSTNAMES ON ONE SERVER @@ -115,5 +132,36 @@ cron { $k: ensure => absent, } } } + + # AD JOIN AND KEYTAB CREATION + if ( $ad_createhostkeytab and $ad_createhostuser and $ad_computers_ou and $ad_domain ) { + $kerberos_domains = split($facts['kerberos_keytab_domains'], ',') + if ( $ad_domain in $kerberos_domains ) { + $ensure_parm = 'absent' + } else { + $ensure_parm = 'present' + + exec { 'run_ad_create_host_keytab_script': + path => ['/usr/bin', '/usr/sbin', '/usr/lib/mit/bin'], + command => Sensitive( + "/root/ad_createhostkeytab.sh '${ad_domain}' '${ad_computers_ou}' '${ad_createhostuser}' '${ad_createhostkeytab}' " + ), + #refreshonly => true, + require => File['/root/ad_createhostkeytab.sh'], + } + + # FOLLOWING IS JUST IN CASE THE run_ad_create_host_keytab_script TIMES OUT, WHICH IT HAS + file { '/root/createhost.keytab': + ensure => absent, + require => Exec['run_ad_create_host_keytab_script'], + } + } + + file { '/root/ad_createhostkeytab.sh': + ensure => $ensure_parm, + mode => '0500', + content => template("${module_name}/ad_createhostkeytab.sh.erb"), + } + } } } diff --git a/templates/ad_createhostkeytab.sh.erb b/templates/ad_createhostkeytab.sh.erb new file mode 100644 index 0000000..294c1fb --- /dev/null +++ b/templates/ad_createhostkeytab.sh.erb @@ -0,0 +1,36 @@ +#!/bin/bash + +# Enable debugging mode +set -x + +# ASSIGN ARGUMENTS FROM COMMAND LINE ARGUMENTS +AD_DOMAIN=$1 # Active Directory domain +AD_OU_COMPUTERS=$2 # Organizational Unit for computers in AD +AD_USER=$3 # User with permissions to create host in AD +KEYTAB_BASE64=$4 # Base64 encoded keytab for creating host + +# ASSIGN STATIC VARIABLES +HOST_FQDN="<%= @fqdn %>" # Fully Qualified Domain Name of the host +KEYTAB_FILE="/root/createhost.keytab" # Path to store the decoded keytab file +OS_NAME="<%= @os['name'] %>" # Operating System name + +# Decode the base64 encoded keytab and save it to a file +echo "${KEYTAB_BASE64}" | base64 --decode > $KEYTAB_FILE + +# Authenticate using the keytab file +kinit -k -t $KEYTAB_FILE $AD_USER + +# Pre-create the computer account in the specified OU +adcli preset-computer --domain="${AD_DOMAIN}" --domain-ou="${AD_OU_COMPUTERS}" -U "${AD_USER}" --login-ccache --os-name="${OS_NAME}" $HOST_FQDN + +# Join the computer to the AD domain +adcli join --domain="${AD_DOMAIN}" -U "${AD_USER}" --login-ccache + +# Destroy the Kerberos ticket cache for the user +kdestroy -p $AD_USER + +# Optionally, list the contents of the keytab file (uncomment for debugging) +# klist -kte + +# Remove the keytab file for security reasons +rm -f $KEYTAB_FILE