|
本帖最后由 subtlelonging 于 2024-10-18 22:47 编辑
今天更新下去掉v6部分,因为v6有公网地址比较简单,论坛就有很多教程了
目前宽带情况,深圳电信下行1000M上行50M,拨号上网如图:
有v6公网IP,没有v4地址,找电信要不到v4,需要办理100元/月的动态IP套餐才有
实现方法:云服务器搭个空站点内嵌飞牛以及写个脚本接收穿透后的端口号
lucky负责穿透,动态域名更新穿透后的地址,webhook通知服务器更新端口号
满足以下几个条件:
1.域名(各大域名厂商自行购买,本人目前使用腾讯云,不想购买可以去申请一些免费域名如freemoon)
2.云服务器(各大云厂商自行购买,本人目前使用的是21年在腾讯云薅羊毛一百多买的7年轻量云1H2G5M)
3.网络NAT类型:必须是NAT1(Full Cone)
4.lucky(我的路由系统是istoreos直接插件安装即可)
最关键的先来确认下自己NAT类型执行如下命令:
- sudo -i
- apt update && apt install -y pipx && pipx ensurepath && source ~/.bashrc && pipx install pystun3 && pystun3
复制代码
如果你的NAT类型也是Full Cone并且能获取到穿透IP和端口
那恭喜你继续往下看
一、域名解析
去域名运营商那里解析下自己的云服务器,再额外添加两条解析记录
第一条:用于v4解析A记录值直接写自己服务器地址,我这里使用fn.subtlelongig.com解析v4
第二条:用于绑定穿透后的IP地址,先随便填写后面lucky会动态更新,我这里使用relay.subtlelonging.com
二、云服务器设置
登录1panel新建一个静态网站绑定下用来解析飞牛的域名并申请ssl证书开启https,如下:
打开网站目录修改首页index.html如下,其中需要将域名替换为你中转用的域名,端口号保留下后面会自动来修改
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>飞牛私有云fnOS</title>
- <style>
- body, html {
- margin: 0;
- padding: 0;
- height: 100%;
- overflow: hidden;
- }
- #my-iframe {
- width: 100%;
- height: 100%;
- border: none;
- }
- </style>
- </head>
- <body>
- <iframe
- allowfullscreen="true"
- webkitallowfullscreen="true"
- mozallowfullscreen="true"
- id="my-iframe"
- src="https://relay.subtlelonging.com:12345">
- </iframe>
- </body>
- </html>
复制代码
接下来ssh登录云服务器,创建一个自动更新端口号的python脚本
先创建文件
写入以下代码,记得将域名替换为自己的
- from flask import Flask, request
- import re
- import logging
- app = Flask(__name__)
- CONFIG_FILE_PATH = "/opt/1panel/apps/openresty/OpenResty/www/sites/fn.subtlelonging.com/index/index.html"
- SRC_PATTERN = re.compile(r'src="https://relay\.subtlelonging\.com:\d+"')
- @app.route('/update_port')
- def update_port():
- ip_port = request.args.get('ip_port')
- if not ip_port:
- return "Error: No ip_port field provided. Please specify an ip_port.", 400
- try:
- with open(CONFIG_FILE_PATH, "r") as file:
- content = file.read()
- # Replace the src content
- updated_content = SRC_PATTERN.sub(f'src="https://relay.subtlelonging.com:{ip_port}"', content)
- with open(CONFIG_FILE_PATH, "w") as file:
- file.write(updated_content)
- app.logger.info(f"Updated port in config file {CONFIG_FILE_PATH} to: {ip_port}")
- return "Port updated successfully", 200
- except Exception as e:
- app.logger.error(f"Error updating port: {e}")
- return "Internal server error", 500
- if __name__ == "__main__":
- logging.basicConfig(level=logging.INFO)
- app.run(host='0.0.0.0', port=15000)
复制代码
接下来安装screen,用于后台执行脚本,随时方便的查看请求信息,当然你也可以选择使用nohup
创建一个名称为updatepost后台会话
创建完成后自动进入screen会话,执行更新端口脚本
执行结果如下:(不知名请求忽略即可,无聊的人很多)
退出screen会话:
下次再想进screen后台会话:
如果忘记会话名称,可以先查看下所有的会话:
还有个关键点,记得打开云服务器防火墙开放15000端口,不然服务器可接收不到我们更新端口的请求!
三、lucky设置
进入locky后先为域名申请证书,步骤过于简单省略,我这里是:relay.subtlelonging.com
进入STUN内网穿透选项,添加一条规则,关键参数如下:
- 规则名称:随意(记住了下边会用到)
- 穿透类型:IPv4-TCP
- 穿透通道本地端口:0(保持默认即可,使用随机端口,你也可以指定端口)
- 防火墙自动放行:开启(这里不开启,你就得去网络-防火墙-端口转发-添加一条转发规则)
- 目标地址:192.168.1.188(飞牛的内网地址)
- 目标端口:8001(飞牛https端口)
- Webhook:启动
- 仅在地址和上一次不同时触发Webhook:启用
- 接口地址:http://110.42.188.189:15000/update_port?ip_port={port}(更改为你云服务器的IP地址)
- 请求方法:GET
- 接口调用成功包含的字符串:port updated successfully
复制代码
添加完成后可以点击Webhook手动触发测试一下,测试结果显示调用成功即可
进入动态域名选项,添加一条任务,DNS服务器设置根据自己的来,最关键获取公网ip方式选择通过脚本获取,填写如下脚本:
- curl -H "openToken:2f8pXDzLq66NiviM78RVwnbCe0FXxore" http://192.168.1.1:16601/api/stunrulelist | jq -r '.list[] | select(.Name=="fnos") | .PublicAddr'
复制代码
需要修改的地方有两处:
第一个openToken,这个关键参数在lucky左测菜单设置里边拉到最下边即可看到,如果你的openToken开关没打开,先打开他会自动生成一个Token
第二个参数Name=="fnos",将fnos修改为你添加穿透规则的名称
还有一个地方需要注意,由于上边脚本使用了jq库来解析返回的json结果,有可能你的openwrt没有安装jq,那么你需要先安装一下,不然脚本执行结果无法正确返回
- opkg update && opkg install jq
复制代码 点击测试指令,能返回穿透后的地址即可
现在可以访问下域名fn.subtlelonging.com
已经达到我们需要的效果
缺点:因为是内嵌网站所以移动终端飞牛APP自然是无法登录,但现在移动终端运营商都是支持ipv6的,所以飞牛app使用v6解析登录
优点:内嵌式最终的流量都是走我们本地带宽上行(严谨的说内嵌方式在请求的过程中消耗了云服务器流量的但是太少了小于1kb可以忽略不计)
本着大多数PC场景下没有ipv6的痛苦,才来想办法来搞定v4,但光用来访问飞牛系统有点大材小用,感觉真正的用途应该是影视不然50M的上行带宽实在浪费
在外边调用飞牛影视播放视频,如果你也想,那么继续动手再添加一个静态网站,绑定一个二级域名,申请SSL证书开启https,我这里使用video.subtlelonging.com
然后修改下index.html,直接复制上边的代码,唯一的区别就是需要在穿透后的地址后边加一个/v即可
- src="https://relay.subtlelonging.com:12345/v">
复制代码 再来修改下上边的updateport脚本:
- from flask import Flask, request
- import re
- import logging
- app = Flask(__name__)
- CONFIG_FILE_PATHS = {
- "fn": "/opt/1panel/apps/openresty/OpenResty/www/sites/fn.subtlelonging.com/index/index.html",
- "video": "/opt/1panel/apps/openresty/OpenResty/www/sites/video.subtlelonging.com/index/index.html"
- }
- SRC_PATTERN = re.compile(r'(src="https?://relay\.subtlelonging\.com:)\d+((?:/v)?)')
- @app.route('/update_port')
- def update_port():
- ip_port = request.args.get('ip_port')
- if not ip_port:
- return "Error: No ip_port field provided. Please specify an ip_port.", 400
- messages = []
- for category in CONFIG_FILE_PATHS:
- try:
- with open(CONFIG_FILE_PATHS[category], "r") as file:
- content = file.read()
- # Replace the src content
- def replacer(match):
- new_url = match.group(1) + ip_port + match.group(2)
- app.logger.info(f"Updated port in config file {CONFIG_FILE_PATHS[category]} to: {ip_port}")
- return new_url
- updated_content = SRC_PATTERN.sub(replacer, content)
- with open(CONFIG_FILE_PATHS[category], "w") as file:
- file.write(updated_content)
- messages.append(f"{category} port updated successfully")
- except Exception as e:
- app.logger.error(f"Error updating port for {category}: {e}")
- messages.append(f"Internal server error for {category}")
- return "\n".join(messages), 200
- if __name__ == "__main__":
- logging.basicConfig(level=logging.INFO)
- app.run(host='0.0.0.0', port=15000)
复制代码
修改完记得运行更新脚本,并去lucky停用再启动下穿透规则更新下端口
然后访问下video.subtlelonging.com试试,已经可以了,登录进去找个视频播放下
然后我们去lucky穿透规则下看看流量情况,每次自动刷新上传都会增加个5M,没毛病跑的是自家上行带宽
最后还有一点,在手机打开影视播放视频的话,飞牛目前没做适配,登录进去只显示一小块,如图:
播放视频也是一样的只显示左边半块
所以为了能正常看视频,在我们index.html文件中添加以下代码(在iframe标签后边加上),通过js调整下飞牛窗口
- <script>
- function adjustIframe() {
- var iframe = document.getElementById('my-iframe');
- var isMobile = window.innerWidth < 768;
- if (isMobile) {
- var scale = window.innerWidth / 800;
- iframe.style.transform = 'scale(' + scale + ')';
- iframe.style.transformOrigin = '0 0';
- iframe.style.width = (100 / scale) + '%';
- iframe.style.height = (100 / scale) + '%';
- } else {
- iframe.style.transform = 'none';
- iframe.style.width = '100%';
- iframe.style.height = '100%';
- }
- }
- window.addEventListener('resize', adjustIframe);
- window.addEventListener('load', adjustIframe);
- </script>
复制代码 现在再去试试,效果如下,页面已经进行了缩放,播放个视频点全屏也能自动横屏播放
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|