How to Enable and Configure Azure JIT for VMs
Tags: azure, virtualmachines, azurejit
Published: 2021-01-15 20:10:48

> _This article was written by Jeff Christman. He is a frequent contributor to the Adam the Automator (ATA) blog. If you'd like to read more from this author, check out his [ATA author page](http://adamtheautomator.com/author/jeff). Be sure to also check out [more how-to posts on cloud computing, system administration, IT, and DevOps on adamtheautomator.com](https://adamtheautomator.com)!_

<!-- wp:paragraph -->
<p>Hackers are continually scanning and actively hunting for accessible virtual machines with open management ports. If you're VMs are in Azure though, you have a tool at your disposal called <a href="https://docs.microsoft.com/en-us/azure/security-center/security-center-just-in-time?tabs=jit-config-asc%2Cjit-request-asc">Azure Just-in-Time Access (JIT)</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Azure JIT is a service that allows you to open network ports "just in time" or only when you need them open and no longer. Part of the <a href="https://azure.microsoft.com/en-us/services/security-center/#features">Azure Security Center</a> suite of products, Azure JIT is a component inside of the broader <a href="https://azure.microsoft.com/en-us/services/azure-defender/">Azure Defender brand</a>. With Azure Defender and JIT, you can control who has access to network ports on any of your Azure virtual machines.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In this article, you learn what Azure Just-In-Time access is, how to enable it, configure options and policies, and how to request access. We will also walk through different ways to allow JIT access using the Azure portal, PowerShell, and the <a href="https://docs.microsoft.com/en-us/rest/api/securitycenter/">Azure Security Center API.</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Once enabled, you'll then learn how request access to VMs and also how to audit Azure JIT activity.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="h-prerequisites">Prerequisites</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This will be a hands-on tutorial blog post. If you would like to follow along, be sure to have the following prerequisites in place before starting this article. You'll need:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>An <a href="https://azure.microsoft.com/en-us/free/">Azure Subscription</a></li><li>Logged into the <a href="https://portal.azure.com/">Azure Portal</a> with an Azure account with the <em>Subscription Owner</em> role. For more detail, check out the <a href="https://docs.microsoft.com/en-us/azure/security-center/security-center-permissions"><em>Permissions in Azure Security Center documentation</em></a>.</li><li>A <em>Standard</em> Azure Defender plan. You can sign up while logged into the Azure Portal via <a href="https://portal.azure.com/#blade/Microsoft_Azure_Security/SecurityMenuBlade/18">Azure Security Center</a>.</li><li><a href="https://shell.azure.com">Azure Cloud Shell</a> or PowerShell. Be sure you log in once to create the storage account it needs at least once. Later on in the article, you'll learn how to enable Azure JIT using PowerShell. Azure Cloud Shell is the easiest way to do that unless you'd like to use the <a href="https://adamtheautomator.com/connect-azaccount-powershell/">Azure PowerShell module</a> installed on your local computer.</li><li>The Azure Defender service enabled. Part of Azure Security Center, you'll need to first <a href="https://portal.azure.com/#blade/Microsoft_Azure_Security/SecurityMenuBlade/18">enable it</a> on your subscription.</li></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><em>If you'd like to manage on-prem Windows or Linux servers, be sure to install the <a href="https://docs.microsoft.com/en-us/azure/security-center/defender-for-servers-introduction">Azure Defender for Servers</a> software.</em></p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="h-azure-jit-pricing">Azure JIT Pricing</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Before you get too far, know that Azure JIT is not free. There are various Azure JIT pricing levels you need to know before diving in headfirst.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>You can find all of the pricing options available on the <a href="https://portal.azure.com/#blade/Microsoft_Azure_Security/SecurityMenuBlade/18">Azure Security Center blade in the Azure portal</a>. Since Azure JIT is part of Azure Defender (which is part of Azure Security Center), the pricing you're looking for is for Azure Defender.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Once you've enabled Azure Defender, you'll notice a <strong>Pricing and Settings</strong> option on the left-hand side of the page as shown below in the Azure portal.</p>
<!-- /wp:paragraph -->

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8qprny8t5ibpk22zhpna.jpg)

<!-- wp:paragraph -->
<p>Azure Defender is free for the first 30 days and anything beyond the initial 30 days will be charged as per the pricing chart below. The chart below shows the per month pricing for the various services available that can utilize Azure Defender. Generally speaking, you can expect a cost of about $15.00 per month for your virtual machines the use Azure Defender and Just-In-Time service.</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p><em>All prices are valid as of 10/06/20. You can find the latest prices on the <a href="https://azure.microsoft.com/en-au/pricing/details/security-center/">Azure Security Center pricing page</a>.</em></p></blockquote>
<!-- /wp:quote -->

