中文 English

Why Did My Blog Redirect to Baidu? A DNS Incident and the AdGuard Home Setting That Actually Fixed It

Published: 2026-09-17 · 阅读量 --
DNS 域名解析 网络 Network 故障排查 Troubleshooting Safety Security 自动化 Automation

The finding: the original DNS resolution path was returning incorrect answers. An HTTP request reached the wrong destination and received a redirect to Baidu’s mobile site. Keeping the same domain but connecting to a verified hosting address produced valid HTTPS and the expected page. After switching AdGuard Home to a DoH upstream, the user confirmed that normal browsing worked again.

We did not identify the exact device or network hop responsible. This is an evidence-based account of a faulty DNS path, not an accusation against a particular router, provider, or redirect destination.

1. I opened my own blog. Why was I looking at Baidu?

The incident began with an ordinary action: opening a familiar blog. The destination was anything but familiar—the browser ended up on Baidu’s mobile site. Had someone compromised the website? Had a domain expired? Was there an unexpected JavaScript redirect? Or was the DNS answer wrong?

The site uses Hugo to generate static pages and GitHub Pages to serve them. Its public custom domain has a CNAME pointing to the Pages site name. Normally, that is as unremarkable as finding a shop in a phone directory: you remember the name, and the directory supplies the number.

But a wrong number in the directory does not mean the real shop has closed. You might call the wrong business, and that business might tell you to go somewhere else. There are now two separate events: finding the wrong destination, then receiving instructions from it.

Original diagram: a wrong address book leads the browser to the wrong front door

Figure 1. An original SVG illustration, not an incident screenshot. Official documentation screenshots below are separately identified and attributed.

2. Asking for directions, knocking on the door, checking identity

Imagine visiting a friend after school. You need an address, a conversation at the door, and some confidence that the person answering is actually your friend.

DNS supplies the address. An A record supplies an IPv4 address; an AAAA record supplies an IPv6 address. A CNAME says that one name is an alias for another, which must then be resolved. A custom domain can have the correct alias while the final address returned through the resolution chain is wrong.

HTTP is the conversation after the connection. A server might say “here is your page,” represented by a successful response such as 200. Or it might say “temporarily go over there,” represented by 302 with a Location header. DNS itself does not send an HTTP redirect. JavaScript navigation and HTML refresh directives are other possible mechanisms, which need their own investigation.

HTTPS adds an identity check. Reaching an address is insufficient: the endpoint must present a certificate valid for the requested domain, under a trusted certificate chain. A hostname mismatch should stop the connection. Disabling certificate validation to “see whether the page works” removes the very check that can expose an incorrect destination.

Original diagram separating DNS resolution, connection establishment and HTTP response

Figure 2. A bad DNS answer and an HTTP redirect are different events in the same chain. TLS can reject an incorrect identity before a normal HTTPS request completes.

Real screenshot of the MDN 302 documentation

Figure 3. Actual browser capture of MDN: 302 Found, explaining the temporary redirect and its Location header.

3. What the investigation actually established

Before changing settings, we compared the original path, independent encrypted lookups, and an HTTPS request directed to a verified hosting address. Complete numeric addresses, device names, and internal network details are intentionally omitted from this public account.

Check Observation What it supports
System lookup and two local DNS paths The same unexpected IPv4 answer The issue was broader than a single browser page
Original AAAA lookup An unexpected IPv6 record mixed with normal records IPv6 also needed investigation
HTTP over the original path 302 Found pointing to Baidu’s mobile site The redirect was directly reproducible
HTTPS over the original path Certificate hostname mismatch The reached endpoint could not authenticate as the blog
Two independent DoH services Matching GitHub Pages IPv4 address sets An independent reference for comparison
AAAA through one of those DoH services The expected Pages IPv6 address set A reference for the IPv6 discrepancy
Same domain, verified hosting address Valid certificate, 200, expected blog title The intended site was still serving content
Retrieved homepage from that path No Baidu target string or meta refresh found No such redirect evidence in the inspected homepage
AdGuard Home switched to upstream DoH User reported normal browsing restored Confirmation at the user-experience level

