ansible/roles/ipa/server/tasks/main.yml
Aurélien Bompard f17dc57b43 Create the sysadmin-main group in IPA
Signed-off-by: Aurélien Bompard <aurelien@bompard.org>
2021-02-22 10:26:01 -05:00

625 lines
17 KiB
YAML

---
# Configuration for IPA
# TODO: consider switching to https://github.com/freeipa/ansible-freeipa
- name: install needed packages
package: name={{ item }} state=present
with_items:
- haveged
- ipa-server
- ipa-server-dns
- ipa-fas
- pynag # needed for nagios checks
tags:
- ipa/server
- packages
# TODO: need pynag for monitoring, not yet in rhel8.
- name: enable haveged
service: name=haveged state=started enabled=yes
tags:
- ipa/server
- config
- name: Copy LDIF file for working around annoying IPA bug in initial sync
copy: src=fix_sasl.ldif dest=/usr/share/ipa/fix_sasl.ldif
tags:
- ipa/server
- config
- name: install IPA
command: ipa-server-install
--realm={{ipa_realm}}
--domain={{ipa_realm}}
--ds-password={{ipa_dm_password}}
--admin-password={{ipa_admin_password}}
--mkhomedir
--no-ntp
--unattended
--no-ssh
--no-sshd
--setup-dns
--forwarder=10.3.163.33
--forwarder=10.3.163.34
--log-file=/var/log/ipainstall.log
creates=/etc/ipa/default.conf
tags:
- ipa/server
- config
when: ipa_initial
- name: install IPA vault
command: ipa-kra-install
--password={{ipa_dm_password}}
--unattended
--log-file=/var/log/ipakrainstall.log
creates=/var/log/ipakrainstall.log
tags:
- ipa/server
- config
when: ipa_initial
- name: determine whether we need to set up replication
stat: path=/etc/ipa/default.conf
register: replication_status
tags:
- ipa/server
- config
when: not ipa_initial
- name: create replica file
delegate_to: ipa01.iad2.fedoraproject.org
command: ipa-replica-prepare
--password={{ipa_dm_password}}
{{inventory_hostname}}
creates=/var/lib/ipa/replica-info-{{inventory_hostname}}.gpg
tags:
- ipa/server
- config
when: not ipa_initial and ansible_distribution_major_version|int < 8 and not replication_status.stat.exists
- name: retrieve replica file
delegate_to: ipa01.iad2.fedoraproject.org
fetch: src=/var/lib/ipa/replica-info-{{inventory_hostname}}.gpg
dest=/tmp/ipa_replica_{{inventory_hostname}}.gpg
flat=yes
tags:
- ipa/server
- config
when: not ipa_initial and ansible_distribution_major_version|int < 8 and not replication_status.stat.exists
- name: deploy replica file
copy: src=/tmp/ipa_replica_{{inventory_hostname}}.gpg
dest=/root/ipa_replica_{{inventory_hostname}}.gpg
mode=0600 owner=root group=root
tags:
- ipa/server
- config
when: not ipa_initial and ansible_distribution_major_version|int < 8 and not replication_status.stat.exists
- name: destroy replica file on ansible host
delegate_to: localhost
file: path=/tmp/ipa_replica_{{inventory_hostname}}.gpg state=absent
tags:
- ipa/server
- config
when: not ipa_initial and ansible_distribution_major_version|int < 8 and not replication_status.stat.exists
- name: deploy replica
command: ipa-replica-install
--setup-ca
--setup-kra
--password={{ipa_dm_password}}
--admin-password={{ipa_admin_password}}
--mkhomedir
--no-ntp
--unattended
--no-ssh
--no-sshd
--setup-dns
--forwarder=10.3.163.33
--forwarder=10.3.163.34
--skip-conncheck
--log-file=/var/log/ipainstall.log
/root/ipa_replica_{{inventory_hostname}}.gpg
creates=/etc/ipa/default.conf
tags:
- ipa/server
- config
when: not ipa_initial and ansible_distribution_major_version|int < 8 and not replication_status.stat.exists
- name: deploy replica
command: ipa-replica-install
--setup-ca
--setup-kra
--admin-password={{ipa_admin_password}}
--no-host-dns
--mkhomedir
--no-ntp
--unattended
--no-ssh
--no-sshd
--skip-conncheck
--force-join
--log-file=/var/log/ipainstall.log
--domain={{ipa_realm}}
--server=ipa01.iad2.fedoraproject.org
creates=/etc/ipa/default.conf
tags:
- ipa/server
- config
when: not ipa_initial and ansible_distribution_major_version|int >= 8 and not replication_status.stat.exists
- name: Disable rewrites
copy: src=ipa-rewrite.conf dest=/etc/httpd/conf.d/ipa-rewrite.conf
notify:
- reload httpd
tags:
- ipa/server
- config
- name: Disable the compat tree
shell: echo "{{ipa_dm_password}}" | ipa-compat-manage disable
tags:
- ipa/server
- config
when: ipa_initial
register: output
changed_when: "'Disabling plugin' in output.stdout"
failed_when: "'Plugin is already disabled' not in output.stdout and output.rc != 0"
notify:
- restart ipa
- name: Disable the nis tree
shell: echo "{{ipa_dm_password}}" | ipa-nis-manage disable
tags:
- ipa/server
- config
when: ipa_initial
register: output
changed_when: "'Disabling plugin' in output.stdout"
failed_when: "'Plugin is already disabled' not in output.stdout and output.rc != 0"
notify:
- restart ipa
- name: Set the expiration date for the admin user
ipauser:
name: admin
password: "{{ ipa_admin_password }}"
# Password expiration date will be a Friday 13th in 30 years. I'm sure we'll remember that.
passwordexpiration: "2050-05-13 00:00:00"
update_password: on_create
ipaadmin_password: "{{ ipa_admin_password }}"
tags:
- ipa/server
- config
when: ipa_initial
- name: Get admin ticket
shell: echo "{{ipa_admin_password}}" | kinit admin
tags:
- ipa/server
- keytab
- config
- krb5
when: ipa_initial
# Reason for removing the next task: we don't store so much private information
# now, and we can't disallow people from seeing other people's email address on
# a case-by-case basis, it's either everyone or hand-picked services, but users
# can't choose to let other users see their info or not.
#
# - name: Disable default permissions so we don't break our privacy policy
# command:
# argv:
# - ipa
# - permission-mod
# - System: Read User Addressbook Attributes
# - --bindtype=permission
# tags:
# - ipa/server
# - config
# when: ipa_initial
# register: output
# changed_when: "'Modified permission' in output.stdout"
# failed_when: "'no modifications to be performed' not in output.stderr and output.rc != 0"
#
# # Because of the previous task, we must explicitely allow users to read their own data
# - name: Allow users to read their own data
# command:
# argv:
# - ipa
# - selfservice-add
# - "Users can read their own addressbook attributes"
# - --permissions=read
# - --attrs=mail
# - --attrs=userCertificate
# - --attrs=ipaCertmapData
# tags:
# - ipa/server
# - config
# when: ipa_initial
# register: output
# changed_when: "'Added selfservice' in output.stdout"
# failed_when: "'already exists' not in output.stderr and output.rc != 0"
# Set the default value back
- name: Restore the default permission on user addressbook attributes
command:
argv:
- ipa
- permission-mod
- "System: Read User Addressbook Attributes"
- --bindtype=all
tags:
- ipa/server
- config
when: ipa_initial
register: output
changed_when: "'Modified permission' in output.stdout"
failed_when: "'no modifications to be performed' not in output.stderr and output.rc != 0"
- name: Configure password policy
ipapwpolicy:
minlife: 0
maxlife: 0
history: 0
minclasses: 0
minlength: 0
maxfail: 0
ipaadmin_password: "{{ ipa_admin_password }}"
tags:
- ipa/server
- config
when: ipa_initial
- name: Create fas_sync user
ipauser:
name: fas_sync
givenname: FAS
sn: Sync
ipaadmin_password: "{{ ipa_admin_password }}"
tags:
- ipa/server
- config
when: ipa_initial
# Certificate generation
- name: Make a directory to store certificate profiles
file:
path: /etc/ipa/certprofiles
state: directory
tags:
- ipa/server
- config
- name: Warn admins that this is not the canonical source
copy:
dest: /etc/ipa/certprofiles/README
content: "This is just a dump of the server values, which are accessible with ipa certprofile-find"
tags:
- ipa/server
- config
- name: Copy the certificate profile for users
template:
src: userCerts.conf
dest: /etc/ipa/certprofiles/userCerts.conf
tags:
- ipa/server
- config
- name: Create the certificate profile
command:
argv:
- ipa
- certprofile-import
- userCerts
- --desc=Profile for user certificates
- --store=true
- --file=/etc/ipa/certprofiles/userCerts.conf
tags:
- ipa/server
- config
when: ipa_initial
register: create_output
changed_when: "'already exists' not in create_output.stderr"
failed_when: "'already exists' not in create_output.stderr and create_output.rc != 0"
- name: Update the certificate profile
command:
argv:
- ipa
- certprofile-mod
- userCerts
- --desc=Profile for user certificates
- --store=true
- --file=/etc/ipa/certprofiles/userCerts.conf
tags:
- ipa/server
- config
when: "ipa_initial and 'already exists' in create_output.stderr"
# Create a new ACL linking the new profile and ipausers group (that all users are members of)
- name: Create the CA ACL for the new certificate profile
command: ipa caacl-add userCerts
tags:
- ipa/server
- config
when: ipa_initial
register: output
changed_when: "'already exists' not in output.stderr"
failed_when: "'already exists' not in output.stderr and output.rc != 0"
- name: Add the ipausers group to the CA ACL
command: ipa caacl-add-user userCerts --group ipausers
tags:
- ipa/server
- config
when: ipa_initial
register: output
changed_when: "'is already a member' not in output.stdout"
failed_when: "'is already a member' not in output.stdout and output.rc != 0"
- name: Add the ipausers group to the CA ACL
command: ipa caacl-add-profile userCerts --certprofile userCerts
tags:
- ipa/server
- config
when: ipa_initial
register: output
changed_when: "'is already a member' not in output.stdout"
failed_when: "'is already a member' not in output.stdout and output.rc != 0"
# HBAC
- name: Don't allow all users to log into all hosts
command: ipa hbacrule-disable allow_all
tags:
- ipa/server
- config
when: ipa_initial
register: output
# Noggin user setup
- name: Register the proper noggin admin password
set_fact:
noggin_password: "{{ (env == 'production')|ternary(noggin_admin_password, noggin_stg_admin_password) }}"
tags:
- ipa/server
- config
- name: Create noggin user
ipauser:
name: noggin
givenname: Noggin
sn: User
password: "{{ (env == 'production')|ternary(noggin_admin_password, noggin_stg_admin_password) }}"
# Password expiration date will be a Friday 13th in 30 years. I'm sure we'll remember that.
# (if unset, IPA will assume the password is expired because it hasn't been set by the user themselves)
passwordexpiration: "2050-05-13 00:00:00"
update_password: on_create
ipaadmin_password: "{{ ipa_admin_password }}"
tags:
- ipa/server
- config
when: ipa_initial
- name: Create the noggin privilege
command:
argv:
- ipa
- privilege-add
- Self-service Portal Administrators
- --desc=Noggin admin users
tags:
- ipa/server
- config
when: ipa_initial
register: output
changed_when: "'already exists' not in output.stderr"
failed_when: "'already exists' not in output.stderr and output.rc != 0"
- name: Setup the noggin privilege
command:
argv:
- ipa
- privilege-add-permission
- Self-service Portal Administrators
- "--permissions=System: Modify Users"
- "--permissions=System: Change User password"
- "--permissions=System: Add Stage User"
- "--permissions=System: Read Stage Users"
- "--permissions=System: Modify Stage User"
- "--permissions=System: Modify User RDN"
- "--permissions=System: Remove Stage User"
- "--permissions=System: Add Users"
- "--permissions=System: Add User to default group"
tags:
- ipa/server
- config
when: ipa_initial
register: output
changed_when: "'Number of permissions added 0' not in output.stdout"
failed_when: "'Number of permissions added 0' not in output.stdout and output.rc != 0"
- name: Create the noggin role
ipa_role:
name: "Self-service Portal Administrator"
description: "Noggin admin user"
privilege:
- "Self-service Portal Administrators"
user:
- noggin
ipa_host: "{{ inventory_hostname }}"
ipa_user: admin
ipa_pass: "{{ipa_admin_password}}"
validate_certs: no
tags:
- ipa/server
- config
when: ipa_initial
# User selfservice permissions
- name: Setup the selfservice permission for passwords
# When ansible-freeipa is upgraded, we'll get ipaselfservice
# ipaselfservice:
# ipaadmin_password: "{{ipa_admin_password}}"
# name: "Users can modify their own password"
# permission: write
# attribute:
# - userPassword
# - krbPrincipalKey
# - sambaLMPassword
# - sambaNTPassword
command:
argv:
- ipa
- selfservice-add
- "Users can modify their own password"
- --permissions=write
- --attrs=userPassword
- --attrs=krbPrincipalKey
- --attrs=sambaLMPassword
- --attrs=sambaNTPassword
register: output
changed_when: "'Added selfservice' in output.stdout"
failed_when: "'already exists' not in output.stderr and output.rc != 0"
tags:
- ipa/server
- config
when: ipa_initial and env == 'staging'
- name: Setup the selfservice permission for addressbook attributes
# When ansible-freeipa is upgraded, we'll get ipaselfservice
# ipaselfservice:
# ipaadmin_password: "{{ipa_admin_password}}"
# name: "User Self service"
# permission: write
# attribute:
# - givenname
# - sn
# - cn
# - displayname
# - gecos
command:
argv:
- ipa
- selfservice-add
- "User Self service"
- --permissions=write
- --attrs=givenName
- --attrs=sn
- --attrs=cn
- --attrs=displayName
- --attrs=gecos
register: output
changed_when: "'Added selfservice' in output.stdout"
failed_when: "'already exists' not in output.stderr and output.rc != 0"
tags:
- ipa/server
- config
when: ipa_initial and env == 'staging'
- name: Destroy admin ticket
command: kdestroy -A
tags:
- ipa/server
- keytab
- config
- krb5
when: ipa_initial
# User groups
- name: Set the members of the admin group
ipa_group:
name: admins
user:
- admin
- fas_sync
- arrfab
ipa_host: "{{ inventory_hostname }}"
ipa_user: admin
ipa_pass: "{{ipa_admin_password}}"
validate_certs: no
tags:
- ipa/server
- config
when: ipa_initial
- name: Create the sysadmin-main group
ipagroup:
ipaadmin_password: "{{ ipa_admin_password }}"
name: sysadmin-main
description: Fedora Main Sysadmin Group
tags:
- ipa/server
- config
when: ipa_initial
- name: Create LDIF directory
file: path=/root/ldif state=directory owner=root group=root mode=0750
tags:
- ipa/server
- config
- name: Copy LDIF files
copy: src={{item}} dest=/root/ldif/{{item}}
with_items:
- grant_anonymous_replication_view.ldif
- grant_fas_sync.ldif
- use_id_fp_o.ldif
tags:
- ipa/server
- config
# This is a special one, in that it needs to apply on each master since it's non-replicated.
- name: Grant access to replication status
command: ldapmodify -Y EXTERNAL -H {{ ipa_ldap_socket }}
-f /root/ldif/{{item}}
with_items:
- grant_anonymous_replication_view.ldif
- grant_fas_sync.ldif
- use_id_fp_o.ldif
tags:
- ipa/server
- config
register: grant_repl_status_output
changed_when: "'Type or value exists' not in grant_repl_status_output.stderr"
failed_when: "'Type or value exists' not in grant_repl_status_output.stderr and 'modifying entry' not in grant_repl_status_output.stdout"
# Make some httpd changes
- name: Configure referer override
template: src=referer-override.conf
dest=/etc/httpd/conf.d/referer-override.conf
notify:
- reload apache
tags:
- ipa/server
- config
- name: Update xmlrpc_uri
lineinfile: dest=/etc/ipa/default.conf
regexp='xmlrpc_uri ='
line='xmlrpc_uri = https://{{ inventory_hostname }}/ipa/xml'
tags:
- ipa/server
- config
# The httpd service should not be started with systemd, the ipa service will
# start it. If systemd starts it, it will run before IPA is available and
# KdcProxy will be disabled because it can't reach LDAP.
- name: Disable the httpd service
service:
name: httpd
enabled: no
tags:
- ipa/server
- config