Ph
Developer Tools AWS

Pi-hole on AWS User Guide

| Product: Pi-hole on AWS

Overview

Pi-hole is an open-source, network-wide DNS sinkhole that blocks ads, trackers and malware domains for every device on your network - no per-device software required. You point your devices, router or DHCP server at Pi-hole as their DNS server, and Pi-hole answers from its bundled blocklists, sinking known ad and tracker domains while resolving everything else through an upstream resolver. The cloudimg image installs Pi-hole 6, which ships pihole-FTL - a single service that is both a fast caching DNS resolver on port 53 and an embedded web server on port 80 hosting the admin dashboard and a REST API. There is no separate lighttpd, PHP or nginx in v6. A unique admin password is generated on the first boot of every instance, and the Pi-hole data directory (the long-term query database, the blocklists and the configuration) lives on a dedicated data volume mounted at /etc/pihole. Backed by 24/7 cloudimg support.

What is included:

  • Pi-hole 6 (pihole-FTL) - a caching DNS resolver on :53 (UDP and TCP) and an embedded web server on :80
  • The admin dashboard at /admin and the REST API at /api, served by pihole-FTL itself
  • Default blocklists (adlists) loaded into Pi-hole's gravity database, ready to block tens of thousands of ad and tracker domains
  • A per instance admin password generated on first boot and recorded in a root-only file
  • The Pi-hole data directory on a dedicated, independently resizable data volume at /etc/pihole
  • pihole-FTL.service as a systemd unit, enabled and active
  • 24/7 cloudimg support

Prerequisites

An Amazon Web Services account where you can launch EC2 instances, an EC2 key pair in the target Region, and a VPC + subnet. A small instance such as t3.small is enough - Pi-hole is lightweight. Security group inbound: allow 22/tcp from your management network, 80/tcp for the dashboard, and 53/udp and 53/tcp for DNS from the clients you want to protect. Pi-hole serves the dashboard over plain HTTP on port 80; for production, terminate TLS in front of it with your own domain.

Step 1: Launch the Instance from the AWS Marketplace

Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Pi-hole by cloudimg. Select the cloudimg listing and choose Select, then Continue on the subscription summary. Pick your instance type and EC2 key pair, and under Network settings select a security group that allows inbound ports 22 and 80, plus DNS (port 53, both UDP and TCP) from the clients that should use the instance as their resolver. Select Launch instance.

Step 2: Launch the Instance from the AWS CLI

aws ec2 run-instances \
  --image-id <ami-id> \
  --instance-type t3.small \
  --key-name <key-name> \
  --subnet-id <subnet-id> \
  --security-group-ids <security-group-id> \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=pi-hole-01}]'

aws ec2 authorize-security-group-ingress --group-id <security-group-id> \
  --protocol udp --port 53 --cidr <your-client-cidr>
aws ec2 authorize-security-group-ingress --group-id <security-group-id> \
  --protocol tcp --port 53 --cidr <your-client-cidr>

Step 3: Connect to your Instance

The SSH login user depends on the operating system of the AMI variant you launched:

AMI variant SSH login user
Pi-hole on Debian 12 admin
ssh -i <path-to-key>.pem admin@<instance-public-ip>

Step 4: Confirm the service is running

systemctl is-active pihole-FTL.service

It reports active. pihole-FTL is the single Pi-hole service - it provides both the DNS resolver and the web dashboard.

Step 5: Retrieve your admin password

The admin password is generated uniquely on the first boot of your instance and written to a root-only file:

sudo cat /root/pi-hole-credentials.txt

This file contains PIHOLE_URL, PIHOLE_API_URL and pihole.admin.pass. Store the password somewhere safe.

Step 6: Confirm the DNS resolver and web server are listening

ss -tlnH | grep ':80 ' && ss -lnuH | grep ':53 '

You see a listener on :80 (the dashboard) and on :53/udp (DNS). Confirm Pi-hole resolves names:

dig +short @127.0.0.1 github.com A

It returns one or more IP addresses, proving the resolver is working.

Step 7: Open the admin dashboard

Browse to http://<instance-public-ip>/admin and sign in with the password from Step 5. The login is password-only (there is no username), and the login page is served by pihole-FTL itself.

Pi-hole admin dashboard login page

After signing in you land on the dashboard, which shows total queries, queries blocked, the percent blocked, the number of domains on your blocklists, and live query and client activity graphs.

Pi-hole admin dashboard with query statistics

The Query Log lists recent DNS queries with their client, type, response time and whether each was blocked (red) or allowed (green).

Pi-hole query log

Under Lists you manage the subscribed blocklists (adlists) Pi-hole uses to sink ad and tracker domains. The image ships with a default blocklist already enabled.

Pi-hole subscribed blocklists

Step 8: Verify the admin API from the command line

Pi-hole v6's authentication API rejects a wrong password (HTTP 401) and accepts the per instance admin password (HTTP 200 with a session). First read the password from the credentials file, then authenticate:

PW=$(sudo grep '^pihole.admin.pass=' /root/pi-hole-credentials.txt | cut -d= -f2-)
curl -s -X POST -H 'Content-Type: application/json' -d "{\"password\":\"<PIHOLE_ADMIN_PASSWORD>\"}" http://localhost/api/auth | head -c 200; echo

The response contains a "session" object with "valid":true and a session ID (sid) - that authenticates subsequent API calls.

Step 9: Point your clients at Pi-hole

To protect your devices, set this instance's public (or private) IP as their DNS server:

  • A single device: set its DNS server to the instance's IP in the OS network settings.
  • Your whole network: set the instance's IP as the DNS server in your router's DHCP settings, so every device on the network uses Pi-hole automatically.

Make sure ports 53/udp and 53/tcp are open in the instance's security group from the clients you want to serve. You can confirm blocking from any client with nslookup doubleclick.net <instance-ip> - a blocked domain resolves to 0.0.0.0.

Step 10: Update blocklists and Pi-hole

Refresh the blocklists (the "gravity" database) at any time:

sudo pihole -g

Pi-hole and its blocklists are maintained in the cloudimg image; you can update the Pi-hole software yourself with sudo pihole -up.

Security notes

The admin dashboard is served over plain HTTP on port 80. Before exposing it beyond a trusted network, restrict port 80 to your management CIDR in the security group and front the dashboard with TLS and your own domain. Keep port 53 reachable only from the clients you intend to serve - an open public resolver can be abused for DNS amplification. The admin password is unique per instance and stored only in the root-only credentials file.

All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.