Skip to content

Instantly share code, notes, and snippets.

@dmi3mis
Forked from luckylittle/RH415.md
Created July 11, 2025 13:46
Show Gist options
  • Select an option

  • Save dmi3mis/067762908f910f7b30fb0d7c0b2c60e3 to your computer and use it in GitHub Desktop.

Select an option

Save dmi3mis/067762908f910f7b30fb0d7c0b2c60e3 to your computer and use it in GitHub Desktop.
Red Hat RH415 Notes

Red Hat Security: Linux in Physical, Virtual and Cloud (RH415)

Last update: Fri Aug 9 09:33:36 UTC 2019 by @luckylittle


1. Managing Security & Risk

# USING YUM TO MANAGE SECURITY ERRATA:
yum updateinfo --security                                   # security related updates
yum updateinfo list updates | grep Critical                 # identify critical RHSAs
yum updateinfo RHSA-2018:1453                               # view RHSA details
yum updateinfo list --cve CVE-2018-1111                     # what needs to be updated to fix CVE
yum update --cve CVE-2018-1111                              # resolve CVE
# SECURING SERVICES:
ss -tlw                                                     # open ports in the listening state
# CUSTOMIZING YOUR SSH SERVICE CONFIGURATION:
vi /etc/ssh/sshd_config
  PermitRootLogin no                                        # do not allow root to SSH to this machine
  PasswordAuthentication no                                 # force only key-based authentication
  # ALLOW/DENY USERS & GROUPS:
  # The allow/deny directives are processed in the following order: DenyUsers, AllowUsers, DenyGroups, and finally AllowGroups
  AllowUsers [email protected].*                              # this would need PermitRootLogin yes
  AllowUsers [email protected]
  AllowUsers [email protected]/24 [email protected]
  #  If all of the criteria on the Match line are satisfied, the keywords on the following lines override those set in the global section of the config file, until either another Match line or the end of the file. The available criteria are User, Group, Host, LocalAddress, LocalPort, and Address:
  Match Address 192.168.0.?                                 # 192.168.0.[0-9] network range
        PermitRootLogin yes
systemctl reload sshd
# SUDO:
su                                                          # switches to the target user (which is root by default), but provides a normal shell with the same environment as the user who invoked the su command
su -                                                        # switches to the target user and invokes a login shell based on the target user's environment. A login shell resets most environment variables, including the target user's PATH
visudo
vi /etc/sudoers
  Defaults timestamp_timeout = 1                            # require password every minute (0 = every time it's used)
  User_Alias FULLTIMERS = millert, mikef, dowdy
  Runas_Alias OP = root, operator
  Host_Alias SERVERS = master, mail, www, ns
  Cmnd_Alias REBOOT = /usr/sbin/reboot
  root ALL = (ALL) ALL                                      # who where = (as_whom) what
  %wheel ALL = (ALL) ALL                                    # we let any user in group wheel run any command on any host as any user
  FULLTIMERS ALL = NOPASSWD: ALL
  lisa SERVERS = ALL
  bob SERVERS = (OP) ALL : 128.138.242.0 = (OP) REBOOT      # the user bob may run anything on the SERVERS and can run reboot on 128.138.242.0 machines as any user listed in the OP Runas_Alias (root and operator)
sudo                                                        # resets the PATH variable based on the 'secure_path' directive in the /etc/sudoers file
sudo -i                                                     # changes to the root user's home directory and opens an interactive login shell based on the root user's environment variables

2. Automating Configuration & Remediation with Ansible

# An example of a typical 'ansible.cfg' file:
[defaults]
inventory       = ./inventory
remote_user     = user
ask_pass        = false
[privilege_escalation]
become          = true
become_method   = sudo
become_user     = root
become_ask_pass = false

3. Protecting Data with LUKS & NBDE

# CREATION OF ENCRYPTED DEVICES AT INSTALLATION USING KICKSTART:
autopart --type=lvm --encrypted --passphrase=PASSPHRASE     # use automated partitioning
part /home --fstype=ext4 --size=10000 --onpart=vda2 --encrypted --passphrase=PASSPHRASE
part pv.01 --size=10000 --encrypted --passphrase=PASSPHRASE # encrypting an LVM physical volume
# ENCRYPTING DEVICES WITH LUKS AFTER INSTALLATION:
parted -l                                                   # lists partition layout on all block devices
parted /dev/vdb mklabel msdos mkpart primary xfs 1M 1G      # msdos label type, primary xfs type partition from 1M to 1G
parted /dev/vdb print
cryptsetup luksFormat /dev/vdb1 [--key-file /path/to/file]  # this will encrypt the drive
cryptsetup luksDump /dev/vdb1
cryptsetup luksOpen /dev/vdb1 example                       # this will decrypt the drive
ls /dev/mapper/example
mkfs.xfs /dev/mapper/example
mount -t xfs /dev/mapper/example /encrypted
umount /encrypted
cryptsetup luksClose example
cryptsetup luksAddKey --key-slot 1 /dev/vdb1                # enter original passhphrase (or key-file) and the new passphrase
cryptsetup luksChangeKey /dev/vdb1                          # change passphrase
# PERSISTENTLY MOUNTING LUKS FILE SYSTEMS:
cat /etc/crypttab
  decrypted1 /dev/vdb1 none _netdev
  decrypted2 UUID=43d8995e-b876-4385-b124-7e402446d6c7 none _netdev
