Update to 2021-12-01 19:13

This commit is contained in:
Daniel Berteaud
2021-12-01 19:13:34 +01:00
commit 4c4556c660
2153 changed files with 60999 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
---
ad_auth: False
ad_domain: "{{ samba_domain }}"
ad_realm: "{{ samba_realm }}"
ad_admin: Administrator
ad_admin_pass: "{{ samba_dc_admin_pass }}"
ad_computer_ou:
ad_access_filter: "(|(memberOf=CN=Domain Admins,CN=Users,DC={{ ad_realm | regex_replace('\\.',',DC=') }})(memberOf=CN=Domain Admins,OU=Groups,DC={{ ad_realm | regex_replace('\\.',',DC=') }}))"
ad_enumerate: True
ad_default_shell: /bin/false
# If access control should evaluate domain GPO. Can be disabled, eforcing or permissive. See man sssd-ad
ad_gpo_access_control: permissive
# If set to True, ansible will re join the host to the domain
ad_force_join: False
# Set to false to disable dyndns update
ad_dyndns_update: True
# Set to false to disable private group
ad_private_groups: True
# sssd doesn't support cross forest approbations, but we can add the Linux box to the other domains
ad_trusted_domains: "{{ samba_trusted_domains | default([]) }}"
# ad_trusted_domains:
# - name: ad.fws.fr
# admin_user: administrator
# admin_pass: s3cr3t.
ad_default_trusted_domain:
access_filter: "{{ ad_access_filter }}"
enumerate: "{{ ad_enumerate }}"
ldap_group_search_base: "{{ ad_ldap_group_search_base | default(False) }}"
ldap_user_search_base: "{{ ad_ldap_user_search_base | default(False) }}"
# You can define a custom search base, with a scope and a filter for groups:
# ad_ldap_group_search_base: CN=Users,dc=ad,dc=domain,dc=com?sub?(|(cn=Domain Users)(cn=Domain Admins))
# ad_ldap_user_search_base: OU=IT,DC=AD,DC=DOMAIN,DC=COM?sub

View File

@@ -0,0 +1,13 @@
---
# Wipe the local cache
- name: restart sssd ad
file: path=/var/lib/sss/db/cache_{{ ad_realm | upper }}.ldb state=absent
changed_when: True
notify: really restart sssd ad
- name: really restart sssd ad
service: name=sssd state=restarted
- name: restart oddjobd
service: name=oddjobd state=restarted

View File

@@ -0,0 +1,17 @@
---
- name: Install sssd and the needed tools
apt:
name:
- sssd-ad
- libnss-sss
- libpam-sss
- oddjob-mkhomedir
- ca-certificates
- krb5-user
- sssd-tools
- adcli
notify:
- restart oddjobd
- restart sssd ad
tags: auth

View File

@@ -0,0 +1,10 @@
---
- name: Install packages
yum:
name:
- sssd-ad
- adcli
- oddjob-mkhomedir
- krb5-workstation
- authconfig
tags: auth

View File

@@ -0,0 +1,100 @@
---
- name: Build trusted domains list
set_fact: ad_trusted_domains_conf={{ ad_trusted_domains_conf | default([]) + [ad_default_trusted_domain | combine(item,recursive=True)] }}
with_items: "{{ ad_trusted_domains }}"
tags: auth
- set_fact: ad_trusted_domains={{ ad_trusted_domains_conf | default([]) }}
tags: auth
- include: install_{{ ansible_os_family }}.yml
- name: Set LDAP base
set_fact: ad_ldap_base=DC={{ ad_realm | regex_replace('\.',',DC=') }}
tags: auth
- include_tasks: pam_{{ ansible_os_family }}.yml
- name: Check if there's a secrets.tdb DB
stat: path=/var/lib/samba/private/secrets.tdb
register: ad_samba_secrets
tags: auth
- name: Deploy sssd configuration
template: src=sssd.conf.j2 dest=/etc/sssd/sssd.conf mode=600
notify: restart sssd ad
tags: auth
- name: Deploy krb5 configuration
template: src=krb5.conf.j2 dest=/etc/krb5.conf
tags: auth
- name: Remove current keytab
file: path=/etc/krb5.keytab state=absent
when: ad_force_join | bool
tags: auth
- name: Check if we already have our keytab file
stat: path=/etc/krb5.keytab
register: ad_keytab
tags: auth
# We need to have our correct hostname before joining the domain !!
- name: Set system hostname
hostname: name={{ system_hostname | default(inventory_hostname | regex_replace('^([^\.]+)\..*','\\1')) }}
tags: auth
- name: Join the domain
command: adcli join {{ ad_realm | upper }} --login-user={{ ad_admin }} --host-fqdn={{ ansible_hostname }}.{{ ad_realm }} --stdin-password
args:
stdin: "{{ ad_admin_pass }}"
no_log: True
when: not ad_keytab.stat.exists
register: ad_join
tags: auth
- name: Check if we're a DC
stat: path=/var/lib/samba/private/secrets.keytab
register: ad_dc_keytab
tags: auth
- name: Add a cron task to renew machine password
cron:
name: sssd_ad
cron_file: renew_ad_pass
minute: "{{ 59 | random(seed=inventory_hostname) }}"
hour: "{{ 23 | random(seed=inventory_hostname) }}"
day: "{{ 28 | random(seed=inventory_hostname) }}"
user: root
job: net ads changetrustpw
state: "{{ (ad_dc_keytab.stat.exists or not ad_samba_secrets.stat.exists) | ternary('absent','present') }}"
tags: auth
- name: Create keytabs dir
file: path=/var/lib/sss/keytabs state=directory owner=sssd mode=700
tags: auth
- name: Join trusted domains
command: adcli join {{ item.name | upper }} --login-user={{ item.admin_user }} --stdin-password --host-keytab=/var/lib/sss/keytabs/{{ item.name | upper }}.keytab
args:
stdin: "{{ item.admin_pass }}"
creates: /var/lib/sss/keytabs/{{ item.name | upper }}.keytab
become_user: sssd
with_items: "{{ ad_trusted_domains }}"
register: ad_trusted_join
tags: auth
- name: Start and enable services
service: name={{ item }} state=started enabled=True
with_items:
- sssd
- oddjobd
tags: auth
# On el8 for example, sssd is already installed and running on a default setup
# so we need to restart it now, so users are available (for eg, ssh authorized_keys setup)
# We can't rely on the handler, because it would only run at the end of the playbook
- name: Restart sssd if needed
service: name=sssd state=restarted
when: ad_join.changed or ad_trusted_join.results | selectattr('changed','equalto',True) | list | length > 0
tags: auth