<!-- wp:heading -->
<h2 id="h-azure-defender-pricing">Azure Defender Pricing</h2>
<!-- /wp:heading -->

<!-- wp:table {"className":"is-style-stripes"} -->
<figure class="wp-block-table is-style-stripes"><table><tbody><tr><td>Resource</td><td>Price</td></tr><tr><td>Azure Defender for Servers</td><td>$14.60/Server/Month</td></tr><tr><td>Azure Defender for App Service</td><td>$14.60/App Service/Month</td></tr><tr><td>Azure Defender for SQL</td><td>$15/Server/Month</td></tr><tr><td>Azure Defender for MySQL</td><td>Free</td></tr><tr><td>Azure Defender for PostgreSQL</td><td>Free</td></tr><tr><td>Azure Defender for Storage</td><td>$0.02/10K Transcations</td></tr><tr><td>Azure Defender for IoT - By Device</td><td>$0.001/month</td></tr><tr><td>Azure Defender for IoT - By Messages</td><td>$0.20/25K Transactions</td></tr><tr><td>Azure Defender for Kubernetes</td><td>$0.00268/vCore/hour</td></tr><tr><td>Azure Defender for ACR</td><td>$0.29/image</td></tr><tr><td>Azure Defender for Key Vault</td><td>$0.01/10K Transactions</td></tr></tbody></table><figcaption>Azure Defender Pricing</figcaption></figure>
<!-- /wp:table -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="h-enabling-azure-jit-on-azure-vms">Enabling Azure JIT on Azure VMs</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The first task you'll need to accomplish is enabling the Azure JIT feature on each of your VMs. This can be done through the <a href="https://portal.azure.com/#blade/Microsoft_Azure_Security/SecurityMenuBlade/18">Azure Security Center in the Azure portal</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For a simple demonstration, this section will show you how to enable JIT on a single VM.</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p><em>If you have hundreds of VMs, don't worry. You'll learn how to enable JIT in bulk with PowerShell a little later.</em></p></blockquote>
<!-- /wp:quote -->

<!-- wp:list {"ordered":true} -->
<ol><li>Once at the Azure Security Center page, click on Azure Defender on the left side of the page. You should then see a Just-in-time VM access title as shown below.</li></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gnjv7va27ep6qvywp31k.jpg)

<!-- wp:paragraph -->
<p>2. Next, click on the Just-in-time VM access tile. This will open the JIT settings blade. Once open, the blade will show three tabs: Configured, Not Configured, and Unsupported. These tabs represent the various state of Azure JIT against each VM in your subscription.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>3. If this is your first time enabling Azure JIT, all of your VMs will be under the Not Configured tab as shown below. To enable JIT on the VM, click on the VM and then click on the Enable JIT on 1 VM button.</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p><em>Note that the <strong>Resource Group</strong> and <strong>Subscription Name</strong> will be unique to your environment.</em></p></blockquote>
<!-- /wp:quote -->

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vtaldn7syojcalx86x2o.jpg)

<!-- wp:paragraph -->
<p>4. Once you click on the Enable JIT button, you'll then see a JIT VM access configuration page. This page allows you to view all of the default ports and also add any existing ports you'd like to actively manage.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>To add a new port, click on <strong>Add</strong> and provide the <strong>Port</strong>, <strong>Protocol</strong>, <strong>Allowed source IPs,</strong> and <strong>IP addresses</strong> fields as required. When complete, click on <strong>OK</strong>.</p>
<!-- /wp:paragraph -->

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lesky0xc8zf8l2knq789.jpg)

<!-- wp:paragraph -->
<p>When complete, you'll then have ensured the ports under management are only open for a specific amount of time (<strong>Max request time</strong>).</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Once you set an access policy, when a user requests access (shown how below), a firewall rule is created with the settings set in the policy. After the <strong>Max request time</strong> has been exceeded, Azure will remove the firewall rule that opened the port, to begin with.</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p><em>Know that </em><a href="https://azure.microsoft.com/en-us/services/azure-bastion/#:~:text=Azure%20Bastion%20is%20a%20new,the%20Azure%20portal%20over%20SSL." target="_blank" rel="noreferrer noopener">Azure Bastion</a><em> and JIT access cannot be used together. If you enable Azure Bastion with an existing JIT access policy enabled on a VM, the bastion host will not connect to the target machine and you will get a connection error!</em></p></blockquote>
<!-- /wp:quote -->

