diff --git a/changelog.md b/changelog.md
index 7b79e79..0b83d3b 100644
--- a/changelog.md
+++ b/changelog.md
@@ -3,7 +3,16 @@
## UNRELEASED
[All Commits](https://github.com/wardenenv/warden/compare/0.16.0..main)
-_No changes yet_
+**Bug Fixes:**
+* `warden install` now automatically trusts the Warden root CA in the Windows CurrentUser Root store when run inside WSL, so Windows browsers can trust local Warden certificates without manual certificate import
+* Expanded Windows / WSL DNS documentation to cover Windows 11 cases where Hyper-V firewall rules prevent DNS resolution from reaching Warden, including `hosts` file and Chrome `--host-resolver-rules` workarounds
+* `warden install` now attempts to import the Warden root CA into the Windows `LocalMachine\Root` store first, falls back to `CurrentUser\Root` when elevation or policy prevents it, and reports both store states via `warden doctor`
+* Warden-issued certificates now publish local CRL/AIA metadata on `http://127.0.0.1/.warden/pki/` so Windows Schannel can validate local HTTPS services such as native DoH
+
+**Enhancements:**
+* Added optional DNS-over-HTTPS support for Windows 11 / WSL workflows via `WARDEN_DNS_OVER_HTTPS_ENABLE=1`, serving `https://doh.warden.test/dns-query` by default
+* Enabling `WARDEN_DNS_OVER_HTTPS_ENABLE=1` now automatically keeps Warden `dnsmasq` enabled for the same global services run because the DoH bridge depends on the existing DNS resolver
+* Enabling `WARDEN_DNS_OVER_HTTPS_ENABLE=1` now starts a `dns-over-https-pki` sidecar that publishes the local CRL/AIA files Windows Schannel uses, without keeping that HTTP publisher active when DoH is disabled
## Version [0.16.0](https://github.com/wardenenv/warden/tree/0.16.0) (2026-02-12)
diff --git a/configuration/dns-resolver.md b/configuration/dns-resolver.md
index 70633ab..568e8a0 100644
--- a/configuration/dns-resolver.md
+++ b/configuration/dns-resolver.md
@@ -72,8 +72,101 @@ Add the local dnsmasq resolver as the first DNS server:
Open the Network & Internet control panel

-Select the correct network interface for your device (ethernet, wifi, etc.), then click the "Edit" button on the line for "DNS Server Assignment"
+Edit `DNS server assignment` and switch it to `Manual`

-Specify ``127.0.0.1`` as the primary DNS host and any public DNS server as the backup (e.g. ``1.1.1.1`` for Cloudflare, ``9.9.9.9`` for Quad9)
-
\ No newline at end of file
+For IPv4, set `Preferred DNS` to `127.0.0.1`
+
+
+:::{warning}
+On some newer Windows 11 systems using WSL2 and Docker Desktop, host-side networking components such as the Hyper-V firewall and `SharedAccess` (`svchost.exe`) may still prevent Windows DNS requests from reaching Warden's local `dnsmasq` service even after `127.0.0.1` is configured as the primary DNS server. In that situation, Warden DNS may work correctly inside WSL while Windows applications still fail to resolve the same domains. When that happens, Windows DNS over HTTPS can be a particularly useful workaround because it avoids relying on plain local DNS traffic to `127.0.0.1`.
+:::
+
+:::{important}
+If plain Windows DNS still does not resolve your Warden domains, try these options in order.
+:::
+
+(windows-doh)=
+#### 1. Enable Windows DNS over HTTPS for Warden
+
+This is the preferred workaround because it is system-wide, works better with Windows-native networking once the Warden root CA is trusted, and may succeed on systems where plain `127.0.0.1` DNS is disrupted by Hyper-V, `SharedAccess`, or similar Windows networking behavior.
+
+ First enable Warden's optional DoH bridge in `~/.warden/.env`:
+
+ ```text
+ WARDEN_DNS_OVER_HTTPS_ENABLE=1
+ ```
+
+ When this option is enabled, Warden will also keep its global `dnsmasq` service enabled because the DoH endpoint forwards queries to the existing local resolver.
+
+ Then restart global services:
+
+ ```bash
+ warden svc up
+ ```
+
+ Warden will expose the DoH endpoint through Traefik at `https://doh.warden.test/dns-query` by default.
+
+ Before Windows can use that URL, make sure the DoH hostname resolves locally. From an elevated PowerShell prompt, add it to the Windows `hosts` file:
+
+ ```powershell
+ $hostsPath = "$env:SystemRoot\System32\drivers\etc\hosts"
+ $entry = "127.0.0.1 doh.warden.test"
+ if (-not (Select-String -Path $hostsPath -SimpleMatch $entry -Quiet -ErrorAction SilentlyContinue)) {
+ Add-Content -Path $hostsPath -Value $entry
+ }
+ ```
+
+ Warden can register the DoH template for `127.0.0.1` automatically when it is installed from WSL with the Windows bridge available.
+ If you want to confirm the template is present, you can verify it with:
+
+ ```powershell
+ Get-DnsClientDohServerAddress -ServerAddress 127.0.0.1
+ ```
+
+ Then configure your network adapter to actually use `127.0.0.1` as DNS.
+
+ Windows 11 UI
+
+ Go to `Settings -> Network & Internet -> [Adapter, for example WiFi or Ethernet] -> Hardware properties`. This should look similar to the following:
+
+ ```{image} screenshots/dns-resolver--win11-doh-settings.png
+ :alt: Windows 11 DNS over HTTPS manual template configuration
+ :width: 400px
+ ```
+
+ The resulting Windows 11 configuration should be:
+
+ * `Preferred DNS`: `127.0.0.1`
+ * `DNS over HTTPS`: `On (manual template)`
+ * `DNS over HTTPS template`: `https://doh.warden.test/dns-query`
+ * `Alternate DNS`: your normal resolver such as `1.1.1.1`
+
+ Save the setting. Once it is applied, `*.test` domains should resolve automatically through Warden.
+
+ :::{note}
+ Keep Warden in `Preferred DNS` and your normal resolver in `Alternate DNS`.
+ If `Alternate DNS` is empty, internet DNS may stop working when Warden is stopped.
+ DoH template registration alone does not set these adapter DNS values for you.
+ :::
+
+
+(windows-chrome-host-resolver)=
+#### 2. Launch Chrome with host resolver overrides
+
+This is often sufficient for browser use because it applies a wildcard mapping without requiring one `hosts` entry per hostname:
+
+```text
+"C:\Program Files\Google\Chrome\Application\chrome.exe" --host-resolver-rules="MAP *.test 127.0.0.1"
+```
+
+Chromium documents --host-resolver-rules ↗ as a request remapping flag that can map hostnames to another hostname, an IP address, or `NOTFOUND`. Chrome will show a warning about the unsupported command-line flag, but the `.test` wildcard resolution itself will still work for that browser session.
+
+
+
+(windows-hosts-fallback)=
+#### 3. Add the required domains to the Windows `hosts` file
+
+This is the most manual option, but it always works if you only need a small set of fixed hostnames.
+
+These workarounds are relatively safe because they do not require changing Windows, WSL, or Hyper-V default networking behavior. The Chrome workaround only affects that browser process and does not fix DNS for Windows generally. Other Windows applications and browsers will still need working DNS resolution or matching `hosts` file entries. For more background on WSL networking and Hyper-V firewall behavior, see Microsoft's [WSL networking documentation](https://learn.microsoft.com/en-us/windows/wsl/networking).
diff --git a/configuration/screenshots/chrome-host-remap.png b/configuration/screenshots/chrome-host-remap.png
new file mode 100644
index 0000000..f0185f3
Binary files /dev/null and b/configuration/screenshots/chrome-host-remap.png differ
diff --git a/configuration/screenshots/dns-resolver--win11-doh-settings.png b/configuration/screenshots/dns-resolver--win11-doh-settings.png
new file mode 100644
index 0000000..6c041b7
Binary files /dev/null and b/configuration/screenshots/dns-resolver--win11-doh-settings.png differ
diff --git a/configuration/screenshots/win-11-wsl-cert.png b/configuration/screenshots/win-11-wsl-cert.png
new file mode 100644
index 0000000..7064fef
Binary files /dev/null and b/configuration/screenshots/win-11-wsl-cert.png differ
diff --git a/configuration/screenshots/windows-11-certs.png b/configuration/screenshots/windows-11-certs.png
new file mode 100644
index 0000000..305f4ab
Binary files /dev/null and b/configuration/screenshots/windows-11-certs.png differ
diff --git a/configuration/screenshots/windows-certlm-import-certificate.png b/configuration/screenshots/windows-certlm-import-certificate.png
new file mode 100644
index 0000000..62d7be2
Binary files /dev/null and b/configuration/screenshots/windows-certlm-import-certificate.png differ
diff --git a/installing.md b/installing.md
index 3b13f65..90084ca 100644
--- a/installing.md
+++ b/installing.md
@@ -14,20 +14,22 @@ Installing Warden
## Installing via Homebrew
Warden may be installed via [Homebrew](https://brew.sh/) on both macOS and Linux hosts:
-
- brew install wardenenv/warden/warden
- warden svc up
+```bash
+ brew install wardenenv/warden/warden
+ warden svc up
+```
## Alternative Installation
Warden may be installed by cloning the repository to the directory of your choice and adding it to your `$PATH`. This method of installation may be when Homebrew does not already exist on your system or when preparing contributions to the Warden project.
-
- sudo mkdir /opt/warden
- sudo chown $(whoami) /opt/warden
- git clone -b main https://github.com/wardenenv/warden.git /opt/warden
- echo 'export PATH="/opt/warden/bin:$PATH"' >> ~/.bashrc
- PATH="/opt/warden/bin:$PATH"
- warden svc up
+```bash
+ sudo mkdir /opt/warden
+ sudo chown $(whoami) /opt/warden
+ git clone -b main https://github.com/wardenenv/warden.git /opt/warden
+ echo 'export PATH="/opt/warden/bin:$PATH"' >> ~/.bashrc
+ PATH="/opt/warden/bin:$PATH"
+ warden svc up
+```
## Windows Installation (via WSL2)
@@ -35,13 +37,36 @@ Install [WSL2 in Windows](https://learn.microsoft.com/en-us/windows/wsl/install)
Install Ubuntu 20.04 or other compatible Linux version from the Windows store or [manually download distibutions](https://docs.microsoft.com/en-us/windows/wsl/install-manual).
Launch Docker for Windows, make sure that the option for WSL2 integration is set.
Launch wsl from your terminal of choice.
+```bash
+ wsl
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
+ brew install wardenenv/warden/warden
+ warden svc up
+```
+In order for DNS entries to be resolved either add entries to your Windows `C:\Windows\System32\drivers\etc\hosts` file or add `127.0.0.1` as the first DNS server in your current network adapter in Windows.
- wsl
- /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
- brew install wardenenv/warden/warden
- warden svc up
-
-In order for DNS entries to be resolved either add them to your Windows hosts file or add 127.0.0.1 as the first DNS server in your current network adapter in Windows.
+:::{warning}
+On some Windows 11 / WSL2 systems, plain DNS to `127.0.0.1` may not work reliably from Windows. If that happens, prefer the DNS over HTTPS setup described on the {doc}`Automatic DNS Resolution ` page.
+
+If you need a quick fallback, open PowerShell as Administrator and run this snippet to add the main Warden global hostnames to the Windows `hosts` file:
+
+```powershell
+$hostsPath = "$env:SystemRoot\System32\drivers\etc\hosts"
+$entries = @(
+ "127.0.0.1 traefik.warden.test",
+ "127.0.0.1 dnsmasq.warden.test",
+ "127.0.0.1 doh.warden.test",
+ "127.0.0.1 webmail.warden.test"
+)
+
+$existing = Get-Content -Path $hostsPath -ErrorAction SilentlyContinue
+foreach ($entry in $entries) {
+ if ($existing -notcontains $entry) {
+ Add-Content -Path $hostsPath -Value $entry
+ }
+}
+```
+:::
:::{warning}
**For performance reasons code should be located in the WSL Linux home path or other WSL local path ~/code/projectname NOT the default /mnt/c path mapping.**
@@ -53,7 +78,7 @@ GUI tools for Windows should use the network paths provided by WSL2: `\\wsl$\Ubu
### Automatic DNS Resolution
-On Linux environments, you will need to configure your DNS to resolve `*.test` to `127.0.0.1` or use `/etc/hosts` entries. On Mac OS this configuration is automatic via the BSD per-TLD resolver configuration found at `/etc/resolver/test`. On Windows manual configuration of the network adapter DNS server is required.
+On Linux environments, you will need to configure your DNS to resolve `*.test` to `127.0.0.1` or use `/etc/hosts` entries. On Mac OS this configuration is automatic via the BSD per-TLD resolver configuration found at `/etc/resolver/test`. On Windows manual configuration of the network adapter DNS server is required, though some Windows 11 / WSL setups may still need `hosts` file entries or a browser-level override if Hyper-V firewall rules prevent DNS from reaching Warden.
For more information see the configuration page for {doc}`Automatic DNS Resolution `.
@@ -64,10 +89,45 @@ In order to sign SSL certificates that may be trusted by a developer workstation
On MacOS this root CA certificate is automatically added to a users trust settings as can be seen by searching for 'Warden Proxy Local CA' in the Keychain application. This should result in the certificates signed by Warden being trusted by Safari and Chrome automatically. If you use Firefox, you will need to add this CA root to trust settings specific to the Firefox browser per the below.
-On Ubuntu/Debian this CA root is copied into `/usr/local/share/ca-certificates` and on Fedora/CentOS (Enterprise Linux) it is copied into `/etc/pki/ca-trust/source/anchors` and then the trust bundle is updated appropriately. For new systems, this typically is all that is needed for the CA root to be trusted on the default Firefox browser, but it may not be trusted by Chrome or Firefox automatically should the browsers have already been launched prior to the installation of Warden (browsers on Linux may and do cache CA bundles)
+On Ubuntu/Debian this CA root is copied into `/usr/local/share/ca-certificates` and on Fedora/CentOS (Enterprise Linux) it is copied into `/etc/pki/ca-trust/source/anchors` and then the trust bundle is updated appropriately. For new systems, this typically is all that is needed for the CA root to be trusted on the default Firefox browser, but it may not be trusted by Chrome or Firefox automatically should the browsers have already been launched prior to the installation of Warden (browsers on Linux may and do cache CA bundles).
+
+When `warden install` is run inside WSL, Warden will also attempt to import the same CA root into the Windows `LocalMachine\Root` certificate store by invoking `powershell.exe` from WSL. If Windows elevation is denied or device policy blocks that store, Warden falls back to `CurrentUser\Root`. This allows Windows browsers and Windows-native networking components such as DNS over HTTPS to trust Warden-issued certificates without a separate manual import step.
+
+If you need to import the certificate manually in Windows, use the same CA file from WSL:
+
+* `\\wsl$\Ubuntu-20.04\home\\.warden\ssl\rootca\certs\ca.cert.pem`
+
+Then in Windows:
+
+1. Press `Win + R`, then open:
+
+ * `certlm.msc` for `LocalMachine\Root`
+ Preferred for Windows DoH. See {ref}`windows-doh`.
+ * `certmgr.msc` for `CurrentUser\Root`
+2. Go to `Trusted Root Certification Authorities -> Certificates`.
+
+ ```{image} configuration/screenshots/windows-certlm-import-certificate.png
+ :alt: Windows certificate console showing the Certificates All Tasks Import action
+ :width: 700px
+ ```
+
+3. Right-click `Certificates`, then choose `All Tasks -> Import...` and select `ca.cert.pem`.
+
+Use `LocalMachine\Root` when possible, especially if you want Windows-native DNS over HTTPS and other system services to trust Warden certificates. Use `CurrentUser\Root` if administrator approval or device policy prevents the machine-wide import.
:::{note}
-If you are using **Firefox** and it warns you the SSL certificate is invalid/untrusted, go to Preferences -> Privacy & Security -> View Certificates (bottom of page) -> Authorities -> Import and select ``~/.warden/ssl/rootca/certs/ca.cert.pem`` for import, then reload the page.
+If you are running **Warden inside WSL** and opening sites in **Windows browsers**, the automatic Windows certificate import performed by `warden install` should usually be sufficient. This behavior has been validated against current Windows builds using Firefox, Chrome, and Edge. If the CA root is regenerated later, run `warden install` again so the updated CA can be imported into Windows. You can also run `warden doctor` to confirm whether the Warden root certificate is present in Windows `LocalMachine Root`, `CurrentUser Root`, or both.
+
+
+
+Some Windows 11 setups may also display a certificate trust confirmation dialog while the root CA is being imported from WSL.
+
+```{image} configuration/screenshots/win-11-wsl-cert.png
+:alt: Windows 11 confirmation dialog when importing the Warden root CA from WSL
+:width: 400px
+```
+
+If you are using **Firefox** inside Linux and it warns you the SSL certificate is invalid/untrusted, go to Preferences -> Privacy & Security -> View Certificates (bottom of page) -> Authorities -> Import and select ``~/.warden/ssl/rootca/certs/ca.cert.pem`` for import, then reload the page.
If you are using **Chrome** or **Chromium** on **Linux** and it warns you the SSL certificate is invalid/untrusted, go to Chrome Settings -> Privacy And Security -> Security -> Manage Certificates -> Local Certificates -> Custom -> Installed By You -> Trusted Certificates -> Import and select ``~/.warden/ssl/rootca/certs/ca.cert.pem`` for import, then reload the page.
:::
diff --git a/services.md b/services.md
index 961660b..b4b00d0 100644
--- a/services.md
+++ b/services.md
@@ -5,6 +5,7 @@ After running `warden svc up` for the first time following installation, the fol
* [https://traefik.warden.test/](https://traefik.warden.test/)
* [https://portainer.warden.test/](https://portainer.warden.test/)
* [https://dnsmasq.warden.test/](https://dnsmasq.warden.test/)
+* [https://doh.warden.test/dns-query](https://doh.warden.test/dns-query) when `WARDEN_DNS_OVER_HTTPS_ENABLE=1`
* [https://webmail.warden.test/](https://webmail.warden.test/)
* [https://phpmyadmin.warden.test/](https://phpmyadmin.warden.test/)
@@ -18,6 +19,7 @@ The following options are available (with default values indicated):
* `WARDEN_RESTART_POLICY=always` may be set to `no` to prevent Docker from restarting these service containers or any other valid [restart policy](https://docs.docker.com/config/containers/start-containers-automatically/#use-a-restart-policy) value.
* `WARDEN_SERVICE_DOMAIN=warden.test` may be set to a domain of your choosing if so desired. Please note that this will not currently change network settings or alter `dnsmasq` configuration. Any TLD other than `test` will require DNS resolution be manually configured.
* `WARDEN_PHPMYADMIN_ENABLE=1` may be set to `0` to disable the phpMyAdmin global service.
+* `WARDEN_DNS_OVER_HTTPS_ENABLE=0` may be set to `1` to enable a local DNS-over-HTTPS endpoint for Windows 11 / WSL clients at `https://doh.warden.test/dns-query` by default
:::{warning}
Setting ``TRAEFIK_LISTEN=0.0.0.0`` can be quite useful in some cases, but be aware that causing Traefik to listen for requests publicly poses a security risk when on public WiFi or networks otherwise outside of your control.