Monitoring servers remotely with Nmap and Ndiff
By using tools from the Nmap project, we can set up a simple but effective monitoring system. Because our monitoring system will depend on Nmap, we can monitor not only open ports but any information the Nmap Scripting Engine can gather. To detect changes on the network, we will need to compare the results of two scans: the base or known good state and the current scan result. Consider the ports that you know that must be open as your base state.
Ndiff was designed to address the issues of using the traditional diff
command with two Nmap scan results in XML format. It compares the files by removing false positives introduced by dynamic fields such as timestamps and producing a more human-friendly output.
This recipe describes how to use Bash scripting, cron, Nmap, and Ndiff to set up a monitoring system that alerts by email if changes are detected in a network or host.
Getting ready
In this recipe, we assume the system has been configured to send email via the mail
command. If you would like to change the notification method, you simply need to update the Bash script and replace the mail
command according to your preferred notification method. For example, you could use curl
to make an HTTP request to your favorite social network or run a script that restarts the service.
How to do it...
To set up a simple monitoring system with Nmap, we are going to need to do a few things:
- Create the
/usr/local/share/nmap-mon/
directory (or whatever location you prefer) to store all the files required for our monitoring system. - Scan your targets and save the result in XML format in the directory that you just created:
# nmap -oX base_results.xml -sV -n <target>
The resulting
base_results.xml
file will be used as your base file, meaning that it should reflect the known good state of your network or host. - Create the
nmap-mon.sh
file in the directory you created earlier and paste the following code:#!/bin/bash #Bash script to email admin when changes are detected in a network using Nmap and Ndiff. # #Don't forget to adjust the CONFIGURATION variables. #Paulino Calderon <calderon@websec.mx> # #CONFIGURATION # NETWORK="YOURTARGET" ADMIN=YOUR@EMAIL.COM NMAP_FLAGS="-n -sV" BASE_PATH=/usr/local/share/nmap-mon/ BIN_PATH=/usr/local/bin/ BASE_FILE=base.xml NDIFF_FILE=ndiff.log NEW_RESULTS_FILE=newscanresults.xml BASE_RESULTS="$BASE_PATH$BASE_FILE" NEW_RESULTS="$BASE_PATH$NEW_RESULTS_FILE" NDIFF_RESULTS="$BASE_PATH$NDIFF_FILE" if [ -f $BASE_RESULTS ] then echo "Checking host $NETWORK" ${BIN_PATH}nmap -oX $NEW_RESULTS $NMAP_FLAGS $NETWORK ${BIN_PATH}ndiff $BASE_RESULTS $NEW_RESULTS > $NDIFF_RESULTS if [ $(cat $NDIFF_RESULTS | wc -l) -gt 0 ] then echo "Network changes detected in $NETWORK" cat $NDIFF_RESULTS echo "Alerting admin $ADMIN" mail -s "Network changes detected in $NETWORK" $ADMIN < $NDIFF_RESULTS fi fi
- Update the configuration values in the previous Bash script according to your system and needs:
NETWORK="YOURTARGET" ADMIN=YOUR@EMAIL.COM NMAP_FLAGS="-sV -n -p-" BASE_PATH=/usr/local/share/nmap-mon/ BIN_PATH=/usr/local/bin/ BASE_FILE=base.xml NDIFF_FILE=ndiff.log NEW_RESULTS_FILE=newscanresults.xml
- Make
nmap-mon.sh
executable by entering the following command:# chmod +x /usr/local/share/nmap-mon/nmap-mon.sh
- Now run the
nmap-mon.sh
script to make sure it is working correctly:# /usr/local/share/nmap-mon/nmap-mon.sh
- Launch your crontab editor to automatically execute the script periodically:
# crontab -e
- Add the following command:
0 * * * * /usr/local/share/nmap-mon/nmap-mon.sh
You should now receive email alerts when Ndiff detects a change in your network.
How it works...
Ndiff is a tool for comparing two Nmap scans. Think about the traditional diff
but for Nmap scan reports. With some help from Bash and cron, we set up a task that is executed at regular intervals to scan our network and compare our current state with an older state, to identify the differences between them. We used some basic Bash scripting to execute our monitoring scan and then executed Ndiff to compare the results:
if [ $(cat $NDIFF_RESULTS | wc -l) -gt 0 ] then echo "Network changes detected in $NETWORK" cat $NDIFF_RESULTS echo "Alerting admin $ADMIN" mail -s "Network changes detected in $NETWORK" $ADMIN < $NDIFF_RESULTS fi
There's more...
You can adjust the interval between scans by modifying the cron line:
0 * * * * /usr/local/share/nmap-mon/nmap-mon.sh
To update your base file, you simply need to overwrite your base file located at /usr/local/share/nmap-mon/
. Remember that when we change the scan parameters to create our base file, we need to update them in nmap-mon.sh
too.
Monitoring specific services
To monitor specific services, you need to update the scan parameters in nmap-mon.sh
:
NMAP_FLAGS="-sV -Pn"
For example, if you would like to monitor a web server, you may use the following command:
NMAP_FLAGS="-sV --script http-google-safe -Pn -p80,443"
These options limit port scanning to ports 80
and 443
; run the http-google-safe
script to check whether your web server has been marked as malicious by the Google Safe Browsing service.