I'm here to tell you there are bad actors in the world who spend their time scanning Microsoft-owned IPv4 address ranges in search of unprotected Windows Server and Linux VMs running in the Azure cloud.
Until Just in Time (JIT) VM Access came along, our safest bet to protect Remote Desktop Protocol (RDP) access to our Windows Server VMs involved one or more of the following workarounds:
- Configure RDP to listen to a non-standard port
- Implement an Azure load balancer with Network Address Translation (NAT)
- Use a jumpbox host located on the same virtual network as your VMs
Today I'd like to show you how JIT VM Access simplifies VM access security in Azure. For me, this is a "no-brainer" feature that every Azure administrator should consider making a default configuration item.
How JIT VM Access works ^
In a nutshell, JIT VM Access provides time-, user-, and location-based access to your VMs running in Azure. The requesting user must have at least write access to a VM controlled through Azure Resource Manager's Role-Based Access Control (RBAC). As long as this is the case, Azure will apply a custom network security group (NSG) to the VM that opens up your chosen management ports for inbound access from your source IP address for a configurable time period. These are typically TCP 3389 for RDP, TCP 5985-5986 for Powershell remoting, and TCP 22 for SSH.
After that time period has elapsed or you disconnect from the session, Azure resets the original NSG binding to the VM, and the management ports remain closed. It will deny access to users attempting to connect to the VM, even with administrative credentials. The following screenshot taken from my macOS administrative workstation shows this.
Before we continue, you need to be aware of two points: one, JIT VM Access is available only in the Azure Security Center Standard pricing tier. As of this writing, the cost is $10 US per VM, per month.
Two, again as of this writing, JIT VM Access is in public preview status. This means Microsoft provides no service-level agreement (SLA) for the feature until it reaches general availability (GA) status.
Enable JIT VM Access ^
Open Security Center and select the Just in time VM access setting. Under Virtual Machines, click the Recommended tab, select one or more VMs from the list, and click Enable JIT on n VMs, where n represents the number of selected VMs. Here's a screenshot to show context:
Enabling JIT involves two processes, one you control and one you don't:
- Azure installs the Microsoft Monitoring Agent if it isn't already installed
- You choose which protocols and ports will be available (shown in the next screen capture)
Select any row in the JIT VM access configuration blade to customize:
- Which port(s) to include
- Which protocols (TCP, UDP, or both)
- Allowed source IP address type (defaults to "by request")
- Allowed IPv4 source address range
- Maximum request time (default is 3 hours)
To change the JIT VM Access rules after you've set up a VM, simply navigate to the Configured tab in the Just in time VM access settings blade, open the "…" menu, and choose Edit.
Request VM access ^
Now let's turn our attention to the VM request workflow. Eventually we should have the controls within each VM's settings menu, but for now we have to reopen Security Center and navigate to Just in time VM access > Virtual machines > Configured, select the VM, and click Request access.
In the Request access blade, toggle your desired management port(s) from Off to On, adjust the allowed source IP (the default is your own public IPv4 address) and time range, and click Open ports. I show you a composite screenshot next.
Give Azure a minute or so to implement the JIT policy, and then attempt a management connection to your VM. As you can see in the next screenshot from my iMac, it's working for me.
Successful RDP connection (macOS perspective)
Audit JIT VM Access ^
On the Security Center – Just in time VM access blade, open the "…" menu for a configured VM and select Activity Log from the shortcut menu. This action opens the Azure activity log, which displays audit trail ("who did what, when") data.
Take a look at the following screenshot. In it you can see a JIT network access request I made for my Windows Server 2016 VM named mem.
What do you think of JIT VM Access? As I stated earlier, I recommend that all my consulting clients enable this feature for their infrastructure-as-a-service (IaaS) VMs as standard practice.
By definition, your VMs running in Azure are internet exposed unless you use ExpressRoute. Therefore, the more you reduce those VMs' attack surface, the safer your line-of-business data is in the Azure cloud.