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.
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/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,
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!