<!-- wp:heading -->
<h2 id="h-requesting-access-to-a-virtual-machine">Requesting Access to a Virtual Machine</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Now that you've enabled JIT on a VM, how do you (or your users) get access to that VM through one of the managed ports?</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>While logged into the Azure portal, navigate to <a href="https://portal.azure.com/#blade/HubsExtension/BrowseResourceBlade/resourceType/Microsoft.Compute%2FVirtualMachines">the VM</a> you'd like to access and select <strong>Connect</strong>.</li><li>Now, select the protocol you'd like to use and change the <strong>Port number</strong> or desired <strong>Source IP</strong>, if required. Typically, when you attempt to connect to a VM, you'll immediately be able to download an RDP file or see SSH methods, for example. When a JIT access policy is applied to a VM, you'll see options like in the below screenshot. </li></ol>
<!-- /wp:list -->

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/sgcifhk2syt7rteqqwgv.jpg)

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p><em>Know that requesting access to VMs only&nbsp;opens the requested port. Just like logging into a virtual machine using RDP, you will need a valid Active Directory account with the appropriate permissions to log in to the virtual machine.</em></p></blockquote>
<!-- /wp:quote -->

<!-- wp:heading {"level":3} -->
<h3 id="h-automating-azure-jit-using-powershell">Automating Azure JIT using PowerShell</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>So let's say you've got hundreds of VMs that you need to control management ports on. Maybe you've got a request from management to get all of VM management ports locked own ASAP. You're not going to want to go through the steps you just took to enable an access policy on a single VM. Let's automate this.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Instead of logging into the Azure Security Center each time and enabling a JIT access policy for each VM, you can write a script using PowerShell. Once you've built the script, you can then incorporate it into a CI/CD pipeline too.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Below you'll find a copy/pastable code snippet for you to get started. This code creates and applies a JIT access policy to the <em>VMName</em> VM that limits Port 22 (SSH) and RDP (3389), all protocols, from all source IPs for a maximum of three hours.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code lang="powershell" class="language-powershell">## Build the policy with the VM's resource ID
$JitPolicy = (@{ id="/subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUP/providers/Microsoft.Compute/virtualMachines/VMNAME"
ports=(@{
     number=22; ## SSH
     protocol="*"; ## all protocols
     allowedSourceAddressPrefix=@("*"); ## any source IP
     maxRequestAccessDuration="PT3H"}, ## up to three hours
     @{
     number=3389;
     protocol="*";
     allowedSourceAddressPrefix=@("*");
     maxRequestAccessDuration="PT3H"})})
$JitPolicyArr=@($JitPolicy)

## Send the policy to Azure and commit it to the VM
Set-AzJitNetworkAccessPolicy -Kind "Basic" -Location "LOCATION" -Name VMNAME -ResourceGroupName "RESOURCEGROUP" -VirtualMachine $JitPolicyArr</code></pre>
<!-- /wp:code -->

<!-- wp:heading -->
<h2 id="h-auditing-jit-access-activity">Auditing JIT Access Activity</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>So you've set up JIT access to a bunch of VMs but is it being used? If so, how often? You need to audit the access policy activity. Auditing can be done via each VM's activity log.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>When someone requests access to a management port and Azure creates an access policy, JIT logs this activity in the activity log. The activity log contains information such as when the request was made, who made the request, if it was successful, and so on.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>To view the activity log, navigate to the JIT VM Access blade in the Azure Portal, click on the three ellipses on the far right of the selected virtual machine, and select <strong>Activity Log</strong>.</p>
<!-- /wp:paragraph -->

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xblvq2uc4x9cjry57w02.jpg)

<!-- wp:paragraph -->
<p>As you can see below, the activity log tracks when an access polity has been applied to a virtual machine, who requested access, and when access was granted or denied.</p>
<!-- /wp:paragraph -->

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4frhqe708l1khgmh9rgl.jpg)

<!-- wp:heading -->
<h2 id="h-further-reading">Further Reading</h2>
<!-- /wp:heading -->

<!-- wp:list -->
<ul><li><a href="https://docs.microsoft.com/en-us/azure/security-center/just-in-time-explained"><strong><em>Understanding Just-In-Time VM Access</em></strong></a></li><li><a href="https://docs.microsoft.com/en-us/azure/security-center/security-center-just-in-time?tabs=jit-config-asc%2Cjit-request-asc"><strong><em>Secure your management ports with Just-In-Time access</em></strong></a></li><li><a href="https://docs.microsoft.com/en-us/learn/modules/secure-vms-with-azure-security-center/3-exercise-jit-vm-access">Microsoft Learn - Exercise - Enable JIT VM Access</a></li><li><a href="https://azure.microsoft.com/en-au/pricing/details/security-center/">Azure Just-in-Time Pricing</a></li></ul>
<!-- /wp:list -->