echo "

Setting a Grub password using Ansible (update)

After an upgrade from RedHat the template for the password is changed and uses a variable that OpenScap doesn't read. This makes that our test fails. On top of that the test checks for the use of common administrator account names like root, admin or administrator. This update solves the issue and from now we use a user instead of root for Grub2.

Today I had to update and verify that we have an entry password for Grub on all machines. We needed to do this to comply with the Certified Cloud Service Provider's OpenScap benchmark.

This only prevents a person with physical access to boot in single user mode! The machine can still be booted without the need of a password.

RHEL6 machines all use legacy boot where on RHEL7 we also make a difference between EFI and non-EFI machines. 

 

First generate the hashes (on a RHEL6 and on a RHEL7 node)

RHEL6

grub-crypt --sha-512

RHEL7

grub2-mkpasswd-pbkdf2

And to finish... Here are the Ansible lines:

playbook lines:

#GRUB
- name: "grub v1 | add password"
  lineinfile: dest=/etc/grub.conf regexp='^password ' state=present line='password --encrypted {{ grub_password_v1_passwd }}' insertafter='^timeout'
  when: rhel6
  tags: grub-password

- stat: path=/sys/firmware/efi/efivars/
  register: grub_efi
  when: rhel7
  tags: grub-password

- name: remove unwanted grub.cfg on EFI systems
  file:
    state: absent
    path: /boot/grub2/grub.cfg
  when: rhel7 and grub_efi.stat.exists == True
  tags: grub-password

- name: Install user template to make sure grub2-mkconfig doesn't mess up the config
  template:
    src: 01_users.j2
    dest: /etc/grub.d/01_users
    owner: root
    group: root
    mode: '0700'
  notify:
     - grub2-mkconfig EFI
     - grub2-mkconfig MBR
  when: rhel7
  tags: grub-password

- name: "grub v2 EFI | add password"
  lineinfile: dest=/etc/grub2-efi.cfg regexp="^password_pbkdf2 {{ grub_user }} " state=present insertafter=EOF line='password_pbkdf2 {{ grub_user }} {{ grub_password_v2_passwd }}'
  when: rhel7 and grub_efi.stat.exists == True
  tags: grub-password

- name: "grub v2 MBR | add password"
  lineinfile: dest=/etc/grub2.cfg regexp="^password_pbkdf2 {{ grub_user }} " state=present insertafter=EOF line='password_pbkdf2 {{ grub_user }} {{ grub_password_v2_passwd }}'
  when: rhel7 and grub_efi.stat.exists == False

vars:

grub_password_v1_passwd: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
grub_password_v2_passwd: grub.pbkdf2.sha512.10000.xxxxxxxxxxxxxxxxxxx
grub_user: loginuser

 Handlers:

- name: grub2-mkconfig EFI
  command: grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
  when: grub_efi.stat.exists == True

- name: grub2-mkconfig MBR
  command: grub2-mkconfig -o /boot/grub2/grub.cfg
  when: grub_efi.stat.exists == False

01_users.j2:

#!/bin/sh -e

cat << "EOF"
set superusers="{{ grub_user }}"
export superusers
password_pbkdf2 {{ grub_user }} {{ grub_password_v2_passwd }}
EOF

Using cvmanager to automate promotion of content views in Red Hat Satellite 6.2

In the past this was done using a bash script consisting of hammer commands ran once a month. Since this stopped working in Satellite 6.2 and wasn't compatible with composite content views we switched to the katello-cvmanager → https://github.com/RedHatSatellite/katello-cvmanager/

The publish.yaml file should contain all the content views in use (NOT the composite ones)

DEV,yaml;TEST.yaml;UAT.yaml;PROD.yaml should contain all the content views and composite content views used in the appropriate environment.

And once a month the monthly_updates.sh script is triggered through the root cron. This will publish a new content view for every update of the repos underneath and afterwards promote the (composite) content views for the environments. Unused content views are deleted except one.

 We ran into an issue with repos that have never been synced (own content) and opened a ticket for that https://github.com/RedHatSatellite/katello-cvmanager/issues/25

For now this is fixed by this line replacement

-if repo.has_key?('last_sync') and repo['last_sync'].has_key?('ended_at') and repo['last_sync']['ended_at']
+if repo.has_key?('last_sync') and repo['last_sync'].is_a?(::Hash) and repo['last_sync'].has_key?('ended_at') and repo['last_sync']['ended_at']

This is the cron job that I run to publish, promote and clean the content views once every month.

30 05 * * 0 [ $(date +\%d) -le 07 ] && cd /opt/satellite6_scripts/katello-cvmanager/ && /opt/satellite6_scripts/katello-cvmanager/monthly_updates.sh | mail -E -s "Satellite Monthly report: Content view updates" systems@company.com

This is the script that I use to trigger all the actions

==> monthly_updates.sh <==

#!/bin/sh
set -e
#Publish all content views
./cvmanager --config=publish.yaml --wait publish

#Update content views for DEV
./cvmanager --config=DEV.yaml --wait update
./cvmanager --config=DEV.yaml --wait promote

