Harden Your Azure Infrastructure Using Azure Security Center Just-In-Time VM Access
Editor's note: The following post was written by Azure MVP Thomas Janetscheck as part of our Technical Tuesday series.
Azure Security Center is the central security management solution within the Azure landscape. It helps you to prevent, detect and respond to security breaches. There’s also one new little feature that helps to prevent security breaches: Just-in-Time Access for Azure VMs. In fact by using it, I dramatically reduced the attack surface to my Azure environment.
Azure IaaS architectural overview
Lots of Azure environments I have seen so far have one or more RDP jump hosts up and running in an Azure VNet - be it to enable remote access for support partners, or as a fall back level for management access in case the VPN connection is faulty. Those servers should be protected using Network Security Groups (NSG) so access is restricted to only a few IP addresses. NSGs are a set of firewall rules that restrict or allow access to Azure network endpoints, such as VM NICs by opening or closing ports or port ranges for any source IP or a defined set of IP addresses or IP address ranges. It’s sad to say that the restriction to only one or some IP addresses is not always implemented. Nevertheless, a typical Azure IaaS environment looks like this:
Azure VMs that are created within the portal always get an external IP address by default unless you opt out from doing so. Default configuration also creates a new NSG with one active inbound rule: RDP access for Windows VMs, SSH connectivity for Linux VMs.
So, by default, any VM you create in Azure portal could potentially be accessed via RDP or SSH – from anywhere at anytime. There might be good reasons to accept this default config, but keep in mind that you have some tasks to complete after deployment has finished in order to harden your cloud infrastructure.
Just-in-Time Access (JIT)
Just-in-Time Access is a new feature currently in preview that enables customers to lock down their Azure VMs in order to reduce attack surface and exposure while keeping the ability to remotely access VMs when needed. JIT is available in the Standard tier of Azure Security Center and only supports VMs that have been deployed through Azure Resource Manager. Technically seen, JIT adds some inbound deny rules to a VM`s NSG so access to the configured ports is blocked. When access is requested a new allow rule with a lower priority is added to the NSG, so access is granted for a given time and a given source IP (or pre-defined IP range).
The allow rule is automatically deleted after the requested time range has passed so the deny rule is activated again. JIT is configured per VM in the Advanced Cloud Defense section of Azure Security Center. In an overview dashboard you see all VMs for which JIT is activated and when they have been last accessed, those VMs that still have to be configured, and VMs which have not been deployed through ARM or which don’t have a NSG activated.
In order to enable JIT for an additional VM move to the Recommended tab, select the respective VM, and push Enable JIT on 1 VMs. JIT rules for SSH, RDP, WinRM and PowerShell remoting are recommended and thus added to the configuration by default, but you can add custom rules or delete the default port policies as well.
In this step you define a maximum scope of what you allow per port. The time range you define in the port policy is the maximum allowed time range for accessing that respective port on the given VM. While requesting access your users can chose a lower time range as well but they cannot extend what is defined in the port policy. The same is true for allowed source IPs: If you allow source IPs per request your users are free to request access for only the IP address they currently want to access the VM from or to specify an IP range. If you define an IP range already in the port policy your users are not allowed to access that port from an IP address which is not pre-defined.
How to access VMs with JIT enabled?
Just-in-Time VM Access can be requested using the Azure Portal or by PowerShell based on Role Based Access Control (RBAC) permissions. On the Configured tab you select the VM you want to access and click to Request access.
Then you select the ports and time range. And you’re done.
Now, think of the following scenario: You have an Azure infrastructure similar to the draft above, and a service provider that is responsible for managing your infrastructure wants to access one of the remote access jump hosts. With JIT enabled, logging in into the Azure portal and requesting access to the VM first is something that seems pretty inconvenient to me. That’s why I use PowerShell to request access to my and my customers’ VMs in Azure:
### Request ASCJIT Access to RDP (Port 3389) for any VM in any eligible ARM subscription ### Login to your Azure AD Ressource Manager Account Login-AzureRmAccount ### In case you have several subscriptions select the proper one Select-AzureRmSubscription (Get-AzureRMSubscription | Out-GridView -Title "Select your Azure Subscription" -PassThru) ### Select the Azure Resource Group and VM $ResourceGroupName = (Get-AzureRmResourceGroup | Out-GridView -Title "Select your Resource Group" -PassThru).ResourceGroupName $VMName = (Get-AzureRmVM -ResourceGroupName $ResourceGroupName | Out-GridView -Title "Select your Virtual Machine" -PassThru).Name ### Enter a time range greater than 6 minutes and request RDP access to the given VM $minutes = Read-Host "Enter the time range to open port 3389 on VM $VMName [minutes]" $ip = Invoke-RestMethod http://ipinfo.io/json | Select -exp ip Invoke-ASCJITAccess -ResourceGroupName $ResourceGroupName -VM $VMName -Port 3389 -Minutes $minutes -AddressPrefix $ip
Having access to several of my own and customer subscriptions, I use Out-GridView in my scripts so I can easily select the right Azure Subscription, Resource Group, and VM. You find the latest version of this script in my Github repository.
Does JIT really make my environment more secure?
As you can see below, my small Azure environment has produced more than 1 million security events within one week with 8 security alerts due to RDP Brute Force Attacks. There is only one resource that’s been attacked which is the only VM I have not activated JIT for.
Digging a bit deeper, you’ll see what usernames have been used to attack my environment or what IP addresses the attacks came from. It’s no surprise that ADMINISTRATOR and ADMIN are the two most used usernames here.
By using Just-in-Time VM Access (JIT), I could dramatically reduce the attack surface to my Azure environment and this is what I recommend my customers to do as well. As I mentioned at the beginning, Network Security Groups (NSG) are a good way to start. Only open the ports that are needed and restrict access to only few IP addresses or ranges. With that configuration you will automatically increase security. But restricting access to only some IP addresses still means that everybody communicating externally from these addresses automatically might get access to resources behind the NSG. With RBAC and JIT you can further restrict access to only a few users that are allowed to request JIT. For security and compliance, I recommend you to give it a try.
Thomas Janetscheck is a Microsoft MVP for Azure and a Cloud Solutions Architect, focused on Azure Security and hybrid infrastructure solutions with Microsoft Azure and on-premises IT environments. He lives in Germany, where he serves his customers in Benelux and the DACH countries. Thomas is one of the Azure Saturday initiators and organizers, as well as leader of two meetups that focus on Azure and Office 365. Thomas loves to share his 15-year working experience in blog posts on https://blog.azureandbeyond.com, in trainings and workshops and as a speaker at meetups and conferences. Follow him on Twitter @azureandbeyond.