Suppress message of the day for specific or multiple users.

The default message of the day looks like this.

$ ssh debian.example.org -l milosz -i ~/.ssh/ext_milosz
Linux buster 4.19.0-4-amd64 #1 SMP Debian 4.19.28-2 (2019-03-15) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Aug 26 22:21:30 2019 from 10.0.2.2
milosz@buster:~$

Remote OpenSSH session

Per-user option

To suppress the message of the day for a specific user, create ~/.hushlogin file on a remote server.

$ touch ~/.hushlogin

Global option for every user

To suppress the message of the day for every user on a remote server, perform three simple steps.

Ensure that PrintLastLog option and PrintMotd respectively are disabled in OpenSSH server configuration /etc/ssh/sshd_config.

PrintMotd no
PrintLastLog no

Reload service after configuration update.

$ sudo systemctl update sshd

Ensure that PAM configuration /etc/pam.d/sshd for OpenSSH server does not use pam_motd module.

# Print the message of the day upon successful login.
# This includes a dynamically generated part from /run/motd.dynamic
# and a static (admin-editable) part from /etc/motd.
# session    optional     pam_motd.so motd=/run/motd.dynamic
# session    optional     pam_motd.so noupdate

Done.

$ ssh debian.example.org -l milosz -i ~/.ssh/ext_milosz
milosz@buster:~$

This behavior is defined in the OpenSSH session.c file.

/*
 * Check for quiet login, either .hushlogin or command given.
 */
int
check_quietlogin(Session *s, const char *command)
{
        char buf[256];
        struct passwd *pw = s->pw;
        struct stat st;
        /* Return 1 if .hushlogin exists or a command given. */
        if (command != NULL)
                return 1;
        snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
        if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
                return 1;
        return 0;
}

Local session

Per-user option

Inspect default /etc/login.defs configuration to check HUSHLOGIN_FILE option.

$ cat /etc/login.defs
[...]
#
# If defined, file which inhibits all the usual chatter during the login
# sequence.  If a full pathname, then hushed mode will be enabled if the
# user's name or shell are found in the file.  If not a full pathname, then
# hushed mode will be enabled if the file exists in the user's home directory.
#
HUSHLOGIN_FILE  .hushlogin
#HUSHLOGIN_FILE /etc/hushlogins
[...]

Create ~/.hushlogin file to suppress the message of the day for a particular user.

$ touch ~/.hushlogin

This behavior is defined in Shadow shadow/libmisc/hushed.c file.

/*
 * If this is not a fully rooted path then see if the
 * file exists in the user's home directory.
 */
if (hushfile[0] != '/') {
	(void) snprintf (buf, sizeof (buf), "%s/%s", pw->pw_dir, hushfile);
	return (access (buf, F_OK) == 0);
}

Global option for multiple users

Alter /etc/login.defs configuration to define system-wide /etc/hushlogins file as HUSHLOGIN_FILE.

$ cat /etc/login.defs
[...]
#
# If defined, file which inhibits all the usual chatter during the login
# sequence.  If a full pathname, then hushed mode will be enabled if the
# user's name or shell are found in the file.  If not a full pathname, then
# hushed mode will be enabled if the file exists in the user's home directory.
#
# HUSHLOGIN_FILE  .hushlogin
HUSHLOGIN_FILE /etc/hushlogins
[...]

Add user login to /etc/hushlogins to suppress the message of the day for the specific user.

$ echo milosz | sudo tee -a /etc/hushlogins

Add login shell to /etc/hushlogins to suppress the message of the day for every user using a particular shell.

$ echo /bin/bash | sudo tee -a /etc/hushlogins

This behavior is defined in Shadow shadow/libmisc/hushed.c file.

/*
 * If this is a fully rooted path then go through the file
 * and see if this user, or its shell is in there.
 */

fp = fopen (hushfile, "r");
if (NULL == fp) {
	return false;
}
for (found = false; !found && (fgets (buf, (int) sizeof buf, fp) == buf);) {
	buf[strlen (buf) - 1] = '\0';
	found = (strcmp (buf, pw->pw_shell) == 0) ||
	        (strcmp (buf, pw->pw_name) == 0);
}

Global option for every user

Ensure that the PAM configuration /etc/pam.d/login for the Shadow login service does not use pam_motd module.

# Print the message of the day upon successful login.
# This includes a dynamically generated part from /run/motd.dynamic
# and a static (admin-editable) part from /etc/motd.
# session    optional     pam_motd.so motd=/run/motd.dynamic
# session    optional     pam_motd.so noupdate

Done.

ko-fi