mirror of
https://github.com/dredx/prole.git
synced 2026-09-24 14:54:34 +00:00
ansible: use krbtgt_KNOE.LOCAL sAMAccountName + UPN for trust account
samba-tool user create rejected the sAMAccountName "krbtgt/KNOE.LOCAL" with "samldb: sAMAccountName contains invalid '/' character". AD/Samba disallow "/" in sAMAccountName even though Kerberos principal names require it (krbtgt/REMOTE@LOCAL). Switch storage name to "krbtgt_KNOE.LOCAL" and add an ldbmodify pass that sets the canonical Kerberos identity on the same object: userPrincipalName = krbtgt/KNOE.LOCAL@PROLE.ORG servicePrincipalName = krbtgt/KNOE.LOCAL msDS-SupportedEncryptionTypes = 28 (RC4+AES128+AES256) Samba KDC resolves principals by UPN/SPN, so a TGS-REQ for krbtgt/KNOE.LOCAL@PROLE.ORG will hit this account. Note: key-salt parity with the MIT side is NOT guaranteed yet. Samba's default salt for AES keys is REALM+UPN; MIT's default for cross-realm krbtgt is REALM+"krbtgt"+REMOTE. If kvno fails with "decrypt integrity check failed" we'll add a keytab-export/import step in a follow-up rather than try to coerce Samba's salt at creation time. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6740e3dcc5
commit
aa541af3f5
@ -66,6 +66,12 @@
|
|||||||
|
|
||||||
vars:
|
vars:
|
||||||
trust_realm: "KNOE.LOCAL"
|
trust_realm: "KNOE.LOCAL"
|
||||||
|
samba_local_realm: "PROLE.ORG"
|
||||||
|
# sAMAccountName cannot contain a slash, so we store the inter-realm TGT
|
||||||
|
# account under an underscore-form name and explicitly set its
|
||||||
|
# userPrincipalName to the canonical Kerberos form below.
|
||||||
|
samba_account_name: "krbtgt_KNOE.LOCAL"
|
||||||
|
trust_principal: "krbtgt/KNOE.LOCAL@PROLE.ORG"
|
||||||
trust_kdc_ip: "" # auto-resolved below if empty
|
trust_kdc_ip: "" # auto-resolved below if empty
|
||||||
# Pull the trust password from the cluster Secret unless caller overrides.
|
# Pull the trust password from the cluster Secret unless caller overrides.
|
||||||
trust_shared_password: "{{ lookup('env', 'PROLE_TRUST_SHARED_PASSWORD') | default('', true) }}"
|
trust_shared_password: "{{ lookup('env', 'PROLE_TRUST_SHARED_PASSWORD') | default('', true) }}"
|
||||||
@ -158,7 +164,7 @@
|
|||||||
# password with the MIT KDC. The MIT side already has
|
# password with the MIT KDC. The MIT side already has
|
||||||
# krbtgt/KNOE.LOCAL@PROLE.ORG (created by init_kdc.sh) using the
|
# krbtgt/KNOE.LOCAL@PROLE.ORG (created by init_kdc.sh) using the
|
||||||
# same trust_shared_password we just fetched from the cluster Secret.
|
# same trust_shared_password we just fetched from the cluster Secret.
|
||||||
- name: Check whether krbtgt/{{ trust_realm }} user already exists in Samba
|
- name: Check whether {{ samba_account_name }} user already exists in Samba
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
cmd: >
|
cmd: >
|
||||||
samba-tool user list
|
samba-tool user list
|
||||||
@ -174,7 +180,7 @@
|
|||||||
- name: Report trust pre-existence
|
- name: Report trust pre-existence
|
||||||
ansible.builtin.debug:
|
ansible.builtin.debug:
|
||||||
msg: >-
|
msg: >-
|
||||||
krbtgt/{{ trust_realm }} user
|
{{ samba_account_name }} user
|
||||||
{{ 'already present in Samba — will reset password to match cluster Secret.'
|
{{ 'already present in Samba — will reset password to match cluster Secret.'
|
||||||
if _trust_exists else 'is missing — will create.' }}
|
if _trust_exists else 'is missing — will create.' }}
|
||||||
|
|
||||||
@ -213,13 +219,13 @@
|
|||||||
# The "no_log" wrapper protects the password but also hides the
|
# The "no_log" wrapper protects the password but also hides the
|
||||||
# error message on failure; if a real run dies here re-run by hand
|
# error message on failure; if a real run dies here re-run by hand
|
||||||
# to see stderr (see playbook header).
|
# to see stderr (see playbook header).
|
||||||
- name: Create inter-realm krbtgt user krbtgt/{{ trust_realm }}
|
- name: Create inter-realm krbtgt user {{ samba_account_name }}
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
argv:
|
argv:
|
||||||
- samba-tool
|
- samba-tool
|
||||||
- user
|
- user
|
||||||
- create
|
- create
|
||||||
- "krbtgt/{{ trust_realm }}"
|
- "{{ samba_account_name }}"
|
||||||
- "{{ trust_shared_password }}"
|
- "{{ trust_shared_password }}"
|
||||||
- "--description=Inter-realm TGT for {{ trust_realm }} (MIT KDC) cross-realm trust"
|
- "--description=Inter-realm TGT for {{ trust_realm }} (MIT KDC) cross-realm trust"
|
||||||
- "--use-username-as-cn"
|
- "--use-username-as-cn"
|
||||||
@ -235,13 +241,13 @@
|
|||||||
# re-runs where the cluster Secret may have been rotated).
|
# re-runs where the cluster Secret may have been rotated).
|
||||||
# Skipped on the fresh-create path because step 3 already set it.
|
# Skipped on the fresh-create path because step 3 already set it.
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
- name: Re-sync krbtgt/{{ trust_realm }} password with cluster Secret
|
- name: Re-sync {{ samba_account_name }} password with cluster Secret
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
argv:
|
argv:
|
||||||
- samba-tool
|
- samba-tool
|
||||||
- user
|
- user
|
||||||
- setpassword
|
- setpassword
|
||||||
- "krbtgt/{{ trust_realm }}"
|
- "{{ samba_account_name }}"
|
||||||
- "--newpassword={{ trust_shared_password }}"
|
- "--newpassword={{ trust_shared_password }}"
|
||||||
- "-U"
|
- "-U"
|
||||||
- "administrator%{{ samba_admin_password }}"
|
- "administrator%{{ samba_admin_password }}"
|
||||||
@ -253,13 +259,13 @@
|
|||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# 5. Disable password expiry on the krbtgt account
|
# 5. Disable password expiry on the krbtgt account
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
- name: Disable password expiry on krbtgt/{{ trust_realm }}
|
- name: Disable password expiry on {{ samba_account_name }}
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
argv:
|
argv:
|
||||||
- samba-tool
|
- samba-tool
|
||||||
- user
|
- user
|
||||||
- setexpiry
|
- setexpiry
|
||||||
- "krbtgt/{{ trust_realm }}"
|
- "{{ samba_account_name }}"
|
||||||
- "--noexpiry"
|
- "--noexpiry"
|
||||||
- "-U"
|
- "-U"
|
||||||
- "administrator%{{ samba_admin_password }}"
|
- "administrator%{{ samba_admin_password }}"
|
||||||
@ -269,26 +275,42 @@
|
|||||||
failed_when: _krbtgt_noexpiry.rc != 0
|
failed_when: _krbtgt_noexpiry.rc != 0
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# 6. Force supported encryption types to AES128+AES256+RC4
|
# 6. Set the Kerberos principal name (UPN + SPN) and force supported
|
||||||
|
# encryption types to AES128+AES256+RC4.
|
||||||
|
#
|
||||||
|
# sAMAccountName cannot contain "/" so we stored the account
|
||||||
|
# under {{ samba_account_name }} (krbtgt_KNOE.LOCAL). For the
|
||||||
|
# Samba KDC to issue tickets for the canonical Kerberos name
|
||||||
|
# krbtgt/KNOE.LOCAL@PROLE.ORG, we set both:
|
||||||
|
#
|
||||||
|
# userPrincipalName = krbtgt/KNOE.LOCAL@PROLE.ORG
|
||||||
|
# servicePrincipalName = krbtgt/KNOE.LOCAL
|
||||||
|
#
|
||||||
# msDS-SupportedEncryptionTypes = 28 = 0x04 (RC4) | 0x08 (AES128) | 0x10 (AES256)
|
# msDS-SupportedEncryptionTypes = 28 = 0x04 (RC4) | 0x08 (AES128) | 0x10 (AES256)
|
||||||
# This must match what the MIT KDC offers (init_kdc.sh defaults
|
# must match what the MIT KDC offers (init_kdc.sh keys the
|
||||||
# to AES256 keys for cross-realm krbtgt principals).
|
# cross-realm krbtgt with AES256).
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
- name: Set msDS-SupportedEncryptionTypes=28 on krbtgt/{{ trust_realm }}
|
- name: Set UPN, SPN, and supported encryption types on {{ samba_account_name }}
|
||||||
ansible.builtin.shell:
|
ansible.builtin.shell:
|
||||||
cmd: |
|
cmd: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
ldif=$(mktemp)
|
ldif=$(mktemp)
|
||||||
DN=$(samba-tool user show "krbtgt/{{ trust_realm }}" \
|
DN=$(samba-tool user show "{{ samba_account_name }}" \
|
||||||
-U "administrator%{{ samba_admin_password }}" \
|
-U "administrator%{{ samba_admin_password }}" \
|
||||||
| awk -F': ' '/^dn:/ {print $2; exit}')
|
| awk -F': ' '/^dn:/ {print $2; exit}')
|
||||||
if [ -z "$DN" ]; then
|
if [ -z "$DN" ]; then
|
||||||
echo "Could not resolve DN for krbtgt/{{ trust_realm }}" >&2
|
echo "Could not resolve DN for {{ samba_account_name }}" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
cat > "$ldif" <<EOF
|
cat > "$ldif" <<EOF
|
||||||
dn: $DN
|
dn: $DN
|
||||||
changetype: modify
|
changetype: modify
|
||||||
|
replace: userPrincipalName
|
||||||
|
userPrincipalName: {{ trust_principal }}
|
||||||
|
-
|
||||||
|
replace: servicePrincipalName
|
||||||
|
servicePrincipalName: krbtgt/{{ trust_realm }}
|
||||||
|
-
|
||||||
replace: msDS-SupportedEncryptionTypes
|
replace: msDS-SupportedEncryptionTypes
|
||||||
msDS-SupportedEncryptionTypes: 28
|
msDS-SupportedEncryptionTypes: 28
|
||||||
EOF
|
EOF
|
||||||
@ -302,13 +324,13 @@
|
|||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# 7. Smoke probe — confirm the user is visible to samba-tool
|
# 7. Smoke probe — confirm the user is visible to samba-tool
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
- name: Smoke probe — samba-tool user show krbtgt/{{ trust_realm }}
|
- name: Smoke probe — samba-tool user show {{ samba_account_name }}
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
argv:
|
argv:
|
||||||
- samba-tool
|
- samba-tool
|
||||||
- user
|
- user
|
||||||
- show
|
- show
|
||||||
- "krbtgt/{{ trust_realm }}"
|
- "{{ samba_account_name }}"
|
||||||
- "-U"
|
- "-U"
|
||||||
- "administrator%{{ samba_admin_password }}"
|
- "administrator%{{ samba_admin_password }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
@ -325,10 +347,10 @@
|
|||||||
- name: Print summary
|
- name: Print summary
|
||||||
ansible.builtin.debug:
|
ansible.builtin.debug:
|
||||||
msg:
|
msg:
|
||||||
- "krbtgt/{{ trust_realm }} present in Samba (PROLE.ORG realm)."
|
- "{{ samba_account_name }} present in Samba (PROLE.ORG realm)."
|
||||||
- "Password is now in sync with knoe-system/knoe-kdc-secrets/trust_shared_password."
|
- "Password is now in sync with knoe-system/knoe-kdc-secrets/trust_shared_password."
|
||||||
- "msDS-SupportedEncryptionTypes set to 28 (RC4 + AES128 + AES256)."
|
- "msDS-SupportedEncryptionTypes set to 28 (RC4 + AES128 + AES256)."
|
||||||
- "From a PROLE.ORG client try:"
|
- "From a PROLE.ORG client try:"
|
||||||
- " kdestroy && kinit chrisfu@PROLE.ORG"
|
- " kdestroy && kinit chrisfu@PROLE.ORG"
|
||||||
- " kvno HTTP/auth.knoe.dev@{{ trust_realm }}"
|
- " kvno HTTP/auth.knoe.dev@{{ trust_realm }}"
|
||||||
- " klist # expect krbtgt/{{ trust_realm }}@PROLE.ORG"
|
- " klist # expect {{ samba_account_name }}@PROLE.ORG"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user