To show a message before someone authenticates over SSH, point the Banner directive in sshd_config at a file:
# in /etc/ssh/sshd_config
Banner /etc/ssh/banner.txtWrite your text into /etc/ssh/banner.txt, reload sshd, and the next person who connects sees that text before the password or key prompt. That is the whole job. The part people get wrong is which file does this: /etc/motd prints after you log in, the Banner file prints before authentication. If the goal is a legal "authorized use only" notice that an attacker sees before they are in, you want Banner, not motd.
The config, end to end
Three steps: write the banner text, register it, reload the daemon.
First the text. Keep it plain ASCII; the banner is sent raw to the client's terminal before any session exists, so fancy escape sequences are a bad idea.
sudo tee /etc/ssh/banner.txt > /dev/null <<'EOF'
***************************************************************************
AUTHORIZED ACCESS ONLY
This system is restricted to authorized users. All activity is logged
and monitored. Unauthorized access is prohibited and will be prosecuted.
***************************************************************************
EOFThen point sshd at it. Edit /etc/ssh/sshd_config and add (or uncomment) the line:
Banner /etc/ssh/banner.txtThe default is Banner none, which is why a stock server shows nothing before the prompt. Set it to an absolute path. Relative paths are not resolved against anything useful, so always give the full path.
Then reload. This is a config-only change, so a reload is enough; you do not need a full restart that would drop existing sessions:
sudo systemctl reload ssh # Debian/Ubuntu: the unit is "ssh"
sudo systemctl reload sshd # RHEL/Fedora/Rocky/Alma: the unit is "sshd"Before reloading anything on a box you care about, validate the config so a typo does not lock out the daemon:
sudo sshd -tNo output means the config parses. If it complains, fix it before you reload.
What it looks like from the client side
Connect and the banner lands before the password prompt:
$ ssh techearl@server.example
***************************************************************************
AUTHORIZED ACCESS ONLY
This system is restricted to authorized users. All activity is logged
and monitored. Unauthorized access is prohibited and will be prosecuted.
***************************************************************************
techearl@server.example's password:The banner is printed by the server during the SSH protocol's pre-auth phase, so it shows even on a connection that then fails authentication. That is the point of it: a notice that is delivered to anyone who reaches the daemon, before they prove who they are.
Banner vs. motd: which one fires when
This is the distinction that trips everyone up. They are different files, set in different places, shown at different moments.
Banner (sshd_config) | /etc/motd | |
|---|---|---|
| When it shows | Before authentication | After successful login |
| Configured in | /etc/ssh/sshd_config (Banner /path) | The file /etc/motd itself |
| Who controls it | SSH daemon | The login/PAM stack (pam_motd) |
| Seen by failed logins | Yes | No |
| Typical use | Legal "authorized use only" notice | Welcome text, host info, update reminders |
| Applies to | SSH connections only | Every login (SSH, console, etc.) |
So if you want every visitor warned regardless of whether they get in, that is Banner. If you want a greeting or system status for users who are already through, that is motd. Plenty of hardened servers set both: a stern pre-auth banner and a quieter post-login motd.
One more wrinkle on the client side. The OpenSSH client prints the banner to stderr, so it shows up even when you run a non-interactive remote command (only stdout gets piped, not stderr). The connecting user can suppress it locally with LogLevel QUIET in their ~/.ssh/config. So treat the banner as a notice you are presenting, not as something you can guarantee a remote script reads or acts on.
Per-group or per-source banners with Match
If you want a different banner for connections from a particular address, user, or group, wrap a second Banner in a Match block. Match blocks live at the end of sshd_config, since everything after a Match line belongs to that conditional until the next Match or end of file:
Banner /etc/ssh/banner.txt
Match Address 10.0.0.0/8
Banner /etc/ssh/banner-internal.txtConnections from the 10.0.0.0/8 range get the internal banner; everyone else gets the default one set above. The same works with Match User, Match Group, and so on. Keep the global Banner line above the first Match so it acts as the fallback.
Caveats worth knowing
The banner is pre-auth and unauthenticated, which has consequences:
- It leaks to anyone who can reach the port. Port scanners, bots, and curious strangers all see it. Do not put hostnames, OS versions, internal IPs, or contact names in it. "Authorized access only" is fine; "prod-db-03 running Ubuntu 22.04, call Dave at..." is an information disclosure.
- It does not stop anyone. A banner is a legal and policy device, not a security control. It deters nobody technically. Pair it with real hardening: disable password authentication and turn off direct root login.
- Cloud images sometimes pre-set it. Some AWS, GCP, and Azure base images ship a
Banneror a dynamic motd already. Check what is there before adding your own so you do not end up with two notices stacked. - Keep it ASCII and short. It is sent raw to the terminal before the session exists. Box-drawing with UTF-8 can render as garbage on minimal clients; long banners just annoy the humans who log in fifty times a day.
- File-transfer tools discard it. The server still sends the banner during the pre-auth handshake, but
sftpandscpclients typically suppress or ignore it rather than print it, so do not rely on it surfacing in an automated transfer.
When not to bother
If the box is your own laptop or a single-user dev VM that nobody else touches, a pre-auth banner is just noise you scroll past. Banners earn their place on shared, internet-facing, or compliance-scoped servers, the ones where "we displayed a notice that access was restricted" is a sentence someone might actually need to say later. For a personal machine, skip it and spend the effort on key-only auth instead.
See also
- Harden sshd by disabling password authentication: the change that actually matters once your banner is in place, forcing key-based logins.
- Disable direct root login over SSH: the other half of a sensible
sshd_config, so the banner sits in front of a daemon that is properly locked down.
Sources
Authoritative references this article was fact-checked against.
- sshd_config(5) Banner directive (OpenBSD)man.openbsd.org
- sshd_config(5) manual page (OpenBSD)man.openbsd.org
- ssh_config(5) LogLevel directive (OpenBSD)man.openbsd.org





