<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Dns on Sysadmin Tales</title>
    <link>https://blog.ssb-tech.net/tags/dns/</link>
    <description>Recent content in Dns on Sysadmin Tales</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 02 Oct 2026 21:39:10 -0400</lastBuildDate>
    <atom:link href="https://blog.ssb-tech.net/tags/dns/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Proxying AdGuard Home DNS-over-HTTPS with Nginx</title>
      <link>https://blog.ssb-tech.net/posts/adguard-home-doh-nginx/</link>
      <pubDate>Tue, 28 Oct 2025 20:38:03 -0400</pubDate>
      <guid>https://blog.ssb-tech.net/posts/adguard-home-doh-nginx/</guid>
      <description>&lt;p&gt;A few months ago I switched from using Pi-hole to AdGuardHome for serving adblocking DNS to not just the clients in my home, but also my mobile devices.&lt;/p&gt;&#xA;&lt;p&gt;There were a few reasons for this, but chief among them was its proper support for DNS-over-TLS (DOT) and DNS-over-HTTPS (DOH).&lt;/p&gt;&#xA;&lt;p&gt;I had previously been running unencrypted DNS via &lt;a href=&#34;https://tailscale.com&#34;&gt;Tailscale&lt;/a&gt;, but because of the way I have things configured, this mean that every DNS request from an external device looked like it was coming from my &lt;a href=&#34;https://tailscale.com/kb/1019/subnets&#34;&gt;subnet router&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;DOT and DOH both support the concept of unique &lt;a href=&#34;https://github.com/AdguardTeam/AdGuardHome/wiki/Clients&#34;&gt;client IDs&lt;/a&gt;, which makes it easier to track down which device a particular request is coming from.&lt;/p&gt;&#xA;&lt;p&gt;However, one of the few problems that I&amp;rsquo;ve encountered with AdGuard is that there&amp;rsquo;s no way to separate the admin interface from the port that DOH uses.&lt;/p&gt;&#xA;&lt;p&gt;I brought up this conundrum in the Discord server for the since defunct &lt;a href=&#34;https://selfhosted.show&#34;&gt;Self-Hosted Podcast&lt;/a&gt;, and one of the users there (thanks Quietsy!) made an interesting suggestion that I must admit hadn&amp;rsquo;t crossed my mind.&lt;/p&gt;&#xA;&lt;p&gt;Simply put a reverse proxy in front of the application and implement access controls based on path.&lt;/p&gt;&#xA;&lt;p&gt;DOH runs over the &lt;code&gt;/dns-query&lt;/code&gt; endpoint, while the admin interface is at the root &lt;code&gt;/&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I logged into the VPS that&amp;rsquo;s running my public-facing AdGuard server and installed nginx.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;sudo apt install nginx&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;Then I stopped AdGuard:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl stop AdGuardHome&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I then edited &lt;code&gt;AdGuardHome.yaml&lt;/code&gt; (The path to this file may vary based on how you installed AdGuard).&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo vim AdGuardHome.yaml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I changed the &lt;code&gt;https_port&lt;/code&gt; from its default 443 to 4433, and the &lt;code&gt;http&lt;/code&gt; listening port from 80 to 8080.&lt;/p&gt;&#xA;&lt;p&gt;Then start AdGuard back up with:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl start AdGuardHome&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then I created a site in Nginx at &lt;code&gt;/etc/nginx/sites-enabled/adguardhome&lt;/code&gt; with the following settings:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;proxy_cache_path /var/cache/adguardhome levels=1:2 keys_zone=adguard_cache:10m max_size=3g inactive=120m use_temp_path=off;&#xA;&#xA;upstream adguardhome {&#xA;    server 127.0.0.1:4433;&#xA;    keepalive 64;&#xA;}&#xA;&#xA;server {&#xA;    server_name adguard.domain.tld;&#xA;    listen 80;&#xA;    # listen [::]:80 default_server;&#xA;&#xA;    return 301 https://$host$request_uri;&#xA;}&#xA;&#xA;server {&#xA;    server_name adguard.domain.tld;&#xA;    listen 443 ssl http2;&#xA;&#xA;    access_log /var/log/nginx/agh.access.log;&#xA;    error_log /var/log/nginx/agh.error.log warn;&#xA;&#xA;    gzip on;&#xA;    gzip_vary on;&#xA;    gzip_proxied any;&#xA;    gzip_comp_level 6;&#xA;    gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;&#xA;&#xA;    ssl_dhparam /etc/nginx/ssl/dhparam.pem;&#xA;    ssl_session_timeout 1d;&#xA;    ssl_session_cache shared:MozSSL:10m;&#xA;    ssl_session_tickets off;&#xA;&#xA;    ssl_protocols TLSv1.2 TLSv1.3;&#xA;    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;&#xA;    ssl_prefer_server_ciphers off;&#xA;&#xA;    ssl_certificate /etc/letsencrypt/live/adguard.domain.tld/fullchain.pem;&#xA;    ssl_certificate_key /etc/letsencrypt/live/adguard.domain.tld/privkey.pem;&#xA;&#xA;    ssl_early_data on;&#xA;&#xA;    add_header X-Frame-Options &amp;#34;SAMEORIGIN&amp;#34; always;&#xA;    add_header X-XSS-Protection &amp;#34;1; mode=block&amp;#34; always;&#xA;    add_header X-Content-Type-Options &amp;#34;nosniff&amp;#34; always;&#xA;    add_header Referrer-Policy no-referrer;&#xA;    add_header Strict-Transport-Security &amp;#34;max-age=63072000&amp;#34; always;&#xA;    add_header Permissions-Policy &amp;#34;interest-cohort=()&amp;#34;;&#xA;&#xA;    # Discourage Google bots from indexing this site&#xA;    add_header X-Robots-Tag &amp;#34;noindex&amp;#34;;&#xA;&#xA;    # Allow the dns-query endpoint&#xA;    location /dns-query {&#xA;    proxy_pass https://adguardhome/dns-query;&#xA;&#xA;    proxy_set_header Host $host;&#xA;    proxy_set_header X-Real-IP $remote_addr;&#xA;    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;&#xA;    proxy_set_header X-Forwarded-Proto $scheme;&#xA;&#xA;    proxy_http_version 1.1;&#xA;    proxy_set_header Connection &amp;#34;&amp;#34;;&#xA;&#xA;    # Timeouts&#xA;    proxy_connect_timeout 90;&#xA;    proxy_send_timeout 300;&#xA;    proxy_read_timeout 90s;&#xA;    }&#xA;&#xA;    # For all other locations, return 403.&#xA;    location / {&#xA;            return 403;&#xA;    }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Enable and start the webserver:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo systemctl enable --now nginx&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, lets use &lt;a href=&#34;https://github.com/mr-karan/doggo&#34;&gt;doggo&lt;/a&gt; to test our DOH configuration.&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;doggo fedoraproject.org @https://adguard.domain.tld/dns-query/client-id&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME                    TYPE    CLASS   TTL     ADDRESS         NAMESERVER&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fedoraproject.org.      A       IN      47s     8.43.85.67      https://adguard.domain.tld/dns-query/client-id&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fedoraproject.org.      A       IN      47s     8.43.85.73      https://adguard.domain.tld/dns-query/client-id&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fedoraproject.org.      A       IN      47s     152.2.23.104    https://adguard.domain.tld/dns-query/client-id&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fedoraproject.org.      A       IN      47s     34.211.44.206   https://adguard.domain.tld/dns-query/client-id&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fedoraproject.org.      A       IN      47s     140.211.169.196 https://adguard.domain.tld/dns-query/client-id&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fedoraproject.org.      A       IN      47s     38.145.32.21    https://adguard.domain.tld/dns-query/client-id&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fedoraproject.org.      A       IN      47s     152.2.23.103    https://adguard.domain.tld/dns-query/client-id&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fedoraproject.org.      A       IN      47s     67.219.144.68   https://adguard.domain.tld/dns-query/client-id&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fedoraproject.org.      A       IN      47s     38.145.32.20    https://adguard.domain.tld/dns-query/client-id&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Perfect!&lt;/p&gt;&#xA;&lt;p&gt;Now, lets make sure I can&amp;rsquo;t access the admin interface from the public facing nginx&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;Getting a 403 error as expected for other paths&#34; loading=&#34;lazy&#34; src=&#34;https://blog.ssb-tech.net/posts/adguard-home-doh-nginx/images/adguardnginx403.png&#34;&gt;&#xA;Awesome.&lt;/p&gt;&#xA;&lt;p&gt;I am also notably &lt;strong&gt;&lt;em&gt;NOT&lt;/em&gt;&lt;/strong&gt; exposing port 53. Only 853 and 443, both of which are using TCP.&lt;/p&gt;&#xA;</description>
    </item>
    <item>
      <title>Adventures in DNS (But it&#39;s actually DHCP this time.)</title>
      <link>https://blog.ssb-tech.net/posts/adventures-in-dhcp-and-dns/</link>
      <pubDate>Mon, 02 Dec 2024 23:57:12 -0500</pubDate>
      <guid>https://blog.ssb-tech.net/posts/adventures-in-dhcp-and-dns/</guid>
      <description>&lt;p&gt;So, story time.&lt;/p&gt;&#xA;&lt;p&gt;Boss has a friend who does IT for an electrical contractor 30 mins or so away from our primary office, and he brings us in because he’s having DNS issues he can’t figure out&lt;/p&gt;&#xA;&lt;p&gt;Get onsite there and go over his setup – typical mess of a network closet with no brand consistency and mismatched patch cables, whatever. Otherwise looks good from a network perspective.&lt;/p&gt;&#xA;&lt;p&gt;However, he mentions that he has no access to the firewall since it’s owned by the ISP.&lt;/p&gt;&#xA;&lt;p&gt;Personally, I would have been on top of the ISP until they either gave me the ability to log into that thing, or had them put it in bridge mode and installed my own firewall. I do not like and do not trust any firewall that I do not control. Sorry, it&amp;rsquo;s just the paranoid sysadmin in me.&lt;/p&gt;&#xA;&lt;p&gt;So we finally start looking at the problem and the issue is that he keeps having to hardcode his DNS settings and he’s having weird WiFi connectivity issues. Everything points to DHCP not setting the DNS settings consistently… which made me suspect a rogue DHCP server.&lt;/p&gt;&#xA;&lt;p&gt;So I connect my laptop and run an ifconfig – and I see that DHCP is coming from some IP address 10.0.0.69. Knowing at this point he didn’t have access to the firewall, I asked him if that was one of his servers, he says no. I asked him where he WAS running DHCP, and was told it was on one of the domain controllers, but he didn’t remember which one. Red flag #1.&lt;/p&gt;&#xA;&lt;p&gt;I do an nmap scan to see if I can grab the vendor of the device that has that IP – it reports back that it’s from Axis Communications. Not being familiar with it, I asked about that vendor, and was told that that was the brand of their security cameras and NVR.&lt;/p&gt;&#xA;&lt;p&gt;I go okay, so there’s your problem right there. You have 2 DHCP servers, and it’s a question of which one responds first to the DHCPDISCOVER broadcast.&lt;/p&gt;&#xA;&lt;p&gt;So we go look at the cameras – no passwords for ANYTHING. we lucked into finding the password for the computer controlling them written on a piece of paper near the rack it was installed in.&lt;/p&gt;&#xA;&lt;p&gt;Eventually I figured out that one of the cameras had DHCP running, and we turned it off, but then we tried getting a new DHCP lease – it got one, but in the wrong subnet entirely.&lt;/p&gt;&#xA;&lt;p&gt;This of course, understandably confuses me. I noticed that the DHCP server is now 192.168.0.1, which isn’t even the right subnet. What the deuce?&lt;/p&gt;&#xA;&lt;p&gt;Ran another network scan, that IP has the same vendor as before, but a different MAC address now, so it’s a totally different device.&lt;/p&gt;&#xA;&lt;p&gt;Turns out, the appliance they have running their cameras? it’s 2 devices in one – a windows PC acting as the controller, and the built in switch which has its own DHCP server (and presumably it’s own operating system and mainboard).&lt;/p&gt;&#xA;&lt;p&gt;Of course, no password for that either, so I Googled and found it’s on a sticker on the bottom of the unit. I found the password, logged in and turned off DHCP. That’s it, right? We’ve fixed it?&lt;/p&gt;&#xA;&lt;p&gt;Tried to get a lease once more… nothing happens at all.&lt;/p&gt;&#xA;&lt;p&gt;Turns out… he was NOT running DHCP on the domain controller. Or anywhere except for this NVR, that had it turned on by default.&lt;/p&gt;&#xA;&lt;p&gt;I installed the DHCP role on one of the domain controllers and configured it with the proper settings, and a reasonable scope, along with primary and secondary DNS for their domain. Did another ipconfig /renew on one of their machines and… success! We got an IP in the correct subnet, and it is assigning the correct DNS servers to the client machines. WiFi works perfectly as well!&lt;/p&gt;&#xA;&lt;p&gt;How the network got into this state and stayed operational for as long as it did? Who can say? Miracles happen every day, right?&lt;/p&gt;&#xA;&lt;p&gt;Like they say, it’s always DNS. But sometimes it’s not DNS, sometimes it’s badly misconfigured DHCP.&lt;/p&gt;&#xA;</description>
    </item>
  </channel>
</rss>
