Communication between apps in same app service plan? - azure

To clarify what I'm not asking about, there's alot of documentation about using endpoints to expose apps in a App Service Plan to a vnet, which is useful for private communication between vnet hosted VMs or other resources outside the app service plan.
What I'm asking about is specifically communication between two apps inside the same app service plan. So if we had PlanA, and AppB and AppC both deployed to that plan, then if PlanA scales to two instances, each instance would have both AppB and AppC inside it. Very similar to an IIS farm hosting multiple applications.
If I want to disable public access for AppC, but still allow AppB to call AppC(imagine if AppC is a API service and AppB is a front end web app), is that possible? How would you resolve that call if the AppC doesn't have a public IP? Would the domain appC.azurewebsites.net resolve to a privateIP that AppB can access?

The fact that two app services run in one app service plan means only that these app services can share the same set of computing resources (CPU, memory, etc.) and it does provide any network isolation or private IP addresses within an app service plan.
If you want to keep the existing setup and restrict access to AppC, you can whitelist IP addresses of AppB as follows:
Go to the AppB in Azure Portal, click Properties and copy the list of Outbound IP addresses.
Go to the AppC, click Networking -> Access Restrictions and deny access to everything apart from the outbound IP addresses you copied in step 1.
The domain appC.azurewebsites.net will still have a public IP address but Azure will only allow accessing it from the IP addresses you configured and return 403 error to any other client.
However, if you want to have a truly private endpoint and more granular control over routing configuration, then consider integrating your app services with Azure virtual network as described here. Virtual networks are not limited to VMs, they can be used for app services too.

Related

Azure Container App: Only allow access over Api Management

