# Domain Name System (DNS)

# Pi-hole - DNS server



# Pi-hole on container in Proxmox

Login into Proxmox





Download Debian distro template for containers. For some reason it might be cancelled or disrupted. As we now, which one template is expecting to find, let's download that manually. Navigate to containers' templates storage, find suitable and hit [Download] button
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/jC11M14U0vnzst2w-image-1776047559608.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/jC11M14U0vnzst2w-image-1776047559608.png)

Download task itself
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/UsKJgEmTpyDkkL9X-image-1776049815356.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/UsKJgEmTpyDkkL9X-image-1776049815356.png)

Template downloaded
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/i3t7w6bp5XxUEJw2-image-1776049915546.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/i3t7w6bp5XxUEJw2-image-1776049915546.png)

Script location:
```url
https://community-scripts.org/scripts/pihole?id=pihole
```
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/ux0DdwBOxOP5PGDD-image-1776046499317.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/ux0DdwBOxOP5PGDD-image-1776046499317.png)

```bash
curl https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/pihole.sh
```
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/Y6N7SHqkQARLqzz3-image-1776046567181.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/Y6N7SHqkQARLqzz3-image-1776046567181.png)


Paste and execute, this will download a script and execute it on hypervisor:

Let's see what is inside of this script
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/mo6uiVFUSvpvfv1s-image-1776046835958.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/mo6uiVFUSvpvfv1s-image-1776046835958.png)


and invoke it's from the shell, when confident:
```bash
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/pihole.sh)"
```
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/nzuwOE9o5M4Yj39H-image-1776046905560.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/nzuwOE9o5M4Yj39H-image-1776046905560.png)

First screen is regarding telemetry data, do you choice using [Tab], [Space], [Enter]:
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/Gi9JZL4CaQe9ZuCg-image-1776046632435.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/Gi9JZL4CaQe9ZuCg-image-1776046632435.png)

Use 'Default Install'
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/fm3JA32eFDzso8Hp-image-1776046983995.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/fm3JA32eFDzso8Hp-image-1776046983995.png)

Begin, this will look for Debian Linux distro (and if necessary download it):
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/gF8qlCoKnv6xfG6o-image-1776049978821.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/gF8qlCoKnv6xfG6o-image-1776049978821.png)[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/nzax3XQYhp96kBVu-image-1776047033341.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/nzax3XQYhp96kBVu-image-1776047033341.png)

Script will download container and do configuration of container

Now, when container is ready, Proxmox's script will invoke Pi-hole script (which is actual application installer)
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/hxLkJJrbF9w06VpY-image-1776050248856.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/hxLkJJrbF9w06VpY-image-1776050248856.png)


Final question is about 'Unbound' service
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/ZSdWS3yzI6J2BHYK-image-1776050468512.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/ZSdWS3yzI6J2BHYK-image-1776050468512.png)


Check in the browser the URL, which is indicated by installer.
```url
http://10.77.81.110/admin
```
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/4lQhoc8zFVnSMSlL-image-1776050541241.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/4lQhoc8zFVnSMSlL-image-1776050541241.png)



Configuration of Pi-hole is described in another page. 

The only change we want to perform is to change IP address. Locate container, open it's network configuration, change from DHCP to STATIC and define desired IP address (remember do define CIDR mask).
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/1rzsf3p8gPnagxkI-image-1776050869616.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/1rzsf3p8gPnagxkI-image-1776050869616.png)

Open container's shell , take a note of network address and perform restart
```bash
ip -br a
shutdown -r now
```

Verify after reboot again
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/H71VTfVlVgtmO6N8-image-1776051082382.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/H71VTfVlVgtmO6N8-image-1776051082382.png)
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/i6C6rYAGzjImQAsk-image-1776050993341.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/i6C6rYAGzjImQAsk-image-1776050993341.png)


Last thing, before go: verify that container has "Start on boot" tick box enabled. Thus, we shall be sure that DNS server will be started with hypervisor. That applies to all machines, which need to be started (such as main router :)
[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/3zDfT7RJKI6tvJsp-image-1776051154530.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/3zDfT7RJKI6tvJsp-image-1776051154530.png)



Next morning, after the first day of DNS traffic

With no filtering lists loads, DNS server serverd 54% of cached traffic to local clients. That is very good, which means, that local clients received DNS response earlier, rather then for original query.

