Are you experiencing issues with your Azure Service Bus? Get to know how to enter Service bus configuration and securing, using multiple options for connectivity. Use Azure private networking and the Azure application gateway for access control and load balancing. Read more below.
The problem:
How can I secure my Azure service bus instance behind an Azure Application Gateway?
Let’s start by describing a hypothetical infrastructure scenario using the diagram below:
The diagram above displays a typical “Standard” SKU deployment of a Service Bus instance – what we have here essentially, is that both intra and extraneous entities are essentially using the same methodology to connect to the service bus instance irrespective* of where they sit from a network perspective.
We are therefore relying on other methodologies such as Azure AD {Entra} capabilities to secure our instance using components such as tokens etc. and of course Microsoft’s own DDoS and other prevention methodologies that are integrated in their PaaS offering – these details are not exactly communicated in full but they’re there.
*{The Azure VM is in fact using the Azure network backbone to connect to the service bus, so there are differences here – they touch mostly on latency issues and internal Azure networking “machinations” that do not change the core principles of this article}
What if I want to take my Service Bus private?
By switching the Service Bus from a Standard to a Premium SKU {Possible on existing ones} or by creating a new premium instance we are given more options – so, let’s look:
If you observe the highlighted area, we are provided with an additional blade on the service bus that can further our capabilities, and is in line functionally, with similar options we see in other PaaS offerings such as Azure Storage accounts – what can be performed then is:
a) We can use a barebones integrated “Firewall” Service that can allow or disallow external and internal network access to the Service bus instance by providing singular IP entries or address ranges:
b) We can “also” enable a private endpoint by providing a private IP to the service bus instance.
c) We can block public access altogether and enable only the private endpoint.
Now, let’s look at an alternate diagram that incorporates a potential combination of the options described before:
In this scenario, we have:
1) Enabled the Service bus Firewall.
2) Enabled public access to a select few IP ranges for external and internal access.
3) Created a private endpoint with a private IP to facilitate internal network access, from multiple sources.
We have been able to moderately secure our service bus instance for external entities using IP ranges and have optimized our internal traffic to use a private IP.
So, how can we improve this setup?
One could say that by taking the service bus private and using its built-in firewall capabilities in conjunction with the authentication mechanisms mentioned earlier we have a satisfactory result, right?
The answer is not so simple. Yes and no, because while one could say that this straightforward setup may satisfy a set of standard requirements, it still does not provide for the security, configuration, flexibility and centralized management capabilities of offerings such as the Azure Application Gateway – a very modular PaaS offering that among other things provides, reverse proxy capabilities, complex and very customizable Firewall Policies, DDoS protection, Bot protection, Load Balancing and other very-very useful things that you can read more about here.
Using the Application Gateway to secure our Azure Service Bus instance.
Now, here’s a very different setup, as shown below:
What has happened here as evidenced on the diagram, is that we have introduced a completely different connectivity and security paradigm, by:
a) Keeping only the private endpoint option of the service bus instance.
b) Introducing the Azure application Gateway as our centralized management solution for our service bus
But let’s take a closer look… What we are in practice getting is:
- A differentiation of our private access capabilities by using the Application Gateway’s private link capabilities to connect our internal entities using a dedicated listener and firewall policy, that keeps our internal traffic secure private, and fast without many restrictions.
- The provisioning of a very secure and hardened external public access for our external entities using the Application Gateway’s public IP capabilities that ultimately lead from the listener to the very same private endpoint IP address as our internal traffic.
- The ability to centrally control all access to the Azure Service Bus using the modular toolset, policies, and rules that Application Gateway gives us.
Connecting to a Service Bus instance behind an Azure Application Gateway
Having secured the Service Bus instance behind the Application Gateway and subsequently exposed through a dedicated listener, let’s now go through ways to connect and ultimately push/receive messages.
Important note: Application Gateway only supports the HTTP(s) protocol, and the default protocol used for the Azure Service bus is the AMQP. But the service supports an additional one, which is AMQP over WebSocket the only one that can work under the scenario proposed.
The following example will:
- Use the latest .NET Azure Messaging Bus
- Use Microsoft Entra (Azure AD) to authenticate the client to access the Service Bus instance.
Authentication
The first step is to get the configure an App Registration that will be used to authenticate the application:
- Register a new App Registration and save the Tenant ID and Client ID.
- Configure a save the client secret.
Then grant permissions to the newly App Registration on the Service Bus instance, by selecting a role and a scope:
- Azure provides the following Azure built-in roles for authorizing access to a Service Bus:
- Azure Service Bus Data Owner: Use this role to allow full access to the Service Bus namespace and its entities (queues, topics, subscriptions, and filters)
- Azure Service Bus Data Sender: Use this role to allow sending messages to Service Bus queues and topics.
- Azure Service Bus Data Receiver: Use this role to allow receiving messages from Service Bus queues and subscriptions.
- The following list describes the levels at which you can scope access to Service Bus resources:
- Queue, topic, or subscription: Role assignment applies to the specific Service Bus entity.
- Service Bus namespace: Role assignment spans the entire topology of Service Bus under the namespace and to the consumer group associated with it.
In our scenario, we’ll configure Azure Data Bus Data Owner at the Service Bus namespace level for simplicity, but best practices dictate that it’s always best to grant only the narrowest possible scope.
Finally, using the Tenant ID, Client ID and Secret saved previously, create a new instance of the ClientSecretCredential class
Configure the Service Bus Client
Let’s start by configuring the options for the Service Bus client, as stated before, it is required to use the AMQP over WebSocket to connect to our protected instance.
Moreover, when using the AMQP over WebSockets, a Custom Endpoint can be configured to instantiate the WebSocket connection.
The ServiceBusClientOptions enables us to exactly this behaviour:
Finally, it now possible to instantiate our ServiceBusClient:
Send and receive messages
Now that we have instantiated our client, it consists of simply using the Azure Messaging Bus package.
Send a message to a queue or topic:
Receive a message to a queue or topic:
Conclusion
To summarize our entry into Azure Service bus configuration and securing, we can turn to multiple options for connectivity depending on our requirements ranging from low key/requirement and/or Test/Uat connectivity scenarios up to heavy load, multi-regional (if desired), security hardened instances using Azure private networking and the Azure application gateway for access control and load balancing.
To know more about this topic – our any other Azure-related one – contact our team of experts in Microsoft Cloud solutions.