I want to restrict access to my Azure Container App with an Api Management in Azure.
I successfully linked the Api Management with the Container App and I have activated a Subscription with an Api Key that will prevent public access over the Api Management Service Url. The problem, however, is that the Container App can still be accessed over the public Url of the Container App.
There is still the option to set the Ingress Traffic in the Container App to Limited to Container Apps Environment but then the Api Management will not have access to the Container App as well.
What is the correct way to properly secure the Container App behind an Api Management Service?
For Azure Container Instances, you don't have the option to configure IP restrictions similar to Azure App Services. Instead you will have to first create a virtual network and configure a Network Security Group to Deny all traffic from the internet and allow only from APIM, and then deploy your Azure Container Instance to this virtual network.
See here for deploying an azure container instance to a virtual network : https://learn.microsoft.com/en-us/azure/container-instances/container-instances-vnet
For configuring network security groups in your virtual network see : https://learn.microsoft.com/en-us/azure/virtual-network/manage-network-security-group#work-with-security-rules
You app service is still accessible over the public internet because you haven't configured Access Restrictions in your App Service's Network.
What you need to do is go to your App service. Then select Networking from the left menu and Turn on Access Restrictions for inbound traffic.
Create an access restriction rule to deny from the internet.
Next create a second acccess rule to allow access from the APIM. Ensure the priority on this one is higher.
Read the Microsoft Docs on how to set app service IP restrictions here : https://learn.microsoft.com/en-us/azure/app-service/app-service-ip-restrictions
Assuming your API management service has a static IP (not a consumption plan), you would need to use you own VNET:
Networking architecture in Azure Container Apps
Then using NSG, you could add an inbound rule to only allow traffic from the APIM service IP on HTTPS (TCP 443).
Azure container apps do now seem to have the ability to restrict inbound ip addresses
https://azure.microsoft.com/en-gb/updates/public-preview-inbound-ip-restrictions-support-in-azure-container-apps/
We have are looking at a similar architecture with a similar dilemma. Everything we have is secured with Azure b2c but if I want to make an internal container/microservice accessible to Azure Api Management I think I'd have to drop b2c (api management has no UI to log into b2c) and make it publicly accessible via the Ingress. If the inbound ip addresses are restricted to api management maybe that is ok. It does worry me that ip addresses can be spoofed although you'd hope Microsoft have thought of that.
Another alternative which I've not investigated but which does work for Azure functions is managed identities. This might not work at all with container apps though
https://www.svenmalvik.com/azure-apim-function-msi/
First, I think that it is good to explain networking architecture in Azure Container Apps.
Azure Container Apps run in the context of an environment, which is supported by a virtual network (VNET). When you create an environment, you can provide a custom VNET, otherwise a VNET is automatically generated for you.
There are two ways to deploy Container Apps environments:
External - Container Apps environments deployed as external resources are available for public requests. External environments are deployed with a virtual IP on an external, public facing IP address.
Internal - When set to internal, the environment has no public endpoint. Internal environments are deployed with a virtual IP (VIP) mapped to an internal IP address. The internal endpoint is an Azure internal load balancer (ILB) and IP addresses are issued from the custom VNET's list of private IP addresses.
I attach the image from Azure portal to show above two options:
Now going further, if you want your container app to restrict all outside access, create an internal Container Apps environment.
Now when it comes to deployment of the Container Apps to the Container Apps Environment, accessibility level you selected for the environment will impact the available ingress options for your container app deployments.
If you are deploying to an external environment, you have two options for configuring ingress traffic to your container app:
Limited to Container Apps Environment - to allow only traffic from other container apps deployed within the shared Container Apps environment.
Accepting traffic from anywhere - to allow the application to be accessible from the public internet.
If you are deploying to an internal environment, you also have two options for configuring ingress traffic to your container app:
Limited to Container Apps Environment - to allow only traffic from other container apps deployed within the shared Container Apps environment.
Limited to vNET (Virtual Network) - to allow traffic from the VNET to make container app to be accessible from other Azure resources or applications within the virtual network or connected to the virtual network through Peering or some type of VPN connectivity
Now in you case, what you are looking for is the architecture where you enable access to Azure Container Apps only through the Azure API Management. In this case you have to deploy Azure Container Apps Environment with Internal mode and set ingress traffic to Limited to VNet (Virtual Network).
I assume that Azure API Management can be accessible from the Internet. In this case you have to deploy Azure API Management inside an Azure Virtual Network. There are two possible modes: internal, and external. In you scenario, you can use external mode. More details can be found here. When API Management instance in the external mode, the developer portal, API gateway, and other API Management endpoints are accessible from the public internet, and backend services are located in the Azure Virtual Network.
Here I also attach the solution architecture to show how all these components are connected together. I also have Azure Front Door here but API Management is deployed with external mode. Please remember that you will also need private DNS Zone for your Azure Container Apps Environment domain, to make it possible to refer to specific APIs from the Azure API Management using URLs, example:
https://ca-tmf-mip-vc-api--v-01.blacklacier-cf61414b.westeurope.azurecontainerapps.io
Helpful links:
Repo with Bicep files to deploy Azure Container App with internal mode
Azure Container Apps Virtual Network Integration

Azure web app access restrictions between Apps

