背景
本身有一个已经备案的域名,一部分服务在共有云,一些家庭服务走了DDNS进行动态解析。之前一直使用Frp搭建tunnel来实现了非80\443端口的免端口访问。
最近购买的服务器到期不想续费了,因此需要寻找其他方法来实现部分非80\443端口服务的免端口访问。
期间尝试了如下几个方案:
使用DNS的隐性URL
基于DNS的隐性URL转发,基本实现原理类似运营商的DNS劫持,早期网通网络经常会在浏览的网页右下角多出来一个广告,这个广告不是页面自带的是运营商添加的。
URL隐性转发就是把要转发的网址包裹在一个ifream中, 有几点局限性:
1、必须是HTTP转HTTP或HTTPS, 因为HTTPS DNS无法往里加料..
2、页面内的链接还是带端口的,如果要让页面内的也去除端口则需要使用如Nginx + sub_filter模块来实现,但是目前浏览器如chrome已经会强制将http转https, 即便是http -> http 也会报错如:
30Mixed Content: The page at '<URL>' was loaded over HTTPS, but requested an insecure element '<URL>'.
This request was automatically upgraded to HTTPS, For more information see <URL>使用Cloudflare的Page Rules
原理是301\302跳转,效果类似隐性URL。 浏览器和页面内部连接还是原来的带端口URL, 只是做了页面跳转。使用Cloudflare的tunnel
和frp相同的原理,需要在本地部署一个客户端。 再没有公网IP的情况下可以使用Cloudflare Tunnel使用Cloudflare的Origin Rules
这个理论是可以的,但是使用的免费二级域名,挂到cloudflare后无法解析。 现象:
1、从国内访问提示找不到ip
2、 checkdns.org 检查解析无解析
3、挂VPN可以访问。
进行多次设置、问题排查后无法解决,遂放弃。这个问题应该出在cloudns.ch这种二级域名上,如果使用自有域名应该没有问题。 也可能是我设置有问题,如有大佬成功可以告知下使用Cloudflare的Workers
最终使用了Cloudflare wokers + cloudns 来实现。 由于备案域名有部分业务在共有云因此不能迁移DNS到cloudflare,因此使用了cloudns免费二级域名。
准备
需要准备以下
公网IP
IPv4、IPv6均可,如果你的宽带没有公网IP不需要往下看了。没有公网只能走Tunnel内网穿透。cloudflare帐号
cloudns域名
注册cloudflare帐号

2.点击“add a website or application”
3.进入这个页面不要关闭,接下来要用

注册cloudns二级域名
打开https://www.cloudns.net/ 进行注册

点击注册,进入注册界面填写对应信息(可能邮箱要注意一下,尽量不要用qq邮箱,用户名之间要有个空格)


看到下方提示就意味着账号已经注册好了(需要到你的邮箱点击链接激活)

登录
进入邮箱点击激活链接。激活后,点击刚刚网页下方黄色字体重新进入登录界面,输入刚刚注册填写的邮箱以及刚刚设置的密码即可登录。
点击激活后即可进入主面板创建域名
点击 “create zone”后弹框选择“free zone”
填写想申请的域名:
如果提示这个说明你的ip不能注册cloudns 需要挂梯子或换个ip (tips:可以使用云主机注册)
注册成功后就会进入如下界面

域名DNS修改
切到刚才cloudflare的界面,填写刚申请的域名,点击continue

选择free并继续,会扫描当前域名的DNS记录,稍等片刻

复制cloudflare的DNS并在cloudns添加

删除原有NS记录并添加cloudflare的

编写Cloudflare Workers
创建woker脚本


点击finsh后,点击“edit code” 编写脚本
export default {
async fetch(request, env, ctx) {
// 获取请求的URL路径和查询字符串,用于转发请求
const url = new URL(request.url);
let pathAndQuery = url.pathname + url.search;
// 构建转发的目标URL
let targetUrl = `https://demo1.sirgo.cloudns.be:8443${pathAndQuery}`;
// 使用fetch API创建一个新的请求到目标地址
let response = await fetch(targetUrl, request);
// 返回从目标服务器获得的响应给客户端
return response;
}
};设置Cloudflare workers
设置worker的外部域名: workers -> 设置 -> 触发器添加域名: demo.sirgo.cloudns.be

设置证书,点击“view certificate”

添加域名demo.sirgo.cloudns.be 的证书txt记录到cloudns

添加域名demo.sirgo.cloudns.be 的NS记录,如图添加好的TXT和NS记录 (稍等片刻,txt记录的验证有些慢,我等了大概10分钟..)

第3、4步骤添加后证书3个月后获取需要重新添加,另外一个办法是使用NS指向这样会自动续期,在clouddns上添加如下NS
(_acme-challenge.xxx.cloudns.biz的NS跟xxx.cloudns.biz的NS一致)_acme-challenge.cloudns.biz NS norman.ns.cloudflare.com _acme-challenge.cloudns.biz NS norman.ns.cloudflare.com _acme-challenge.demo.cloudns.biz NS stella.ns.cloudflare.com _acme-challenge.demo.cloudns.biz NS stella.ns.cloudflare.com示例:
cloudns上如下配置:
重新给worker设置域名后,边缘证书处将显示如下:
添加域名:demo1.sirgo.cloudns.be 记录,可以使用A记录或cname。 注意:需要在cloudflare和cloudns上都添加才可以。我这里使用cname


验证
浏览器访问:https://demo.sirgo.cloudns.be如下。 如果碰到connection rest说明被墙了。可以稍等一会重试。或者使用代理访问进行验证。 我这里使用的联通目前偶尔会connection rest

总结
cloudns申请的免费的二级域名可以挂到cloudflare上但是似乎有些问题,一些A\CNAME等记录在cloudflare上设置后似乎并不是生效,需要在cloudns上再次设置。
cloudflare上的worker在进行转发时是有限制的不可以带端口(可以转发到其他网站,如www.baidu.com)。
下面贴出相关设置
cloudflare上的DNS记录

cloudns上的DNS设置

cloudflare上的证书设置

问题
使用cloudflare worker在国内有时会被墙,可以使用cf优选IP相关脚本,然后设置到本地hosts文件或者自己搭建DNS 这样可能会好点(没有实践)
cloudflare workder中转发时不可以设置host header,其他的诸如:x-real-ip,x-forword-for是可以的。因此如果应用依赖host字段,需要相关设置或加一层nginx代理修改host:
#示例
location / {
proxy_pass http://192.168.0.222:8090;
proxy_set_header Host 'demo.sirgo.cloudns.be'; #设置host使应用获取正确的host字段
}
评论区