Let’s be honest here, data security is really important to me. Some people probably think that I go to extremes to ensure that my data as well as my customers data is secured. With that, sometime ago, I wrote a blog post on utilizing a VPN server that I built on an Azure Virtual Machine to help facilitate a secure connection whenever I am away from my home network. Using a VPN server is a great way to ensure security and peace of mind.
Turns out that the server got hacked. And it was my fault.
See, if you leave certain ports open to the outside world like I did, you are just asking for hackers to attack you. And that’s exactly what happened. When I first created the virtual machine, I mistakenly left port 3389, which is used to make remote desktop protocol (RDP) connections, open and available to the world. There wasn’t any rule in place limiting those connections to a certain IP address or ranges so it was a free for all for hackers. By the way, hackers will routinely scan IP addresses looking for open ports so it was only natural that eventually one would find me.
Ironically, the hackers wanted bitcoin funds to release the virtual machine back to me. I quickly laughed at them and promptly deleted the entire machine off of Azure. Once the VM was removed, I was able to get a new virtual machine stood up, along with the VPN software re-installed, and available for connections within about 30 minutes. I did make sure to apply certain Network Security Group (NSG) rules to help prevent this from happening again.
Azure Advisor
This was a great learning lesson for me, however it got me thinking about network security in Azure and ways to prevent this. One way to do this is to utilize the Azure Advisor. The Advisor offers up security recommendations (as well as recommendations in other categories) that will help further harden your Azure foot print. These recommendations can range from NSG rules, enabling auditing, or installing endpoint protection solutions that will actively monitor for viruses and malware. Here’s an example of what a report looks like,
As you can see, you can walk through all of the recommendations and decide on whether or not to implement them. Keep in mind that some of the recommendations might incur additional costs against the respective subscriptions so make sure to evaluate them carefully.
Powershell
In conjunction with Azure Advisor, I also decided to utilize Powershell. I thought that having a script that I could easily run on an ad-hoc basis would help me to identify any open ports that I might have. Later I’ll automate this in some fashion, probably via Runbooks, but for now just having a script is handy enough for me.
The script is fairly basic in that it will loop through all of the subscriptions that are associated with your login, look for any NSG’s in which the source address is “*” (which this means basically the world) and the Access method is set to “Allow”. This, of course, is adjustable for your needs so feel free to play around with the settings. The script will also output the NSG’s which satisfy those requirements to a file and then subsequently open the file.
Let’s walk through it!!
First, I’m going to set a path to the local file in which to export the output. After that I need to authenticate to my Azure subscription. If you are already connected and authenticated in the context of Powershell, the script will check for that and skip the login process accordingly.
- $path = "c:\temp\openports.txt"
- #log into Azure Account if needed
- IF (-NOT (get-azcontext)){
- Login-AzAccount
- }
Once we are authenticated and logged in, we can then start to loop through things. First we’ll loop through every subscription and within every subscription, check every NSG for open ports. If the NSG has an open port, it will output the results into the file we specified in the step above.
- #get all of the subs
- $subs = get-azsubscription
- #loop through the subscriptions
- foreach($sub in $subs){
- set-azcontext -SubscriptionID $sub.ID
- $nsgs = Get-AzNetworkSecurityGroup
- foreach($nsg in $nsgs){
- $nsg | get-aznetworksecurityruleconfig | where-object -FilterScript {$_.sourceaddressprefix -eq "*" -and $_.Access -eq "Allow"} | out-file -FilePath $path -Append
- }
- }
At this time, the file has been populated. We can now just open the file with the Invoke-Item cmdlet which will open the text file into Notepad.
- #open the file
- invoke-item $path
Here is the entire script put together,
- #############################################################################
- # MIT License
- #
- # Copyright (c) 2017-Present John Morehouse
- #
- # Permission is hereby granted, free of charge, to any person obtaining a copy
- # of this software and associated documentation files (the "Software"), to deal
- # in the Software without restriction, including without limitation the rights
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- # copies of the Software, and to permit persons to whom the Software is
- # furnished to do so, subject to the following conditions:
- # The above copyright notice and this permission notice shall be included in all
- # copies or substantial portions of the Software.
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- # SOFTWARE.
- #############################################################################
-
- $path = "c:\temp\openports.txt"
- #log into Azure Account if needed
- IF (-NOT (get-azcontext)){
- Login-AzAccount
- }
- #get all of the subs
- $subs = get-azsubscription
- foreach($sub in $subs){
- set-azcontext -SubscriptionID $sub.ID
- $nsgs = Get-AzNetworkSecurityGroup
- foreach($nsg in $nsgs){
- $nsg | get-aznetworksecurityruleconfig | where-object -FilterScript {$_.sourceaddressprefix -eq "*" -and $_.Access -eq "Allow"} | out- file -FilePath $path -Append
- }
- }
- #open the file
- invoke-item $path
You can also find the script in Github located here.
Summary
As a data professional, security should and is always on my mind. Understanding the risks of using technology will help you find methods to prevent unauthorized access. In this case, the hacker only really caused me about 30 minutes of time to rebuild my server, however they taught me a great lesson in security. Even in your development environments, make sure to review your security rules so that this doesn’t happen to you.