Excalibur's Sheath

SSH Banners and MOTDs

Oct 30, 2016 • linux,ssh

A while ago, I wrote about some fun things to do to help secure your servers. Among the things I included was information about SSH banners, and Message of the Day files. At the time, I was not able to generate dynamic content for the Message of the day. Recently, I learned how to accomplish dynamic content on CentOS/Redhat based Linux systems. My goals for this project was to show the following:

  • System Information
  • User Information
  • Weather and Fortune
  • System Name
  • Warnings and Rules

MOTD Script

System Information

The system Information, I wanted to show is the following:

  • Hostname
  • Version of Linux
  • CPU Usage
  • Memory Information
  • Processes Running
  • Uptime
  • Disk Usage
  • Number of Available Updates

my motd script uses the following code to capture this information:

Hostname

echo -e "`uname -n`"

Version of Linux

echo -e "`cat /etc/redhat-release`"

CPU Usage Capture the Information in variables:

LOAD1=`cat /proc/loadavg | awk {'print $1'}`
LOAD5=`cat /proc/loadavg | awk {'print $2'}`
LOAD15=`cat /proc/loadavg | awk {'print $3'}`

Display it like this:

echo -e "$LOAD1, $LOAD5, $LOAD15 (1, 5, 15 min)"
  • LOAD1 - One Minute Load
  • LOAD2 - Five Minute Load
  • LOAD3 - Fifteen Minute Load

Memory Information

To get the memory Information I do the following:

MEMORY1=`free -t -m | grep "Mem" | awk '{print $3" MB";}'`
MEMORY2=`free -t -m | grep "Mem" | awk '{print $2" MB";}'`

Display it like this:

echo -e "$MEMORY1 / $MEMORY2"
  • $MEMORY1 - Memory Used
  • $MEMORY2 - Total Memory

Processes Running

To get the number of processes running I use the following:

PSA=`ps -Afl | wc -l`

Display it like this:

PSA=`ps -Afl | wc -l`
  • PSA - Number of running Processes

Uptime

To get system uptime I do the following:

uptime=`cat /proc/uptime | cut -f1 -d.`
upDays=$((uptime/60/60/24))
upHours=$((uptime/60/60%24))
upMins=$((uptime/60%60))
upSecs=$((uptime%60))

Display it like this:

echo -e "$upDays days $upHours hours $upMins minutes $upSecs seconds"
  • upDays - Number of days up
  • upHours - Number of Hours up less Days
  • upMins - Number of Minutes up less Days and Hours
  • upSecs - Number of Seconds up less Days, Hoursm and Minutes

Disk Usage

To get the disk usage I do the following:

DISKC=`df -Ph | grep /dev/vda1 | awk '{print $2}'`
DISKU=`df -Ph | grep /dev/vda1 | awk '{print $3}'`
DISKP=`df -Ph | grep /dev/vda1 | awk '{print $5}'`

Display it like this:

echo -e "$DISKU / $DISKC Used - $DISKP Used"
  • DISKC - Total amount of storage
  • DISKU - Amount of used storage
  • DISKP - Percent of disk used

Number of updates Available

The previous commands were all built into the operating system. For updates, I could have used a yum command to poll the updates everytime a login occurs, but that would have meant waiting 2-5 minutes after logging in to get a prompt. I decided to run the command to check for updates daily, and then save the results for use in logins. Because of that I have a checkupdates.sh script.

checkupdates.sh

#! /bin/bash

UPDATES=`yum check-update --quiet | grep '^[a-Z0-9]' | wc -l`
echo "There are $UPDATES update(s) available." > updates.txt

I have a cron job:

0 0 * * * /etc/motd.d/checkupdates.sh

I use the following code in the motd script to get the contents of the updates.txt file

UPDATES1=`cat /etc/motd.d/updates.txt`

Display it like this:

echo -e "$UPDATES1"

User Information

The user information I wanted to show was:

  • Number of Users Logged in
  • The logged in User

Number of Users Logged In

I show the number of users logged in like this:

echo -e "`users | wc -w` user(s) logged on"

User Logged In As

I show the logged in user with the following command:

echo -e "`whoami`"

Weather and Fortune

I get and display the weather with this command:

echo -e "`curl -s wttr.in/84601 | head -n 7`"

For fortune, I want shorter fortunes, and I want topics relevant to Linux, Computers, Programming, etc.

echo -e "$(fortune -s 75% linux 5% computers 10% perl 10% startrek)"

System Name

I have a section of my script, which I generate using toilet, which has the system name I’m using. I generate it, and save it to my motd script, and add echo commands. This is my first step in creating my motd file. I used another system to generate this, because there is not a CentOS package for Toilet.

sudo toilet --metal -f future {MY SYSTEM NAME} > /etc/motd.d/motd 

Warnings and Rules

I always add a message about access permissions to my SSH Banners, and to my motd scripts. In the motd file I add a smaller message, because the SSH Banner includes a much larger message.

echo -e ":::::::::::::::::::::::::::::::::::::::-RULES-:::::::::::::::::::::::::::::::::::::"
echo -e "      This is a private system that you are not to give out access to anyone"
echo -e "      without permission from the admin. No illegal files or activity. Stay,"
echo -e "     in your home directory, keep the system clean, and make regular backups."
echo -e "       -==  DISABLE YOUR PROGRAMS FROM KEEPING SENSITIVE LOGS OR HISTORY ==-"

Complete Script

Below is my complete motd script I have included the color escape codes I use to colorize my motd script. I have removed them in the above code examples for readability.

Here is my complete motd script:

#! /bin/bash

#System Information

#Get the date and IP Address of my last login
LASTIP1=`lastlog | grep $USER | awk '{print $3}'`
LASTTIME1=`lastlog | grep $USER |awk '{print $4" "$5" "$6" "$7" "$8}'`

#Get Disk usage, total size, and percent used.
DISKC=`df -Ph | grep /dev/vda1 | awk '{print $2}'`
DISKU=`df -Ph | grep /dev/vda1 | awk '{print $3}'`
DISKP=`df -Ph | grep /dev/vda1 | awk '{print $5}'`

#Memory 
MEMORY1=`free -t -m | grep "Mem" | awk '{print $3" MB";}'`
MEMORY2=`free -t -m | grep "Mem" | awk '{print $2" MB";}'`
PSA=`ps -Afl | wc -l`

#System load
LOAD1=`cat /proc/loadavg | awk {'print $1'}`
LOAD5=`cat /proc/loadavg | awk {'print $2'}`
LOAD15=`cat /proc/loadavg | awk {'print $3'}`

#System uptime
uptime=`cat /proc/uptime | cut -f1 -d.`
upDays=$((uptime/60/60/24))
upHours=$((uptime/60/60%24))
upMins=$((uptime/60%60))
upSecs=$((uptime%60))

#Updates
UPDATES1=`cat /etc/motd.d/updates.txt`

#Get Weather Information for my location
WEATHER=`curl -s wttr.in/84601 | head -n 7`

#Print Server Name
{THIS WAS GENERATED WITH TOILET first and the rest of the code built around it}
#End Print Server Name
echo -e "\033[0;1;36m===================================================================================\033[0m"
echo -e "\033[0;0;35m - Hostname ...............: \033[0;0;33m`hostname -n`\033[0m"
echo -e "\033[0;0;35m - Release ................: \033[0;0;33m`cat /etc/redhat-release`\033[0m"
echo -e "\033[0;0;35m - Users ..................: \033[0;0;33m`users | wc -w` user(s) logged on\033[0m"
echo -e "\033[0;1;36m===================================================================================\033[0m"
echo -e "\033[0;0;35m - Current User ...........: \033[0;0;32m`whoami`\033[0m"
echo -e "\033[0;0;35m - Last On ................: \033[0;0;32m$LASTTIME1 From $LASTIP1\033[0m"
echo -e "\033[0;0;35m - CPU usage ..............: \033[0;0;32m$LOAD1, $LOAD5, $LOAD15 (1, 5, 15 min)\033[0m"
echo -e "\033[0;0;35m - Memory used ............: \033[0;0;32m$MEMORY1 / $MEMORY2\033[0m"
echo -e "\033[0;0;35m - Swap in use ............: \033[0;0;32m`free -m | tail -n 1 | awk '{print $3}'` MB\033[0m"
echo -e "\033[0;0;35m - Processes ..............: \033[0;0;32m$PSA running\033[0m"
echo -e "\033[0;0;35m - System uptime ..........: \033[0;0;32m$upDays days $upHours hours $upMins minutes $upSecs seconds\033[0m"
echo -e "\033[0;0;35m - Disk space  ............: \033[0;0;32m$DISKU / $DISKC Used - $DISKP Used\033[0m"
echo -e "\033[0;1;36m===================================================================================\033[0m"
echo -e "$UPDATES1"
echo -e "\033[0;1;36m===================================================================================\033[0m"
echo -e "\e[33m$(fortune 75% linux 5% computers 10% perl 10% startrek)\e[0m"
echo "`curl -s wttr.in/84601 | head -n 7`"
echo -e "\033[0;1;31m:::::::::::::::::::::::::::::::::::::::-RULES-:::::::::::::::::::::::::::::::::::::\033[0m"
echo -e "\033[0;1;31m      This is a private system that you are not to give out access to anyone\033[0m"
echo -e "\033[0;1;31m      without permission from the admin. No illegal files or activity. Stay,\033[0m"
echo -e "\033[0;1;31m     in your home directory, keep the system clean, and make regular backups.\033[0m"
echo -e "\033[0;1;31m       -==  DISABLE YOUR PROGRAMS FROM KEEPING SENSITIVE LOGS OR HISTORY ==-\033[0m"
#SSH Banner The SSH Banner is displayed before login. I moved my big message to this file. It is a lot simpler, and is static. The SSH Banner, from my research does not allow escape codes, so color is out. Sometimes I use Toilet/Figlet to generate a systemname again, or I’ll just type it in normal text. ##SSH Banner Example

{SYSTEM NAME}

:::::::::::::::::::::::::::::::::::::-RULES-::::::::::::::::::::::::::::::::::::
This computer system is the private property of its owner, for authorized use
only. Users (authorized or unauthorized) have no explicit or implicit
expectation of privacy.

Any or all uses of this system and all files on this system may be intercepted,
monitored, recorded, copied, audited, inspected, and disclosed to your employer,
to authorized site, government, and law enforcement personnel, as well as
authorized officials of government agencies, both domestic and foreign.

By using this system, the user consents to such interception, monitoring,
recording, copying, auditing, inspection, and disclosure at the discretion of
such personnel or officials. Unauthorized or improper use of this system may
result in civil and criminal penalties and administrative or disciplinary
action, as appropriate. By continuing to use this system you indicate your
awareness of and consent to these terms and conditions of use.

LOG OFF IMMEDIATELY if you do not agree to the conditions stated in this
warning.

    ~== DISABLE YOUR PROGRAMS FROM KEEPING SENSITIVE LOGS OR HISTORY ==~

This script would not have been possible without the following pages I found as I was working on this. You will find Ideas, and text from all of these have been incorporated into what I wrote.