That last row matters. A successful terminal request is useful evidence, but it cannot tell us whether a phone still has an old cache entry, or whether another browser uses its own resolver. An API response, a saved configuration, and a working browser are related outcomes—not interchangeable ones.

Original evidence diagram: original path, independent lookup and same-host request

Figure 4. The observations support a faulty original DNS path. They do not identify the exact hop that modified, supplied, or cached the answer.

Why preserve the domain when testing a different address?

Entering a numeric address directly changes the HTTP host and the name checked by TLS. A shared hosting platform needs the requested domain to know which site to serve. Testing the address alone can therefore make a healthy hosting service look broken.

The curl --resolve option changes the connection address while preserving the domain for TLS SNI, certificate validation, and the HTTP request. This is a template; obtain the address from an independently verified source, rather than copying an unfamiliar value from a tutorial:

# BLOG_HOST: the public domain under investigation
# VERIFIED_ADDRESS: an independently checked hosting address
# For IPv6, enclose the address in brackets as required by curl
curl --noproxy '*' --connect-timeout 5 --max-time 20 \
  --resolve "${BLOG_HOST}:443:${VERIFIED_ADDRESS}" \
  -I "https://${BLOG_HOST}/"

HEAD is convenient for inspecting headers, but servers can handle HEAD and GET differently. Retrieve the actual page and open it in a browser as well. The proxy option makes this a direct-path test; if normal access uses a proxy, test that path separately so the comparison remains meaningful.

Real screenshot of GitHub Pages custom-domain documentation

Figure 5. Browser capture of GitHub Pages custom-domain documentation. Both routing and domain identity matter on shared hosting.

4. Why changing to a famous DNS address was not enough

One particularly useful observation was that ordinary UDP queries sent to two well-known public resolver addresses still returned the same unexpected answer. A TCP query to one of them returned normal Pages addresses instead.

Writing a provider’s destination address into a command does not prove that its answer arrived unchanged. Transparent forwarding, interception, a faulty cache, or another component on the path could explain the result. These observations are consistent with DNS poisoning or hijacking, but they do not establish who did it or where it happened.

Think of calling a different shop while someone keeps interrupting the telephone line. Changing the number may not remove the interference. Protecting the communication channel addresses a different part of the problem.

Traditional DNS over TCP happened to work in this comparison. That does not make it an authenticated or encrypted protocol. It lacks the transport confidentiality and server authentication offered by TLS, so one successful TCP lookup is not a durable security guarantee.

What DoH changes

DNS over HTTPS carries DNS queries and responses inside HTTPS. Instead of shouting an address question across a crowded street, you send it in a sealed envelope to an office whose identity you have checked. Intermediaries have a much harder time reading or altering the contents, and an impersonator must get past certificate validation.

The envelope still does not guarantee that the office is honest or infallible. The chosen resolver can see the queries, apply filtering, make configuration mistakes, or return unsuitable answers. DoH is not an anonymity system. It also cannot repair a compromised web application, an incorrect authoritative DNS record, or malware controlling the client.

Real screenshot of RFC 8484

Figure 6. Browser capture of RFC 8484: DNS Queries over HTTPS, which specifies the mapping between DNS query-response pairs and HTTPS exchanges.

5. AdGuard Home has two encrypted directions

This is the configuration distinction worth remembering:

Device → client-side DNS → AdGuard Home → upstream DNS → recursive resolver

The first link carries questions from devices to AdGuard Home. The second carries forwarded questions from AdGuard Home to its upstream resolver. The relevant change in this incident was on the second link: using HTTPS endpoints in DNS settings → Upstream DNS servers.

The separate Encryption settings section generally configures AdGuard Home itself to serve HTTPS, DoH, DoT, or related protocols. That involves certificates, listening ports, and client configuration. Enabling incoming encrypted service while retaining the faulty plaintext upstream does not necessarily solve the original issue.

Original diagram of the client link and the upstream link

