You are on page 1of 12
Using Azure Functions to automate Just-in-time Access Rick en (Fallow ] Mr. Brown Ave (F888), Tatung County, Talwan (2020-01-01) What is the problem we are trying to solve? In Azure Security Center, you can lock down inbound traffic to your VMs with just-in-time (JIT) virtual machine (VM) access. This reduces exposure to attacks while providing easy access to connect to VMs when needed. My customer recently implemented JIT for their Azure VMs (1500+) and raised the question of how to automate the JIT Access requests to VMs since there are so many maintenance tasks such as: + Invoke backup jobs on application VMs * Apply license/maintenance updates for virtual appliances Those tasks require opening specific ports to allow traffic from specific IP addresses. Security Admins can manually approve the requests in Azure portal but it’s not practical since those maintenance tasks themselves are triggered by automation. Let’s see how we can automate the process with Azure Function App with a user-assigned identity. By the end of this article, we will learn 3 things: 1. What is Just-In-Time (JIT) Access and how to request for access. 2. How to create a custom Azure AD RBAC role with just enough permissions to initiate JIT access. igned managed 3. How to deploy a PowerShell Function App with user-a identity to initiate opening JIT Access. How does JIT access work? When JIT is enabled, Security Center locks down inbound traffic to your Azure VMS by creating an NSG rule, You select the ports on the VM to which inbound traffic will be locked down. These ports are controlled by the just-in-time solution. When a user requests access to a VM, Security Center checks that the user has Role-Based Access Control (RBAC) permissions for that VM. If the request is approved, Security Center automatically configures the Network Security Groups (NSGs) and Azure Firewall to allow inbound traffic to the selected ports and requested source IP addresses or ranges, for the amount of time that was specified, After the time has expired, Security Center restores the NSGs to their previous states. Those connections that are already established are not being interrupted, however. Let's put the pieces together Funetion App initiating IT Access The key component in the diagram above is the PowerShell Function App. It can be either HTTP-Triggered or Timer-Triggered to open up JIT access to ‘VMs. The Function App has a user-assigned managed identity. Create the Function App Follow the instructions to create an HTTP-triggered Function App (with Runtime stack: PowerShell Core). If you need pre-warmed instances to avoid cold start, try Premium/Dedicated Plan instead of the default choice of Consumption Plan. Let's enable your Function app with user-assigned managed identity by following the instructions. Take a note of the Client ID and Object ID of the managed identity, we will need those later: ee What does the PowerShell Function do? ‘Your Function App should be deployed already, let’s use this run.ps1 from my GitHub repo as a reference. You can simply copy & paste into the editor in Azure portal and update the variables section based on your environment. It basically does 2 things: 1. Obtain the Access Token from Azure Active Directory (you will know why in the next section). 2. Present the Access Token as the Bearer token while making our HTTP POST call to Security Center's REST API endpoint. The JIT Access is submitted as JSON body. Obtain the Access Token (make sure to include cctient_id=suamrciientrd): SresourceiR = “nttps:/Jmanagenent. azure. con/” StokenduthURE = Senv:ZDENTETY ENDPOINT + “resourcesSresoUrceURTAcLient_Sé-SUMMECLLentTdbaps-vers StokenResponse ~ Trvoke-Restethod -Rethod Get Headers @X-IOENTTTY-HERDER*="Benvs IDENTITY HERD CObtainToken pst hosted wit © by Gib view ra Obtain Access Token Invoke HTTP POST to Security Center REST API: SottAecesstpiUrk = "https://nanagenent.azure.con/subseriptions/Ssubscrigtontd/resoureesrovpe/$3 Sheaders.Aaa(Authorization","$(StokerResponse. coke type) "+" * + “s(Stokentesponse access 204 3500 maquest Body Sooay2zrRequest = 8 vireuaimachines = 8¢ turatson-s2TTAccessDuratson Voweesoureokadressine’ix-SatloueeSourcenadressiretix » » Justification « "Open part 22 for Aoigee maintenance requested by SUAMCLLentTd = ouration $ | ConvertTo-ason -Depen 6 Srosp = Invoke-Rorthothod -Wethod Post -Unt $01TAccessAoilet -eacers. Sender ody $hody Tog Invokes haste wits © by Gia ew ra HTTP Post Security Team: "Wait! This function will open up port 22? Really?!” In order for our Function app to initiate JIT access, we need to create a custom RBAC role with just enough permissions and proper scopes to JIT policies as well as to the target VM . See the following PowerShell exampl 48) et vietual Machine Contributor Role Definition Srole = ot-Askolebefsnision “Virtual Machine Contributor” Srote td = Sunt Sroteane « "Dust In Tine WE aezess User” Srole.descrigtion = ‘Users that can enable access to Azure Virtual Machines.” Srole.Actions.Clesr() ‘role. Actions.Add(“hlcrosoft, SecurSty/locations/JithetworthccessPolictes/inttiate/action*) Srole.Actions.Add(“hlcrosoft.Secunity/locationsjitNetwortaccessPolicles/*/read") Srole.Actions.Add("wicrosot*.Carpute/virtualmachines/read”) Srole. Actions Add("Mlerosof* Network/networstntenfaces/*/read") Srote.sssignabiescopes.Clear() ‘role. AssgnableScopes.Add("/subscriptons/7#2ccSe6-2f4a-4496-25ct-6ce14749f86/resourceroups/2 ‘role. AssgnableScopes.Ada(/subscriptions/7F2¢cSe6-2649-4486-05c4-sce1472986/resourceCroups/3 eweastolee¢anition Role $role Customolepst hosted with © by Gib view rm And then assign this custom role to the user assigned managed identity’s object ID (locate it in the Azure portal) you created earlier. 1 User Assigned Managed Identity Le considered an SP owssotolensstgonens -ObgectId det4n758-2661-412¢-RP92-55836107/9ee -RoleefAntttomtane “Tost In ns -Objocttd desy754-2608-412¢-8852-38836107 90 -RolebefinitiorNane “ust In AssgnRol pst hosted wth © by Gis ew ra That's it! Once the Function app is triggered (either by HTTP or by a timer), the NSG inbound rule will be added to allow port 22 access from that specific IP address for 5 minutes (up to 24 hrs). Test it with Postman API, let’s use Since we are invoking HTTP PO: Postman for a quick test: (0 the Security Center RE Conclusion This is a generic solution to automate JIT Access using Function App. You can simply change the ports and IP ranges in the function based on your requirement. If PowerShell is not your choice of language, you can easily implement the same REST calls in other languages such as Python, Have fun with Azure © and Go Serverless!! ‘Azure AzureFunetions Azure Active Directory Powershell Securty

You might also like