Make Azure Functions not publicly accessible? - azure

Currently my functions are accessible publicly. Is there a way to make it so that they can only be accessed via something else, like an API gateway, and not directly? I tried adding a VNET via the "networking" blade but I don't think that did anything (I could still call the functions publicly)...I think that just makes it so the functions could access resources on a private network. I didn't see any options in the settings to make the IP private. I'm not very well versed in networking related issues, so apologies if I'm being unclear.

The built-in keys support is meant to provide an option for this. You can require all requests to include an API key which is only shared with resources you care about. In fact, all HTTP-triggered functions require a key by default. You would have to explicitly choose to remove this requirement.
Keys aren't a networking solution though, and if you leak the keys, someone could access your APIs (until you roll the keys). You are correct that the VNet support is point-to-site, meaning it can access resources, but the function app is not protected itself. An App Service Environment would solve that, although Kai's comment on the original question is correct - ASE is not yet available for Functions.
In addition to keys, you could look at using App Service Authentication / Authorization to require an AAD service principal. This is effectively like a key, but has additional benefits if you are modeling other entities in AAD. Unless you know you need this, though, I would stick with keys.

With CORS functionnality you can restrict access to your Azure Function. To configure this, check the following link : Azure Function Settings, at the CORS section.

You can apply access restrictions to an Azure Function. The documentation can be found here.
You can use PowerShell AZ module to create a rule (or the portal if you prefer).
Add-AzWebAppAccessRestrictionRule `
-ResourceGroupName "ResourceGroup" `
-WebAppName "AppName" `
-Name "Ip example rule" `
-Priority 100 `
-Action Allow `
-IpAddress 122.133.144.0/24
Docs for Add-AzWebAppAccessRestrictionRule can be found here.

IP restrictions can be used to restrict access to whitelisted IPs. You can do it via the the Portal -
https://learn.microsoft.com/en-gb/azure/app-service/app-service-ip-restrictions
or in the web.config with ipSecurity

Related

Azure Web App: Cannot add a VNET Restriction Rule using PowerShell when VNET is on a different subscription

I have a web application in azure and I want to make sure that only my build server (or any other VM on the same subnet) are the only ones which are able to access the SCM site. I thought the most obvious thing would be to create an access restriction rule and in fact that works, I am able to create it from the portal with no issue whatsoever.
The problem, however, happens when I try to automate this using powershell. My build server subnet is located on a subscription different from the one where my web application is.
I am executing the following powershell script:
$subnetId = "/subscriptions/$VNETSubscriptionId/resourceGroups/$VNETResourceGroup/providers/Microsoft.Network/virtualNetworks/$buildServerVNET/subnets/$buildServerSubNet"
Add-AzWebAppAccessRestrictionRule -ResourceGroup $webAppRg -WebAppName $webAppname -Name VNETAccess -Priority 1000 -Action Allow -SubnetId $subnetId
And I get the following error:
Add-AzWebAppAccessRestrictionRule : The client '{{my user credential}}' with object id '81fa4eb1-5553-4daa-af44-3c717b19eda2' does not have authorization to perform action 'Microsoft.Network/virtualNetworks/subnets/read' over scope '/subscriptions/{{websiteSubscriptionId}}/resour
ceGroups/{{VNETResourceGroup}}/providers/Microsoft.Network/virtualNetworks/{{buildServerVNET}}/subnets/{{buildServerSubNet}}' or
the scope is invalid. If access was recently granted, please refresh your credentials.
The error seems to indicate that the cmdlet is searching for the subnet on the same subscription id than the website instead of the subscription where the subnet is located, since the resourceId string that is being returned on the error messsage has the wrong subscription Id. It is using the one where the website is instead of using the one where the build server is.
What else needs to be done in order to create this rule through powershell?
The error message is confused.
In fact, after my validation, you need to add the -IgnoreMissingServiceEndpoint parameter when adding a subnet from a different subscription. Read this GitHub case WebApp:Add-AzWebAppAccessRestrictionRule.md - incorrect use of subscription context over SubnetId param
When using a subnet from a different subscription, we cannot validate
the subnet to see if the correct service endpoint (Microsoft.Web) has
been set. If you use -IgnoreMissingServiceEndpoint the rule can be
added.

How to restrict/stop public (internet) access to Azure function?