Figure 7. The links have separate configuration responsibilities. Using an upstream DoH service does not require installing a certificate on every household device.

Real screenshot of AdGuard Home encryption documentation

Figure 8. Actual capture of AdGuard Home encryption documentation. This page focuses on serving encrypted DNS. The website selected Chinese based on the browser language when captured.

6. Manual configuration: six steps beyond clicking Save

Step 1: preserve the existing configuration

Record global upstreams, fallback resolvers, bootstrap resolvers, domain-specific forwarding rules, and per-client overrides. Keep backups private. They may reveal internal addresses or service names even when they contain no passwords. If upstreams are managed by a file or another configuration system, continue using that workflow.

Step 2: select and test encrypted upstreams

The encrypted lookup interfaces from AliDNS and Tencent supplied valid comparison results in this incident. Their commonly used DoH configuration endpoints are:

https://dns.alidns.com/dns-query
https://doh.pub/dns-query

Test them from AdGuard Home before saving. This is not a performance ranking or a promise that every network can reach them. Some other overseas encrypted endpoints timed out during this investigation, illustrating why security properties and network reachability must be checked separately.

A self-hosted DoH endpoint is also an option. It still needs valid certificates, a reachable path, and verified DNS behavior. Moving a faulty resolver behind HTTPS would preserve the fault inside a better-protected channel.

Step 3: understand bootstrap resolution

A DoH endpoint is usually a hostname, so AdGuard Home must first discover its address. A bootstrap resolver answers that initial question: “where is the office that will answer my other questions?”

Retain or supply a locally verified bootstrap resolver. Avoid circular dependencies in which the bootstrap lookup depends on the very DoH service it is trying to start. An incorrect bootstrap answer will normally cause TLS identity checking to fail rather than authenticate an impostor, but it can still cause an outage. Disabling certificate validation is not the remedy.

This article deliberately does not print complete numeric addresses. Obtain necessary bootstrap addresses from official provider information and configure them privately.

Step 4: remove an unsafe fallback path

An encrypted primary upstream can be undermined operationally by a fallback that returns to the original faulty plaintext path. The problem may reappear whenever the primary becomes unavailable.

For a simple personal deployment, clear unnecessary fallback entries or use another verified encrypted upstream. For a business deployment, review availability requirements first. A tutorial should not silently discard an existing failover design or split-DNS configuration.

Step 5: clear caches and inspect IPv6

Clear AdGuard Home’s cache, refresh relevant client caches, and restart the browser. Windows provides Clear-DnsClientCache. On Ubuntu using systemd-resolved, use sudo resolvectl flush-caches. On macOS:

sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

These commands affect particular caches; they do not purge every browser, application, router, and resolver in the network.

Check DHCP-provided DNS settings, IPv6 resolver information delivered through RA or DHCPv6, browser Secure DNS, and VPN-specific resolution. Multiple DNS servers are not universally treated as a strict primary-then-backup sequence. Leaving a faulty resolver in the list can produce intermittent behavior.

Original diagram showing IPv4, IPv6 and browser DNS paths

Figure 9. Disabling IPv6 is not the default fix. Audit both address families and the actual client paths.

Step 6: verify the original browsing experience

Check A and AAAA results again. In AdGuard Home’s query log, verify whether the client request arrived, which upstream handled it, and whether a cached answer was used. Then open the original HTTPS URL in the normal browser. Check the certificate behavior, final destination, and actual page content. Repeat on another device when useful.

Real screenshot of AdGuard Home configuration documentation

Figure 10. Actual capture of AdGuard Home Configuration. Configuration fields and UI labels can change between versions.

7. A reversible toolkit for Windows, Ubuntu and macOS

Download the complete offline toolkit. It contains three operating-system launchers and a shared Python configuration client:

Prerequisites are explicit: install Python 3.10 or later beforehand. The program uses only the standard library: no pip packages, hosted agent, cloud automation platform, or runtime script downloads. Python is not guaranteed to be present on Windows or macOS; the launchers stop when it is missing rather than installing software silently.

