From 3ddc3934da378dd765e0774a4a33c78aafe97ebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Bompard?= Date: Thu, 6 May 2021 13:58:03 +0200 Subject: [PATCH] Add a periodic cleanup script for stage users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Aurélien Bompard --- roles/ipa/server/files/cleanup-stage-users.py | 24 ++++++ roles/ipa/server/tasks/main.yml | 25 ++---- roles/ipa/server/tasks/scripts.yml | 76 +++++++++++++++++++ roles/keytab/user/defaults/main.yml | 4 + roles/keytab/user/tasks/main.yml | 67 ++++++++++++++++ 5 files changed, 176 insertions(+), 20 deletions(-) create mode 100644 roles/ipa/server/files/cleanup-stage-users.py create mode 100644 roles/ipa/server/tasks/scripts.yml create mode 100644 roles/keytab/user/defaults/main.yml create mode 100644 roles/keytab/user/tasks/main.yml diff --git a/roles/ipa/server/files/cleanup-stage-users.py b/roles/ipa/server/files/cleanup-stage-users.py new file mode 100644 index 0000000000..9166bd98dc --- /dev/null +++ b/roles/ipa/server/files/cleanup-stage-users.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +import os +import socket +from datetime import datetime, timedelta + +from python_freeipa import ClientMeta + +KEEP_DAYS = 7 + +os.environ["KRB5_CLIENT_KTNAME"] = "/etc/krb5.sys-cleanup-stage-users.keytab" +hostname = socket.gethostname() +client = ClientMeta(hostname) +client.login_kerberos() +threshold = datetime.utcnow() - timedelta(days=KEEP_DAYS) +for user in client.stageuser_find()["result"]: + username = user["uid"][0] + created_on = datetime.strptime( + user["fascreationtime"][0]["__datetime__"], "%Y%m%d%H%M%SZ" + ) + if created_on > threshold: + continue + print(f"Deleting old stage user: {username}") + client.stageuser_del(username) diff --git a/roles/ipa/server/tasks/main.yml b/roles/ipa/server/tasks/main.yml index f0b8c43f10..bb7d2a9ed5 100644 --- a/roles/ipa/server/tasks/main.yml +++ b/roles/ipa/server/tasks/main.yml @@ -213,7 +213,6 @@ shell: echo "{{ipa_admin_password}}" | kinit admin tags: - ipa/server - - keytab - config - krb5 when: ipa_initial @@ -292,6 +291,7 @@ name: fas_sync givenname: FAS sn: Sync + userclass: system ipaadmin_password: "{{ ipa_admin_password }}" tags: - ipa/server @@ -412,6 +412,7 @@ # (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 + userclass: system ipaadmin_password: "{{ ipa_admin_password }}" tags: - ipa/server @@ -537,11 +538,13 @@ when: ipa_initial +- import_tasks: scripts.yml + + - name: Destroy admin ticket command: kdestroy -A tags: - ipa/server - - keytab - config - krb5 when: ipa_initial @@ -646,21 +649,3 @@ tags: - ipa/server - config - - -- name: Ensure python dep is present - pip: - name: python-freeipa - tags: - - ipa/server - - otp_script - -- name: Copy file for checking if sysadmins have otp set - template: - src: check_sysadmin_otp.py.j2 - dest: /root/check_sysadmin_otp.py - owner: root - group: root - tags: - - ipa/server - - otp_script diff --git a/roles/ipa/server/tasks/scripts.yml b/roles/ipa/server/tasks/scripts.yml new file mode 100644 index 0000000000..9af02a590d --- /dev/null +++ b/roles/ipa/server/tasks/scripts.yml @@ -0,0 +1,76 @@ +- name: install needed packages for scripts + package: + name: "{{ item }}" + state: present + with_items: + - python3-freeipa + - python3-requests-gssapi + tags: + - ipa/server + - packages + + +# +# Cleanup stage users +# +- name: Create script user to cleanup stage users + ipauser: + name: sys-cleanup-stage-users + givenname: Cleanup stage users + sn: Script + userclass: system + ipaadmin_password: "{{ ipa_admin_password }}" + tags: + - ipa/server + - config + + +- name: Create the Stage User Administrator role + ipa_role: + name: "Stage User Administrator" + description: "Role for users that need to perform admin tasks on stage users." + privilege: + - "Stage User Administrators" + user: + - sys-cleanup-stage-users + ipa_host: "{{ inventory_hostname }}" + ipa_user: admin + ipa_pass: "{{ipa_admin_password}}" + validate_certs: no + tags: + - ipa/server + - config + + +- name: Get the keytab for the stage users cleanup script + include_role: + name: keytab/user + vars: + user: sys-cleanup-stage-users + tags: + - ipa/server + - config + + +- name: Deploy the stage users cleanup sript + copy: + src: cleanup-stage-users.py + dest: /etc/cron.daily/cleanup-stage-users + mode: 0755 + tags: + - ipa/server + - config + + +# +# OTP check for sysadmins +# +- name: Copy file for checking if sysadmins have otp set + template: + src: check_sysadmin_otp.py.j2 + dest: /root/check_sysadmin_otp.py + owner: root + group: root + tags: + - ipa/server + - otp_script diff --git a/roles/keytab/user/defaults/main.yml b/roles/keytab/user/defaults/main.yml new file mode 100644 index 0000000000..70f9a911e1 --- /dev/null +++ b/roles/keytab/user/defaults/main.yml @@ -0,0 +1,4 @@ +owner_user: root +owner_group: root +host: "{{inventory_hostname }}" +kt_location: "/etc/krb5.{{user}}.keytab" diff --git a/roles/keytab/user/tasks/main.yml b/roles/keytab/user/tasks/main.yml new file mode 100644 index 0000000000..184d88671d --- /dev/null +++ b/roles/keytab/user/tasks/main.yml @@ -0,0 +1,67 @@ +--- +- name: Determine whether we need to get keytab + stat: path={{kt_location}} + register: keytab_status + check_mode: no + changed_when: "1 != 1" + tags: + - keytab + - config + - krb5 + +- name: Get admin ticket + delegate_to: "{{ ipa_server }}" + shell: echo "{{ipa_admin_password}}" | kinit admin + check_mode: no + changed_when: "1 != 1" + tags: + - keytab + - config + - krb5 + when: not keytab_status.stat.exists + +- name: Retrieve keytab + delegate_to: "{{ ipa_server }}" + command: ipa-getkeytab --retrieve --server {{ipa_server}} --keytab {{kt_location}} --principal {{user}} + register: retrieve_result + check_mode: no + changed_when: "1 != 1" + failed_when: "not ('Keytab successfully retrieved' in retrieve_result.stderr or 'krbPrincipalKey not found' in retrieve_result.stderr)" + tags: + - keytab + - config + - krb5 + when: not keytab_status.stat.exists + +- name: Create keytab if it did not exist + delegate_to: "{{ ipa_server }}" + command: ipa-getkeytab --server {{ipa_server}} --keytab {{kt_location}} --principal {{user}} + tags: + - keytab + - config + - krb5 + when: not keytab_status.stat.exists and 'krbPrincipalKey not found' in retrieve_result.stderr + +- name: Destroy admin ticket + delegate_to: "{{ ipa_server }}" + command: kdestroy -A + tags: + - keytab + - config + - krb5 + when: not keytab_status.stat.exists + +- name: Set keytab permissions + file: path={{kt_location}} owner={{owner_user}} group={{owner_group}} mode=0640 state=file + tags: + - keytab + - config + - krb5 + +- name: Set keytab ACL + acl: name={{kt_location}} entity={{extra_acl_user}} etype=user permissions=r state=present + tags: + - keytab + - config + - krb5 + when: extra_acl_user is defined