#Update content views for TEST
./cvmanager --config=TEST.yaml --wait update
./cvmanager --config=TEST.yaml --wait promote

#Update content views for UAT
./cvmanager --config=UAT.yaml --wait update
./cvmanager --config=UAT.yaml --wait promote

#Update content views for PROD
./cvmanager --config=PROD.yaml --wait update
./cvmanager --config=PROD.yaml --wait promote

#clean up unused content views
./cvmanager --config=publish.yaml --wait clean

==> PROD.yaml <==

---
:settings:
:user: read_only_user
:pass: *changme*
:uri: https://localhost
:timeout: 300
:org: 1
:lifecycle: 4
:keep: 1
:promote_cvs: true
:checkrepos: true
:cv:
rhel-7-server-x86_64: latest
rhel-6-server-x86_64: latest
capsule-7-x86_64: latest
:promote:
- rhel-7-server-x86_64
- rhel-6-server-x86_64
- capsule-7-x86_64

==> TEST.yaml <==

---
:settings:
:user: read_only_user
:pass: *changme*
:uri: https://localhost
:timeout: 300
:org: 1
:lifecycle: 2
:keep: 1
:promote_cvs: true
:checkrepos: true
:cv:
rhel-7-server-x86_64: latest
rhel-6-server-x86_64: latest
capsule-7-x86_64: latest
cv-repo-remi: latest
:promote:
- rhel-7-server-x86_64
- rhel-6-server-x86_64
- capsule-7-x86_64
- cv-repo-remi

==> UAT.yaml <==

---
:settings:
:user: read_only_user
:pass: *changme*
:uri: https://localhost
:timeout: 300
:org: 1
:lifecycle: 10
:keep: 1
:promote_cvs: true
:checkrepos: true
:cv:
cv-repo-remi: latest
:ccv:
cv-RHEL7-app-php7:
cv-repo-remi: latest
rhel-7-server-x86_64: latest
cv-RHEL6-app-php7:
cv-repo-remi: latest
rhel-6-server-x86_64: latest
:promote:
- cv-repo-remi
- cv-RHEL7-app-php7
- cv-RHEL6-app-php7

==> DEV.yaml <==

---
:settings:
:user: read_only_user
:pass: *changme*
:uri: https://localhost
:timeout: 300
:org: 1
:lifecycle: 9
:keep: 1
:promote_cvs: true
:checkrepos: true
:cv:
rhel-7-server-x86_64: latest
rhel-6-server-x86_64: latest
cv-repo-remi: latest
:ccv:
cv-RHEL7-app-php7:
cv-repo-remi: latest
rhel-7-server-x86_64: latest
cv-RHEL6-app-php7:
cv-repo-remi: latest
rhel-6-server-x86_64: latest
:promote:
- rhel-7-server-x86_64
- rhel-6-server-x86_64
- cv-repo-remi
- cv-RHEL7-app-php7
- cv-RHEL6-app-php7

==> publish.yaml <==

---
:settings:
:user: read_only_user
:pass: *changme*
:uri: https://localhost
:timeout: 300
:org: 1
:lifecycle: 1
:keep: 1
:promote_cvs: true
:checkrepos: true
:publish:
- rhel-7-server-x86_64
- rhel-6-server-x86_64
- capsule-7-x86_64
- cv-repo-remi
- cv-RHEL7-app-php7
- cv-RHEL6-app-php7

 

Use Ansible to report which systems need to reboot

I created this cronjob using an Ansible playbook to see if any of the Ansible managed hosts are up too long or have a newer kernel installed than the one running. This gives us a monthly overview to see which machines should be rebooted. This script is only valid for RPM and Red Hat based systems. Please adapt root on the end of the cron line to match the e-mail address you want to send your report to and make sure the system mail service is configured correctly.

/etc/cron.d/uptime-and-kernel-upgrade-report

# Send a report mail every month with the ansible managed hosts that have an uptime equal or higher than 300 days OR have a newer kernel installed than the one running
0 0 1 * * sysauto /usr/bin/flock -x -n /opt/systems/ansible -c 'cd /opt/systems/ansible/ ; ansible-playbook playbooks/systems/check_uptime_and_kernel_upgrade.yml | grep " has " | sed -e "s/^[ \t]*//" | mail -E -s "Monthly report: Systems that need a reboot" root'

check_uptime_and_kernel_upgrade.yml

- hosts: all
tasks:
- name: "Check for machines that have an uptime that exceeds 300 days"
shell: echo "$(hostname) has been up for $(uptime | cut -d ',' -f 1 | cut -d ' ' -f 4) days"
when: ansible_uptime_seconds > 25920000
register: uptime_exceeded
- name: "Check for machines that aren't running the latest installed kernel"
shell: LAST_KERNEL=$(rpm -q --last kernel | perl -pe 's/^kernel-(\S+).*/$1/' | head -1);CURRENT_KERNEL=$(uname -r);test $LAST_KERNEL = $CURRENT_KERNEL || echo "$(hostname) has a newer kernel installed than the one running"
ignore_errors: true
register: reboot_hint
- debug: var=uptime_exceeded.stdout_lines
- debug: var=reboot_hint.stdout_lines

 

Home