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:

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
# =================================
1 Like

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.

1 Like

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!

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.