This particular challenge was to:
- Write a script using any language that takes an IP address and list of ports from standard input
- Check to see if the ports are open
- If not, send a command via SSH to the server at the IP address to start the service that makes the port open
- Output the results to a log file
- For extra credit let the script run against a server brought up by a vagrantfile
I extended the requirements in three ways:
- Add a “Usage” section to the script which is displayed if arguments are missing or are “/?”, “/h” or “-h” for example.
- Add the ability to close as well as open the ports. This is to readily support testing if not for completeness sake.
- Build a test script that verifies that the solution meets the requirements.
Also in the interest of user friendliness, I followed these principles:
- Just before running a command that could take time depending on the speed of software, networks or servers, echo to the terminal a line explaining what operation is in the works.
- In the log file be more terse and to the point unless there was an error. In that case try to bring in information that can help lead to a solution such as the command being run, its standard output and error output. Try this out by deliberately messing with the name of the Linux command or service embedded in the script. Where there is no error, check out the sample logs generated by running the test script in the link below.
This challenge is a natural follow on to the previous challenge which brings up a virtual server on one’s personal computer utilizing a vagrant file. So we’ll take the extra credit by running against that. See: http://www.seaver99.com/using-vagrant-to-deploy-a-server-and-website/
Since the virtual server has a website and port 80 is where the website is accessed from the browser, testing the script could have the very tangible result of taking the website on or off line.
The scripting language I chose is DOS Batch. This is handy because I’m running Windows on my personal computer and have used DOS Batch in the past.
In order to begin, I had to find a utility to check the status of ports and ended up downloading and using Nmap. See https://nmap.org . With Nmap, I also discovered some additional open ports on the server which allowed me to extend testing to multiple ports. So in addition to port 80, I also support port 111 which it turns out is easy to open and close as well on the virtual server.
In order to test graceful failing where the script is not programmed to start or stop a service to open or close a port, I arbitrarily chose port 99 which was closed on the virtual server in the first place.
Google and Stack Overflow continue to be my constant consultants. I used these to determine which commands I would use on the virtual server to start and stop services and which services controlled which ports. Nmap also provides some intelligence on this as well.
Once I knew how to check a port and make it open or closed from the DOS command line I was ready to begin scripting. To review the language (and quirks) of DOS batch, I read the beginning and other portions of https://en.wikibooks.org/wiki/Windows_Batch_Scripting#Introduction .
I worked through the inevitable bugs in the development process by temporarily:
- Commenting out the initial command of @echo off
- Inserting extra ECHO commands
- Inserting TYPE commands to dump the contents of a temp or log file to the screen
Once I got the main script into satisfactory shape, I capped this project with the automated test script also in DOS batch.
See my solution at: https://github.com/bseaver/Demonstration-Projects/tree/master/mini/portsopen
… and thanks for looking!