cat /etc/fstab
  /dev/mapper/decrypted1 /encrypted xfs _netdev 1 2
# NBDE - UNATTENDED DEVICE DECRYPTION AT BOOT TIME:
yum -y install tang                                         # Tang servers validate the keys
systemctl enable tangd.socket --now                         # tangd service binds to the 80/TCP port
firewall-cmd --zone=public --add-service=http --permanent
cd /var/db/tang                                             # cryptographic keys are generated at first start
jose jwk gen -i '{"alg":"ES512"}' -o signature.jwk          # creating new keys manually
jose jwk gen -i '{"alg":"ECMR"}' -o exchange.jwk            # creating new keys manually
mv -v gxB7oqYiEu3zrLay.jwk .gxB7oqYiEu3zrLay.jwk            # rename both old keys to have leading period
mv -v k25k6PbmgUu-pWWUb210x.jwk .k25k6PbmgUu-pWWUb210x.jwk

yum install clevis clevis-luks clevis-dracut                # Clevis clients reach out to tang servers
clevis luks bind -d /dev/vda1 tang '{"url":"http://demotang.lab.example.com"}'
luksmeta show -d /dev/vda1                                  # verify that Clevis key was placed in LUKS header
dracut -f                                                   # enable Dracut to unlock encrypted partitions using NBDS
systemctl enable clevis-luks-askpass.path                   # when decrypting non-root file system

# SSS policy which defines three Tang servers, and requires at least two of them to be available for automatic decryption to occur
cfg=$'{"t":2,"pins":{"tang":[\n
> {"url":"http://demotang1.lab.example.com"},\n
> {"url":"http://demotang2.lab.example.com"},\n
> {"url":"http://demotang3.lab.example.com"}]}}'
clevis luks bind -d /dev/vdb1 sss "$cfg"

# JSON format of the above cfg example:
{
  "t": 2,
  "pins": {
    "tang": [
      {
        "url": "http://demotang1.lab.example.com"
      },
      {
        "url": "http://demotang2.lab.example.com"
      },
      {
        "url": "http://demotang3.lab.example.com"
      }
    ]
  }
}

4. Restricting USB Device Access

# USBGUARD:
yum -y install usbguard
yum -y install usbutils udisks2                             # provides lsusb, udisksctl
usbguard <list-devices|allow-device id|block-device id|reject-device id|list-rules|append-rule rule|remove-rule id|generate-policy>
systemctl enable usbguard --now

usbguard generate-policy > /etc/usbguard/rules.conf         # authorizes the currently connected USB devices
systemctl restart usbguard
usbguard list-rules
# Rule output example:
1: allow id 1d6b:0002 serial "0000:00:04.7" name "EHCI Host Controller"
hash "CsKOZ6IY8v3eojsc1fqKDW84V+MMhD6HsjjojcZBjSg=" parent-hash
"qiR4Ubbd7AIXLCz201hJYzaO9KIrOvqqRgqs2vM2NOY=" with-interface 09:00:00
# AUTHORIZING A DEVICE TO PERSISTENTLY INTERACT WITH THE SYSTEM:
usbguard list-devices                                       # if a new USB device is attached to the system after the default policy is generated it is not authorized to access the system and is assigned a block rule target
usbguard allow-device 6                                     # will not persist across reboots
usbguard allow-device -p 6                                  # will add it to /etc/usbguard/rules.conf and persist
systemctl restart usbguard

usbguard list-devices
usbguard list-rules
usbguard watch                                              # watch terminal for IPC activity
# PREVENTING A DEVICE FROM INTERACTING WITH THE SYSTEM, WHITE/BLACKLISTING:
usbguard block-device <ID>                                  # set its rule target to block
usbguard list-devices --blocked
usbguard reject-device <ID>                                 # set its rule target to reject
usbguard generate-policy -X -t reject \
  > /etc/usbguard/rules.conf                                # generate a new base policy with a reject rule target that will ignore any additional USB devices that'll try to interact with the system
grep usbguard /etc/group                                    # 'groupadd usbguard' & 'usermod -aG usbguard richard' if needed
vi /etc/usbguard/usbguard-daemon.conf
  RuleFile=/etc/usbguard/rules.conf                         # do not edit this file directly, but rather elsewhere and then move it here
  IPCAccessControlFiles=/etc/usbguard/IPCAccessControl.d/
  IPCAllowedGroups=usbguard
