Pi-Hole in Azure Virtual Machine

As you may have noticed, lately I am spending lots of time trying out some Linux appliances and running them in Azure. One example would be FreeNAS appliance, couple of weeks ago.

This mini project came out from me trying to install and setup Pi-Hole on a Synology in a Docker container. Since my Synology setup is bit complicated I opted for public cloud setup and decided not to mess with my home networking.

Public cloud setup has some advantages and disadvantages over local installation. Main disadvantages are that you are exposing inbound port 53 to the Internet and sometimes latency to cloud service providers can be high. First issue can be tackled in multiple ways, by configuring VPN for public cloud VM, which adds to the cost ,or by utilizing firewall rules to allow only certain clients to access port 53 on your Pi-Hole. Later one can be tricky if you have dynamic IP addresses.

One of the main advantages is that Pi-Hole server in public cloud can be used for multiple clients and scaled as needed.

Lets see what I did and how I solves some of the issues along way.


In Azure portal I used already prepared Ubuntu image, selected standard disks, fixed IP address and Standard A1 v2 (1 vcpus, 2 GB memory) compute size. Initially I exposed only port 22 so I can administer the machine.

I then followed standard Pi-Hole installation procedure located on Pi-Hole document page.

I opted for Quad9 DNS provider although you can choose any other available or add custom. I did not modify any IP addresses of the VM since they are managed by Azure.

Make sure you note your initial admin password at the end of the installation.

Password can be changed later on in command line with following command:

$ pihole -a -p
Enter New Password (Blank for no password):
Confirm Password:
[✓] New password set

After setup is complete you will be able to connect to your Pi-Hole admin page via http://ip-address/admin.

Post setup configuration

Task number one is to setup your clients to use Pie-Hole as DNS server. In my case, my home routers DHCP service is configuring all clients with 3 DNS servers, primary is Pie-Hole, secondary is and tertiary is

Main issue in public cloud setup is port 53 which is opened for everyone. This is not good practice so you should employ some kind of protection. VPN adds cost so logical answer is firewall. Luckily, Ubuntu has iptables firewall which is easy to use and setup.

My issue was that I have dynamic IP address allocated from my ISP provides, so I had to devise a way to auto update firewall rules when my IP address changes. Ports that are needed are 22, 80 and 53. I decided to open port 22 for all so I do not have to worry on being blocked from accessing admin interface.

I created a small bash script and added it to cron so it runs every 5 minutes. Script looks like this:

ip="$(ufw status | egrep 53 | awk '{ print $3 }' | head -1)"
ipnew="$(dig +short YourDyndnsName | grep -Eo '[0-9\.]{7,15}' | head -1)"
if [$ip != $ipnew]
for NUM in $(ufw status numbered | grep -e 53 -e 80 | awk -F"[][]" '{print $2}' | tr --delete [:blank:] | sort -rn); do
    yes | ufw delete $NUM
ufw allow from "$ipnew" to any port 80
ufw allow from "$ipnew" to any port 53

First line gets current dynamic IP address stored in iptables rules list. Second one gets current IP address of my router which is connected to DynDns service. If those are different, script removes old IP address for ports 53 and 80 and then adds new rules with new IP address.

As mentioned, this runs as cron task every 5 minutes:

# m h  dom mon dow   command
*/5 * * * * /usr/local/sbin/ufwdynamichostupdate  2>&1 > /dev/null

Since script runs every 5 minutes, it is possible that at some point for some short time, clients will not be able to access Pi-Hole DNS. In that case, they will fall back to secondary DNS that is also provided by my home router.

You May Also Like

About the Author: Marin

Started as trainer and administrator in Algebra, 5 years later became head of operating systems department at Algebra private college. At that time, he became IT Pro group lead and 5-year Microsoft MVP. Joined Microsoft in 2014. and after covering roles of Infrastructure and Azure TSP for 4 years, moved to Span to take the role of Senior Solutions Architect for cloud solutions. Currently holds Microsoft Azure MVP award. Personal time is occupied by enjoying short trips with his family and close friends, tinkering with home automation and networking and spending money on too many gadgets.


  1. I have installed Pi Hole on a Debian VM on azure and opened up the ports in the NSG, but the Pi Hole is still not resolving DNS queries. I am not a Linux guy, but I have Googled around and found how to open the ports on the VM. But it’s still not working. The VM has a private and public IP, so I’m not sure which one to use in the Pi Hole settings. Also, I can only find the Public IP, but not the Public IP for the gateway. Can you offer any suggestions?

    1. I have disabled firewall in Linux VM for this purpose. Unfortunately this open up other problems such as directly exposing DNS ports to the internet. I had to devise a script that will automatically add my dynamic IP address as only one authorized to do DNS queries. If you are using it for external clients, public IP is point of entry. Public IP of your on-prem gateway?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.