NGINX with DNS over TLS = only localhost

Expected Behaviour:

Show an IP of the device that is using the pihole

Actual Behaviour:

Shows localhost since it is being proxied trough nginx
nginx proxy:

upstream dns-servers {
  zone dns 64k;
  server 127.0.0.1:53; #unbound 
}
server {
  listen 853 ssl; # managed by Certbot
  #proxy_bind $remote_addr transparent;
  #proxy_bind $remote_addr:$remote_port transparent;
  proxy_pass dns-servers;
  ssl_preread on;


  ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem; # managed by Certbot
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
  ssl_protocols        TLSv1.2 TLSv1.3;

  ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:E$
  ssl_prefer_server_ciphers       on;
  ssl_handshake_timeout           10s;
  ssl_session_cache               shared:DoT:10m;
  ssl_session_timeout             1d;
  ssl_session_tickets             off;

  #proxy_protocol on;
  #set_real_ip_from  10.0.0.0/8;
  #proxy_bind $remote_addr:$remote_port transparent;
  #set_real_ip_from $proxy_protocol_addr;
}

Debug Token:

https://tricorder.pi-hole.net/e4x15dwila

Is this a recent configuration change? Your debug log show significant activity from 21 clients in the previous 24 hours.

   [2019-12-13 19:42:08.262 1280] Imported 341916 queries from the long-term database
   [2019-12-13 19:42:08.262 1280]  -> Total DNS queries: 341916
   [2019-12-13 19:42:08.262 1280]  -> Cached DNS queries: 306397
   [2019-12-13 19:42:08.262 1280]  -> Forwarded DNS queries: 26245
   [2019-12-13 19:42:08.262 1280]  -> Exactly blocked DNS queries: 9268
   [2019-12-13 19:42:08.262 1280]  -> Unknown DNS queries: 6
   [2019-12-13 19:42:08.262 1280]  -> Unique domains: 3172
   [2019-12-13 19:42:08.262 1280]  -> Unique clients: 21
   [2019-12-13 19:42:08.262 1280]  -> Known forward destinations: 1

From the PIv4 address of the Pi-Hole, it appears you are running an open resolver. The Pi-Hole host is on a different IP range than the IP for which Pi-Hole is configured.

*** [ DIAGNOSING ]: Networking
[✓] IPv4 address(es) bound to the ens3 interface:
   10.0.0.27/24 does not match the IP found in /etc/pihole/setupVars.conf (https://discourse.pi-hole.net/t/use-ipv6-ula-addresses-for-pi-hole/2127)
   10.0.0.12/24 does not match the IP found in /etc/pihole/setupVars.conf (https://discourse.pi-hole.net/t/use-ipv6-ula-addresses-for-pi-hole/2127)

If this is the case, you should secure this from external traffic.

It's correct. There are around 21 connected clients. And it is secured with iptables and fail2ban :wink:

Perhaps not.

dig +short cnn.com @132.xxx.xxx.xx7
151.101.1.67
151.101.65.67
151.101.129.67
151.101.193.67

Uhm van you perhaps send me a pm on how to secure it more without doing ip filtering ?
Let's get back on topic. How to get it working so I can see an ip instead of localhost for the nginx stream.

Thanks but that is for DNS over HTTPS. He uses a conf file for it but with TLS you will need to have a stream where that command isn't allowed like this:
https://www.bentasker.co.uk/documentation/linux/470-building-a-dns-over-tls-server

Put a VPN on it and it will be very secure. As is, you have port 53 exposed to the world.

Yea I know but lets get back to the question :wink: how to get that IP from a proxy stream

But when using unbound you're missing out on all the goodies of pihole...

So maybe a feature request that pihole supports dot ?

Exactly!

I see there is already a feature request going on. Lets move the discussion to there.

exactly. And there is a option for nginx to get the ip, but that means using 2 servers, which I am not keen about. Since I only am renting 1 VPS.

  • I had the same issue, when running Pihole on a VPC, as there is proxy in between.
  • All my android clients were showing up as localhost
  • What you need is to make NGINX as transparent proxy, so it would forward the source IP to Pihole.
  • Following are the changes you need to make, in order to get this working.
  • This code is for Ubuntu 18.04 LTS. Please change syntax accordingly.
# =================================
# =================================
# Enabling NGINX Transparency Proxy
# https://www.nginx.com/blog/ip-transparency-direct-server-return-nginx-plus-transparent-proxy/
# =================================
# =================================
# Edit DNS-Over-TLS server block (e.g. /etc/nginx/streams/dns-over-tls)
# Replace upstream DNS IP with Server Interface IP on which pihole is listening
  server [XXXX:XXXX::XXXX]:53;            # For IPv6
  server X.X.X.X:53;                      # For IPv4

# Add the NGINX Proxy Bind to your server block
  proxy_bind $remote_addr transparent;

# =================================
# Run NGINX as Root, instead of www-data

sed -i 's/www-data/root/' /etc/nginx/nginx.conf
# =================================
# Add IPtables marking rules to tag DNS response packets
# You can use any number to tag the packets within kernal

# For IPv6
ip6tables -t mangle -A OUTPUT -p tcp --sport 53 -j MARK --set-xmark 7

# For IPv4
iptables -t mangle -A OUTPUT -p tcp --sport 53 -j MARK --set-xmark 7

# =================================
# Add IP rules to divert DNS response packets to NGINX
# We need this so NGINX can intercept the DNS response and send over TLS tunnel
# I used table 99, but you could use any number

# For IPv6
ip -6 rule add fwmark 7 lookup 99
ip -6 route add local ::/0 dev lo table 99

# For IPv4
ip rule add fwmark 7 lookup 99
ip route add local 0.0.0.0/0 dev lo table 99

# =================================
# Restart NGINX service

service nginx restart
# =================================
# Save IP6tables & IPtables rules

apt install iptables-persistent -y

ip6tables-save > /etc/iptables/rules.v6
iptables-save > /etc/iptables/rules.v4
# =================================
# Ignore localhost queries (Optional), as I don't care what my VPC is doing.

echo "IGNORE_LOCALHOST=yes" >> /etc/pihole/pihole-FTL.conf
service pihole-FTL restart
# =================================

It does work but 1 issue though. When I have my android phone connected via 4g it works fine. When I connect to my home router via wifi that has it DNS set to the pihole's public IP I get stream timeouts from nginx on my server:
2020/01/03 17:44:46 [error] 7235#7235: *1 upstream timed out (110: Connection timed out) while proxying connection, client: ******, server: 0.0.0.0:853, upstream: "10.0.0.27:53", bytes from/to client:390/0, bytes from/to upstream:0/0

Not expected. Where is your Pihole hosted? Public Cloud or your home network?

Also, your router's DNS settings shouldn't matter. Because, your phone will setup TCP connection to your DNS-Over-TLS server over 853 port.

Try the following troubleshooting commands, and see the outputs.

=================================

nslookup dnsname.domain.com # DNS resolution for Pihole DNS-Over-TLS server 4G and Wifi network
netstat -tulpane # See what port your server is listening
pihole tail # Pihole logs
ip6tables -t mangle # IPtables IPv6 Mangle Table, check rule hitcount
ip6tables -t mangle # IPtables IPv4 Mangle Table, check rule hitcount
tcpdump -n -i any tcp port 853 -w dump.pcap # TCPDump command to verify DNS-Over-TLS packets

if you like paste the output of these commands or message me directly with outputs.

It's hosted on a external free server in the cloud. And I had a typo in my iptables. Fail2ban was set incorrectly and banned everyone. That stuff is still new to me and you can fuck it up easily. Thanks for the help though!