usbguard add-user -g usbguard --devices=modify,list,listen --policy=list --exceptions=listen

# RULE OPTIONS:
allow/reject name <DEVICE_NAME> serial <SER_NUM> via-port <PORT_ID> hash <HASH> with-interface <INTERFACE_TYPE>
# RULE OPERATORS (via-port <OPERATOR> {...}, with-interface <OPERATOR> {...}):
all-of                                                      # must contain all specified values to match
one-of                                                      # must contain at least one
none-of                                                     # must not contain any
equals                                                      # must contain exactly the same
equals-ordered                                              # must contain exactly the same also in the same order
# RULE CONDITIONS:
localtime(time_range)                                       # true if local time is in the range
allowed-matches(query)                                      # true if device matches query
rule-applied                                                # true if rule currently being evaluated ever matched device before
rule-applied(past_duration)                                 # same as above, but if it matched devce in the past duration of time
rule-evaluated                                              # true if was ever evaluated before
rule-evaluated(past_duration)                               # same as above, but if it was evaluated in the past duration of time
random                                                      # probability is 0.5 by default, can be changed by p_true
true
false
# CREATING POLICIES THAT MATCH A SPECIFIC DEVICE:
allow 1050:0011 name "Yubico Yubikey II" serial "0001234567" via-port "1-2" hash
"044b5e168d40ee0245478416caf3d998"
reject via-port "1-2"                                       # allow Yubikey on a specific port, reject all other devices on that port

# CREATING POLICIES THAT MATCH MULTIPLE DEVICES `{ interface class:subclass:protocol }`:
allow with-interface equals { 08:*:* }                      # allow USB mass storage devices (class 08), deny all other via implicit rule

# REJECT DEVICES WITH SUSPICIOUS COMBINATION OF INTERFACES:
allow with-interface equals { 08:*:* }
reject with-interface all-of { 08:*:* 03:00:* }
reject with-interface all-of { 08:*:* 03:01:* }
reject with-interface all-of { 08:*:* e0:*:* }
reject with-interface all-of { 08:*:* 02:*:* }              # this whole block allows keyboard-only USB if there's not one already plugged

# APPLY THE POLICY CHANGES:
install -m 0600 -o root -g root ~/rules.conf /etc/usbguard/rules.conf ; systemctl restart usbguard

5. Controlling Authentication with PAM

# DESCRIBING THE PAM CONFIGURATION FILE SYNTAX:
# Application configuration files in /etc/pam.d/ follow a standard format for their rules - parsed and executed top to bottom:
type control module [module arguments]
# 'type' can only be auth, account, password, session - in this order
# 'control' is usually just required, requisite, sufficient, optional, include, substack
# A dash (-) character in front of a type (such as "-session" near the end of the /etc/pam.d/system-auth file) indicates to silently skip the rule if the module file is missing.
# PAM looks for the modules in the /usr/lib64/security/ directory.
man -k pam_                                                 # e.g.: man pam_faildelay

# USING SSSD AND PAM:
yum -y install sssd
authconfig --enablesssd --enablesssdauth --update
# PREPARING FOR CONFIGURATION UPDATE:
authconfig --savebackup=/root/pambackup
authconfig --restorebackup=/root/pambackup                  # restore process doesn't remove the links to your *-local files. It only restored the *-ac files and preserved your custom modifications.
# authconfig modifies only the *-ac files (/etc/pam.d/system-auth-ac and /etc/pam.d/password-auth-ac)
# most of the PAM service configuration files include the system-auth and password-auth files, which are symlinks to *-ac files
# ensure that a secondary root shell is open at all times to recover from potential errors
# ONLY ALLOWING MANUAL CONFIGURATION:
cd /etc/pam.d
cp system-auth-ac system-auth-local                         # Make a copy of the existing system-auth-ac
cp password-auth-ac password-auth-local                     # ...and password-auth-ac files to use for manual configuration
rm system-auth password-auth                                # Remove the symbolic links
ln -s system-auth-local system-auth                         # Recreate the links to point to your custom system-auth-local and password-auth-local files
ln -s password-auth-local password-auth                     # now you can edit the custom system-auth-local and password-auth-local files without risking an overwrite by authconfig

# ALLOWING BOTH MANUAL AND AUTHCONFIG CONFIGURATION:
cd /etc/pam.d
cp system-auth-ac system-auth-local                         # Make a copy of the of the existing system-auth-ac
cp password-auth-ac password-auth-local                     # ...and password-auth-ac files to use for manual configuration
rm system-auth password-auth                                # Remove the symbolic links
ln -s system-auth-local system-auth                         # Recreate the links to point to your custom system-auth-local and password-auth-local files
ln -s password-auth-local password-auth
vi /etc/pam.d/system-auth-local                            # In you custom files, include the *-ac files
  auth     include system-auth-ac
  account  inlcude system-auth-ac
  password inlcude system-auth-ac
  session  include system-auth-ac
