mirror of
https://github.com/NexusOne23/noid-privacy.git
synced 2026-02-07 12:11:53 +01:00
113 lines
5.3 KiB
PowerShell
113 lines
5.3 KiB
PowerShell
function Set-DoHPolicy {
|
|
<#
|
|
.SYNOPSIS
|
|
Enforce DNS-over-HTTPS (DoH) system-wide according to the selected mode
|
|
|
|
.DESCRIPTION
|
|
Sets Windows registry keys to enforce DoH policy based on $script:DoHMode:
|
|
- DoHPolicy = 3 (REQUIRE DoH - mandatory encryption, no fallback)
|
|
- DoHPolicy = 2 (ALLOW DoH - encryption preferred, fallback to UDP allowed)
|
|
- EnableAutoDoh = 2 (Enable automatic DoH upgrade)
|
|
- netsh global doh = yes
|
|
|
|
DoHPolicy values: 0=Default, 1=Prohibit, 2=Allow, 3=Require
|
|
|
|
In REQUIRE mode this prevents Windows from silently falling back to
|
|
unencrypted DNS on port 53. In ALLOW mode, encrypted DoH is still used
|
|
for supported servers, but fallback to classic DNS is permitted for
|
|
VPN/mobile/enterprise scenarios.
|
|
|
|
.PARAMETER DryRun
|
|
Show what would be configured without applying changes
|
|
|
|
.EXAMPLE
|
|
Set-DoHPolicy
|
|
|
|
.NOTES
|
|
Requires Administrator privileges
|
|
Based on Microsoft DNS Client documentation
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter()]
|
|
[switch]$DryRun
|
|
)
|
|
|
|
try {
|
|
# Determine DoH mode (REQUIRE or ALLOW)
|
|
$dohModeValue = if ($script:DoHMode -eq "ALLOW") { 2 } else { 3 }
|
|
$dohModeText = if ($script:DoHMode -eq "ALLOW") { "ALLOW (with fallback)" } else { "REQUIRE (no fallback)" }
|
|
|
|
Write-Log -Level INFO -Message "Enforcing DoH policy ($dohModeText)" -Module $script:ModuleName
|
|
|
|
if ($DryRun) {
|
|
Write-Log -Level INFO -Message "[DRYRUN] Would set DoH policy to $dohModeText" -Module $script:ModuleName
|
|
Write-Log -Level DEBUG -Message "[DRYRUN] DoHPolicy = $dohModeValue ($($script:DoHMode))" -Module $script:ModuleName
|
|
Write-Log -Level DEBUG -Message "[DRYRUN] EnableAutoDoh = 2 (enforce)" -Module $script:ModuleName
|
|
Write-Log -Level DEBUG -Message "[DRYRUN] DohFlags = 1 (use DoH)" -Module $script:ModuleName
|
|
Write-Log -Level DEBUG -Message "[DRYRUN] netsh global doh = yes" -Module $script:ModuleName
|
|
return $true
|
|
}
|
|
|
|
# Registry path for DNS Client settings
|
|
$dnsClientPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient"
|
|
$dnsParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters"
|
|
|
|
# Ensure policy path exists
|
|
if (-not (Test-Path $dnsClientPath)) {
|
|
New-Item -Path $dnsClientPath -Force | Out-Null
|
|
Write-Log -Level DEBUG -Message "Created registry path: $dnsClientPath" -Module $script:ModuleName
|
|
}
|
|
|
|
# CRITICAL ORDER: netsh FIRST (may reset registry values), then Registry entries AFTER
|
|
# This ensures Registry values persist and are not overwritten by netsh
|
|
|
|
# 1. FIRST: Activate DoH globally via netsh (this may reset EnableAutoDoh!)
|
|
try {
|
|
netsh dnsclient set global doh=yes 2>&1 | Out-Null
|
|
|
|
if ($LASTEXITCODE -eq 0) {
|
|
Write-Log -Level DEBUG -Message "netsh global DoH activated" -Module $script:ModuleName
|
|
}
|
|
else {
|
|
Write-Log -Level WARNING -Message "netsh global DoH returned exit code $LASTEXITCODE" -Module $script:ModuleName
|
|
}
|
|
}
|
|
catch {
|
|
Write-Log -Level WARNING -Message "Could not activate global DoH via netsh: $_" -Module $script:ModuleName
|
|
}
|
|
|
|
# 2. SECOND: EnableAutoDoh = 2 (Enable automatic DoH) - AFTER netsh!
|
|
if (-not (Test-Path $dnsParamsPath)) {
|
|
New-Item -Path $dnsParamsPath -Force | Out-Null
|
|
}
|
|
$existing = Get-ItemProperty -Path $dnsParamsPath -Name "EnableAutoDoh" -ErrorAction SilentlyContinue
|
|
if ($null -ne $existing) {
|
|
Set-ItemProperty -Path $dnsParamsPath -Name "EnableAutoDoh" -Value 2 -Force | Out-Null
|
|
} else {
|
|
New-ItemProperty -Path $dnsParamsPath -Name "EnableAutoDoh" -Value 2 -PropertyType DWord -Force | Out-Null
|
|
}
|
|
Write-Log -Level SUCCESS -Message "Set EnableAutoDoh = 2 (Automatic DoH enabled)" -Module $script:ModuleName
|
|
|
|
# 3. THIRD: DoHPolicy = 2 (ALLOW) or 3 (REQUIRE) - LAST for highest priority
|
|
# Values: 0=Default, 1=Prohibit, 2=Allow, 3=Require
|
|
$existing = Get-ItemProperty -Path $dnsClientPath -Name "DoHPolicy" -ErrorAction SilentlyContinue
|
|
if ($null -ne $existing) {
|
|
Set-ItemProperty -Path $dnsClientPath -Name "DoHPolicy" -Value $dohModeValue -Force | Out-Null
|
|
} else {
|
|
New-ItemProperty -Path $dnsClientPath -Name "DoHPolicy" -Value $dohModeValue -PropertyType DWord -Force | Out-Null
|
|
}
|
|
Write-Log -Level SUCCESS -Message "Set DoHPolicy = $dohModeValue ($dohModeText)" -Module $script:ModuleName
|
|
|
|
# NOTE: Global DohFlags removed - we use per-adapter DohFlags instead (set in Invoke-DNSConfiguration)
|
|
# Per-adapter DohFlags are more reliable and prevent conflicts
|
|
|
|
Write-Log -Level SUCCESS -Message "DoH policy verified: $dohModeText" -Module $script:ModuleName
|
|
return $true
|
|
}
|
|
catch {
|
|
Write-ErrorLog -Message "Failed to set DoH policy" -Module $script:ModuleName -ErrorRecord $_
|
|
return $false
|
|
}
|
|
}
|