mirror of
https://github.com/dredx/prole.git
synced 2026-09-27 02:04:30 +00:00
Add morgana and zinfandel (macOS) and morgoth + fairyland (Windows)
to the workstations inventory.
Extend workstation_kerberos.yml to handle Windows targets:
- Chrome and Edge AuthServerAllowlist set via win_regedit under
HKLM\SOFTWARE\Policies\{Google\Chrome,Microsoft\Edge}
- krb5.conf and plist tasks skip on Windows (uses built-in SSPI/AD)
- Windows hosts in [workstations_windows] group with WinRM/NTLM
transport; switch to kerberos transport after domain join
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
247 lines
9.4 KiB
YAML
247 lines
9.4 KiB
YAML
---
|
|
# workstation_kerberos.yml — Configure Kerberos client + browser SPNEGO on managed endpoints.
|
|
#
|
|
# Run this playbook once during laptop provisioning (or re-run idempotently).
|
|
# It replaces the per-user "defaults write" workaround with a managed, auditable
|
|
# policy that is identical across every machine.
|
|
#
|
|
# WHAT IT DOES
|
|
# ------------
|
|
# 1. Writes /etc/krb5.conf (or /Library/Preferences/edu.mit.Kerberos on macOS)
|
|
# so that kinit resolves PROLE.ORG principals against myrddin.prole.org.
|
|
# 2. Deploys Chrome managed preferences (AuthServerAllowlist) so Chrome/Edge
|
|
# automatically negotiates Kerberos for *.prole.org without any per-user
|
|
# browser configuration.
|
|
# 3. Symlinks/copies a krb5.conf into place for any Kerberos CLI tools.
|
|
#
|
|
# USAGE
|
|
# -----
|
|
# # All managed workstations:
|
|
# ansible-playbook infrastructure/playbooks/workstation_kerberos.yml
|
|
#
|
|
# # Single machine:
|
|
# ansible-playbook infrastructure/playbooks/workstation_kerberos.yml \
|
|
# --limit <hostname>
|
|
#
|
|
# # Dry-run:
|
|
# ansible-playbook infrastructure/playbooks/workstation_kerberos.yml \
|
|
# --check --diff
|
|
#
|
|
# HOSTS
|
|
# -----
|
|
# Targets the "workstations" inventory group. Add new machines there as
|
|
# engineering headcount grows — no playbook changes required.
|
|
#
|
|
# ADDING A NEW REALM
|
|
# ------------------
|
|
# Extend the krb5_realms list in vars below. The template generates the
|
|
# [realms] and [domain_realm] sections automatically.
|
|
|
|
- name: Configure Kerberos client and browser SPNEGO on managed workstations
|
|
hosts: workstations
|
|
gather_facts: true
|
|
become: true
|
|
|
|
vars:
|
|
krb5_default_realm: "PROLE.ORG"
|
|
krb5_realms:
|
|
- realm: "PROLE.ORG"
|
|
kdc: "myrddin.prole.org"
|
|
admin_server: "myrddin.prole.org"
|
|
domain_suffixes:
|
|
- ".prole.org"
|
|
- "prole.org"
|
|
|
|
# Chrome / Chromium / Edge — negotiate Kerberos for these domains.
|
|
# *.prole.org covers git.prole.org, svc.prole.org, db.prole.org, etc.
|
|
chrome_negotiate_domains: "*.prole.org"
|
|
|
|
tasks:
|
|
# -----------------------------------------------------------------------
|
|
# 1. krb5.conf — shared by kinit, curl --negotiate, Python krb5, etc.
|
|
# -----------------------------------------------------------------------
|
|
- name: Write /etc/krb5.conf
|
|
ansible.builtin.copy:
|
|
dest: /etc/krb5.conf
|
|
owner: root
|
|
group: "{{ 'wheel' if ansible_os_family == 'Darwin' else 'root' }}"
|
|
mode: '0644'
|
|
content: |
|
|
[libdefaults]
|
|
default_realm = {{ krb5_default_realm }}
|
|
dns_canonicalize_hostname = false
|
|
rdns = false
|
|
# Ticket forwarding is disabled by default; enable per-service via
|
|
# [appdefaults] if needed (e.g. SSH GSSAPIDelegateCredentials).
|
|
forwardable = false
|
|
|
|
[realms]
|
|
{% for r in krb5_realms %}
|
|
{{ r.realm }} = {
|
|
kdc = {{ r.kdc }}
|
|
admin_server = {{ r.admin_server }}
|
|
}
|
|
{% endfor %}
|
|
|
|
[domain_realm]
|
|
{% for r in krb5_realms %}
|
|
{% for d in r.domain_suffixes %}
|
|
{{ d }} = {{ r.realm }}
|
|
{% endfor %}
|
|
{% endfor %}
|
|
when: ansible_os_family != "Windows"
|
|
|
|
# macOS also checks this legacy path; symlink for compatibility.
|
|
- name: Symlink macOS legacy Kerberos config
|
|
ansible.builtin.file:
|
|
src: /etc/krb5.conf
|
|
dest: /Library/Preferences/edu.mit.Kerberos
|
|
state: link
|
|
force: true
|
|
when: ansible_os_family == "Darwin"
|
|
|
|
# -----------------------------------------------------------------------
|
|
# 2. Chrome managed policy — macOS
|
|
# Placed in /Library/Managed Preferences/ so it applies to all users on
|
|
# the machine. No per-user Chrome configuration required.
|
|
# -----------------------------------------------------------------------
|
|
- name: Ensure Chrome managed preferences directory exists (macOS)
|
|
ansible.builtin.file:
|
|
path: /Library/Managed Preferences
|
|
state: directory
|
|
owner: root
|
|
group: wheel
|
|
mode: '0755'
|
|
when: ansible_os_family == "Darwin"
|
|
|
|
- name: Deploy Chrome SPNEGO managed policy (macOS)
|
|
ansible.builtin.copy:
|
|
dest: /Library/Managed Preferences/com.google.Chrome.plist
|
|
owner: root
|
|
group: wheel
|
|
mode: '0644'
|
|
content: |
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
|
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
<plist version="1.0">
|
|
<dict>
|
|
<!-- Domains for which Chrome will negotiate Kerberos automatically. -->
|
|
<key>AuthServerAllowlist</key>
|
|
<string>{{ chrome_negotiate_domains }}</string>
|
|
<!-- Domains to which Chrome may delegate (forward) the Kerberos ticket. -->
|
|
<key>AuthNegotiateDelegateAllowlist</key>
|
|
<string>{{ chrome_negotiate_domains }}</string>
|
|
</dict>
|
|
</plist>
|
|
when: ansible_os_family == "Darwin"
|
|
notify: Restart Chrome (macOS)
|
|
|
|
# Microsoft Edge on macOS uses the same managed-preferences directory with
|
|
# a different bundle ID.
|
|
- name: Deploy Edge SPNEGO managed policy (macOS)
|
|
ansible.builtin.copy:
|
|
dest: /Library/Managed Preferences/com.microsoft.Edge.plist
|
|
owner: root
|
|
group: wheel
|
|
mode: '0644'
|
|
content: |
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
|
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
<plist version="1.0">
|
|
<dict>
|
|
<key>AuthServerAllowlist</key>
|
|
<string>{{ chrome_negotiate_domains }}</string>
|
|
<key>AuthNegotiateDelegateAllowlist</key>
|
|
<string>{{ chrome_negotiate_domains }}</string>
|
|
</dict>
|
|
</plist>
|
|
when: ansible_os_family == "Darwin"
|
|
|
|
# -----------------------------------------------------------------------
|
|
# 2b. Chrome / Chromium managed policy — Linux
|
|
# Google Chrome looks in /etc/opt/chrome/policies/managed/
|
|
# Chromium looks in /etc/chromium/policies/managed/
|
|
# -----------------------------------------------------------------------
|
|
- name: Ensure Chrome policy directory exists (Linux)
|
|
ansible.builtin.file:
|
|
path: "{{ item }}"
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: '0755'
|
|
loop:
|
|
- /etc/opt/chrome/policies/managed
|
|
- /etc/chromium/policies/managed
|
|
when: ansible_os_family != "Darwin"
|
|
|
|
- name: Deploy Chrome/Chromium SPNEGO managed policy (Linux)
|
|
ansible.builtin.copy:
|
|
dest: "{{ item }}/kerberos.json"
|
|
owner: root
|
|
group: root
|
|
mode: '0644'
|
|
content: |
|
|
{
|
|
"AuthServerAllowlist": "{{ chrome_negotiate_domains }}",
|
|
"AuthNegotiateDelegateAllowlist": "{{ chrome_negotiate_domains }}"
|
|
}
|
|
loop:
|
|
- /etc/opt/chrome/policies/managed
|
|
- /etc/chromium/policies/managed
|
|
when: ansible_os_family != "Darwin"
|
|
|
|
# -----------------------------------------------------------------------
|
|
# 2c. Chrome + Edge managed policy — Windows
|
|
# Policy lives in the registry under HKLM\SOFTWARE\Policies\<vendor>\<app>.
|
|
# No GPO infrastructure required — win_regedit writes keys directly.
|
|
# If the machine is later joined to PROLE.ORG AD, these keys can be
|
|
# replaced by a proper GPO; they are idempotent either way.
|
|
# -----------------------------------------------------------------------
|
|
- name: Set Chrome SPNEGO policy keys (Windows)
|
|
ansible.windows.win_regedit:
|
|
path: "{{ item.path }}"
|
|
name: "{{ item.name }}"
|
|
data: "{{ chrome_negotiate_domains }}"
|
|
type: String
|
|
state: present
|
|
loop:
|
|
- path: HKLM:\SOFTWARE\Policies\Google\Chrome
|
|
name: AuthServerAllowlist
|
|
- path: HKLM:\SOFTWARE\Policies\Google\Chrome
|
|
name: AuthNegotiateDelegateAllowlist
|
|
- path: HKLM:\SOFTWARE\Policies\Microsoft\Edge
|
|
name: AuthServerAllowlist
|
|
- path: HKLM:\SOFTWARE\Policies\Microsoft\Edge
|
|
name: AuthNegotiateDelegateAllowlist
|
|
when: ansible_os_family == "Windows"
|
|
notify: Restart Chrome (Windows)
|
|
|
|
# -----------------------------------------------------------------------
|
|
# 3. Verify — print where to check policy was applied
|
|
# -----------------------------------------------------------------------
|
|
- name: Show policy verification URL
|
|
ansible.builtin.debug:
|
|
msg: >
|
|
Chrome/Edge policy applied on {{ inventory_hostname }}.
|
|
Verify at chrome://policy (or edge://policy) in a browser.
|
|
Expected: AuthServerAllowlist = {{ chrome_negotiate_domains }}
|
|
|
|
handlers:
|
|
# Chrome must be fully quit and restarted (not just reloaded) for managed
|
|
# preferences to take effect on macOS.
|
|
- name: Restart Chrome (macOS)
|
|
ansible.builtin.debug:
|
|
msg: >
|
|
Chrome policy updated on {{ inventory_hostname }}.
|
|
Ask the user to quit Chrome completely (Cmd-Q) and relaunch.
|
|
Managed preferences take effect on next launch — no reinstall needed.
|
|
|
|
- name: Restart Chrome (Windows)
|
|
ansible.builtin.debug:
|
|
msg: >
|
|
Chrome/Edge policy updated on {{ inventory_hostname }}.
|
|
Ask the user to close all Chrome and Edge windows and relaunch.
|
|
Registry policy takes effect on next browser start — no reinstall needed.
|