Hello, I haven’t posted for quite some time with work and life getting a little nuts, but I just finished a fun project that I thought I should share while still fresh. I manage about 30 branch office sites with SonicWall firewalls and we do not run GMS for a variety of reasons. As a result, attempting to standardize GEO filter exclusions has become a bit of a nightmare. Our sites are pretty much locked down to US communications only, but exceptions need to be made across all sites quite frequently. Enter SSH scripting. I’ve used batch, PowerShell, and kix scripts for years, but never really to configure equipment via SSH. This was a challenge at first. I am sure there are many different ways to tackle this, but here is the solution I came up with.
Even if you don’t run SonicWALLs, I am sure this code could be changed to accommodate a verity of switches and firewalls that support SSH.. A great guide for automating tasks. Feel free to steal my approach if it works for you. For all intents and purposes it is beta, but I have used it multiple times to push out wide scale address objects. I don’t really like that it takes so long to run against each firewall and would like to come back and streamline it some. You’ll notice many “sleep” statements I have throughout the body of the script which exist to allow the variable capture to take place. This sometimes didn’t work depending on your connection speed to the site and I wanted to give the commands plenty of time to complete before attempting to capture output.
I apologize in advance for the state of some of the pictures below, I know they turned out quite small.
First a bit about the platform I am running on
Windows 7 X64
PowerShell version 3
I am using the Posh-SSH PowerShell module that can be downloaded via Github: Click Here
This script was written with Posh-SSH version 2.0.1, but it appears they have released 2.0.2 at the time of this post.
The build of Posh-SSH I developed the script on as well as my script can be downloaded direct from my site:
Posh SSH 2.0.1: Click Here.
Script file: Click Here.
This script will likely work with updated versions of Posh, but just in case.
Another pre-requisite is that all of your SonicWALL firewalls must have SSH enabled. In my specific scenario I am contacting each firewall through a site to site VPN which required not only that SSH was enabled on the X0 (LAN) interface, but that the VPN have SSH enabled. Here are some screenshots from a firewall running SonicWALL firmware version 220.127.116.11.
1. Modify X0 interface and confirm SSH enabled
2. Modify VPN to allow SSH connections through the VPN in which you are using to connect
In the config, browse to VPN> Settings and click the “pen” icon next to the VPN you want to modify.
3. Add Posh-SSH commands to Powershell on our system
To make the Posh-SSH commands available on my system I simply copied the Posh-SSH folder (you can download from my site or the github site) to the “Documents\WindowsPowerShell\Modules\Posh-SSH” path in my local user profile. After that run a PowerShell session and issue the command “import-module Posh-SSH“. You shouldn’t receive any output, but if you issue the “get-module” command you should now see Posh-SSH listed. Now the Cmdlets used in the SSH script will execute successfully.
At this point Posh-SSH should be functional and we can begin reviewing this script. Again the script and the original version of Posh-SSH that I developed the script on can be downloaded using the links at the top of this post.
The script is commented pretty well, this first piece sets the running dir, configures logging, and indicates which firewalls we want to configure by IP. They’re all private addresses so in my case the SSH session will be hosted over site to site VPNs. This could work over the WAN as well, but this is a bit more secure.
Hard code the username used to log into each firewall. Originally I tried to get fancy here and prompt for input while the script was running, but later found that no other account aside from admin was supported with SSH. Fun. Not sure if that is a limitation of the current firmware build, but not great for auditing.
This section of the script will collect information from the admin regarding the exception in which to create. Will allow the admin to choose FQDN, Host, or Network object. It isn’t perfect, the admin needs to pay attention to the prompts and enter data as instructed. I didn’t program any validation, so a space in the wrong place may throw things off. I did however account for wildcard domains using “*” and if you follow the prompts it will take care of this nicely.
Collect a “friendly” name for the new address object and check that it doesn’t break the character limit of the SonicWALL. If it does, trim.
This section of code runs if you chose to create a Fully Qualified Domain Name address object. It basically determines if there is a wildcard involved. If so, there is a series trims and checks that run against what you’ve entered to ensure the object is created correctly. It seems the “*” is special and triggers regex unless escaped correctly. I am sure there are better ways to code this, but here it is.
More code that fires if Host or Network object was chose. Asks for necessary input from admin based on each.
Now that all of the information about the address object has been created the “foreach” loop can start. This first section is sort of awful.. The environment that I work in has a unique admin password on each firewall, but you could definitely remove the password statement here and declare it above if you’d like. This section sets the friendly name of the firewall for logging purposes.
This section of the script takes the “secure” password collected above and pulls it back to a new variable in plantext. This can later be used to login to SSH sessions. Depending on the firmware running on the SonicWALL device, I found that it would sometimes ask for a password after login and it couldn’t be the “secure” string. Fun.
This section of the script basically completes the SSH connection with data entered thus far.
Trying to complete login. This acts differently with different firmware builds, so had to get a little creative. Comments below…
Still logging in and verifying we’re seeing config prompt….
And….. Still logging in and verifying config prompt. Would have been super sweet if SonicWALL standardized these SSH prompts across firmware. |:-)
We’re done logging in! Write the model and firmware version info to logs.
One note I will make on this first line is that I had TZ205’s in my environment which do not have the GEO IP filter feature at all. You’ll notice that have an exception if a 205 is seen based on model information collected earlier. If you have other devices in your environment that run 5.9 firmware, but don’t have the feature, you may want to add them as exceptions too.. Otherwise the following script block is just going to throw a lot of errors. Option two is to simply not include those IPs in the list at the top.
Otherwise the rest of the script is basically running all of the commands needed from the SonicWALL config prompt to create the object. I’ve used it numerous times in my environment and it sure beats logging into each device. Helps to standardize too. I plan to write more scripts to remove objects and perhaps to even create and modify VPNs.
Duplicate entry check built in.
Check to see if the firewall is running firmware build 18.104.22.168. If so, they changed the default Geo exception group.
the Else statement for unsupported firmware and closing the SSH session