Last active
January 21, 2024 01:56
-
-
Save pd12bbf7608ae1/90642c3fcdf233fb3744cc2bb8ad4aac to your computer and use it in GitHub Desktop.
Wireguard Dynamic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$config = [PSCustomObject]@{ | |
interfaceName = "wg0" # wg 命令中的端口名称 | |
endPoint = [PSCustomObject]@{ | |
publicKey = "123456=" # 对端公钥 | |
domains = @( | |
"example.org", | |
"example.com") # 对端域名 可有多个 | |
type = "A" # 或者AAAA | |
sshPort = "22" | |
sshPublicKey = "123456" # sha256 | |
sshPublicKeyType = "ed25519" | |
} | |
pingTimeout = 3 # 超时时间 | |
pingCount = 3 # ping计数 | |
pingIp = "192.168.1.1" # 对端检测用IP | |
}; | |
function GetAliDns { # 获取 ali dns 结果 | |
param ( | |
[string]$domain, | |
[string]$type | |
) | |
if ($domain.Length -eq 0 -or $type.Length -eq 0) { | |
return "" | |
} | |
$type = $type -eq 'AAAA' ? 28 : 1 | |
$result = Invoke-RestMethod -ConnectionTimeoutSeconds 5 -Method Get -Uri "https://dns.alidns.com/resolve?name=${domain}&type=${type}" | |
if ($? -eq $false) { | |
Write-Host -ForegroundColor Red "AliDns 失败" | |
return "" | |
} | |
if ($result.Answer.Length -eq 0) { | |
Write-Host -ForegroundColor Red "AliDns 找不到域名" | |
return "" | |
} | |
# return $result.Answer[0].data # 解决 CName 问题 | |
foreach($answer in $result.answer) { | |
if ($answer.type -eq $type) {return $answer.data} | |
} | |
Write-Host -ForegroundColor Red "AliDns 找不到指定类型" | |
return "" | |
} | |
function GetTencentDns { # 获取 doh.pub 结果 | |
param ( | |
[string]$domain, | |
[string]$type | |
) | |
if ($domain.Length -eq 0 -or $type.Length -eq 0) { | |
return "" | |
} | |
$type = $type -eq 'AAAA' ? 28 : 1 | |
$result = Invoke-RestMethod -ConnectionTimeoutSeconds 5 -Method Get -Uri "https://doh.pub/resolve?name=${domain}&type=${type}" | |
if ($? -eq $false) { | |
Write-Host -ForegroundColor Red "TencentDns 失败" | |
return "" | |
} | |
if ($result.Answer.Length -eq 0) { | |
Write-Host -ForegroundColor Red "TencentDns 找不到域名" | |
return "" | |
} | |
# return $result.Answer[0].data # 解决 CName 问题 | |
foreach($answer in $result.answer) { | |
if ($answer.type -eq $type) {return $answer.data} | |
} | |
Write-Host -ForegroundColor Red "TencentDns 找不到指定类型" | |
return "" | |
} | |
function GetCloudflareDns { # 获取 Cloudflare dns 结果 | |
param ( | |
[string]$domain, | |
[string]$type | |
) | |
if ($domain.Length -eq 0 -or $type.Length -eq 0) { | |
return "" | |
} | |
$type = $type -eq 'AAAA' ? 28 : 1 | |
$result = Invoke-RestMethod -ConnectionTimeoutSeconds 8 -Method Get -Uri "https://1.0.0.1/dns-query?name=${domain}&type=${type}" -Headers @{"accept" = "application/dns-json"} | |
if ($? -eq $false) { | |
Write-Host -ForegroundColor Red "CloudflareDns 失败" | |
return "" | |
} | |
if ($result.Answer.Length -eq 0) { | |
Write-Host -ForegroundColor Red "CloudflareDns 找不到域名" | |
return "" | |
} | |
# return $result.Answer[0].data # 解决 CName 问题 | |
foreach($answer in $result.answer) { | |
if ($answer.type -eq $type) {return $answer.data} | |
} | |
Write-Host -ForegroundColor Red "CloudflareDns 找不到指定类型" | |
return "" | |
} | |
function GetLocalDns { # 获取 本地 dns 结果 | |
param ( | |
[string]$domain, | |
[string]$type | |
) | |
$result = Resolve-DnsName -Name $domain -Type $type | |
if ($? -eq $false) { | |
Write-Host -ForegroundColor Red "LocalDns 失败" | |
return "" | |
} | |
if ($result.Length -eq 0) { | |
Write-Host -ForegroundColor Red "LocalDns 找不到域名" | |
return "" | |
} | |
foreach($answer in $result) { | |
if ($answer.Type -eq $type) {return $answer.IPAddress} | |
} | |
Write-Host -ForegroundColor Red "LocalDns 找不到指定类型" | |
return "" | |
} | |
function CheckEndpoint { # 获取目标是否为可用主机 | |
param ( | |
[string]$ip | |
) | |
$result = (ssh-keyscan -T 3 -t $config.endPoint.sshPublicKeyType -p $config.endPoint.sshPort $ip 2>$null | ssh-keygen -l -E sha256 -f - 2>$null) | |
$fingerPrint = (($result -split ' ')[1] -split ':')[1] | |
if ($fingerPrint -ceq $config.endPoint.sshPublicKey) { | |
Write-Host "${ip} 有效" | |
return $true | |
} | |
Write-Host -ForegroundColor Red "${ip} 无效" | |
return $false | |
} | |
function GetDomainIp { # 获取IP并进行检查 返回检查成功的IP | |
foreach($domain in $config.endPoint.domains) { | |
Write-Host "尝试域名 ${domain}" | |
$aliIp = GetAliDns $domain $config.endPoint.type | |
if ($aliIp.Length -ne 0 -and (CheckEndpoint $aliIp)) { # 获得可能可用IP | |
Write-Host "使用 IP ${aliIp}" | |
return $aliIp | |
} | |
$tencentIp = GetTencentDns $domain $config.endPoint.type | |
if ($tencentIp.Length -ne 0 -and (CheckEndpoint $tencentIp)) { | |
Write-Host "使用 IP ${tencentIp}" | |
return $tencentIp | |
} | |
$localIp = GetLocalDns $domain $config.endPoint.type | |
if ($localIp.Length -ne 0 -and (CheckEndpoint $localIp)) { | |
Write-Host "使用 IP ${localIp}" | |
return $localIp | |
} | |
$cloudflareIp = GetCloudflareDns $domain $config.endPoint.type | |
if ($cloudflareIp.Length -ne 0 -and (CheckEndpoint $cloudflareIp)) { | |
Write-Host "使用 IP ${cloudflareIp}" | |
return $cloudflareIp | |
} | |
Write-Host -ForegroundColor Red "域名 ${domain} 失败" | |
} | |
Write-Host -ForegroundColor Red "域名全部失败" | |
return "" | |
} | |
function Main { | |
$date = (Get-Date) | |
Write-Host -ForegroundColor Yellow $date | |
# 检测接口是否启动 | |
Get-NetAdapter -Name $config.interfaceName 1>$null 2>$null | |
if (!$?) { | |
Write-Host -ForegroundColor Red "找不到接口" | |
return | |
} | |
Write-Host "测试对端连通性..." | |
# 首先检查对端是否接通 | |
if (Test-Connection -Delay 1 -Count $config.pingCount -TimeoutSeconds $config.pingTimeout -Quiet -TargetName $config.pingIp) { | |
Write-Host "可以联通 退出" | |
return | |
} | |
# 需要重设 | |
Write-Host -ForegroundColor Red "无法联通 $($config.endPoint.publicKey)" | |
$currentEndpoint = ((wg show $config.interfaceName endpoints | Select-String -CaseSensitive -SimpleMatch -Pattern "$($config.endPoint.publicKey)" | Select-Object -First 1) -split "`t")[1] # 获取IP 端口 | |
if ($currentEndpoint.Length -eq 0) { | |
Write-Host -ForegroundColor Red "找不到对端 退出" | |
return | |
} | |
Write-Host "当前对端 ${currentEndpoint}" | |
if ($currentEndpoint -match '\[(.*?)\]') { # ipv6 地址 | |
$currentIp = $Matches[1] | |
$currentPort = (($currentEndpoint -split "]")[1] -split ":")[1] | |
} else { | |
$currentIp = ($currentEndpoint -split ":")[0] | |
$currentPort = ($currentEndpoint -split ":")[1] | |
} | |
# Write-Host $currentIp $currentPort | |
if ($currentIp.Length -eq 0 -or $currentPort -eq 0) { | |
Write-Host -ForegroundColor Red "找不到对端IP或端口 退出" | |
return | |
} | |
# 已有目前的 对端 IP 端口 | |
$newIp = GetDomainIp | |
if ($newIp.Length -eq 0) { # 找不到IP | |
Write-Host -ForegroundColor Red "找不到可用IP 退出" | |
return | |
} | |
if ($config.endPoint.type -eq "AAAA") { | |
$newIp = '[' + $newIp + ']' | |
} | |
# 更改接口地址 | |
wg set $config.interfaceName peer $config.endPoint.publicKey endpoint "${newIp}:${currentPort}" | |
# 等待 | |
Start-Sleep -Seconds 5 | |
# 测试对端连接性 | |
if (Test-Connection -Delay 1 -Count $config.pingCount -TimeoutSeconds $config.pingTimeout -Quiet -TargetName $config.pingIp) { | |
Write-Host "联通成功" | |
} else { | |
Write-Host -ForegroundColor Red "联通失败" | |
} | |
} | |
Main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment