无公网访问——使用Lucky的STUN内网穿透

感谢 qaz741wsd856 作者的分享,非常优秀的教程
打通大内网第一期 无公网部署https和反向代理 (基于Lucky的STUN穿透) - 简书

因为现在运营商已经不再发放公网ipv4地址,所以只能使用公网ipv6地址作为服务站点。但是ipv6并不是所有网络环境都具备的,为了使服务更加普适,我尝试利用STUN内网穿透实现此需求。

内容完全参考原教程,我只是将部署过程中的过程调整了一些,省略了一些:

首先确认满足以下条件:

  • NAT类型为NAT1,即fullcone;
  • 光猫桥接或开启dmz;
  • 路由器能刷机或者开启upnp/dmz

我在办理宽带时已经做好光猫桥接,并在红米AX6000路由器上安装了Lucky插件。基于此前提,有以下的实现步骤:

开启STUN内网穿透

进入Lucky插件后台,点击STUN内网穿透选项

更新STUN服务列表

添加穿透规则

点击穿透规则列表 - 添加穿透规则具体设置如下:


运气好的话,就能看到STUN穿透公网地址显示出穿透成功的公网ipv4地址:端口号,访问测试一下。如果没问题,那么就接着下面的步骤;如果没地址,那就算了。

设置cloudflare的重定向规则

因为使用STUN穿透时,不光ip地址会变,端口也会变,使用起来十分不便利。
这时可以利用cloudflare的重定向规则,访问域名时自动跳转到穿透后的IP:端口,不损失速度。
如何实现地址更新呢?其实就是利用webhook,将变更的IP地址填入cloudflare的请求体,PATCH请求重定向规则的API,实现自动绑定地址到域名的效果。

解析域名

访问cloudflare,在你的网址的DNS中添加一个A类型的记录,ipv4地址从下面站点优选一个填入,代理状态勾选:

配置重定向规则

点击左侧菜单的规则-重定向规则,在单一重定向页面下点击创建规则,规则名称随意设置。

当传入请求匹配时...处选择自定义筛选表达式,字段选择主机名,运算符选择等于需填入自行设置的用于跳转的域名;示例为test.yourdomain.comtest为自定义的二级域名前缀,yourdomain.com换成你的顶级域名。

URL 重定向处选择类型为动态并勾选保留查询字符串,状态码选择302307均可;表达式填入当前STUN穿透成功的地址即可,然后点击部署。
image

抓包获取请求内容

部署规则成功后,重新点击编辑,这时按F12打开开发者工具,点击右侧开发者工具的网络或者network选项卡,然后再点击保存按钮。

接下来可以在开发者工具中看到一串数字+字母的项,点击它,在标头选项卡下复制并保存下它的请求网址;然后切换到载荷选项卡,右键第一行复制并保存它的值。
image
image
请求网址:

https://dash.cloudflare.com/api/v4/zones/区域id/rulesets/规则集id/rules/规则id

请求载荷:

{
  "id": "c7087a0fb757480xxxxxxxxxxxxxxxx",
  "version": "1",
  "action": "redirect",
  "expression": "(http.host eq \"test.yourdomain.com\")",
  "description": "redirect",
  "last_updated": "2024-05-28T08:14:45.555123Z",
  "ref": "c7087a0fb757480xxxxxxxxxxxxxxxx",
  "enabled": true,
  "action_parameters": {
    "from_value": {
      "status_code": 307,
      "target_url": {
        "expression": "concat(\"http://183.6.66.666:6666\", http.request.uri.path)"
      },
      "preserve_query_string": true
    }
  }
}

自动更新重定向规则

创建cloudflare令牌

我们需要一个cloudflare编辑重定向的令牌:

  • 点击Cloudflare控制台右上角-我的个人资料,在左侧菜单点击API令牌,页面中点击创建令牌

  • 在令牌创建页面选择创建自定义令牌

  • 权限和区域资源如图设置,区域资源第三列选择你要用于跳转的域名

然后点击继续-创建令牌

  • 保存第二行双引号里的内容Authorization: Bearer ******-****,作为接下来要使用Webhook的请求头
curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \  
     -H "Authorization: Bearer ******-****" \  
     -H "Content-Type:application/json"

编辑webhook

  • 接口地址:
https://api.cloudflare.com/client/v4/zones/区域id/rulesets/规则集id/rules/规则id

将请求网址的前半部分https://dash.cloudflare.com/api/ 替换为https://api.cloudflare.com/client/即可

  • 请求方法:PATCH
  • 请求头:
Authorization:Bearer API 令牌
  • 请求主体:
    把之前保存的请求载荷删去last_updatedversion后,将expression中的ip:端口替换为#{ipAddr}
    你的idref应该与规则id一致,description就是之前设置的规则名称。
    参考样式:
{
  "id": "c7087a0fb757480xxxxxxxxxxxxxxxx",
  "action": "redirect",
  "expression": "(http.host eq \"test.yourdomain.com\")",
  "description": "redirect",
  "ref": "c7087a0fb757480xxxxxxxxxxxxxxxx",
  "enabled": true,
  "action_parameters": {
    "from_value": {
      "status_code": 307,
      "target_url": {
        "expression": "concat(\"http://#{ipAddr}\", http.request.uri.path)"
      },
      "preserve_query_string": true
    }
  }
}

填完后点击Webhook手动触发测试,查看返回内容中是否包含接口调用成功字符串:"success": true
image

配置全局Stun Webhook

因为更新webhook已经被占用,可以使用全局webhook来通知更新情况,我这里使用反代后的tg bot接口:
请求主体:

{
  "chat_id": "",
  "text": {
    "Device": "Lucky STUN",
    "ipv6": {
        "time": "#{time}",
        "addr": "#{ipAddr}",
        "rule name": "#{ruleName}"
    }
}
}

然后就完事了,访问域名看看是不是正常跳转了。

23 个赞

因为有重定向表达式会触发waf,劳烦各位去原教程处查阅:
image

1 个赞

很强

2 个赞

就喜欢看这些不用在路由器上刷Openwrt或者加软路由的东西。

2 个赞

我是给路由器开了ssh的

1 个赞

我记得给红米AX6000开 ssh 不用刷机吧。

1 个赞

很强的分享

2 个赞

不用刷机,就是要重启几次,开后台啥的,我也分享了教程

2 个赞

太强了!

2 个赞

有技术啊!

1 个赞

看起来不错,这样是不是可以不用 cftunnel 了?

1 个赞

要用cf tunel,因为stun还是不稳定,用CF穿透lucky面板备用调试

1 个赞

其次我也是这个方案,然后再搭建一个homepage,实时获取重定向跳转界面的端口,通过反向代理固定域名,现在访问homepage,域名不变,端口自动添加,你需要记忆的就不是端口,而是域名前缀,我感觉这样还安全一点(我不会说是我没有公网ip),毕竟端口不固定

1 个赞

可以再加个验证

1 个赞

没技术,都是原教程写得好

1 个赞

我不太明白这个原理,是说在第一次重定向的基础上,在建立一个域名来二次重定向吗?实现固定域名加端口自动?

1 个赞

应该是我没表达清楚:joy:
我有两个域名,A和B
平时内网服务访问都是用A+随机端口,但是不想记端口
所以像你这样用CF重定向跳转,实现访问B域名跳转到A域名加端口
而内网也搭建了一个反代服务器,所以现在只需要记忆:
B域名和每个服务的拼音或者汉字就好了,我现在的步骤也就是

访问B域名,跳转到我搭建kuma服务,更改A域名前缀,访问xx服务简写.a.com:随机端口

而且我是定时重启stun穿透更换端口的,所以我说感觉毕竟安全,因为端口不固定,我都记不住哈哈
上面看着麻烦,其实就那么两步,不需动脑

2 个赞

你这么弄是因为完全没有公网ip是吧?所有的服务都是用stun穿透

1 个赞

cy
佬强,很有用 :+1:

是的,完全没有,有也不打算用了,因为stun能跑满上行

1 个赞