Handbook sections

Login banners and MOTD

Last reviewed

A login banner is both a legal notice you must display before authentication and a place where systems quietly leak their OS and kernel version: fix both.

The threat

The text shown around the login: prompt is easy to overlook, yet it works against you in two distinct ways.

First, information leakage. Default banners on many distributions interpolate escape sequences: \s prints the OS name, \r the kernel release, \m the architecture, \v the version, \l the terminal line. /etc/issue.net is the worst offender: it is sent over the network, before any authentication, so an unauthenticated attacker who merely opens a TCP connection to sshd (when Banner /etc/issue.net is set) gets a free fingerprint: "Ubuntu 24.04, kernel 6.8". That is exactly the input needed to pick a targeted exploit, and it is handed over for free.

Second, the missing legal warning. With no explicit authorized-use notice, an intruder can argue the system looked open to access. Many jurisdictions and frameworks (CIS, and corporate policy) require a banner that states access is restricted and monitored before the user authenticates, otherwise prosecuting unauthorized access becomes harder.

Why harden it

Neither problem is a remote-code-execution bug, so banners get neglected, but both are cheap to fix and both matter. Suppressing the OS/version escapes removes a reconnaissance gift to every scanner that touches the port or the console. Putting a clear authorized-use notice in place establishes intent and supports incident response. The cost is a one-line text file with the right mode; the upside is one fewer fingerprint and a defensible legal posture.

This spans every entry path: the local TTY (/etc/issue, read by getty before the prompt), the remote pre-auth banner (/etc/issue.net, served by SSH when configured), and the post-login message (/etc/motd, rendered by pam_motd). A consistent, neutral notice on all three is the goal.

Defense principles applied

  • Minimize information disclosure: strip every \s/\m/\r/\v/\l escape so no OS, kernel or architecture detail is broadcast pre-auth. Authorized users get those facts deliberately with uname -a after login; there is no reason to volunteer them earlier.
  • Defense in depth: cover all three surfaces (local, remote, post-login), not just SSH; an attacker at a physical console or serial line sees /etc/issue too.
  • Least surprise / accountability: a single neutral authorized-access notice, owned root:root and mode 0644, that states the system is monitored and access is restricted.
  • Effective over nominal: the banner only deters remotely if SSH actually serves it (sshd -T must report banner /etc/issue.net); writing the file is necessary but not sufficient.

What Pavois audits

Pavois ships three rules in this domain, one per surface, all mapped to CIS:

  • banner-issue: reads /etc/issue (the local-console pre-login banner) and asserts it is non-empty and free of \[smrvlSMRVL] escapes.
  • banner-issue-net: reads /etc/issue.net (the banner offered to remote/SSH logins) with the same two assertions: present, and no OS/version escapes leaking over the network.
  • banner-motd: reads /etc/motd (the post-login message rendered by pam_motd) and applies the same checks.

These are static files consumed directly by getty, sshd and pam_motd, so reading the file is the effective configuration here: there is no resolved-state command between the file and what the terminal displays. The complementary SSH side (whether sshd -T actually reports banner /etc/issue.net) is covered by Pavois's effective-config SSH control, so the handbook view ties the file content to whether it is genuinely served. pavois harden apply writes each file with a neutral authorized-access notice, root:root ownership and mode 0644, and no dynamic escapes: no reboot or service restart required, since each consumer reads the file on the next login.

How do you set and verify it?

  1. Write a neutral notice (no OS/version escapes) to /etc/issue, /etc/issue.net and /etc/motd, owned root:root, mode 0644.
  2. Point SSH at it: set Banner /etc/issue.net in sshd_config, then systemctl reload sshd.
  3. Confirm the remote banner is actually served: sshd -T | grep -i banner must report banner /etc/issue.net, and ssh -o PreferredAuthentications=none user@host shows the text before any prompt.
  4. Confirm no leak: grep -E '\\[smrvlSMRVL]' /etc/issue /etc/issue.net returns nothing.

What should the banner say?

A short, neutral authorized-use notice: the system is for authorized users only, activity may be monitored and logged, and unauthorized access is prohibited. Do not include the hostname, OS, version, internal organisation details, or a friendly welcome (which undercuts the legal posture).

FAQ

Why is /etc/issue.net worse than /etc/issue? Because SSH can serve it before authentication, over the network, so its escapes leak the OS and kernel to anyone who connects. /etc/issue only shows at a local TTY.

I wrote the banner but SSH doesn't show it. SSH serves a banner only when Banner /etc/issue.net is set in sshd_config; check sshd -T | grep banner and reload sshd.

Should the banner welcome users? No. A welcome can be argued as an invitation; use a restricted-access, monitored-system notice instead.