diff --git a/.github/workflows/ansible-lint.yml b/.github/workflows/ansible-lint.yml index 9663246..b14d229 100644 --- a/.github/workflows/ansible-lint.yml +++ b/.github/workflows/ansible-lint.yml @@ -23,10 +23,10 @@ jobs: echo 'collections_paths = ./collections' >> ansible.cfg - name: Install role requirements - run: ansible-galaxy role install -r ansible/playbooks/requirements.yml + run: ansible-galaxy role install -r ansible/roles/requirements.yml - name: Install collection requirements - run: ansible-galaxy collection install -r ansible/playbooks/requirements.yml + run: ansible-galaxy collection install -r ansible/roles/requirements.yml - name: Ansible Lint uses: ansible/ansible-lint-action@master diff --git a/ansible/.gitignore b/ansible/.gitignore new file mode 100644 index 0000000..7694a07 --- /dev/null +++ b/ansible/.gitignore @@ -0,0 +1,11 @@ +#keep tmp folder empty +tmp/* +!tmp/Readme.md + +#keep folder holding public roles empty +roles/public/* +!roles/public/Readme.md + +#keep fodler holding ansible collections empty +collections/* +!README.md diff --git a/ansible/README.md b/ansible/README.md index dabe5f7..f37c0e3 100644 --- a/ansible/README.md +++ b/ansible/README.md @@ -13,19 +13,23 @@ Loosely copied from the CentOS ansible infrastructure. ├── ansible.cfg ├── files -> playbooks/files ├── handlers -> playbooks/handlers -├── inventory +├── inventories +│ ├── production +│ | ├── group_vars +│ | ├── host_vars +│ | hosts +│ ├── staging +│ ├── devellopment ├── pkistore ├── playbooks │ ├── files -│ ├── group_vars -│ ├── host_vars │ ├── handlers │ ├── tasks │ ├── templates │ ├── vars -│ └── requirements.yml -├── roles +├── roles/local │ └── +| └── requirements.yml ├── tasks -> playbooks/tasks ├── templates -> playbooks/templates └── vars -> playbooks/vars diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg index b7db254..516592e 100644 --- a/ansible/ansible.cfg +++ b/ansible/ansible.cfg @@ -1 +1,69 @@ -# Empty +[defaults] + +######################################## +# Display settings +######################################## + +# Output display +force_color = 1 +nocows = True + + +# Note: http://docs.ansible.com/ansible/intro_configuration.html#ansible-managed +ansible_managed = Ansible managed +#ansible_managed = Ansible managed - {file} on {host} + + +# Warn when ansible think it is better to use module. +# Note: http://docs.ansible.com/ansible/intro_configuration.html#id88 +command_warnings = True + +# Enable this to debug tasks calls +display_args_to_stdout = False +display_skipped_hosts = false + +######################################## +# Playbook settings +######################################## + + +# Default strategy +strategy = free + +# Number of hosts processed in parallel +forks = 20 + + +######################################## +# Behaviour settings +######################################## + + +# Make role variables private +retry_files_enabled = True + +# Fact options +gathering = smart +#gathering = !all +#gathering = smart,network,hardware,virtual,ohai,facter +#gathering = network,!hardware,virtual,!ohai,!facter + +# facts caching +#fact_caching_connection = tmp/facts_cache +#fact_caching = json +fact_caching = memory +fact_caching_timeout = 1800 + +# Enable or disable logs +# Note put to false in prod +no_log = False + + +######################################## +# Common destinations +######################################## + +log_path = tmp/ansible.log +known_hosts = tmp/known_hosts +roles_path = roles/local:roles/public +collections_paths = collections diff --git a/ansible/collections/Readme.md b/ansible/collections/Readme.md new file mode 100644 index 0000000..f71f93c --- /dev/null +++ b/ansible/collections/Readme.md @@ -0,0 +1 @@ +Leave empty, this is a placeholder folder for ansible collections diff --git a/ansible/inventories/production/group_vars/ipa/main.yml b/ansible/inventories/production/group_vars/ipa/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/ansible/inventories/production/group_vars/ipaclients/main.yml b/ansible/inventories/production/group_vars/ipaclients/main.yml new file mode 100644 index 0000000..3ded04c --- /dev/null +++ b/ansible/inventories/production/group_vars/ipaclients/main.yml @@ -0,0 +1,7 @@ +--- + +ipaclient_domain = rockylinux.org +ipaclient_realm = ROCKYLINUX.ORG +ipaadmin_principal = admin +ipaclient_no_ntp = true +ipaclient_mkhomedir = true diff --git a/ansible/inventories/production/group_vars/ipareplicas/main.yml b/ansible/inventories/production/group_vars/ipareplicas/main.yml new file mode 100644 index 0000000..e9e570e --- /dev/null +++ b/ansible/inventories/production/group_vars/ipareplicas/main.yml @@ -0,0 +1,14 @@ +--- + +ipaadmin_principal = admin +ipaclient_no_ntp = true +ipaclient_mkhomedir = true +ipaserver_realm = ROCKYLINUX.ORG +ipaserver_hostname = ipa002.rockylinux.org +ipareplica_domain = rockylinux.org +ipareplica_auto_forwarders = true +ipareplica_setup_firewalld = true +ipareplica_setup_ca = true +ipareplica_setup_kra = true +ipareplica_setup_dns = true +ipa_dns_master = 10.100.1.110 diff --git a/ansible/inventories/production/group_vars/ipaservers/main.yml b/ansible/inventories/production/group_vars/ipaservers/main.yml new file mode 100644 index 0000000..20606d7 --- /dev/null +++ b/ansible/inventories/production/group_vars/ipaservers/main.yml @@ -0,0 +1,14 @@ +--- + +ipaserver_domain = rockylinux.org +ipaserver_realm = ROCKYLINUX.ORG +ipaserver_setup_dns = true +ipaserver_setup_kra = true +ipaserver_auto_forwarders = true +ipaserver_no_host_dns = true +ipaserver_hostname = ipa001.rockylinux.org +ipaserver_allow_zone_overlap = true +ipaserver_setup_firewalld = true +ipaclient_no_ntp = true +ipaclient_mkhomedir = true +ipaserver_reverse_zones = ["1.100.10.in-addr.arpa."] diff --git a/ansible/inventories/production/hosts.ini b/ansible/inventories/production/hosts.ini new file mode 100644 index 0000000..73f2170 --- /dev/null +++ b/ansible/inventories/production/hosts.ini @@ -0,0 +1,24 @@ +# Generic inventory hosts +[kvm] +kvm001 ansible_host=10.100.2.110 +kvm002 ansible_host=10.100.2.111 +kvm003 ansible_host=10.100.2.112 + +[ipa:children] +ipaserver +ipareplicas +ipaclients + +[ipsilon] +idp001 ansible_host=10.100.x.x + +# Playbook and role specific inventory hosts and groups +[ipaserver] +ipa001 ansible_host=10.100.1.110 + +[ipareplicas] +ipa002 ansible_host=10.100.1.111 + +[ipaclients] +build-a-box ansible_host=10.100.1.112 + diff --git a/ansible/inventory/idpinventory b/ansible/inventory/idpinventory deleted file mode 100644 index 29c704b..0000000 --- a/ansible/inventory/idpinventory +++ /dev/null @@ -1,3 +0,0 @@ -# Placeholder -[ipsilon] -idp.rockylinux.org diff --git a/ansible/inventory/ipainventory b/ansible/inventory/ipainventory deleted file mode 100644 index e915a91..0000000 --- a/ansible/inventory/ipainventory +++ /dev/null @@ -1,48 +0,0 @@ -[ipaservers] -ipa001.rockylinux.org ansible_host=10.100.1.110 -ipa002.rockylinux.org ansible_host=10.100.1.111 - -[ipaserver] -ipa001.rockylinux.org ansible_host=10.100.1.110 - -[ipaserver:vars] -ipaserver_domain=rockylinux.org -ipaserver_realm=ROCKYLINUX.ORG -ipaserver_setup_dns=true -ipaserver_setup_kra=true -ipaserver_auto_forwarders=true -ipaserver_no_host_dns=true -ipaserver_hostname=ipa001.rockylinux.org -ipaserver_allow_zone_overlap=true -ipaserver_setup_firewalld=true -ipaclient_no_ntp=true -ipaclient_mkhomedir=true -ipaserver_reverse_zones=["1.100.10.in-addr.arpa."] - -[ipareplicas] -ipa002.rockylinux.org ansible_host=10.100.1.111 - -[ipareplicas:vars] -ipaadmin_principal=admin -ipaclient_no_ntp=true -ipaclient_mkhomedir=true -ipaserver_realm=ROCKYLINUX.ORG -ipaserver_hostname=ipa002.rockylinux.org -ipareplica_domain=rockylinux.org -ipareplica_auto_forwarders=true -ipareplica_setup_firewalld=true -ipareplica_setup_ca=true -ipareplica_setup_kra=true -ipareplica_setup_dns=true -ipa_dns_master=10.100.1.110 - -# This is for example purposes - it is likely we'll use "all" instead of -# putting everything under an ipaclient -[ipaclients] -build-a-box.rockylinux.org ansible_host=10.100.1.112 - -[ipaclients:vars] -ipaclient_domain=rockylinux.org -ipaadmin_principal=admin -ipaclient_no_ntp=true -ipaclient_mkhomedir=true diff --git a/ansible/inventory/kvmhostsinventory b/ansible/inventory/kvmhostsinventory deleted file mode 100644 index 8380360..0000000 --- a/ansible/inventory/kvmhostsinventory +++ /dev/null @@ -1,4 +0,0 @@ -[kvmhosts] -kvm001.rockylinux.org ansible_host=10.100.2.110 -kvm002.rockylinux.org ansible_host=10.100.2.111 -kvm003.rockylinux.org ansible_host=10.100.2.112 diff --git a/ansible/playbooks/files/etc/authselect/custom/sssd-rocky/CentOS-8-system-auth b/ansible/playbooks/files/etc/authselect/custom/sssd-rocky/CentOS-8-system-auth new file mode 120000 index 0000000..62848fb --- /dev/null +++ b/ansible/playbooks/files/etc/authselect/custom/sssd-rocky/CentOS-8-system-auth @@ -0,0 +1 @@ +RedHat-8-system-auth \ No newline at end of file diff --git a/ansible/playbooks/files/etc/authselect/custom/sssd-rocky/RedHat-8-system-auth b/ansible/playbooks/files/etc/authselect/custom/sssd-rocky/RedHat-8-system-auth new file mode 100644 index 0000000..d4e9a0d --- /dev/null +++ b/ansible/playbooks/files/etc/authselect/custom/sssd-rocky/RedHat-8-system-auth @@ -0,0 +1,40 @@ +{imply "with-smartcard" if "with-smartcard-required"} +auth required pam_env.so +auth required pam_faildelay.so delay=2000000 +auth required pam_faillock.so preauth audit silent deny=5 unlock_time=900 {include if "with-faillock"} +auth [success=1 default=ignore] pam_succeed_if.so service notin login:gdm:xdm:kdm:xscreensaver:gnome-screensaver:kscreensaver quiet use_uid {include if "with-smartcard-required"} +auth [success=done ignore=ignore default=die] pam_sss.so require_cert_auth ignore_authinfo_unavail {include if "with-smartcard-required"} +auth sufficient pam_fprintd.so {include if "with-fingerprint"} +auth sufficient pam_u2f.so cue {include if "with-pam-u2f"} +auth required pam_u2f.so cue nouserok {include if "with-pam-u2f-2fa"} +auth [default=1 ignore=ignore success=ok] pam_succeed_if.so uid >= 1000 quiet +auth [default=1 ignore=ignore success=ok] pam_localuser.so {exclude if "with-smartcard"} +auth [default=2 ignore=ignore success=ok] pam_localuser.so {include if "with-smartcard"} +auth [success=done authinfo_unavail=ignore ignore=ignore default=die] pam_sss.so try_cert_auth {include if "with-smartcard"} +auth sufficient pam_unix.so {if not "without-nullok":nullok} try_first_pass +auth requisite pam_succeed_if.so uid >= 1000 quiet_success +auth sufficient pam_sss.so forward_pass +auth required pam_faillock.so authfail audit deny=5 unlock_time=900 fail_interval=900 {include if "with-faillock"} +auth required pam_deny.so + +account required pam_access.so {include if "with-pamaccess"} +account required pam_faillock.so {include if "with-faillock"} +account required pam_unix.so +account sufficient pam_localuser.so +account sufficient pam_succeed_if.so uid < 1000 quiet +account [default=bad success=ok user_unknown=ignore] pam_sss.so +account required pam_permit.so + +password requisite pam_pwquality.so try_first_pass local_users_only minlen=14 dcredit=-1 lcredit=-1 ucredit=-1 ocredit=-1 retry=3 +password requisite pam_pwhistory.so use_authok remember=5 +password sufficient pam_unix.so sha512 shadow {if not "without-nullok":nullok} try_first_pass use_authtok +password sufficient pam_sss.so use_authtok +password required pam_deny.so + +session optional pam_keyinit.so revoke +session required pam_limits.so +-session optional pam_systemd.so +session optional pam_oddjob_mkhomedir.so umask=0077 {include if "with-mkhomedir"} +session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid +session required pam_unix.so +session optional pam_sss.so diff --git a/ansible/playbooks/files/etc/pam.d/CentOS-7-system-auth-ac b/ansible/playbooks/files/etc/pam.d/CentOS-7-system-auth-ac new file mode 120000 index 0000000..456a8fc --- /dev/null +++ b/ansible/playbooks/files/etc/pam.d/CentOS-7-system-auth-ac @@ -0,0 +1 @@ +RedHat-7-system-auth-ac \ No newline at end of file diff --git a/ansible/playbooks/files/etc/pam.d/RedHat-7-system-auth-ac b/ansible/playbooks/files/etc/pam.d/RedHat-7-system-auth-ac new file mode 100644 index 0000000..c20a81b --- /dev/null +++ b/ansible/playbooks/files/etc/pam.d/RedHat-7-system-auth-ac @@ -0,0 +1,34 @@ +#%PAM-1.0 +# This file is auto-generated. +# User changes will be destroyed the next time authconfig is run. +auth required pam_env.so +auth required pam_faildelay.so delay=2000000 +auth required pam_faillock.so preauth audit silent deny=5 unlock_time=900 +auth [default=1 success=ok] pam_localuser.so +auth [success=done ignore=ignore default=bad] pam_unix.so nullok try_first_pass +auth requisite pam_succeed_if.so uid >= 1000 quiet_success +auth sufficient pam_sss.so forward_pass +auth [default=die] pam_faillock.so authfail audit deny=5 unlock_time=900 +auth required pam_deny.so + +account required pam_faillock.so +account required pam_unix.so +account sufficient pam_localuser.so +account sufficient pam_succeed_if.so uid < 1000 quiet +account [default=bad success=ok user_unknown=ignore] pam_sss.so +account required pam_permit.so + +password requisite pam_pwquality.so try_first_pass minlen=14 dcredit=-1 lcredit=-1 ucredit=-1 ocredit=-1 local_users_only retry=3 +password requisite pam_pwhistory.so use_authok remember=5 +password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok +password sufficient pam_sss.so use_authtok +password required pam_deny.so + +session optional pam_keyinit.so revoke +session required pam_limits.so +-session optional pam_systemd.so +session optional pam_oddjob_mkhomedir.so umask=0077 +session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid +session required pam_unix.so +session optional pam_sss.so + diff --git a/ansible/playbooks/init-rocky-ansible-host.yml b/ansible/playbooks/init-rocky-ansible-host.yml new file mode 100644 index 0000000..3c6e57d --- /dev/null +++ b/ansible/playbooks/init-rocky-ansible-host.yml @@ -0,0 +1,52 @@ +--- + +- hosts: localhost + connection: local + vars: + force_purge: true + roles_installation_dir: roles/public + collection_installation_dir: collections + installation_prefix: ../ + pre_tasks: +# example prepare ansible box for execution +# - name: install required pip modules on the host running ansible +# pip: +# name: +# - jmespath +# - netaddr +# - python-consul +# - pyvmomi +# - python-ldap +# - twine + + - name: Remove existing public roles + file: + path: "{{ installation_prefix }}{{ roles_installation_dir }}" + state: absent + when: force_purge | bool + + - name: Install all public roles + command: > + ansible-galaxy role install + {{ ( force_purge | bool ) | ternary('--force','') }} + --role-file {{ installation_prefix }}roles/requirements.yml + --roles-path {{ installation_prefix }}{{ roles_installation_dir }} + + - name: Install needed collections + command: > + ansible-galaxy collection install + {{ ( force_purge | bool ) | ternary('--force-with-deps','') }} + -r {{ installation_prefix }}roles/requirements.yml + -p {{ installation_prefix }}{{ collection_installation_dir }} + + - name: cleanup old ssh known_hosts - remove + file: + path: "../tmp/known_hosts" + state: absent + mode: "0644" + + - name: cleanup old ssh known_hosts - blank + file: + path: "../tmp/known_hosts" + state: touch + mode: "0644" diff --git a/ansible/playbooks/init-rocky-install-kvm-hosts.yml b/ansible/playbooks/init-rocky-install-kvm-hosts.yml index 06ee06e..1d737c6 100644 --- a/ansible/playbooks/init-rocky-install-kvm-hosts.yml +++ b/ansible/playbooks/init-rocky-install-kvm-hosts.yml @@ -3,7 +3,7 @@ # Created: @SherifNagy # Modified to current standards: @nazunalika - name: Configure KVM host - hosts: kvmhosts + hosts: kvm become: true pre_tasks: diff --git a/ansible/playbooks/init-rocky-system-config.yml b/ansible/playbooks/init-rocky-system-config.yml index 11d6e0b..2bc6d12 100644 --- a/ansible/playbooks/init-rocky-system-config.yml +++ b/ansible/playbooks/init-rocky-system-config.yml @@ -30,7 +30,7 @@ - name: Configure harden settings include: tasks/harden.yml - - name: Configure PAM and SSSD + - name: Configure PAM include: tasks/authentication.yml post_tasks: diff --git a/ansible/playbooks/role-rocky-ipa-client.yml b/ansible/playbooks/role-rocky-ipa-client.yml index 0d22d46..44b83f1 100644 --- a/ansible/playbooks/role-rocky-ipa-client.yml +++ b/ansible/playbooks/role-rocky-ipa-client.yml @@ -1,6 +1,6 @@ --- # Configures an IPA client for the Rocky infrastructure -# Variables are in inventory/ipainventory + - name: Configure IPA client hosts: ipaclients become: true diff --git a/ansible/playbooks/role-rocky-ipa-replica.yml b/ansible/playbooks/role-rocky-ipa-replica.yml index 449bfe5..aa9511a 100644 --- a/ansible/playbooks/role-rocky-ipa-replica.yml +++ b/ansible/playbooks/role-rocky-ipa-replica.yml @@ -1,6 +1,6 @@ --- # Creates an IPA replica -# Variables are in inventory/ipainventory + - name: Configure IPA server hosts: ipareplicas become: true diff --git a/ansible/playbooks/role-rocky-ipa.yml b/ansible/playbooks/role-rocky-ipa.yml index 9cc9aa9..d219c17 100644 --- a/ansible/playbooks/role-rocky-ipa.yml +++ b/ansible/playbooks/role-rocky-ipa.yml @@ -1,6 +1,5 @@ --- # Creates the first server for an IPA infrastructure -# Variables for the infrastructure are in inventory/ipainventory # Recommended specs for the IPA systems, that scale based on number of objects: # CPU: 2 cores # Memory: 4GB @@ -44,7 +43,7 @@ - reload_networkmanager roles: - - role: ipaserver + - role: freeipa.ansible_freeipa.ipaserver state: present post_tasks: diff --git a/ansible/playbooks/tasks/authentication.yml b/ansible/playbooks/tasks/authentication.yml index 6521ec9..c863e99 100644 --- a/ansible/playbooks/tasks/authentication.yml +++ b/ansible/playbooks/tasks/authentication.yml @@ -1,3 +1,65 @@ --- # Configures PAM and SSSD post-ipa client installation. It is recommended that # that we use a custom authselect profile and build it out from there. +- name: Enterprise Linux 7 PAM Configuration + copy: + src: "etc/pam.d/{{ ansible_distribution }}-{{ ansible_distribution_major_version }}-system-auth-ac" + dest: "{{ item }}" + mode: "0644" + owner: root + group: root + with_items: + - /etc/pam.d/system-auth-ac + - /etc/pam.d/password-auth-ac + when: + - ansible_facts['os_family'] == 'RedHat' + - ansible_facts['distribution_major_version'] == '7' + +- name: Enterprise Linux 8 PAM Configuration + when: + - ansible_facts['os_family'] == 'RedHat' + - ansible_facts['distribution_major_version'] == '8' + block: + - name: Ensure Custom Profile is removed + file: + state: absent + path: /etc/authselect/custom/sssd-rocky + + - name: Create custom authselect profile based on sssd + command: > + /usr/bin/authselect create-profile sssd-rocky + --base-on sssd + --symlink-dconf + --symlink-meta + --symlink=postlogin + --symlink=smartcard-auth + --symlink=fingerprint-auth + + - name: Override system-auth and password-auth + copy: + src: "etc/authselect/custom/sssd-aoc/{{ ansible_distribution }}-{{ ansible_distribution_major_version }}-system-auth" + dest: "{{ item }}" + mode: '0644' + owner: root + group: root + with_items: + - /etc/authselect/custom/sssd-aoc/system-auth + - /etc/authselect/custom/sssd-aoc/password-auth + + - name: Select New Profile + command: > + /usr/bin/authselect select custom/sssd-aoc + without-nullok + with-faillock + with-mkhomedir + with-sudo + --force + + - name: Apply new settings + command: /usr/bin/authselect apply-changes + + - name: Enable oddjobd + service: + name: oddjobd + state: started + enabled: yes diff --git a/ansible/playbooks/tasks/variable_loader_common.yml b/ansible/playbooks/tasks/variable_loader_common.yml index a60f7b0..a0c4f48 100644 --- a/ansible/playbooks/tasks/variable_loader_common.yml +++ b/ansible/playbooks/tasks/variable_loader_common.yml @@ -10,7 +10,7 @@ include_vars: "{{ item }}" with_first_found: - "ipaserver.yml" - when: "'ipaservers' in group_names" + when: "'ipaserver' in group_names" - name: Check if system is EFI stat: diff --git a/ansible/playbooks/vars/RedHat.yml b/ansible/playbooks/vars/RedHat.yml index 284156c..64c9bab 100644 --- a/ansible/playbooks/vars/RedHat.yml +++ b/ansible/playbooks/vars/RedHat.yml @@ -6,6 +6,7 @@ bin_sudo: /usr/bin/sudo kernel_boot_options: audit=1 grub_config_path_link: /etc/grub2.cfg grub_config_path_efi: /etc/grub2-efi.cfg +ipatype: client # Removing TFTP for now because there will likely be tftp/pxe servers remove_packages: diff --git a/ansible/roles/local/Readme.md b/ansible/roles/local/Readme.md new file mode 100644 index 0000000..2c0ace4 --- /dev/null +++ b/ansible/roles/local/Readme.md @@ -0,0 +1 @@ +Put all local roles here diff --git a/ansible/roles/public/Readme.md b/ansible/roles/public/Readme.md new file mode 100644 index 0000000..d5521bf --- /dev/null +++ b/ansible/roles/public/Readme.md @@ -0,0 +1 @@ +Do not put any roles here, This is a placeholder for public roles installed via galaxy diff --git a/ansible/roles/requirements.yml b/ansible/roles/requirements.yml new file mode 100644 index 0000000..c1d5195 --- /dev/null +++ b/ansible/roles/requirements.yml @@ -0,0 +1,13 @@ +--- + +roles: + - name: geerlingguy.mysql + # monitoring + - name: cloudalchemy.node-exporter + - name: cloudalchemy.prometheus + +collections: + # freeipa + - name: freeipa.ansible_freeipa + version: 0.3.1 + - name: community.general diff --git a/ansible/ssh_config b/ansible/ssh_config new file mode 100644 index 0000000..8da16ef --- /dev/null +++ b/ansible/ssh_config @@ -0,0 +1,4 @@ +ControlMaster auto +ControlPersist 30m +UserKnownHostsFile tmp/known_hosts +HashKnownHosts no diff --git a/ansible/tmp/Readme.md b/ansible/tmp/Readme.md new file mode 100644 index 0000000..095c3ee --- /dev/null +++ b/ansible/tmp/Readme.md @@ -0,0 +1 @@ +Keep folder empty