[![](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/scaled-1680-/9NrSQA23AibamPP0-image-1776138176574.png)](https://storage.googleapis.com/iau-data-dox/uploads/images/gallery/2026-04/9NrSQA23AibamPP0-image-1776138176574.png)

# Pi-hole - DNS server

Purpose: Trusted and Filtering Feature Domain Name Resolution
Solution: Pi-hole (https://pi-hole.net/)
OS: Debian GNU/Linux 12 (bookworm)


preparations:



setup
```
# Pi-hole Automated Installer
This installer will transform your device into a network-wide ad blocker!
[OK]

# Open Source Software
The Pi-hole is free, but powered by your donations:
https://pi-hole.net/donate/
[OK]
```

Decide and assign static IP address
```
# Static IP Needed
The Pi-hole is a SERVER so it needs a STATIC IP ADDRESS to function properly.

IMPORTANT: If you have not already done so, you must ensure that this device has a static IP.

Depending on your operating system, there are many ways to achieve this, through DHCP reservation, or by manually assigning one. 
Please continue when the static addressing has been configured.
[Continue]


# Select Upstream DNS Provider. To use your own, select Custom.
(*)  Cloudflare (DNSSEC)


# Blocklists
Pi-hole relies on third party lists in order to block ads.
You can use the suggestion below, and/or add your own after installation.
Select 'Yes' to include:
StevenBlack's Unified Hosts List
[Yes]


# Enable Logging
Would you like to enable query logging?
[Yes]


# Select a privacy mode for FTL.                                     https://docs.pi-hole.net/ftldns/privacylevels/
(*) 0  Show everything
[Continue]
```

```
# Installation Complete!

Configure your devices to use the Pi-hole as their DNS server using:

IPv4: 10.166.0.2
IPv6: Not Configured
If you have not done so already, the above IP should be set to static.
View the web interface at http://pi.hole/admin:80 or
http://10.166.0.2:80/admin

Your Admin Webpage login password is (superpass)
```


Configure admin dashboard listening port
```bash
vi /etc/pihole/pihole.toml
```
Let's disable IPv6, disable HTTP and swap HTTPS port
```bash
#  port = "80o,443os,[::]:80o,[::]:443os"
  port = "445os"
```

Restart service and check port has been changed
```bash
systemctl restart pihole-FTL
ss -ntap | grep hole
````


## Advanced usage

Install database cient
```bash
apt install sqlite
```

Set pattern
```bash
# export pattern="dox.installanduse.com"
# export pattern="dox.2dz.fi"
export pattern="ntp"
```

List domains from gravity database (blocking list)
```bash
sqlite3 /etc/pihole/gravity.db \
    "SELECT domain FROM gravity \
    WHERE domain LIKE '%${pattern}%' \
    COLLATE NOCASE ORDER BY domain;"
```

List schema
```bash
sqlite3 -noheader /etc/pihole/pihole-FTL.db .schema
```

List queries from pihole-FTL database (log)
```bash
sqlite3 -noheader /etc/pihole/pihole-FTL.db \
    "SELECT DISTINCT domain
    FROM queries
    WHERE domain LIKE '%${pattern}%'
    ORDER BY domain;"
```

Detail
```bash
sqlite3 -noheader /etc/pihole/pihole-FTL.db \
    "SELECT DISTINCT d.domain
    FROM query_storage q
    JOIN domain_by_id d ON d.id = q.domain
    WHERE d.domain LIKE '%${pattern}%'
    ORDER BY d.domain;"
```

Query and client
```bash
sqlite3 -noheader /etc/pihole/pihole-FTL.db \
    "SELECT c.ip || ' ' || d.domain
    FROM query_storage q
    JOIN domain_by_id d ON d.id = q.domain
    JOIN client_by_id c ON c.id = q.client
    WHERE d.domain LIKE '%${pattern}%'
    ORDER BY c.ip, d.domain;"

# can be used by adding suffix " | uniq"
```

Queries by specific client
```bash
export pattern="dox.2dz.fi"
export src="192.168.0.0"

sqlite3 -noheader /etc/pihole/pihole-FTL.db \
    "SELECT DISTINCT d.domain
    FROM query_storage q
    JOIN domain_by_id d ON d.id = q.domain
    JOIN client_by_id c ON c.id = q.client
    WHERE c.ip = '${src}'
      AND d.domain LIKE '%${pattern}%'
    ORDER BY d.domain;"
```

With count, most frequent
```bash
sqlite3 -noheader /etc/pihole/pihole-FTL.db \
    "SELECT d.domain, COUNT(*)
    FROM query_storage q
    JOIN domain_by_id d ON d.id = q.domain
    WHERE d.domain LIKE '%${pattern}%'
    GROUP BY d.domain
    ORDER BY COUNT(*) DESC, d.domain;"
```

Only last 24 hours
```bash
sqlite3 -noheader /etc/pihole/pihole-FTL.db \
    "SELECT DISTINCT d.domain
    FROM query_storage q
    JOIN domain_by_id d ON d.id = q.domain
    WHERE d.domain LIKE '%${pattern}%'
      AND q.timestamp > unixepoch('now','-1 day')
    ORDER BY d.domain;"
```

Detail: timestamp + source IP + domain
```bash
sqlite3 -noheader /etc/pihole/pihole-FTL.db \
    "SELECT datetime(q.timestamp,'unixepoch','localtime') || ' ' || c.ip || ' ' || d.domain
    FROM query_storage q
    JOIN domain_by_id d ON d.id = q.domain
    JOIN client_by_id c ON c.id = q.client
    WHERE d.domain LIKE '%${pattern}%'
    ORDER BY q.timestamp;"
```

# Public name servers (NSs)



# Public NSs' FQDNs to IPv4 list

```
2026-06-23  * init /A
```


```bash
vi FQDNs.list
```
```list
anycast.dns.nextdns.io
child-noads.joindns4.eu
common.dot.dns.yandex.net
dns-tls.bitwiseshift.net
dns-tls.qis.io
dns.alidns.com
dns.alidns.com
dns.cloudflare.com
dns.decloudus.com
dns.digitale-gesellschaft.ch
dns.google
dns.jupitrdns.com
dns.larsdebruin.net
dns.neutopia.org
dns.nextdns.io
dns.opendns.com
dns.pub
dns.pumplex.com
dns.rabbitdns.org
dns.surfsharkdns.com
dns.switch.ch
dns10.quad9.net
dnsovertls.sinodun.com
dnsovertls1.sinodun.com
doh.dns.sb
doh.ffmuc.net
doh.libredns.gr
doh.nl.ahadns.net
doh.opendns.com
doh.qis.io
doq.ffmuc.net
dot.ffmuc.net
dot.libredns.gr
dot.nl.ahadns.net
dot.pub
dot.sb
dot.seby.io
freedns.controld.com
getdnsapi.net
ns1.dnsprivacy.at
ns2.dnsprivacy.at
one.one.one.one
ordns.he.net
p0.freedns.controld.com
resolver-eu.lelux.fi
resolver.dnsprivacy.org.uk
sm2.doh.pub
unfiltered.adguard-dns.com
unfiltered.joindns4.eu
unicast.censurfridns.dk
wikimedia-dns.org
```

Resolve A records
```bash
while IFS= read -r line; do echo $line && dig +short A "$line"; done < FQDNs.list
```
```
dig: '' is not a legal name (unexpected end of input)
anycast.dns.nextdns.io
45.90.30.0
45.90.28.0
child-noads.joindns4.eu
86.54.11.11
86.54.11.211
common.dot.dns.yandex.net
77.88.8.8
77.88.8.1
dns-tls.bitwiseshift.net
81.187.221.24
dns-tls.qis.io
157.230.188.174
dns.alidns.com
223.6.6.6
223.5.5.5
dns.alidns.com
223.5.5.5
223.6.6.6
dns.cloudflare.com
162.159.61.8
172.64.41.8
dns.decloudus.com
46.224.208.209
dns.digitale-gesellschaft.ch
185.95.218.43
185.95.218.42
dns.google
8.8.8.8
8.8.4.4
dns.jupitrdns.com
155.248.232.226
dns.larsdebruin.net
dns.neutopia.org
dns.nextdns.io
steering.nextdns.io.
185.240.84.237
170.39.225.135
dns.opendns.com
208.67.220.220
208.67.222.222
dns.pub
120.53.53.53
1.12.12.12
dns.pumplex.com
13.248.169.48
76.223.54.146
dns.rabbitdns.org
104.21.32.168
172.67.153.19
dns.surfsharkdns.com
194.169.169.169
dns.switch.ch
130.59.31.251
130.59.31.248
dns10.quad9.net
9.9.9.10
149.112.112.10
dnsovertls.sinodun.com
dnsovertls1.sinodun.com
doh.dns.sb
na.doh.sb.
us-chi.doh.sb.
104.128.62.173
doh.ffmuc.net
anycast.ffmuc.net.
5.1.66.255
doh.libredns.gr
116.202.176.26
doh.libredns.gr/ads
doh.nl.ahadns.net
5.2.75.75
doh.opendns.com
146.112.41.2
doh.qis.io
157.230.188.174
doq.ffmuc.net
anycast.ffmuc.net.
5.1.66.255
dot.ffmuc.net
anycast.ffmuc.net.
5.1.66.255
dot.libredns.gr
116.202.176.26
dot.nl.ahadns.net
5.2.75.75
dot.pub
1.12.12.12
120.53.53.53
dot.sb
45.11.45.11
185.222.222.222
dot.seby.io
45.76.113.31
freedns.controld.com
76.76.2.11
getdnsapi.net
185.49.141.38
ns1.dnsprivacy.at
ns2.dnsprivacy.at
one.one.one.one
1.1.1.1
1.0.0.1
ordns.he.net
74.82.42.42
p0.freedns.controld.com
76.76.2.11
resolver-eu.lelux.fi
resolver.dnsprivacy.org.uk
sm2.doh.pub
106.55.91.174
unfiltered.adguard-dns.com
94.140.14.141
94.140.14.140
unfiltered.joindns4.eu
86.54.11.200
86.54.11.100
unicast.censurfridns.dk
89.233.43.71
```

# Lists of Public Name Servers sources

Lists publically available of name servers:

<table border="1" id="bkmrk-adguard-https%3A%2F%2Fadgu" style="border-collapse: collapse; width: 100%;"><colgroup><col style="width: 28.2857%;"></col><col style="width: 71.7123%;"></col></colgroup><tbody><tr><td>  
</td><td>  
</td></tr><tr><td>AdGuard</td><td>[https://adguard-dns.io/kb/general/dns-providers/](https://adguard-dns.io/kb/general/dns-providers/)</td></tr><tr><td>  
</td><td>  
</td></tr><tr><td>  
</td><td>  
</td></tr><tr><td>  
</td><td>  
</td></tr><tr><td>  
</td><td>  
</td></tr><tr><td>  
</td><td>  
</td></tr><tr><td>  
</td><td>  
</td></tr><tr><td>  
</td><td>  
</td></tr><tr><td>  
</td><td>  
</td></tr></tbody></table>

# Public NSs (DoH, DoT, DoQ)

```ini
#
# AdGuard DNS
https://unfiltered.adguard-dns.com/dns-query
h3://unfiltered.adguard-dns.com/dns-query
tls://unfiltered.adguard-dns.com
quic://unfiltered.adguard-dns.com
#
#
# Ali DNS
https://dns.alidns.com/dns-query
tls://dns.alidns.com
quic://dns.alidns.com:853
#
#
# Cloudflare DNS
https://dns.cloudflare.com/dns-query
tls://one.one.one.one
#
#
# ControlD
https://freedns.controld.com/p0
tls://p0.freedns.controld.com
#
#
# DeCloudUs DNS
https://dns.decloudus.com/dns-query
tls://dns.decloudus.com
#
#
# DNS Privacy
tls://getdnsapi.net
tls://unicast.censurfridns.dk
tls://anycast.censurfridns.dk
#
#
# DNS.SB
https://doh.dns.sb/dns-query
#
#
# DNSPod Public DNS+
https://dns.pub/dns-query
https://sm2.doh.pub/dns-query
tls://dot.pub
#
#
# Hurricane Electric Public Recursor
https://ordns.he.net/dns-query
tls://ordns.he.net
#
#
# NextDNS
https://dns.nextdns.io
tls://dns.nextdns.io
https://anycast.dns.nextdns.io
tls://anycast.dns.nextdns.io
#
#
# Quad9 DNS
https://dns10.quad9.net/dns-query
tls://dns10.quad9.net
#
#
# Surfshark DNS
https://dns.surfsharkdns.com/dns-query
quic://dns.surfsharkdns.com
#
#
# Wikimedia DNS
https://wikimedia-dns.org/dns-query
tls://wikimedia-dns.org
#
#
# Digitale Gesellschaft DNS
https://dns.digitale-gesellschaft.ch/dns-query
tls://dns.digitale-gesellschaft.ch
#
#
# DNS4EU
https://unfiltered.joindns4.eu/dns-query
tls://child-noads.joindns4.eu
#
#
# LibreDNS
https://doh.libredns.gr/dns-query
https://doh.libredns.gr/ads
tls://dot.libredns.gr
#
#
# SWITCH DNS
https://dns.switch.ch/dns-query
tls://dns.switch.ch
tls://130.59.31.248
#
#
# FFMUC DNS (Freifunk München)
tls://dot.ffmuc.net
https://doh.ffmuc.net/dns-query
h3://doh.ffmuc.net/dns-query
quic://doq.ffmuc.net
#
#
# Seby DNS
tls://dot.seby.io
#
#
```



For reference: major vendors list, can be used to DNS boot-straping (initial resolution of main list)
```ini
# Google DNS
https://dns.google/dns-query
tls://dns.google
#
#
# Apple DNS
https://doh.dns.apple.com/dns-query
https://17.253.18.115
https://17.253.18.117
https://17.253.18.149
https://17.253.18.151
https://64.78.200.1
https://64.78.201.1
#
#
# Yandex DNS
https://common.dot.dns.yandex.net/dns-query
tls://common.dot.dns.yandex.net
#
#
# Cisco OpenDNS
https://doh.opendns.com/dns-query
tls://dns.opendns.com
#
#

```