How to set a dynamic Message of the Day (motd) in Debian Jessie 8.2 for ssh?

This has changed over the years:

First there was /etc/motd (static).

Then Ubuntu came up with their own package update-motd based on a script called from cron.

Finally, PAM copied Ubuntu's idea of /etc/update-motd.d/, and therefore Debian and others also have that behaviour.

There is an explanation here

https://ownyourbits.com/2017/04/05/customize-your-motd-login-message-in-debian-and-ubuntu/

So this is how things are currently: PAM will just read /var/run/motd.dynamic and /etc/motd if it exists (paste from post)

  • /etc/motd – The classic, static file. Does not exist anymore in Ubuntu 16.04 LTS, not even as a symbolic link to /var/run/motd. If it is created, however its contents will be printed too.
  • /var/run/motd – This was used by Ubuntu’s first implementation. It is not used anymore. It is just ignored by PAM.
  • /var/run/motd.dynamic – This is what is shown on login currently. It is updated by /etc/init.d/motd at every boot. It is also updated by PAM by running the scripts in /etc/update-motd.d/, if they exist.
  • /etc/motd.tail – The Ubuntu package used to populate /etc/update-motd.d. One of them would cat the contents of this file so it was easy to add static content. That script does not exist in the package anymore, so the file does not have the intended effect.

The example from the post

mkdir /etc/update-motd.d
rm -f /etc/motd                  # in Debian still exists
cat > /etc/update-motd.d/10logo <<EOF
#!/bin/sh
echo
cat /etc/issue
EOF

cat > /etc/update-motd.d/20updates <<'EOF'
#!/bin/sh
echo
echo "uptime is $( uptime )"
echo "date   is $( date   )"
EOF

chmod a+x /etc/update-motd.d/*

I am able to test simple dynamic-motd with fortune example on my Debian Jessie 8.2 host as below and found the issue to be related to a buggy behavior.

mkdir /etc/update-motd.d
cd /etc/update-motd.d

Created two test files as below and made them executable

root@debian:/# cd /etc/update-motd.d/
root@debian:/etc/update-motd.d# ls -l 
total 8
-rwxr-xr-x 1 root root 58 Dec  1 23:21 00-header
-rwxr-xr-x 1 root root 41 Dec  1 22:52 90-fortune
root@debian:/etc/update-motd.d# cat 00-header 
#!/bin/bash
echo
echo 'Welcome !! This is a header'
echo
root@debian:/etc/update-motd.d# cat 90-fortune 
#!/bin/bash
echo
/usr/games/fortune
echo

However at this time, there was no change in motd. So i strace'd sshd process.From that trace (interesting parts shown below), you can see that newly created motd.new file is renamed to /var/run/motd. However it's later trying to read from /run/motd.dynamic - which was never created

20318 rename("/var/run/motd.new", "/var/run/motd") = 0
20318 open("/run/motd.dynamic", O_RDONLY) = -1 ENOENT (No such file or directory)
20318 open("/etc/motd", O_RDONLY)       = 8

The issue seem to be related to inconsistencies with pam_motd module. See bug report https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=743286;msg=2

Simply changing motd file location from /run/motd.dynamic to /run/motd in /etc/pam.d/sshd - makes it work for me

root@debian:/etc/pam.d# grep pam_motd sshd
#session    optional     pam_motd.so motd=/run/motd.dynamic
session    optional     pam_motd.so motd=/run/motd
session    optional     pam_motd.so noupdate

Here is the sample MOTD seen during ssh login ...

Welcome !! This is a header


* Culus fears perl - the language with optional errors


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.
You have new mail.
Last login: Tue Dec  1 23:49:57 2015 from x.x.x.x