Skip to content

Commit

Permalink
SVCPLAN-6686: Add support for AD createhost functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
billglick committed Dec 4, 2024
1 parent 5616e90 commit 6726ca7
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 26 deletions.
31 changes: 9 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 [email protected]. 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)
28 changes: 28 additions & 0 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)

##### <a name="-profile_system_auth--kerberos--ad_computers_ou"></a>`ad_computers_ou`

Data type: `Optional[String]`

Optional String of AD OU where computer objects should be created

##### <a name="-profile_system_auth--kerberos--ad_createhostkeytab"></a>`ad_createhostkeytab`

Data type: `Optional[String]`

Optional String of base64 encoding of AD krb5 createhost keytab file

##### <a name="-profile_system_auth--kerberos--ad_createhostuser"></a>`ad_createhostuser`

Data type: `Optional[String]`

Optional String of user with permissions to create host in AD

##### <a name="-profile_system_auth--kerberos--ad_domain"></a>`ad_domain`

Data type: `Optional[String]`

Optional String of the Active Directory domain that the computer should join

##### <a name="-profile_system_auth--kerberos--cfg_file_settings"></a>`cfg_file_settings`

Data type: `Hash`
Expand Down
1 change: 1 addition & 0 deletions data/os/RedHat.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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: |
Expand Down
75 changes: 71 additions & 4 deletions manifests/kerberos.pp
Original file line number Diff line number Diff line change
Expand Up @@ -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
#
Expand Down Expand Up @@ -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
) {
Expand Down Expand Up @@ -80,6 +96,7 @@
}
}

# KERBEROS HOST PRINCIPAL CREATION
if ( $createhostkeytab and $createhostuser ) {
# CREATE KEYS AND SETUP RENEWAL
file { '/root/createhostkeytab.sh':
Expand Down Expand Up @@ -115,5 +132,55 @@
cron { $k: ensure => absent, }
}
}

# AD JOIN AND KEYTAB CREATION
if ( $ad_createhostkeytab and $ad_createhostuser and $ad_computers_ou and $ad_domain ) {
# Step 1: Ensure a temporary script file is in place only if a command fails
exec { 'check_keytab_command':
path => ['/usr/bin', '/usr/sbin', '/usr/lib/mit/bin'],
command => "echo 'host is missing from keytab'",
unless => "klist -kte 2>&1 | grep 'host/${facts['networking']['fqdn']}' | grep -i '${ad_domain}'",
logoutput => true,
notify => Exec['run_ad_create_host_keytab_script'],
}

file { '/root/ad_createhostkeytab.sh':
ensure => file,
mode => '0700',
content => Sensitive(template("${module_name}/ad_createhostkeytab.sh.erb")),
require => [
Exec['check_keytab_command'],
],
}

# Step 2: Run the script if the command fails
exec { 'run_ad_create_host_keytab_script':
path => ['/usr/bin', '/usr/sbin', '/usr/lib/mit/bin'],
command => '/root/ad_createhostkeytab.sh',
refreshonly => true,
require => [
Exec['check_keytab_command'],
File['/root/ad_createhostkeytab.sh'],
],
notify => Exec['delete_ad_create_host_keytab_script'],
}

# Step 3: Ensure the temporary script file is deleted once it has been run
exec { 'delete_ad_create_host_keytab_script':
command => '/bin/rm /root/ad_createhostkeytab.sh',
onlyif => 'test -f /root/ad_createhostkeytab.sh',
path => ['/bin', '/usr/bin'],
require => [
Exec['check_keytab_command'],
Exec['run_ad_create_host_keytab_script'],
File['/root/ad_createhostkeytab.sh'],
],
}

# THE kerberos $crons FOR UPGRADING/REFRESHING HOST KEYTAB DO NOT SEEM TO WORK WITH AD.
# BUT IF YOU NEED TO UPDATE A HOST KEYTAB:
# YOU CAN MANUALLY REMOVE THOSE FROM THE LOCAL KEYTAB AND LET PUPPET CREATE A NEW ONE.
# THE VERSION NUMBERS SEEM TO ITERATE AUTOMATICALLY WHEN USING adcli TO RECREATE THEM.
}
}
}
34 changes: 34 additions & 0 deletions templates/ad_createhostkeytab.sh.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash

# Enable debugging mode
set -x

# ASSIGN VARIABLES
AD_DOMAIN="<%= @ad_domain %>" # Active Directory domain
AD_OU_COMPUTERS="<%= @ad_computers_ou %>" # Organizational Unit for computers in AD
AD_USER="<%= @ad_createhostuser %>" # User with permissions to create host in AD
HOST_FQDN="<%= @fqdn %>" # Fully Qualified Domain Name of the host
KEYTAB_BASE64="<%= @ad_createhostkeytab %>" # Base64 encoded keytab for creating 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

0 comments on commit 6726ca7

Please sign in to comment.