mirror of
https://github.com/NexusOne23/noid-privacy.git
synced 2026-02-07 12:11:53 +01:00
300 lines
14 KiB
PowerShell
300 lines
14 KiB
PowerShell
function Backup-DNSSettings {
|
|
<#
|
|
.SYNOPSIS
|
|
Backup current DNS settings for all physical network adapters
|
|
|
|
.DESCRIPTION
|
|
Creates a comprehensive backup of DNS configuration including:
|
|
- Current DNS server addresses (IPv4 and IPv6)
|
|
- DHCP status (was DNS obtained from DHCP?)
|
|
- DoH configuration
|
|
- Adapter interface information
|
|
|
|
Backup is stored using the framework's rollback system.
|
|
|
|
.PARAMETER DryRun
|
|
Show what would be backed up without actually creating backup
|
|
|
|
.EXAMPLE
|
|
Backup-DNSSettings
|
|
Creates backup of current DNS settings
|
|
|
|
.OUTPUTS
|
|
System.String - Path to backup file or $null if failed
|
|
|
|
.NOTES
|
|
DHCP awareness is critical for correct rollback behavior
|
|
#>
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter()]
|
|
[switch]$DryRun
|
|
)
|
|
|
|
try {
|
|
Write-Log -Level INFO -Message "Backing up DNS settings..." -Module $script:ModuleName
|
|
|
|
# Get all physical adapters
|
|
$adapters = @(Get-PhysicalAdapters) # Force array
|
|
|
|
if ($adapters.Count -eq 0) {
|
|
Write-Log -Level WARNING -Message "No physical adapters found to backup" -Module $script:ModuleName
|
|
return $null
|
|
}
|
|
|
|
Write-Log -Level DEBUG -Message "Found $($adapters.Count) adapter(s) to backup" -Module $script:ModuleName
|
|
|
|
# Get netsh global DoH state
|
|
$netshGlobalDoh = $null
|
|
try {
|
|
$netshResult = netsh dnsclient show global 2>&1 | Out-String
|
|
if ($netshResult -match "DoH\s*:\s*(\w+)") {
|
|
$netshGlobalDoh = $matches[1]
|
|
Write-Log -Level DEBUG -Message "netsh global DoH state: $netshGlobalDoh" -Module $script:ModuleName
|
|
}
|
|
}
|
|
catch {
|
|
Write-Log -Level DEBUG -Message "Could not retrieve netsh global DoH state: $_" -Module $script:ModuleName
|
|
}
|
|
|
|
# Get all netsh DoH encryption entries
|
|
$netshDohEntries = @()
|
|
try {
|
|
$netshEncryption = netsh dnsclient show encryption 2>&1 | Out-String
|
|
# Parse netsh output for DoH servers
|
|
# Format: "Server: X.X.X.X | Template: https://... | Auto-upgrade: yes | UDP fallback: no"
|
|
$lines = $netshEncryption -split "`n"
|
|
foreach ($line in $lines) {
|
|
if ($line -match "Server:\s*(\S+)") {
|
|
$server = $matches[1]
|
|
$template = $null
|
|
$autoupgrade = $null
|
|
$udpfallback = $null
|
|
|
|
if ($netshEncryption -match "Server:\s*$([regex]::Escape($server)).*?Template:\s*(\S+)") {
|
|
$template = $matches[1]
|
|
}
|
|
if ($netshEncryption -match "Server:\s*$([regex]::Escape($server)).*?Auto-upgrade:\s*(\w+)") {
|
|
$autoupgrade = $matches[1]
|
|
}
|
|
if ($netshEncryption -match "Server:\s*$([regex]::Escape($server)).*?UDP fallback:\s*(\w+)") {
|
|
$udpfallback = $matches[1]
|
|
}
|
|
|
|
if ($template) {
|
|
$netshDohEntries += @{
|
|
Server = $server
|
|
Template = $template
|
|
AutoUpgrade = $autoupgrade
|
|
UdpFallback = $udpfallback
|
|
}
|
|
Write-Log -Level DEBUG -Message "Found netsh DoH entry: $server" -Module $script:ModuleName
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch {
|
|
Write-Log -Level DEBUG -Message "Could not retrieve netsh DoH entries: $_" -Module $script:ModuleName
|
|
}
|
|
|
|
$dohEntries = @()
|
|
try {
|
|
$allDoh = Get-DnsClientDohServerAddress -ErrorAction SilentlyContinue
|
|
if ($allDoh) {
|
|
foreach ($entry in $allDoh) {
|
|
if ($entry.ServerAddress -and $entry.DohTemplate) {
|
|
$dohEntries += @{
|
|
ServerAddress = $entry.ServerAddress
|
|
DohTemplate = $entry.DohTemplate
|
|
AllowFallbackToUdp = $entry.AllowFallbackToUdp
|
|
AutoUpgrade = $entry.AutoUpgrade
|
|
}
|
|
}
|
|
}
|
|
Write-Log -Level DEBUG -Message "Backed up $($dohEntries.Count) DoH entries from Get-DnsClientDohServerAddress" -Module $script:ModuleName
|
|
}
|
|
}
|
|
catch {
|
|
Write-Log -Level DEBUG -Message "Could not retrieve DoH entries via Get-DnsClientDohServerAddress: $_" -Module $script:ModuleName
|
|
}
|
|
|
|
# Get DoH Policy Registry settings
|
|
$dohPolicySettings = @{}
|
|
try {
|
|
$dnsClientPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient"
|
|
if (Test-Path $dnsClientPath) {
|
|
$dohPolicy = (Get-ItemProperty -Path $dnsClientPath -Name "DoHPolicy" -ErrorAction SilentlyContinue).DoHPolicy
|
|
if ($null -ne $dohPolicy) {
|
|
$dohPolicySettings['DoHPolicy'] = $dohPolicy
|
|
}
|
|
}
|
|
|
|
$dnsParamsPath = "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters"
|
|
if (Test-Path $dnsParamsPath) {
|
|
$enableAutoDoh = (Get-ItemProperty -Path $dnsParamsPath -Name "EnableAutoDoh" -ErrorAction SilentlyContinue).EnableAutoDoh
|
|
if ($null -ne $enableAutoDoh) {
|
|
$dohPolicySettings['EnableAutoDoh'] = $enableAutoDoh
|
|
}
|
|
|
|
# NOTE: Global DohFlags no longer used (we use per-adapter DohFlags instead)
|
|
# Kept for backward compatibility with old backups, but not written anymore
|
|
}
|
|
|
|
Write-Log -Level DEBUG -Message "Backed up DoH policy settings: $($dohPolicySettings.Count) keys" -Module $script:ModuleName
|
|
}
|
|
catch {
|
|
Write-Log -Level DEBUG -Message "Could not retrieve DoH policy settings: $_" -Module $script:ModuleName
|
|
}
|
|
|
|
$backupData = @{
|
|
Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
|
ComputerName = $env:COMPUTERNAME
|
|
NetshGlobalDoh = $netshGlobalDoh
|
|
NetshDohEntries = $netshDohEntries
|
|
DohEntries = $dohEntries
|
|
DohPolicySettings = $dohPolicySettings
|
|
Adapters = @()
|
|
}
|
|
|
|
foreach ($adapter in $adapters) {
|
|
Write-Log -Level DEBUG -Message "Backing up adapter: $($adapter.Name)" -Module $script:ModuleName
|
|
|
|
# Get current DNS configuration
|
|
$dnsConfig = Get-DnsClientServerAddress -InterfaceIndex $adapter.InterfaceIndex -ErrorAction SilentlyContinue
|
|
|
|
# Collect DNS addresses first
|
|
$ipv4Addresses = @()
|
|
$ipv6Addresses = @()
|
|
|
|
foreach ($config in $dnsConfig) {
|
|
if ($config.AddressFamily -eq 2) { # IPv4
|
|
if ($config.ServerAddresses.Count -gt 0) {
|
|
$ipv4Addresses = $config.ServerAddresses
|
|
}
|
|
}
|
|
elseif ($config.AddressFamily -eq 23) { # IPv6
|
|
if ($config.ServerAddresses.Count -gt 0 -and
|
|
$config.ServerAddresses -notcontains "fec0:0:0:ffff::1" -and
|
|
$config.ServerAddresses -notcontains "fec0:0:0:ffff::2" -and
|
|
$config.ServerAddresses -notcontains "fec0:0:0:ffff::3") {
|
|
# Only if not DHCP placeholder addresses
|
|
$ipv6Addresses = $config.ServerAddresses
|
|
}
|
|
}
|
|
}
|
|
|
|
# CRITICAL FIX: Determine DHCP status AFTER collecting all addresses
|
|
# DNS is from DHCP only if NO addresses are configured (neither IPv4 nor IPv6)
|
|
$isDHCP = ($ipv4Addresses.Count -eq 0) -and ($ipv6Addresses.Count -eq 0)
|
|
|
|
# Get DoH configuration for this adapter's DNS servers
|
|
$dohConfig = @()
|
|
try {
|
|
$allDohServers = Get-DnsClientDohServerAddress -ErrorAction SilentlyContinue
|
|
if ($allDohServers) {
|
|
foreach ($dohServer in $allDohServers) {
|
|
if ($ipv4Addresses -contains $dohServer.ServerAddress -or
|
|
$ipv6Addresses -contains $dohServer.ServerAddress) {
|
|
$dohConfig += @{
|
|
ServerAddress = $dohServer.ServerAddress
|
|
DohTemplate = $dohServer.DohTemplate
|
|
AllowFallbackToUdp = $dohServer.AllowFallbackToUdp
|
|
AutoUpgrade = $dohServer.AutoUpgrade
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch {
|
|
Write-Log -Level DEBUG -Message "Could not retrieve DoH configuration: $_" -Module $script:ModuleName
|
|
}
|
|
|
|
# Get DohFlags registry settings for this adapter
|
|
$dohFlags = @{}
|
|
try {
|
|
$interfaceGuid = $adapter.InterfaceGuid
|
|
$dohFlagsBasePath = "HKLM:\System\CurrentControlSet\Services\Dnscache\InterfaceSpecificParameters\$interfaceGuid\DohInterfaceSettings\Doh"
|
|
|
|
if (Test-Path $dohFlagsBasePath) {
|
|
# Check each DNS server IP
|
|
$allDnsIPs = $ipv4Addresses + $ipv6Addresses
|
|
foreach ($dnsIP in $allDnsIPs) {
|
|
$dohFlagsPath = "$dohFlagsBasePath\$dnsIP"
|
|
if (Test-Path $dohFlagsPath) {
|
|
$flagValue = (Get-ItemProperty -Path $dohFlagsPath -Name "DohFlags" -ErrorAction SilentlyContinue).DohFlags
|
|
if ($null -ne $flagValue) {
|
|
$dohFlags[$dnsIP] = $flagValue
|
|
Write-Log -Level DEBUG -Message "Found DohFlags for $dnsIP : $flagValue" -Module $script:ModuleName
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch {
|
|
Write-Log -Level DEBUG -Message "Could not retrieve DohFlags: $_" -Module $script:ModuleName
|
|
}
|
|
|
|
# Get DHCP DNS Override setting for this adapter
|
|
$dhcpOverrideDisabled = $null
|
|
try {
|
|
$dnsClient = Get-DnsClient -InterfaceIndex $adapter.InterfaceIndex -ErrorAction SilentlyContinue
|
|
if ($dnsClient) {
|
|
$dhcpOverrideDisabled = (-not $dnsClient.RegisterThisConnectionsAddress)
|
|
Write-Log -Level DEBUG -Message "DHCP Override disabled: $dhcpOverrideDisabled" -Module $script:ModuleName
|
|
}
|
|
}
|
|
catch {
|
|
Write-Log -Level DEBUG -Message "Could not retrieve DHCP override setting: $_" -Module $script:ModuleName
|
|
}
|
|
|
|
$adapterBackup = @{
|
|
InterfaceIndex = $adapter.InterfaceIndex
|
|
InterfaceAlias = $adapter.Name
|
|
InterfaceDescription = $adapter.InterfaceDescription
|
|
InterfaceGuid = $adapter.InterfaceGuid
|
|
Status = $adapter.Status
|
|
IsDHCP = $isDHCP
|
|
IPv4Addresses = $ipv4Addresses
|
|
IPv6Addresses = $ipv6Addresses
|
|
DoHConfiguration = $dohConfig
|
|
DohFlags = $dohFlags
|
|
DhcpOverrideDisabled = $dhcpOverrideDisabled
|
|
}
|
|
|
|
$backupData.Adapters += $adapterBackup
|
|
|
|
$statusText = if ($isDHCP) { "DHCP" } else { "Static" }
|
|
$dnsText = if ($isDHCP) { "from DHCP" } else { "$($ipv4Addresses.Count) IPv4, $($ipv6Addresses.Count) IPv6" }
|
|
Write-Log -Level INFO -Message " - $($adapter.Name): $statusText ($dnsText)" -Module $script:ModuleName
|
|
}
|
|
|
|
if ($DryRun) {
|
|
Write-Log -Level INFO -Message "[DRYRUN] Would backup DNS settings for $($adapters.Count) adapter(s)" -Module $script:ModuleName
|
|
Write-Log -Level DEBUG -Message "[DRYRUN] - netsh global DoH state" -Module $script:ModuleName
|
|
Write-Log -Level DEBUG -Message "[DRYRUN] - netsh DoH encryption entries" -Module $script:ModuleName
|
|
Write-Log -Level DEBUG -Message "[DRYRUN] - DoH Policy Registry (DoHPolicy, EnableAutoDoh, DohFlags)" -Module $script:ModuleName
|
|
Write-Log -Level DEBUG -Message "[DRYRUN] - Per-adapter DohFlags registry" -Module $script:ModuleName
|
|
Write-Log -Level DEBUG -Message "[DRYRUN] - DHCP DNS override settings" -Module $script:ModuleName
|
|
Write-Log -Level DEBUG -Message "[DRYRUN] - DNS server addresses" -Module $script:ModuleName
|
|
return "DRYRUN"
|
|
}
|
|
|
|
# Convert to JSON and save using rollback system
|
|
$backupJson = $backupData | ConvertTo-Json -Depth 10
|
|
$backupFile = Register-Backup -Type "DNS" -Data $backupJson
|
|
|
|
if ($backupFile) {
|
|
Write-Log -Level SUCCESS -Message "DNS settings backed up successfully" -Module $script:ModuleName
|
|
return $backupFile
|
|
}
|
|
else {
|
|
Write-Log -Level ERROR -Message "Failed to register DNS backup" -Module $script:ModuleName
|
|
return $null
|
|
}
|
|
}
|
|
catch {
|
|
Write-ErrorLog -Message "Failed to backup DNS settings" -Module $script:ModuleName -ErrorRecord $_
|
|
return $null
|
|
}
|
|
}
|