无公网ip的一种穿透使用方案,利用lucky的stun穿透暴露端口,设置伪DDNS

现在访问内网应用的几种方式:

前期解决问题

lucky的stun穿透有官方的讲解文档,其实就是连接公共stun服务器,产生一条通道,并维持住,利用NAT1的对称性,将这条通道给其他通信用。所以前提要求lucky运行的机器,1就是上网的拨号机,或者2拨号机的DMZ指向机。

拿图举个例子,(主机可能是路由器,电脑这些设备)ip就是这些机器的名字,端口就是123,124这些通道线路,stun服务器会获得运营商外网网关的ip:111,外网网关和主机之间又相当于一个互联网,外网网关会把主机ip:124和外网网关ip:111对应起来,通常防火墙的策略是只准出不准进,所以通道要双向通信,主机需要防火墙配置允许124进,UPNU的功能是通过协议自动放行一些端口线路,比如lucky监听stun穿透端口124在开启upnup的情况下就会配置自动放行124进。dmz的意思是把目标机的端口号和本机的端口号一一对应起来。upnp在放行的时候也会建立端口的对应关系。所以通常NAT1和dmz以及upnp不同时开。端口的对应关系也可以通过防火墙的转发规则,或者有些品牌路由器的虚拟服务器,手动对应。

openwrt防火墙放行设置参考

lucky的stun穿透

设置过程请参考lucky教程,或者《打通大内网...》这篇教程。

屏幕截图 2024-09-05 230524.png

webhook是后续写伪DNS的设置,可以后续设置。

wireguard采用udp通信就选ipv4-udp,虽然软件提示udp不要开启“不使用Lucky内置端口转发”,因为测试失败,但是我在openwrt上测试通过防火墙配置转发规则是可用的。关闭时lucky会进行转发,开启后需要自己处理,用防火墙策略的话可以节省系统资源。该设置根据情况开启,开启后需要防火墙转发16789到wireguard监听端口(比如我后续设置的41645).参考配置如下

屏幕截图 2024-09-05 231345.png

伪DDNS

这里是cloudflare的域名解析,其他解析可以参考,或者也注册cloudflare来操作,并购买域名或者申请免费域名。相关教程网络上很多。

手动添加一条txt记录,方便查询id。

在lucky手动添加“计划任务”:

屏幕截图 2024-09-05 232851.png

接口地址:

https://api.cloudflare.com/client/v4/zones/区域id/dns_records?name=bqr.0nz.fun&type=TXT

请求方式:get

请求头:

X-Auth-Key: cloudflare个人资料中api令牌
X-Auth-Email: cloudflare注册邮箱
Content-Type: application/json

替换区域id,域名name,和请求头中的key、email。

区域id在cloudflare当前域名的右下角。

手动执行一次会获得dns记录的id。

根据获得的dns记录id填写stun穿透下的webhook,在端口变化的时候就会自动修改txt记录了。

stun穿透webhook接口地址:

https://api.cloudflare.com/client/v4/zones/区域id/dns_records/dns记录的id

请求方式:put

请求头:

X-Auth-Key: cloudflare个人资料中api令牌
X-Auth-Email: cloudflare注册邮箱
Content-Type: application/json

脚本查询txt记录修改wireguard配置

wireguard本来有preup和postup设置的,但是Windows现行版本下策略禁止执行脚本命令,就直接用powershell脚本修改配置文件了,wireguard启动的时候从配置文件导入隧道即可.

# 定义文件路径
$filePath = "./wg0.conf"

# 定义域名
$domain = "bqr.0nz.fun"

# 获取 TXT 记录
$txtRecords = Resolve-DnsName -Name $domain -Type TXT

# 检查是否有 TXT 记录
if ($txtRecords.Strings) {
    # 将 TXT 记录的值赋给 newString
    $newString = "Endpoint = " + $txtRecords.Strings[0]
} else {
    Write-Output "未找到 TXT 记录。"
    exit
}

# 读取文件内容
$fileContent = Get-Content -Path $filePath -Raw

# 使用正则表达式提取旧的 IP 地址格式的 Endpoint 值
$pattern = 'Endpoint\s*=\s*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+'
$matches = [regex]::Matches($fileContent, $pattern)

if ($matches.Count -gt 0) {
    foreach ($match in $matches) {
        $oldString = $match.Value
        Write-Output "找到旧的 Endpoint 值: $oldString"

        # 替换字符串
        $newContent = $fileContent -replace [regex]::Escape($oldString), $newString

        # 将修改后的内容写回文件
        Set-Content -Path $filePath -Value $newContent

        Write-Output "替换完成。"
    }
} else {
    Write-Output "未找到匹配的 IP 地址格式的 Endpoint 值。"
}

修改配置文件路径和域名名称,新建txt,粘贴代码,重命名为pre.ps1,注意连txt后缀名一起修改。(脚本只匹配一个peer,多peer的请修改脚本(问gpt怎么改))

wireguard的配置文件wg0.conf

[Interface]
PrivateKey = aExxxxxxxxxxxlA=
Address = 172.16.0.2/32
DNS = 223.5.5.5

[Peer]
PublicKey = uQsxxxxxxxxxxxxxx2Q=
PresharedKey = IAxxxxxxxxxxxx0A=
AllowedIPs = 192.168.1.1/24
Endpoint = 117.174.138.139:35369
PersistentKeepalive = 25

右键powershell运行一次pre.ps1,再启动wireguard新建隧道从文件导入,选择wg0.conf即可。