View File

@@ -0,0 +1,9 @@
---
- name: Deploy pam config
template: src=deb_pam_common_{{ item }}.j2 dest=/etc/pam.d/common-{{ item }}
with_items:
- account
- auth
- password
- session

View File

@@ -0,0 +1,13 @@
---
- name: Check if authconfig needs to update pam config
command: "grep -c -P '^auth\\s+sufficient\\s+pam_sss.so' /etc/pam.d/system-auth"
register: ad_authconfig_done
changed_when: False
failed_when: False
tags: auth
- name: Configure the PAM stack
command: authconfig --enablesssd --enablesssdauth --enablemkhomedir --update
when: ad_authconfig_done.stdout | int < 1
tags: auth

View File

@@ -0,0 +1,5 @@
account required pam_unix.so
account sufficient pam_localuser.so
account sufficient pam_succeed_if.so uid < 1000 quiet
account [success=1 new_authtok_reqd=done default=ignore] pam_sss.so
account required pam_permit.so

View File

@@ -0,0 +1,4 @@
auth [success=2 default=ignore] pam_unix.so nullok_secure
auth [success=1 default=ignore] pam_sss.so use_first_pass
auth requisite pam_deny.so
auth required pam_permit.so

View File

@@ -0,0 +1,4 @@
password sufficient pam_sss.so
password [success=1 default=ignore] pam_unix.so obscure try_first_pass sha512
password requisite pam_deny.so
password required pam_permit.so

View File

@@ -0,0 +1,9 @@
session [default=1] pam_permit.so
session requisite pam_deny.so
session required pam_permit.so
{% if ansible_service_mgr == 'systemd' %}
session optional pam_systemd.so
{% endif %}
session optional pam_oddjob_mkhomedir.so skel=/etc/skel umask=0077
session optional pam_sss.so
session required pam_unix.so

View File

@@ -0,0 +1,8 @@
[libdefaults]
default_realm = {{ ad_realm | upper }}
dns_lookup_realm = false
dns_lookup_kdc = true
rdns = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true

View File

@@ -0,0 +1,5 @@
[libdefaults]
default_realm = {{ ad_realm | upper }}
dns_lookup_realm = false
dns_lookup_kdc = true
rdns = true

View File

@@ -0,0 +1,66 @@
[sssd]
services = nss, pam, pac
config_file_version = 2
domains = {{ ad_realm | upper }}{% for domain in ad_trusted_domains %}, {{ domain.name | upper }}{% endfor %}
default_domain_suffix = {{ ad_realm | upper }}
[nss]
shell_fallback = /bin/false
[pam]
[domain/{{ ad_realm | upper }}]
id_provider = ad
access_provider = ad
ad_hostname = {{ ansible_hostname }}.{{ ad_realm | lower }}
fallback_homedir = /home/%d/%u
default_shell = {{ ad_default_shell }}
cache_credentials = true
krb5_store_password_if_offline = true
ad_access_filter = {{ ad_access_filter }}
{% if ad_ldap_user_search_base is defined %}
ldap_user_search_base = {{ ad_ldap_user_search_base }}
{% endif %}
{% if ad_ldap_group_search_base is defined %}
ldap_group_search_base = {{ ad_ldap_group_search_base }}
{% endif %}
{% if ad_samba_secrets.stat.exists %}
# Membership password is updated with net ads
ad_maximum_machine_account_password_age = 0
{% endif %}
{% if ad_enumerate %}
enumerate = true
{% endif %}
ad_gpo_access_control = {{ ad_gpo_access_control }}
{% if not ad_dyndns_update %}
dyndns_update = false
{% endif %}
{% if ad_private_groups %}
auto_private_groups = true
{% endif %}
{% for domain in ad_trusted_domains %}
[domain/{{ domain.name | upper }}]
id_provider = ad
access_provider = ad
fallback_homedir = /home/%d/%u
default_shell = /bin/false
cache_credentials = true
krb5_store_password_if_offline = true
ldap_krb5_keytab = /var/lib/sss/keytabs/{{ domain.name | upper }}.keytab
krb5_keytab = /var/lib/sss/keytabs/{{ domain.name | upper }}.keytab
{% if domain.enumerate %}
enumerate = true
{% endif %}
ad_access_filter = {{ domain.access_filter }}
{% if domain.ldap_user_search_base is defined and domain.ldap_user_search_base %}
ldap_user_search_base = {{ domain.ldap_user_search_base }}
{% endif %}
{% if domain.ldap_group_search_base is defined and domain.ldap_group_search_base %}
ldap_group_search_base = {{ domain.ldap_group_search_base }}
{% endif %}
ad_gpo_access_control = {{ domain.ad_gpo_access_control | default(ad_gpo_access_control) }}
{% endfor %}