Creating a Dynamic MOTD in Raspbian (or Debian) Jessie

I recently covered how to change the static motd in Raspbian Jessie. If you are interested or want some background for this article, you can read about that here. This post will cover how to setup a dynamic motd in Rapsbian (and therefore Debian) Jessie to give users up to date, relevant information about the system upon login.

Why Go Dynamic?

The static message we created in my previous post was a huge improvement over the default motd. For myself, I will hopefully never go on a trip again without taking the proper steps to get my OpenVPN server running, assuming I read the message. However, a dynamic motd allows an admin to display all sorts of information to a user, including whether there are updates available for the system. This can be especially helpful if your Pis are set up a single task machines that receive intermittent use. A dynamic motd can also tell the user which distro and kernel version are running, how many people are logged in, the current load on the system, etc. Essentially, a dynamic motd can display any information that you can get from a script!

What Is A Dynamic motd?

A dynamic motd is created on the fly upon each login. In the case of Raspbian, pam_motd looks for executable scripts in a specific directory (/etc/update-motd.d/), runs them in ascending order, and prints the specified information which becomes the motd. The scripts can be written in any language, but the examples will be simple, so we’ll use shell scripts. The scripts should be titled in the following format: NN-descriptiveName, where NN is a two digit number which determines the order in which pam_motd will execute the scripts. Note that there is not and should not be any file extension for these scripts.

How To Go Dynamic

The nice thing about Raspbian is that it used to use a dynamic motd, and some of the necessary components remain. For example, the instruction to run pam_motd is already in /etc/pam.d/sshd. Therefore, creating a dynamic motd is relatively straight forward. We need only create the necessary directory, our scripts and one symlink. Note that if you are not running as root, you may need to prepend the following commands with sudo. The following is the set of scripts I use as the motd on my Pi Zero OpenVPN server.

Creating the Framework
mkdir /etc/update-motd.d
cd /etc/update-motd.d
touch 00-header && touch 90-updates-available && touch 99-footer
chmod +x /etc/update-motd.d/*
rm /etc/motd
ln -s /var/run/motd /etc/motd    
Writing the Scripts

Now that we have the framework setup, we just need to populate the scripts with the relevant info. The following is how I setup my scripts. You can, of course, use whatever number of scripts, naming scheme, etc. works best for you. At the end of the article I will have links to articles and discussions that helped me in setting up my scripts which may provide some other ideas for your own dynamic motd.

00-header

Note that this script requires that the lsb-release package be installed on your system.

#!/bin/bash
#
#    00-header - create the header of the MOTD
#    Copyright (C) 2016 Chris Bickhaus
#    Copyright (C) 2009-2010 Canonical Ltd.
#
#    Authors:   Chris Bickhaus <contact@bickhaus.net>
#       Dustin Kirkland <kirkland@canonical.com>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

#The following 5 lines correspond to the line which displays distro details below

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

echo
printf "######################################################################\n"
printf "############# Welcome to xxx@xxxxxxx: an OpenVPN server. #############\n"
printf "######################################################################\n"
echo
printf "    DO NOT forget to forward port 1194 on the network's firewall!"
echo
printf "######################################################################\n"

echo
printf "Server OS: %s (%s %s %s)\n" "$DISTRIB_DESCRIPTION" "$(uname -o)" "$(uname -r)" "$(uname -m)"
echo
printf "*Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent\n"
printf "permitted by applicable law.\n"
echo
printf "######################################################################\n"
echo
90-updates-available

Note that this script requires that the update-notifier-common package be installed on your system. Also be advised that if you use this script on a relatively slow Pi like the Zero, it will slow the time it takes to login by seconds (Think about how long it takes to run apt update on your Zero). I decided the trade off in speed was worth the reminder to update my Zero, since it is rarely used outside of when I travel. If you would like an example of a script that merely checks to see if there are updates, rather than actually running apt update, you can see the original script I based mine on here. You can also look into how Ubuntu accomplishes this.

#!/bin/bash
#
#    90-updates-available - inform user whether updates can be installed
#      Copyright (c) 2016 Chris Bickhaus
#      Copyright (c) 2013 Nick Charlton
#
#    Authors:    Chris Bickhaus <contact@bickhaus.net>
#                Nick Charlton <hello@nickcharlton.net>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

apt update > /dev/null
echo
/usr/lib/update-notifier/apt-check --human-readable
/usr/lib/update-notifier/update-motd-reboot-required
echo
#!/bin/sh
#
#    99-footer - allows for a static message to be appended to dynamically created motd
#                (message should be stored as /etc/motd.tail)
#    
#    Copyright (c) 2013 Nick Charlton
#    Copyright (c) 2009-2010 Canonical Ltd.
#
#    Authors: Nick Charlton <hello@nickcharlton.net>
#             Dustin Kirkland <kirkland@canonical.com>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

[ -f /etc/motd.tail ] && cat /etc/motd.tail || true

That’s it. Next time you login, you should see your dynamic motd! Note that on one of my systems, I did not remove the motd file prior to logging out. This required me to change the symlink to ln -s /var/run/motd.new /etc/motd in order for the motd to display, even after removing /etc/motd. Whoops. If you have any questions or dynamic motd setups you would like to share, leave a comment below.

Further Reading

The following are man pages and mailing list discussions I found helpful:

  • Debian motd Wiki page.
  • Ubuntu update-motd manpage.
  • Debian Mailing List thread re:motd handling in Jessie

These are tutorials and a stack exchange answer I found helpful:

  • oitibs.com dynamic motd tutorial with a neat system info script
  • oitibs.com script I based my update script on. This one also displays other system info that I’m not interested in displaying. I tried to use the updates-available scripts that are on my Ubuntu 16.04 system, but they did not work.
  • Here is a stack exchange answer that gave me the idea to change the symlink as noted above when the motd wouldn’t display. They opted for editing /etc/pam.d/sshd which I did, until I realized I could just change the symlink.
comments powered by Disqus