I have 2 app service plans in the same Azure region running 1 app each - web frontend on one, API on the other.
I want to use access restrictions on the API to only allow access from the front end app.
I set access restriction rules using all the outgoing IP addresses associated with the frontend app (I note that these are exactly the same as the outgoing IP addresses on the API app as well) however when the frontend app tries to contact the API I get an error:
403 forbidden 'The web app you have attempted to reach has blocked your access.'
The 2 apps can communicate as normal when the access restrictions are removed.
I turned on diagnostic settings and ran a query on IP blocking by the app.
Turns out that the FE app is using an IPv6 address instead of the v4 addresses listed in the app properties.
This is because the app has a vnet integration set up connecting to a Subnet delegated to Webservice/serverfarm.
Azure does not make it obvious that using delegated subnets forces an integrated app to use IPv6 and there does not appear to be a way to discover what v6 addresses may be in use. MS forum response suggests any firewall rule for a web app attached to a delegated subnet should allow ALL IPv6 addresses (!!) as a way of working around the problem.
https://learn.microsoft.com/en-us/answers/questions/493483/why-is-my-azure-web-app-showing-an-ipv6-outbound-i.html
You can control the IP address of outbound traffic from your FE web app by using regional VNet integration together with a virtual network NAT gateway to direct traffic through a static public IP address. Regional VNet integration is available on Standard, Premium, PremiumV2 and PremiumV3 App Service plans. To learn more about this setup, see NAT gateway integration.
Once you FE web app has a static IP you can use that on the API web app restriction in an ALLOW rule.
If your requirement fits, you may also leverage Service Endpoints.
With service endpoints,to ensure inbound traffic to your API app comes only from the subnet used by your front-end web app.
With this route, you need to use VNet Integration with your front end app and service endpoints with your API app. Set service endpoints on the integration subnet used by your Front End application. This solution is fast to set up and easy as well.
-This feature works together with IP access restrictions. Service endpoints aren't compatible with remote debugging. There are some considerations you need to make, you may take a look at them here and also other combination of networking features available on App Service and related scenarios.
As a side note:
-IP-based access restriction rules only handle virtual network address ranges when your app is in an App Service Environment. If your app is in the multitenant service, you need to use service endpoints to restrict traffic to select subnets in your virtual network.
-On App Service, you could have those two separate apps in the same App Service Plan (ASP), since you pay only for ASP, saving costs.
So, you can continue to add apps to an existing plan as long as the plan has enough resources to handle the load. The apps in the same App Service plan all share the same compute resource.

Connecting two App Services within the same VNet

I have two NodeJS App Services.
They can connect to each other with no problem using the URL which is created for App Services by default. (That is through the public internet.)
Then I successfully enabled VNet Integration for both App Services, and assigned the same VNet and also subnet two both of them.
How should I modify the connection URL now to connect to appservice2 from appservice1 (without using the URLs which are publicly available on the internet)?
I could not find any host name or IP address information in Azure Portal using which I could have successfully established the connection.
Thanks for any suggestions!
When you want two app services to connect to each other over a private network, there are generally two steps you have to take to set this up correctly. Note that the app service URL will always stay the same, it is only the networking part that changes.
Both app services should have vnet integration enabled, which allows the app service to route its traffic through the vnet.
If you want others (e.g. another app service) to connect to an app service via a vnet you can choose between:
a) Service endpoints
b) Private endpoints
Reading your question, I assume you completed the first step correctly. But you have to complete either step 2a or 2b to get this to work properly. I would recommend you choose service endpoints because they are more straightforward than working with private endpoints. Below you'll find a detailed description and considerations for every step.
1. Vnet Integration
The subnet you use as an integration subnet has to be a dedicated subnet. This means it is only used for vnet integration.
Only one app service plan can be used with this dedicated subnet, this one app service plan may include multiple app services.
If there is a network security group attached to that subnet, it needs to allow outbound traffic.
If there is an azure firewall attached to your vnet and you want to make a call to a public endpoint, it should allow outbound traffic.
Vnet route all should be enabled if you want all the outbound traffic to travel over the vnet.
If you want to read more, I would recommend reading this documentation.
Here is a simple example of how you would create vnet integration by selecting the dedicated subnet:
Service Endpoints
Service endpoints allow you to lock down inbound access to your app so that the source address must come from a set of subnets that you select.
Service endpoints are automatically provisioned by azure when you enable access restrictions to the app service.
This is a much simpler alternative to private endpoints.
Does not work in large-scale networks where you want to connect from an on-prem network to an azure vnet.
You may turn to this documentation to read about all the features and limitations of service endpoints.
Here is an example of how you would enable services endpoints for your app service by creating an access restriction:
Private Endpoints
Private endpoints also need a subnet, but you can connect as many private endpoints to the subnet as there are IP addresses available.
When you use private endpoints, you also need to have a private DNS zone. Otherwise, the app service URL does not resolve correctly to an IP address.
Private endpoints are more complex than service endpoints because of the extra subnet and DNS requirements.
Here is a nice tutorial that let's you set up an app service with private endpoint.
The following example shows you how to create a private endpoint for your app service. You have the option to let azure create a private DNS zone automatically, or you can do this manually:
If you want to access app services without public internet, then enabling VNET integration in those services alone won't be enough. You need to create a private endpoint that provides the IP from the virtual network to access the app service internally within the VNET and it also disables public access to the app service over the internet. Also please be aware that the private endpoint implementation will have some cost implications as well.
If your requirement is just to establish a secure connection between your virtual network & app service and to avoid access over the public internet, a service endpoint is the simplest solution. If you also need to access the app service from on-premises through an express route or Azure Gateway, a regionally peered virtual network, or a globally peered virtual network, Private Endpoint is the solution.
Steps to set up a service endpoint are detailed in the provisioning service endpoint link
Steps to set up a private endpoint are detailed in the connect to the web app using private endpoint link
Also if you want to deep dive into private endpoint configuration for app service, I would recommend you to read through the following tutorial

