家用服务器公网访问方案

Share

前言

因为ipv4地址数量受限,家庭宽带几乎都没有公网IP。在局域网内可以使用类似192.168.0.100这样的内网IP进行访问,但是想要在外访问或是提供给朋友使用是不行的。

方案一:内网穿透

可以使用具备公网IP的服务器进行中转,用户访问具备公网IP的服务器,该公网服务器再与家庭服务器通信,最终用户访问到家庭内网。

方案对比

方案 价格 优缺点
使用免费服务如ngrok、cloudflare tunnel 速度受限,部分功能需要收费如绑定域名
购买云服务器搭建 价格高,需要部署维护
购买FRP服务如sakura frp 有流量和带宽限制

个人建议

临时需求可以使用ngrok,例如给朋友看正在开发的网站

长期需求建议购买FRP服务,服务器安装frp软件后,可以通过网页配置隧道如下图,可以使用香港的服务器省去域名的备案,但不太适合云盘等大流量应用。

frp-web

方案二:DDNS

内网穿透需要付费,并且有带宽和流量限制,额外的一个中转服务器也会影响访问速度。

好在ipv6已经逐渐普及,若服务端和客户端同时支持ipv6网络,则可以通过ipv6访问。

首先通过test-ipv6网站判断是否支持ipv6

test-ipv6

家庭宽带需要注意路由器中是否开启了对ipv6的支持,例如TP-Link路由器,可以访问管理页面(http://192.168.0.1)进行设置

tplink

确认ipv6已经开启,可以通过如 http://[2408:8207:1851:2a04:887b:b937:3ee4:5d41]:80/ 的URL进行访问。

然而这个IP地址会发生变化,同时也很长无法记忆。我们需要把变化的IP地址和域名进行绑定,动态的设置DNS记录,也就是DDNS(Dynamic DNS)。

使用docker部署 ddns-go

docker run -d --name ddns-go --restart=always --net=host -v /opt/ddns-go:/root jeessy/ddns-go

部署后使用web界面配置DNS服务商的API TOKEN,以及需要绑定的域名即可

对于DDNS服务,使用不同的域名服务商需要配置不同的参数。对于cloudflare,API TOKEN可以在侧边进行创建,选择「编辑区域DNS」模板

token

多服务配置

到这里已经可以使用绑定的域名访问默认端口了,然而本地一般有多个服务,希望每一个子域名对应一个端口也就是一个服务。

例如访问jellyfin.example.com到本地的8096端口,访问cloudreve.example.com到本地的5212端口。

我使用了以下两种方案

1. 使用cloudflare规则

如果你愿意使用cloudflare的代理(大陆访问会造成一些延迟),可以使用cloudflare的Origin Rules。

rules

侧边栏选择规则,创编origin-rules规则,匹配规则选择 主机名 = [你希望的子域名],下方的目标端口重写到服务对应的端口即可。需要注意DNS记录需要开启cloudflare的代理

2. 使用反向代理

前提是家里的80/443端口没有被封禁。

使用Caddy(对比nginx配置简单些)进行反向代理

安装后,修改配置文件/etc/caddy/Caddyfile,参考配置如下

a.example.com {
         tls user@example.com
         encode gzip
         reverse_proxy localhost:8888
}

b.example.com {
         tls user@example.com
         encode gzip
         reverse_proxy localhost:6666
}

保存后运行systemctl reload caddy即可

结论

除了内网穿透和DDNS,也有如zerotier这样的组网方案,不过不太适用于我。

游戏服务大多不支持ipv6,提供给用户使用的网站考虑到用户网络不一定支持ipv6因此都使用内网穿透。

对于仅个人使用的web服务,选择DDNS。

Read more

WASM初探

前言 最近开发上线了xhair.pro, 其核心的数据是通过爬虫下载.dem文件并使用一些开源的解析库如demoinfocs-golang,demoparser解析获取最终的数据 在本地下载解析上传可以随意配置环境,但浏览器无法直接运行Golang或Rust的代码。想要将解析的能力制作成web应用,需要使用WebAssembly技术。 WASM WebAssembly 是一种新的编码方式,可以在现代的 Web 浏览器中运行——它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如 C/C++、C# 和 Rust 等语言提供编译目标,以便它们可以在 Web 上运行。它也被设计为可以与 JavaScript 共存,允许两者一起工作。 我们可以把Rust、Go等语言编译成.wasm后缀的二进制文件,浏览器可以通过WebAssembly的API加载该模块,并调用相关能力 实践 不同编程语言需要通过不同的方式编译至wasm,我尝试了Go与Rust。 Golang实践 1. 首先需要配置Go的环境 go 安装 2. 初始化项目 mkdir w

By pureink

前端表单开发经验

前言 表单是前端开发中常见的场景,注册登录、调查问卷,乃至租赁一个云服务器都是在填写表单。 本文根据我的表单开发经验分享表单开发中,为什么需要表单库进行辅助。 原生表单 前端技术上,表单对应form标签,MDN有详细的介绍。 以一个注册表单为例,我们需要如下标签 这离用户体验还很远,想要完善它的功能,都要依靠JS,原生表单有很多能力缺口,例如: 1. 无法展示错误信息 为了告知用户错误的原因,常见在输入框底部进行红色文案的提示,如下图。HTML会给校验失败的元素添加CSS 伪类 :invalid,但这还远远不够。 2. 不支持自定义校验 内置支持require、pattern正则这些能力,但确认密码的校验需要和第一次填写的密码进行对比,没有相关的属性可以用。 React中的表单 尝试在React下实现一个完整的注册表单。 我们维护了两个状态对象,一个formValue代表表单值,一个error用于渲染错误信息。每一个input输入框传入value与onChange使其受控,用户输入后会修改formValue并进行校验。同时提交时也会重新进行校验,满足条

By pureink