Microsoft Azure Virtual Machines: Public IP Configuration Is Not Always As It Seems
If you’re not familiar enough with the SKU attribute of the Azure public IP address, you may think you’re configuring your virtual machines as public to the internet … but you aren’t.
Anyone managing computing resources knows that one of the most important attributes of their configuration is exposure to public network access. Public exposure is important for two reasons. From a security perspective, it’s significant to know who (or what) can have network access to a resource and to limit that access as much as possible. From an operational perspective, you want to be sure that services that are required to be public (or very loosely restricted) are, in fact, configured as such.
As a security company, we usually deal with limiting access strictly to resources that are required to be exposed. This time, we want to shine a light on the opposite situation.
In our work, we’ve picked up on an issue involving how Microsoft Azure virtual machines are configured for public exposure. The approach may have you thinking you have configured a machine to be public when, in fact, you haven’t. We thought we'd put out a caveat, as this is a misconfiguration you don’t want to learn about at the wrong time.
Configuring Azure public network access for a virtual machine
Azure documentation describes the various configurations in which access to a VM can be configured to be accessible to the internet:
Fig. 1: Different configurations of virtual machine access to the internet
Image source: Microsoft Azure documentation
When you look at VM4 in Figure 1, you may be under the impression that a virtual machine with no network security group (NSG) attached to its network interface and located in a subnet with no NSG on it would, if assigned a public IP address, be public to the internet. However, a closer look at one of the attributes of a public IP — the SKU — and its implications, reveals a different reality:
Fig. 2: Security information for the SKU attribute of a public IP address in Azure
Image source: Microsoft Azure documentation
The marked section in Figure 2 explains that, for such access to be possible, a standard SKU (currently the default when a new public IP address is created along with a virtual machine) requires an NSG allowing public access to be attached to the virtual machine.
This means that for your virtual machine to be public in an architecture such as that of VM4 in Figure 1, you have to use a public IP address with basic SKU (which doesn’t support features such as working with availability zones).
Alternatively, you can attach an NSG to the virtual machine, or to the subnet it is in, that allows such public access. Doing so makes the virtual machine’s architecture similar to that of VM1, VM2 or VM3 in Figure 1.
If this is news to you, cut yourself some slack — even Azure gets this wrong.
Demonstration of a virtual machine and its IP: Taking it out for a spin
To understand just how unclear this gets, we set up a demonstration of a virtual machine in an architecture resembling that of the VM4 instance in Figure 1.
We expect the virtual machine to be public — but it won’t be.
First, let’s create the virtual machine:
Fig. 3: Creating a VM, starting with the basics tab
Image source: Tenable, 2023
After setting up attributes such as subscription, resource group and name in the basics tab, we head over to configure the networking. We create the virtual machine on a public subnet (that has no NSG attached to it) and with a new public IP address.
Fig. 4: Configuring networking as part of creating a VM
Image source: Tenable, 2023
This setup will supposedly suffice for the virtual machine to be public.
However, as you see in the right column of Figure 4, above, the default SKU is marked as standard. We will select this option (as we may not yet have read up on the difference between standard and basic SKUs) and move on.
Once we choose this configuration for our new public IP address, we even get a warning about the virtual machine being provisioned as public:
Fig. 5: Virtual machine creation wizard warning about the newly created virtual machine being public
Image source: Tenable, 2023
To make testing the connection a bit easier, we will load this virtual machine with custom data that will install an Apache web server and start serving a simple web page:
Fig. 6: Loading the new virtual machine with custom data that starts up an Apache web server serving a simple web page
Image source: Tenable, 2023
As a side note (and to give credit where due), below is the full custom data that we created very easily using ChatGPT:
Figure 7: ChatGPT generating custom data for serving a web page on the VM
Image source: Tenable, 2023
After creating the virtual machine, we can get its public IP address from the overview page:
Fig. 8: Extracting the public IP address for the virtual machine created
Image source: Tenable, 2023
Sure enough, even though Figure 1 led us to believe otherwise, we do not have a connection from our local machine:
Fig. 9: No connection to the newly created virtual machine
Image source: Tenable, 2023
Now for the really interesting part: It’s one thing for the Azure documentation and VM creation wizard to be unclear on this issue. But Azure itself misunderstands the configuration: the Azure Network troubleshooting utility reports the virtual machine as public for HTTP communication:
Fig. 10: Azure Connection troubleshooting utility showing the virtual machine as supposedly public
Image source: Tenable, 2023
This is quite an oversight.
With Azure’s own tool for evaluating network connectivity getting it wrong, the average Azure customer is hardly at fault for not knowing any better.
Setting up the Azure virtual machine public IP the right way
Unfortunately, we can’t (and probably, at least in production environments, wouldn’t want to) downgrade the SKU of the public IP address from standard to basic.
If we want the virtual machine to be public, the required (and currently missing) component that will allow public access to our virtual machine is an NSG.
We will therefore set up an NSG allowing inbound HTTP traffic:
Fig. 11: NSG allowing public inbound HTTP (and HTTPS) access
Image source: Tenable, 2023
We then attach the NSG to the virtual machine’s network interface:
Fig. 12: Attaching the NSG to the network interface of the virtual machine
Image source: Tenable, 2023
And… boom, we now have public access as intended:
Fig. 13: We now have access to the virtual machine and can view the web page served
Image source: Tenable, 2023
Conclusion
Just to be clear, the critical tone we take with Azure here is not about the convoluted criteria for allowing public access for a virtual machine with a public IP address with the standard SKU.
In fact, it makes perfect sense that, by default, a machine won’t actually be public unless an NSG is configured with rules making it public.
However, Azure’s documentation, user interface and native network evaluation tools should clearly reflect this configuration nuance, as customers rely on the provider’s accuracy when setting up their environments.
This is an unusual and maybe somewhat of an edge case that (hopefully) won’t be too troublesome for your deployments.
However, it is a good example of a larger lesson: do your due diligence before assuming anything will work as expected anywhere (especially in production). You can perform due diligence with formal testing or by using an analysis tool, such as Tenable Cloud Security, that provides accurate information on the configuration of your environment. Also, when analyzing your architecture for faults (such as unintended public access), make sure you do a thorough analysis (again, either your own or using precise third-party analysis tools such as Tenable Cloud Security) to avoid false positives.
Related Articles
- Cloud
- Cloud