Access Azure website by IP cause 404 error

I have an azure website that I can access by
myname.azurewebsites.net
In Azure dashboard, the IP is 104.214.237.135
When I try to access my website by IP I have a 404 error
I don't understand. My plan App Service is S1
Regards
Azure App Service is a multi-tenant service, except for App Service Environments. Apps that are not in an App Service environment (not in the Isolated tier) share network infrastructure with other apps. As a result, the inbound and outbound IP addresses of an app can be different, and can even change in certain situations.
App Service Environments use dedicated network infrastructures, so apps running in an App Service environment get static, dedicated IP addresses both for inbound and outbound connections.
Azure AppService IP addresses are shared between tenants and not guaranteed to be static. Your app is bound to the hostname, not the IP address. Unless you are using App Service Environment, you cannot use a static / dedicated IP address with Azure AppServices. You can add additional custom hostnames to your app.

How do I restrict the clients that can access my Azure App Service?

Given that I create an Azure 'App Service'
How do I ensure that this service is only callable from ...
A.> 2 existing external servers (whose IP addresses will be known)
B.> 3 other App Services which I will be creating, but whose IP Addresses may not be known since I may need to scale those out (Over multiple additional instances)
To clarify... Is there some Azure service that will allow me to treat this collective of machines (both real and virtual) as a single group, such that I can apply some test on incoming requests to see if they originate from this group?
on Azure WebApps, You may wish to know; the IP Restrictions (https://learn.microsoft.com/en-us/azure/app-service/app-service-ip-restrictions) allow you to define a list of IP addresses that are allowed to access your app. The allow list can include individual IP addresses or a range of IP addresses defined by a subnet mask. When a request to the app is generated from a client, the IP address is evaluated against the allow list. If the IP address is not in the list, the app replies with an HTTP 403 status code.
You can use IP and Domain Restrictions to control the set of IP addresses, and address ranges, that are either allowed or denied access to in your websites. With Azure WebApps you can enable/disable the feature, as well as customize its behavior, using web.config files located in their website.
Additionally, VNET Integration gives your web app access to resources in your virtual network but does not grant private access to your web app from the virtual network. Private site access is only available with an ASE configured with an Internal Load Balancer (ILB).
If you haven’t checked this already, checkout Integrate your app with an Azure Virtual Network for more details on VNET Integration (https://learn.microsoft.com/en-us/azure/app-service/web-sites-integrate-with-vnet)
I strongly suggest dropping the whole what's my IP approach and throwing in OAuth. Azure AD gives you access tokens with moderate effort —
Service to service calls using client credentials (shared secret or certificate)
Else, TLS client authentication would be next on my list. Although that tends to really suck if you have to deal with several programming stacks, TLS offloaders and what not.

Resources