vi /etc/pam.d/password-auth-local
  auth     include password-auth-ac
  account  inlcude password-auth-ac
  password inlcude password-auth-ac
  session  include password-auth-ac                         # you can now use the custom *-local files for manual configuration, but include the *-ac files for the configuration you do through authconfig
# DESCRIBING THE PAM_PWQUALITY MODULE:
authconfig --passminlen=12 --update
grep pam_pwquality /etc/pam.d/system-auth /etc/pam.d/password-auth # these can be only specified in /etc/pam.d/ files: try_first_pass local_users_only retry authtok_type
vi /etc/security/pwquality.conf                             # negative values indicate/enforce the minimum number of characters required for each class
  minlen = 8                                                # passwords must be a minimum of eight characters in length
  lcredit = 0                                               # policy does not specify anything regarding lowercase characters
  ucredit = -1                                              # passwords must contain at least one uppercase character
  dcredit = -2                                              # passwords must contain at least two digits
  ocredit = -1                                              # passwords must contain at least one other/special character
# PAM_TIME MODULE:
vi /etc/security/time.conf                                 # configure the pam_time module
  sshd|login;*;!root&student;Al1800-2300                    # users can only log in using SSH or the console between 6PM and 11PM on any given day. This restriction does not apply to root and student - they will be able to log in at any time

# PAM_ACCESS MODULE:
authconfig --help | grep access
authconfig --enablepamaccess --update                       # enables pam_access (check /etc/security/access.conf during account authorization)
vi /etc/security/access.conf
  +:root student: ALL                                       # root and student users can log in from anywhere
  +:(operators):172.25.250.254                              # members of the operators group can only log in if they attempt access from workstation (172.25.250.254)
  -:ALL:ALL                                                 # other users are not allowed to log in
# LOCKING ACCOUNTS WITH MULTIPLE FAILED LOGINS:
authconfig --help | grep faillock
man pam_faillock
authconfig --enablefaillock --faillockargs="deny=3 fail_interval=60 unlock_time=600" --update
faillock                                                    # list failed login attempts
faillock --user user1                                       # restricts the output to a specific account
faillock --user user1 --reset                               # removes the failure records for a user, as a side effect516298
 this also unlocks the account if it was locked
authconfig --disablefaillock --update

6. Recording System Events with Audit

# CONFIGURE CLIENT:
/etc/audit/auditd.conf                                      # main config file
  log_file                                                  # location of the log file, /var/log/audit/audit.log by default
  max_log_file                                              # trigger max_log_file_action when file reaches X MB
  max_log_file_action                                       # ROTATE or KEEP_FILES
  num_logs                                                  # keep number of X old logs
  space_left                                                #
  space_left_action                                         #
  admin_space_left                                          #
  admin_space_left_action                                   #
  disk_full_action                                          #
  disk_error_action                                         #
  flush = INCREMENTAL_ASYNC                                 #
  freq = 50                                                 #
  log_format = ENRICHED                                     #
  name_format                                               #
/etc/audisp/plugins.d/syslog.conf                           #
  active = yes                                              #
  yum install audispd-plugins
/etc/audisp/plugins.d/au-remote.conf                        #
  active = yes                                              #
/etc/audisp/audisp-remote.conf                              #
  remote_server                                             #
  port                                                      #
/etc/audit/audit.rules                                      # do not edit this, it is automatically generated from the /etc/audit/rules.d/
/etc/audit/rules.d                                          # all files ending in *.rules are combined into /etc/audit/audit.rules by augenrules
systemctl status auditd; systemctl is-enabled auditd

# CONFIGURE SERVER COLLECTING AUDITD EVENTS:
/etc/rsyslog.conf                                           #
/etc/audit/auditd.conf                                      #
  tcp_listen_port = 60

7. Monitoring File System Changes

8. Mitigating Risk with SELinux

9. Managing Compliance with OpenSCAP

10. Automating Compliance with Red Hat Satellite

11. Analyzing and Remediating Issues with Red Hat Insights


Note: To generate beautiful PDF file, install latex and pandoc: sudo yum install pandoc pandoc-citeproc texlive

And then use pandoc v1.12.3.1 to output Github Markdown to the PDF: pandoc -f markdown_github -t latex -V geometry:margin=0.3in -o RH415.pdf R415.md

For better result (pandoc text-wrap code blocks), you may want to try my listings-setup.tex: pandoc -f markdown_github --listings -H listings-setup.tex -V geometry:margin=0.3in -o RH415.pdf RH415.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment