Login banners and warning messages are a simple but legally important security control on Linux systems. Before users authenticate, a visible warning that unauthorized access is prohibited can be critical for legal enforcement action if a system is breached. After login, a message of the day can display system status information relevant to administrators. Many compliance frameworks including PCI DSS and HIPAA explicitly require that authorized-use-only notices be displayed at login. This tutorial covers configuring all banner types on RHEL 9.

Prerequisites

  • RHEL 9 system with sudo or root access
  • OpenSSH server installed and running
  • Basic knowledge of sshd_config options

Step 1 — Configure the Pre-Login Console Banner (/etc/issue)

The file /etc/issue is displayed on the local console before a user logs in. It supports a small set of escape sequences for dynamic content such as the hostname and OS version. This banner appears on physical and virtual console sessions but not SSH sessions by default.

# Back up the original file
sudo cp /etc/issue /etc/issue.bak

# Write a legally compliant pre-login banner
sudo tee /etc/issue > /dev/null << 'EOF'
*******************************************************************************
*                         AUTHORIZED ACCESS ONLY                              *
*                                                                              *
*  This system is the property of MyCompany. Access is restricted to          *
*  authorized personnel only. All activities on this system are monitored     *
*  and recorded. Unauthorized access or use is strictly prohibited and may    *
*  result in civil and criminal penalties under applicable law.               *
*                                                                              *
*  By continuing, you acknowledge and consent to monitoring of this session.  *
*******************************************************************************

Hostname: n
OS:       s r (l)

EOF

Step 2 — Configure the Pre-Login SSH Banner (/etc/issue.net)

The file /etc/issue.net is the SSH equivalent of /etc/issue. Unlike /etc/issue, it does not support escape sequences — write it as plain text. SSH will not display it unless the Banner directive is set in sshd_config.

# Write the SSH pre-login banner
sudo tee /etc/issue.net > /dev/null << 'EOF'
*******************************************************************************
*                         AUTHORIZED ACCESS ONLY                              *
*                                                                              *
*  This system is the property of MyCompany. Unauthorized access or use is   *
*  strictly prohibited and may be subject to civil and criminal penalties.    *
*  All activities on this system are subject to monitoring and recording.     *
*  There is no expectation of privacy on this system.                         *
*                                                                              *
*  By proceeding past this point you acknowledge that you are an authorized   *
*  user and agree to the acceptable use policy.                               *
*******************************************************************************
EOF

# Enable the banner in sshd_config
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

sudo sed -i 's|^#Banner.*|Banner /etc/issue.net|' /etc/ssh/sshd_config
# If the line does not exist at all, add it
grep -q "^Banner" /etc/ssh/sshd_config || 
  echo "Banner /etc/issue.net" | sudo tee -a /etc/ssh/sshd_config

sudo systemctl reload sshd

Step 3 — Configure the Post-Login Message of the Day (/etc/motd)

The /etc/motd file is displayed immediately after a successful login, before the shell prompt. It is a good place to put operational notices such as maintenance windows or policy reminders. Keep it brief so it does not become background noise that users ignore.

# Write a static MOTD
sudo tee /etc/motd > /dev/null << 'EOF'

  Welcome to MyCompany Production Server.

  - All changes must be tracked in the change management system.
  - Do not store sensitive data in home directories.
  - Report security incidents immediately to [email protected]

EOF

Step 4 — Create a Dynamic MOTD with /etc/update-motd.d/

On systems that support it, scripts in /etc/update-motd.d/ are executed at login and their output is assembled into the MOTD dynamically. This allows you to show real-time system metrics such as disk usage and uptime. Scripts must be executable and are run in alphabetical order.

# Create a script that shows system status
sudo tee /etc/update-motd.d/10-sysinfo > /dev/null << 'EOF'
#!/bin/bash
echo ""
echo "  System Information"
echo "  ------------------"
echo "  Hostname : $(hostname -f)"
echo "  Uptime   : $(uptime -p)"
echo "  Load     : $(cut -d' ' -f1-3 /proc/loadavg)"
echo "  Memory   : $(free -h | awk '/^Mem:/ {print $3 " used / " $2 " total"}')"
echo ""
echo "  Disk Usage (mounted filesystems):"
df -h --output=target,pcent,used,avail | grep -v "^Filesystem" | 
  awk '{printf "  %-25s %s used, %s free (%s)n", $1, $3, $4, $2}'
echo ""
echo "  Last login information:"
last -n 3 -a | head -4
echo ""
EOF

sudo chmod +x /etc/update-motd.d/10-sysinfo

# Ensure PAM session includes pam_motd so scripts are executed
grep -q "pam_motd" /etc/pam.d/sshd || 
  echo "session    optional     pam_motd.so motd=/run/motd.dynamic" 
  | sudo tee -a /etc/pam.d/sshd

Step 5 — Harden SSH to Suppress Default System Information

By default, SSH may display the OS version in the pre-authentication banner (via the DebianBanner or equivalent setting) or show the SSH software version. Suppressing unnecessary system information reduces the information available to potential attackers during reconnaissance.

# Suppress the SSH version string detail in the banner
sudo grep -q "^VersionAddendum" /etc/ssh/sshd_config && 
  sudo sed -i 's/^VersionAddendum.*/VersionAddendum none/' /etc/ssh/sshd_config || 
  echo "VersionAddendum none" | sudo tee -a /etc/ssh/sshd_config

# Disable PrintLastLog if you are handling last login via MOTD script instead
grep -q "^PrintLastLog" /etc/ssh/sshd_config && 
  sudo sed -i 's/^PrintLastLog.*/PrintLastLog no/' /etc/ssh/sshd_config || 
  echo "PrintLastLog no" | sudo tee -a /etc/ssh/sshd_config

# Validate sshd_config syntax before reloading
sudo sshd -t && sudo systemctl reload sshd
echo "sshd reloaded successfully"

Step 6 — Verify Banner Display

Test that banners appear correctly by making an SSH connection and checking the console behavior. Verification is important before presenting these banners to auditors as evidence of compliance.

# Test SSH connection - you should see the /etc/issue.net banner before login prompt
ssh -o "StrictHostKeyChecking=no" localhost

# Confirm Banner directive is active in sshd_config
sudo sshd -T | grep -i banner

# Check that /etc/motd and dynamic MOTD scripts are readable
cat /etc/motd
run-parts /etc/update-motd.d/ 2>/dev/null

# Verify PAM motd module is configured
grep pam_motd /etc/pam.d/sshd

Conclusion

You have configured pre-login console banners via /etc/issue, pre-login SSH banners via /etc/issue.net with the sshd Banner directive, a static post-login MOTD, and a dynamic MOTD that displays real-time system information. You also suppressed unnecessary SSH version information that aids reconnaissance. These controls satisfy the banner requirements found in PCI DSS 2.2.7, HIPAA Administrative Safeguards, and CIS RHEL 9 benchmarks.

Next steps: How to Harden SSH Configuration on RHEL 9, How to Configure PAM on RHEL 9, and How to Audit User Login Activity with auditd on RHEL 9.