Skip to content

Instantly share code, notes, and snippets.

@pd12bbf7608ae1
Last active January 21, 2024 01:56
Show Gist options
  • Save pd12bbf7608ae1/90642c3fcdf233fb3744cc2bb8ad4aac to your computer and use it in GitHub Desktop.
Save pd12bbf7608ae1/90642c3fcdf233fb3744cc2bb8ad4aac to your computer and use it in GitHub Desktop.
Wireguard Dynamic
$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