Find them und patch them…

I want to start this post by pointing out that the title is like something you’d find in a classic German war movie.  Except this time, it’s about servers.  Anyway, I got this email from a reader:

Hi Linux Guy,
I have a project where I need to patch Linux systems – problem is that the client doesn’t even know how or what versions of linux are out there in the environment.

What would you recommend as a discovery method or tool to obtain the system information for linux systems?  I recall that, back in my earlier days of IT and experimenting, I used a port-scanner to identify online systems in my neighborhood on the internet :S  That, I believe, also identified operating system based on which ports are open, so I am thinking some sort of SNMP tool.

Looking for your wisdom and guidance.
-Nick-

I appreciate your kind words!

I think the answer you need is to start with NMAP.  But the *question* before the answer is, “Mr. or Mrs. Customer, do you mind me port-scanning machines in your infrastructure?”  Without approval in writing, scanning someone’s machines or subnets can get you in hot water — even legal trouble — if you aren’t careful.

Of course, first you need to be sure you’re scanning for Linux machines.  You can limit your scan to a simple set of addresses, if they know which addresses they would like scanned. If they don’t know, then you might have to do subnet scans, so make sure you get a complete list of subnets.  Here’s an example of using nmap to quickly determine which addresses in a single subnet are worthy of scanning:

nmap -F 192.168.1.0/24

Note: If you don’t like waiting for the command to return results, press the a key (such as space bar) to show real-time results while waiting.

Then, you can limit the search down to a more refined list.  And whether you started with a specific list of addresses or a subnet list, you can scan and learn roughly what they are via the OS signature best-guess with nmap.  While you cannot completely trust the certainty of the nmap OS fingerprint, it’s certainly good enough to let you know if the machines are truly Linux.  Of course, they may be port-blocked too, or behind other firewalls, so you can’t necessarily trust that your results will be all-inclusive; but you can reasonably trust the positives that you get.  From our above example, image we got four positive responses, so now we probe them further in this example:

nmap -O --osscan-guess 192.168.1.2,4,9,13,14

By the way, there’s a great nmap tutorial with other quick tips here.

Imagine that two of those four turned out to be Linux in the field “Aggressive OS guesses“, “OS CPE“, or “OS Details“.  Next, you can filter your list down to only the Linux systems, and you can run a loop to ssh and get the values of either a.) the contents of the modern distribution identifier file (/etc/issue or /etc/os-release for newer distros), or b.) whether or not an older-style distribution-specific identifier file exists and what’s in it (for example, /etc/SuSE-release).

Of course, in order to do that loop ssh, you will need to know the credential to use to access the system. It matters whether they have key-based ssh or password-based, so you’ve have to adjust your scripting for that.  But to give you the main idea, I whipped up this script that uses a all-systems user ID called “linuxadmin”, but you’ll have to type the password for each system unless the ssh keys are already set up.  For example:

#!/bin/bash
# Enter your refined list of Linux machines to check, separated by spaces
HOSTLIST="192.168.1.2 192.168.1.13"
# Enter the username of your LInux management user ID
USERID="linuxadmin"
# Declre the output file
OUTPUTFILE="/tmp/outputfile.txt"
echo "LINUX MACHINE LOCAL RELEASE FILE RESULTS">$OUTPUTFILE
echo "----------------------------------------">>$OUTPUTFILE
for HOST in $HOSTLIST
do
  # Try on port custom port
  RESULT=`ssh $USERID@$HOST -p 2222 "grep PRETTY_NAME /etc/os-release || grep SUSE /etc/SuSE-release"`
  if [ "XX$RESULT" = "XX" ]; then
    # If no result, try on regular old port
    RESULT=`ssh $USERID@$HOST "grep PRETTY_NAME /etc/os-release || grep SUSE /etc/SuSE-release"`
  fi
  # Finally, we write the results to the file
  echo "For $HOST: $RESULT">>$OUTPUTFILE
done
echo ""
echo "Displaying contents of the output file at $OUTPUTFILE:"
echo ""
cat $OUTPUTFILE

That should do it!  This scrpt could certainly be improved, but I’d have to know more about the situation once you do some discovery.

Good luck out there!

Leave a Comment

Your email address will not be published. Required fields are marked *