The Helpers
figlet and lolcat come in handy when you’re pimping your console, so let’s go ahead and install them:
sudo apt-get install figlet lolcat
We may also need an assist from strace, so:
sudo apt-get install strace
PAM
Ubuntu first implemented dynamic MOTD with scripts, then PAM adopted the same approach internally.
For this example, I’m going to use PAM.
PAM will run scripts under the /etc/update-motd.d directory. However, we will have to create these scripts ourselves:
sudo mkdir -p /etc/update-motd.d sudo chmod 755 /etc/update-motd.d sudo touch /etc/update-motd.d/00header sudo chmod 755 /etc/update-motd.d/00header
PAM Session Configuration: SSH Login
The motd= path of /run/motd.dynamic in the default pam.d/sshd and pam.d/login config files will probably be wrong1 for your distribution, so we will need to update the session options for SSH and console logins.
For SSH logins, I like to show both the dynamic MOTD from /run/motd, as well as the static one I keep at /etc/motd:
/etc/pam.d/sshd
# Print the message of the day upon successful login. # This includes a dynamically generated part from /run/motd # and a static (admin-editable) part from /etc/motd. session optional pam_motd.so motd=/run/motd session optional pam_motd.so noupdate
PAM Session Configuration: Console Login
Since the kernel console is limited to 16 colors, and my /etc/motd file uses 256-color escape codes, I only show the dynamic MOTD for console login by commenting out the noupdate line:
/etc/pam.d/login
# Prints the message of the day upon succesful login. # (Replaces the `MOTD_FILE' option in login.defs) session optional pam_motd.so motd=/run/motd #session optional pam_motd.so noupdate
OpenSSH Server
We will also need to ensure that the OpenSSH server leaves MOTD rendering up to PAM. If you skip this step, /etc/motd may be rendered twice!
/etc/ssh/sshd_config
PrintMotd no Banner none UsePAM yes
The Script (this example REQUIRES figlet AND lolcat)
/etc/update-motd.d/00header
#!/bin/sh # redirect errors to stdout -- just in case exec 2>&1 [ -r /etc/lsb-release ] && . /etc/lsb-release if [ -z "$DISTRIB_DESCRIPTION" ] && [ -x /usr/bin/lsb_release ]; then # Fall back to using the very slow lsb_release utility DISTRIB_DESCRIPTION=$(lsb_release -s -d) fi # lolcat MIGHT NOT BE IN $PATH YET, SO BE EXPLICIT LOLCAT=/usr/games/lolcat # UPPERCASE HOSTNAME, APPLY FIGLET FONT "block" AND CENTERING INFO_HOST=$(echo $(hostname) | awk '{print toupper($0)}' | figlet -tc -f block) # GET OS/ARCH/DATE, APPLY FIGLET FONT "term" AND CENTERING INFO_OS=$(printf "%s (%s)\n%s" "$DISTRIB_DESCRIPTION" "$(uname -r)" "$(date)" | figlet -tc -f term) # RUN IT ALL THROUGH lolcat FOR COLORING # NOTE: needs -f to force color output since intermediate file is not a TTY printf "%s\n%s\n" "$INFO_HOST" "$INFO_OS" | $LOLCAT -f
Troubleshooting
Since the file paths for this dynamic-MOTD scheme seem to be a work-in-progress2, you may need to use different filenames than the ones I have provided.
strace will help you find out which files PAM is looking for:
# GET PID OF sshd SERVICE root@vm-dev:~$ ps ax | grep 'sbin/sshd' 16820 ? Ss 0:00 /usr/sbin/sshd -D 26386 pts/4 S+ 0:00 grep sbin/sshd # RUN strace ON FILE OPERATIONS FOR THE PID OF sshd, # THEN PERFORM AN SSH LOGIN TO SEE WHICH FILES ARE ACCESSED # NOTE: NEEDS -f OPTION TO CAPTURE OPERATIONS OF CHILD PROCESSES root@vm-dev:~# strace -e open,access,rename -f -p 16820 2>&1 | grep motd [pid 24141] open("/lib/x86_64-linux-gnu/security/pam_motd.so", O_RDONLY|O_CLOEXEC) = 8 [pid 24146] open("/var/run/motd.new", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 [pid 24147] access("/etc/update-motd.d/00header", X_OK) = 0 [pid 24148] open("/etc/update-motd.d/00header", O_RDONLY) = 3 [pid 24141] rename("/var/run/motd.new", "/var/run/motd") = 0 [pid 24141] open("/run/motd", O_RDONLY) = 8 [pid 24141] open("/etc/motd", O_RDONLY) = 8