I have several Azure Functions (Premium plan) which do some stuff and load the results to the storage blob. The connection to the storage account is restricted by a v-net so no public access to the storage account, however, I check and found that my (HTTP) azure functions can be triggered on the public internet.
How can I restrict this in the azure function, is there a way to do it through configuration?
Is this the way it's done?
Please help if there're other ways
You can set access restrictions in the portal through the networking blade. Click on Networking, then Configure Access Restrictions, and you can set access rules in there based on various options.
Instead of allowing specific IPS, i would request you to look at access restrictions to an Azure Function.
Add-AzWebAppAccessRestrictionRule -ResourceGroupName "ResourceGroup" -WebAppName "AppName" `-Name "Multi-source rule" -IpAddress "192.168.1.0/24,192.168.10.0/24,192.168.100.0/24" `
-Priority 100 -Action Allow

How do you configure Azure Function authentication by code?

I want to configure the authentication for my Azure function via code, be it powershell, ARM template or an API? is this possible?
i'm under the impression that an Azure Function is nothing more then an App Service so i would assume it resolve around there.
https://learn.microsoft.com/en-us/powershell/module/az.websites/?view=azps-2.0.0#app_service - there doesn't seem to be anything in the powershell.
https://resources.azure.com/ doesn't seem to give much information.
Here is some documentation on how to use managed identities for App Service and Azure Functions: https://learn.microsoft.com/en-us/azure/app-service/overview-managed-identity
You could create an PowerShell function app with MSI (Managed Service Identity) enable in a consumption plan. Here is some documentation (https://azure.microsoft.com/en-us/resources/templates/101-functions-managed-identity/) on how to do that.
Once the function app is created, you can grant it access to a given resource https://learn.microsoft.com/en-us/powershell/module/az.resources/new-azroleassignment?view=azps-2.0.0#examples
Lastly, the PowerShell function app comes with a profile.ps1 which contains code to authenticate against Azure via MSI out the box.
# Authenticate with Azure PowerShell using MSI.
# Remove this if you are not planning on using MSI or Azure PowerShell.
if ($env:MSI_SECRET -and (Get-Module -ListAvailable Az.Accounts)) {
Connect-AzAccount -Identity
}
Please give it a try and let us know if you run into any issues.
Azure Functions Authentication are still pending. Currently AFAIK there is not a way to add authentication via code except with the Function Host Keys
You can track the issue here in Github
Using terraform is a really good way of configuring these, a good example is below. Also az CLI 'az webapp auth' seems to have really good support now. PowerShell still seems to be lagging behind.
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/function_app

Azure SSL certificate tag

I have uploaded an SSl certificate on the azure portal for my web app.
Is there a way to add key-value tag for the cert? From the documentation, I see tags only for resource-group etc but not for a particular cert.
If you are able to see the certificate in your resource group, just add tag as usual.
On my side, the certificate is hidden because it's managed by Azure. I can show it by clicking the checkbox on top of your resource group.
If after you click the certificate and there is no Tags bar on its panel, you can choose to use cloud shell to add tag. You can find the cloud shell on top right of your portal.
The first time you run it, you may need to create storage for the shell, just follow the steps azure provides. Then we can add tags. Use powershell script as an example, just two commands to achieve your goal.
$r = Get-AzureRmResource -ResourceName certificatename -ResourceGroupName resourcegroupname
Set-AzureRmResource -Tag #{ TagName="TagValue"} -ResourceId $r.ResourceId -Force
Things work on my side. Any further question, just ask.
Looking at the REST API documentation for Create or Update Certificate, looks like it is possible to assign tags to SSL Certificates. I believe this functionality is not exposed on the Portal. I looked up Azure Powershell Cmdlets as well and couldn't find anything there (it is entirely possible that I may have missed out something).
If you need to assign tags to SSL Certificate, you can always use REST API and invoke that API using either writing code or using a tool like Postman. Other thing you should look at is Azure SDK. In all likelihood, you will find some functionality there which will let you assign tags to a SSL certificate.

How to use Azure PowerShell to identify type of service?

I can use Azure Powershell to get a list of services from my subscription e.g. using Get-AzureService.
What I can't currently easily work out is how to tell if the service is a VM (new or classic) or a cloud service (web/worker role).
What I am currently doing to identify a cloud service is using Get-AzureDeployment on the service-name and looking for a non-empty SdkVersion property but I feel this is a bit cludgy. Is there a better way?
Afaik there's no way to do this through the Get-AzureService without using (as you said) the Get-AzureDeployment.
You should be able to fetch the information using the new AzureResourcemanager cmdlets (Switch-AzureMode -Name AzureResourceManager) and using Get-AzureResource.
The ResourceId (in ARM mode) will give you a clue of what kind of provider it is.

Resources