Public DoH still depends on the selected provider. If avoiding a third-party recursive service is a requirement, supply your own DoH endpoint. A self-hosted recursive resolver still requires access to the relevant authoritative DNS infrastructure. Internet resolution cannot honestly be described as entirely offline.

The toolkit assumes that AdGuard Home is already installed, initialized, and manageable. It performs API preflight, server-side upstream tests, a private backup, a targeted upstream update, configuration read-back, another upstream test, and cache clearing. It clears the global fallback list deliberately. On failure, it attempts to restore and verify the old values and exits unsuccessfully.

It does not install AdGuard Home or change router DHCP, operating-system DNS, bootstrap configuration, or per-client settings. It refuses file-managed upstreams and domain-specific forwarding rules instead of overwriting them. Avoid concurrent administrative edits while running it. On Windows, put backups in a directory with an ACL restricted to the current user; the files may contain private resolver information.

Original automation diagram: preflight, backup, apply, verify and rollback

Figure 11. A successful script result proves that the requested settings were applied and read back. It does not prove that every client has adopted the intended DNS path.

Method A: a human starts the automatic configuration

Extract the archive, open its directory, and run the appropriate launcher. Supply the trusted management URL, administrator name, and upstream URLs when prompted. Password input is hidden.

The API connection must use verified HTTPS. HTTP is allowed only on loopback for use through a trusted SSH tunnel. The toolkit never disables TLS certificate checking and refuses management API redirects to avoid forwarding credentials to an unexpected destination.

# Windows 11, with Python and its py launcher installed
powershell -NoProfile -File .\windows11.ps1 --apply
# Ubuntu 26.04
bash ./ubuntu26.sh --apply

# macOS 26
bash ./macos26.sh --apply

Without --apply, the script reads configuration and tests candidate upstreams without saving settings. If PowerShell execution policy blocks the launcher, review the file and follow local policy; do not permanently weaken the system’s policy just to follow a tutorial.

Method B: an agent runs the same local workflow

Create a private plan.json with this structure. Replace the brace-delimited placeholders locally; the template cannot run unchanged and real configuration must not enter a public repository:

{
  "base_url": "https://{your-management-endpoint}",
  "username": "{administrator}",
  "upstreams": [
    "https://dns.alidns.com/dns-query",
    "https://doh.pub/dns-query"
  ]
}

Keep the password in a separate local file readable only by the intended user. Use owner-only permissions on Linux/macOS and appropriate ACLs on Windows. If the management endpoint uses a private CA, set the optional ca_file field to a trusted CA file instead of bypassing verification.

A local agent can then run:

python3 configure_doh.py --plan plan.json --password-file password.txt
python3 configure_doh.py --plan plan.json --password-file password.txt --apply

Use py -3 instead of python3 on Windows. There is no built-in model service dependency. When using an external agent service, do not paste passwords or unredacted logs into the conversation. A suitable task instruction is:

Operate only the designated AdGuard Home instance. Read the script and private plan, and report a redacted summary. Apply only after preflight succeeds and keep the backup private. Do not change client networking, bootstrap resolvers, domain routing, or file-managed configuration. Do not print credentials, full addresses, or machine names. Check the exit code, then verify A/AAAA answers, query logs, certificate validation, and the browser page separately. If browser access is unavailable, report configuration success with end-to-end verification still pending.

To undo a run, identify its JSON backup in the private backup directory and use the same plan and credentials:

python3 configure_doh.py --plan plan.json --password-file password.txt \
  --restore "{path-to-this-run-backup}" --apply

Before restoring, the program checks whether the relevant settings still match the values it originally applied. If somebody has changed them since, it refuses to overwrite the newer edit. Restoring the old upstreams may also restore the original incident; rollback is an undo mechanism, not another repair method.

Testing scope: the shared core was exercised against a local simulated API for success, rejection, and rollback cases. Bash launchers received syntax checks and invocation checks on the current macOS environment. This article does not claim production testing on actual Windows 11, Ubuntu 26.04, and three separate AdGuard Home installations. The server’s built-in upstream test checks its test query, not every domain or every client.

8. Questions that commonly derail this investigation

Does a redirect to Baidu prove Baidu caused it?

No. A Location header identifies a requested destination, not the responsible party. An incorrect server or an intercepting component can issue a redirect to an unrelated public service. Attribution requires additional evidence.

Are different DNS answers always evidence of poisoning?

No. CDNs, geographic routing, cache age, and ECS can legitimately produce different answers. Here, the conclusion rests on multiple observations: an unexpected address, an unrelated redirect, a certificate mismatch, and a valid same-domain HTTPS comparison. Address inequality alone is weak evidence.

If HTTPS is secure, why did this happen?

The HTTP path redirected; the HTTPS path failed hostname validation. The latter was a protective outcome. HTTPS-first behavior and HSTS can reduce exposure to plaintext HTTP, but they do not repair the underlying DNS answer. What the user types, the browser’s upgrade policy, and its existing HSTS state affect the visible result.

Real screenshot of the MDN HSTS documentation

Figure 12. Actual capture of MDN: Strict-Transport-Security. HSTS constrains HTTPS use; it is not a replacement for DNS troubleshooting.

Could a hosts-file entry fix it permanently?

It can provide a temporary comparison, but pinning a hosting address indefinitely creates maintenance risk. The platform can change routing or addresses. Repair the resolution path and follow the hosting provider’s domain requirements instead of turning today’s address into a permanent assumption.

Are DNSSEC and DoH the same protection?

No. DoH protects transport to the chosen resolver. DNSSEC can authenticate DNS data when the zone is signed and the validation chain is intact. Think of a sealed delivery bag versus a verifiable signature on the document inside. Enabling validation does not magically sign unsigned data, and neither mechanism fixes malicious website code.

Why does my laptop work while my phone still fails?

Check whether the phone uses cellular service, an IPv6-provided resolver, a VPN, or browser-specific Secure DNS. Then inspect caching. A green dashboard cannot establish which path that phone actually took, and a factory reset is a poor first diagnostic step.

Why did advertising protection not prevent it?

Filtering decides which queries are allowed or blocked. Encrypted upstream transport determines how allowed queries are sent. A permitted domain can still receive an incorrect answer through a faulty upstream path. The effective change here was the resolution path, not another advertising blocklist.

9. The final check belongs in the browser

The acceptance test was straightforward: open the same URL normally, validate the identity, and see the expected content. After the upstream DoH change, the user confirmed that this worked. That completed the incident loop.

Original acceptance diagram: configuration, resolution and user experience

Figure 13. Each layer needs its own evidence. “Settings saved” cannot stand in for “the page is correct.”

Unexpected redirects invite rushed fixes: rebuilding the website, changing unrelated domain records, or turning off security checks. A more useful starting point is three simple questions: Who supplied the address? Which endpoint did I reach? Did it prove its identity? Separating those questions turns a seemingly mysterious redirect into a sequence of testable engineering claims.

Sources and image provenance

Documentation was checked and screenshots captured on September 17, 2026. This article contains 13 images: six genuine official-page browser captures and seven original SVG diagrams. No typeset transcript is presented as a terminal screenshot, and no later screenshot is represented as an image captured during the original failure. Documentation screenshots illustrate the cited technical points; their content belongs to the respective authors.

  1. AdGuard Home Configuration: upstreams, bootstrap behavior, and configuration fields.
  2. AdGuard Home encryption: serving encrypted DNS.
  3. AdGuard Home OpenAPI: DNS configuration, upstream testing, and cache clearing. A deployed release may differ from the main branch.
  4. RFC 8484: the DoH protocol.
  5. MDN: 302 Found: temporary redirect semantics.
  6. MDN: Strict-Transport-Security: HSTS and certificate-error behavior.
  7. GitHub Pages custom domains: hosting-domain and DNS configuration.

Related reading: DNS history, architecture, and encrypted protection, and GeoIP, CDN, and HTTP redirects. 阅读中文版.

本文阅读量 --