家宽建站的几种方式

15,460次阅读
2条评论

共计 9020 个字符,预计需要花费 23 分钟才能阅读完成。

更新记录

2023-10-26

由于租用到了国内的 300Mbps 大带宽vps,所以现在基本全面转向使用 frp 方式进行内网穿透。

ddns + 端口映射只作为备用的入口,不打算在上面运行任何大流量 web 服务器,避免运营商的审查。

2023-08-26

本文章的评论数量是压测导致,目的是为了测试腾讯云cdn的限流和限QPS功能。压测结果符合预期。到达预定的量级时可以触发设定好的规则。

需要注意的是腾讯云的统计会有 5~10 分钟的延时,所以尽量限制下上传速率,否则也可能会被刷爆流量。

背景

很早我就购置了一台 itx 服务器放在家里,尽管机箱不大,但是配置已经足够满足我的使用。

我会将很多服务运行在这台服务器上,同时绝大部分服务都可以提供公网访问,例如笔记、云盘、个人博客、密码管理工具、自建GPT聊天机器人、给媳妇用的流媒体plex等等。

我已经习惯将我的一切服务放在云上,享受无论身处何地随时可用的快乐。

家宽建站的几种方式

配置如下:

  • 主板:MS-Terminator B660M
  • CPU:Intel i5 12400
  • 内存:酷兽 32GB * 2
  • 电源:益衡 7025B 250W

需求慢慢的越来越多,对网络的质量要求和安全要求也越来越高。网络性能一般可以通过四个指标来观测:丢包​、延时​、抖动​、速率​。

一些静态的资源对网络质量要求并不高,但是流媒体软件不一样。同时,之前的服务大多是提供给自己用,均做了加密鉴权,不太担心被攻击。现在这个博客上线后,是会公开在互联网上,对安全和防攻击的要求也提上了日程。

经过一段时间的梳理和实践,现在新的网络方案已经上线。

我将家宽暴露在互联网上,我使用了以下几种方式:

  1. 租用 vps 部署 frp​ 进行内网穿透。
  2. 向运营商索要公网IP,通过 ddns​ + 端口映射​方式将直接暴露在互联网上。
    1. 运营商封禁了 80​、8080​、443​ 等web端口,使用非标web端口,会增大用户的使用成本,域名+端口的形式不美观且难以记忆。对于一些个人用的服务其实影响并不大,但是对于需要提供在公网的服务,例如本博客站点,是绝对不适合的。
    2. 将家宽服务作为源站,使用cdn作为网关回源家宽服务。利用cdn提供的 80​ 和 443​ 端口对公网提供服务。

网络链路存在木桶效应,最差的端点会直接限制网络性能的上限。上述方案并不冲突,可以根据不同的场景组合起来使用,消去单一架构带来的短板。

我现在的家宽网络:30Mbps上行,1000Mbps下行。对外服务使用到的是上行。

即无论我在其它侧如何优化,30Mbps上行带宽是我能提供的最大能力,对我目前而言已经足够使用。

下文会具体介绍三种网络方案,可以组合使用,以平衡成本和网络性能。

家宽建站的几种方式

vps 部署 frp 进行内网穿透

适用场景

结论放前面

此方式适用:

  • 预算不够,且对网络带宽要求不高的服务,以静态资源居多

  • 对网络稳定性要求不高的服务

通过此方式穿透到家里服务的有:

  • 思源笔记
  • 虚拟化平台 web管理界面
  • 堡垒机
  • 路由器 web 管理界面
  • 迅雷 docker 版
  • grafana 监控面板
  • 密码管理工具
  • GPT web端机器人

我租用过的 vps 和独立服务器有很多台,它们分布在 各家大大小小的云厂,全球各个区域,从1core & 0.5GB RAM 到80 core & 512G RAM。

计算和存储不在本文展开讨论,根据网络的不同我认为可以分为两大类:

  1. 大陆
    1. 优点:延时低,丢包率低,抖动小
    2. 缺点:带宽或流量的成本极其高昂;提供 web 服务 域名需要备案
  2. 非大陆,港澳台 + 国外
    1. 优点:带宽或流量成本低;无需备案
    2. 缺点:延时高,丢包率高,抖动大,80 443端口容易被阻断。同时晚高峰期质量极其差劲,即使部分云提供的 vps 网络链路是经过优化的,例如 cn2​、9929​。但是对比国内的依然很差劲。

最开始为了大带宽,我使用的是非大陆的 vps。

最开始 vps 位于香港,线路为 cn2。延时很漂亮,延时最低只有45ms左右。但是丢包率太高,日均大约有10%,导致我的服务网络稳定性很差,时通时不通。成本约为150/年。

后来用的是美国 vps ,线路为 9929。延时比较高,但是丢包率对比香港低太多了,日均1%左右。成本约为200元/年。

在写本文之前,我的所有的服务都依赖于此 vps 提供的公网网络。而现在,我使用的是国内的阿里云广州折扣服务器,线路为三线BGP。成本为45元/年。

美国vps配置如下:

  • 硬件
    • 核心数:1 core
    • 内存:1GB
    • 硬盘:10G
  • 网络
    • 带宽:1000 Mbps
    • 线路:9929

阿里云广州配置如下:

  • 硬件
    • 核心数:2 core
    • 内存:2GB
    • 硬盘:40G
  • 网络
    • 带宽:4 Mbps
    • 线路:三网BGP

硬件配置已经完全足够,因为我并不依赖云上VPS提供的计算和存储,仅利用它的公网网络。

美国 vps 的网络纸面带宽很漂亮,其实并没有什么用,从国内连接是跑不满的。同时我家宽带上行是 30Mbps,按上文说的木桶效应,用美国 vps 穿透到家里的服务器,能提供的理论最大带宽也只会有 30Mbps。

现在之所以换成 广州的 4Mbps 服务器,是因为我可以通过 ddns + 端口映射​ 方式来实现大带宽场景。一些简单的网站,4Mbps 已经足够使用,例如笔记、密码管理、GPT机器人。

更新:已购入国内 300Mbps VPS,基本所有场景都可以覆盖和满足。

但是传言在高并发(QPS > 1000)时,frp 会有性能问题,我的服务暂时没有这么高的量级,遇到了再解决吧。

frp部署方式

github下载链接

下载时选择对应CPU架构的版本。

服务端 frps 部署

服务端部署在能够提供公网能力的vps上,请注意安全组和防火墙不要拦截 frp 服务端口,以便在家里部署的 frpc 可以主动访问 vps 上部署的 frps。

# 下载frp二进制包
wget https://github.com/fatedier/frp/releases/download/v0.51.3/frp_0.51.3_linux_amd64.tar.gz

# 解压缩
tar xf frp_0.51.3_linux_amd64.tar.gz

# 复制二进制到环境变量目录
cd frp_0.51.3_linux_amd64/
cp frps /usr/local/bin/

# 创建配置文件目录
mkdir /etc/frp

# 编辑配置文件
# vim /etc/frp/frps.ini
[common]
bind_addr = 0.0.0.0
bind_port = 7300
token = 178a634a52a077394fd2b53
tls_enable = true

log_file = /var/log/frps.log
log_level = info
log_max_days = 365

# 使用 systemd 管理frps,编辑配置文件
# vim /etc/systemd/system/frps.service
[Unit]
Description=Frp Server Service
After=network.target

[Service]
Type=simple
Restart=on-failure
RestartSec=5s
ExecStart=/usr/local/bin/frps -c /etc/frp/frps.ini
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target

# 启动frps
systemctl start frps.service

# 配置开机自启
systemctl status frps.service

# 检查服务状态
# systemctl status frps.service
● frps.service - Frp Server Service
     Loaded: loaded (/etc/systemd/system/frps.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2022-12-08 17:44:20 CST; 8 months 13 days ago
   Main PID: 66650 (frps)
      Tasks: 6 (limit: 2194)
     Memory: 42.3M
     CGroup: /system.slice/frps.service
             └─66650 /usr/local/bin/frps -c /etc/frp/frps.ini

# netstate -anltup|grep 7300
tcp6       0      0 :::7300                 :::*                    LISTEN      66650/frps

Bash

可以看到,frps 的配置项很简单

  • bind_port = 7300 :监听7300作为服务端口
  • token = 178a634a52a077394fd2b53:配置密钥,下文中 frpc 也配置成一样的
  • tls_enable = true:开启tls混淆

客户端 frpc 部署

frpc 部署在家里虚拟机上。它会主动请求 frps。

下文以最简单的方式,将家里一台内网虚拟机的22端口穿透到公网。

# 下载frp二进制包
wget https://github.com/fatedier/frp/releases/download/v0.51.3/frp_0.51.3_linux_amd64.tar.gz

# 解压缩
tar xf frp_0.51.3_linux_amd64.tar.gz

# 复制二进制到环境变量目录
cd frp_0.51.3_linux_amd64/
cp frpc /usr/local/bin/

# 创建配置文件目录
mkdir /etc/frp

# 编辑配置文件
# vim /etc/frp/frpc.ini
[common]
server_addr = 8.134.***.***
server_port = 7300
token = 178a634a52a077394fd2b53
tls_enable = true

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 20222

# 使用 systemd 管理frpc,编辑配置文件
# vim /etc/systemd/system/frpc.service
[Unit]
Description=Frp Client Service
After=network.target

[Service]
Type=simple
Restart=on-failure
RestartSec=5s
ExecStart=/usr/local/bin/frpc -c /etc/frp/frpc.ini
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target

# 启动frps
systemctl start frpc.service

# 配置开机自启
systemctl status frpc.service

# 检查服务状态
# systemctl status frps.service
● frpc.service - Frp Client Service
   Loaded: loaded (/etc/systemd/system/frpc.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2023-08-17 09:33:50 CST; 5 days ago
  Process: 31962 ExecReload=/usr/bin/frpc reload -c /etc/frp/frpc.ini (code=exited, status=0/SUCCESS)
 Main PID: 18753 (frpc)
    Tasks: 5
   Memory: 8.7M
   CGroup: /system.slice/frpc.service
           └─18753 /usr/local/bin/frpc -c /etc/frp/frpc.ini

Bash

可以看到,frpc 的配置文件相比 frps 复杂一些

  • [common] :此块用于定义公共配置,
    • server_addr = 8.134.. :部署 frps 的 vps 公网IP
    • server_port = 7300:frps 的端口
    • token = 178a634a52a077394fd2b53:密钥,和 frps 配置保持一致
    • tls_enable = true:开启tls混淆
  • [ssh]:此块用于定义不同的映射规则,可以有多个,名字不冲突即可
    • type = tcp:映射到公网的服务,在本地端口的类型
    • local_ip = 127.0.0.1:映射到公网的服务,在本地的IP
    • local_port = 22:映射到公网的服务,在本地的端口
    • remote_port = 20222:映射到公网的服务,在公网服务器创建的端口

验证

首先我们在公网 vps 查看,由 frpc 向 frps 申请的端口是否已经成功监听

# netstat -anltup|grep 20222
tcp6       0      0 :::20222                :::*                    LISTEN      66650/frps
Bash

成功后,我们随便找台机器进行测试 ssh访问

# ssh root@8.134.180.141 -p 20222
root@8.134.180.141's password:
Bash

输入密码后,可以发现我们可以使用 公网 vps 的 IP 和 端口,ssh连接到家里的虚拟机。

部署 nginx 作为网关

实际使用中,我非常不建议把家里服务的端口直接穿透暴露在公网上。主要是因为安全问题,22 和 3389 这种远程控制端口暴露在公网极其不安全。同样的,其他服务端口也有一样的问题。

我在家里部署了 nginx 作为网关,统一控制家里所有服务的流量。nginx可以加密鉴权,也可以精细控制流量如何路由分发。

nginx如何部署与使用,部分步骤可以参考站内文章:使用 nginx 代理 tcp 端口使用 acme 获取免费 https 证书

这里不再展开说明nginx配置,根据你的服务进行个性化定义。

ddns + 端口映射

适用场景

结论放前面

此方式适用:

  • 对网络传输速率要求较高的服务。
  • 对端口要求不敏感的服务。家庭宽带不能使用 80 443 等常见的web端口。

我通过此方式穿透到家里服务的有:

  • plex流媒体服务,用来给媳妇在外面看家里下载好的影视剧
  • nextcloud私人网盘,用来在外传输文件

如果你有足够的预算,其实可以不需要使用此方式。

  • 云厂 vps 绑定按流量计费的公网IP,费用大约为 0.8 元/GB
  • 云厂 vps 绑定按带宽计费的公网IP,费用大约为 20元/Mbps

家庭带宽,其实运营商本质上不希望你暴露在公网提供服务。原因很简单。家宽其实是国家补贴的,国家是高价出售商业带宽来补贴家用带宽。

流媒体服务也好,网盘服务也好,对传输速率的要求很高。最少云上的 4Mbps带宽是完全不能承载我的使用。让我在云上花几百元每月的价格购买和家宽同样能力的 30Mbps IP,我是万万舍不得的😂。

本方案的原理:

  • 先从运营商处申请独立的公网IP,如果不申请,你和你的小区其他宽带用户其实是公用一个IP出口,光猫分配到的IP只是一个内网IP,是不能提供对外服务的。
  • 申请到的公网IP是动态IP,每次重新拨号(路由器重启)等,IP 会发生改变。利用 ddns 方式,当IP发生变化时,可以将域名动态的解析到每次变更后的新IP上。
  • 有了公网IP后,可以在路由器上配置端口映射,将 公网ip:port​ 映射到家里的 内网ip:port​ 上。即实现服务对外提供访问。

公网IP获取

我的家宽使用的是电信,直接拨打电信人工客服 10000 号,说明自己需要公网IP即可。大约两小时左右后重启光猫,就可以获取到动态公网 IP 了。

每次重新拨号,公网 IP 地址都会发生改变。

请提前从运营商处获取到宽带的 账号​ 和 密码​。下文会使用到。

路由转桥接配置

默认光猫使用的是路由模式,路由模式下,拨号是由光猫完成的。以及下文所说的端口映射也需要配置在光猫上,因为是光猫拨号获取到的公网IP。

而桥接模式下,光猫仅用于做光电信号转换,拨号和端口映射都可以在路由器上实现。

根据光猫的 cidr 配置和型号,访问路由转桥接的后台页面地址也不一样。

我家光猫的IP是 192.168.1.1​,即访问 `http://192.168.1.1:8080/bridge_route.gch`​就可以进行路由转桥接配置:

家宽建站的几种方式

在转换为桥接模式后,此时光猫已经不承载拨号功能。并且家庭网络也会彻底断开。

需要在路由器上配置PPPoE​拨号上网。我使用的路由器是华硕 AC5300​。

WAN 联机类型:PPPoE

填入账号密码进行拨号。

配置界面:
家宽建站的几种方式

ddns

ddns 的原理其实很简单。每次家里的公网 IP 变化后,有很多种方式可以获取到。当发生变化时,调用 dns 域名托管商的接口,更新你的域名解析。

我从 github 上找了一个:github.com/jeessy2/ddns-…

配置

# 下载二进制包
wget https://github.com/jeessy2/ddns-go/releases/download/v5.6.1/ddns-go_5.6.1_linux_x86_64.tar.gz

# 解压缩
tar xf ddns-go_5.6.1_linux_x86_64.tar.gz

# 启动服务,-f 参数 指定探测周期,单位为秒
./ddns-go -s install -f 60

# 检查服务状态
# systemctl status ddns-go.service 
● ddns-go.service - 简单好用的DDNS。自动更新域名解析到公网IP(支持阿里云、腾讯云dnspod、Cloudflare、Callback、华为云、百度云、Porkbun、GoDaddy、Google Domain)
   Loaded: loaded (/etc/systemd/system/ddns-go.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2023-08-20 20:28:53 CST; 2 days ago
 Main PID: 14109 (ddns-go)
    Tasks: 8
   Memory: 6.3M
   CGroup: /system.slice/ddns-go.service
           └─14109 /data/scripts/ddns-go -l :9876 -f 60 -cacheTimes 5 -c /root/.ddns_go_config.yaml

Aug 22 23:56:42 centos-ops ddns-go[14109]: 2023/08/22 23:56:42 IPv4未改变,将等待 2 次后与DNS服务商进行比对
Aug 22 23:57:42 centos-ops ddns-go[14109]: 2023/08/22 23:57:42 IPv4未改变,将等待 1 次后与DNS服务商进行比对
Aug 22 23:58:44 centos-ops ddns-go[14109]: 2023/08/22 23:58:44 你的IP 27.16.212.229 没有变化, 域名 cdnsrc.bwbit.com

Bash

这个服务在执行 install 后,会做几件主要的事情:

  • 使用 systemd 管理服务
  • 生成配置文件,路径 /root/.ddns_go_config.yaml
  • 提供 web端服务用于可视化编辑配置,端口为 9876
  • 定时检查IP变化,将 IP 更新到配置文件指定的 dns 托管商和需要更新的域名

从浏览器使用 ip:port​ 访问服务,例如 192.168.2.10:9876

​​家宽建站的几种方式​​

配置项目很简单:

  • 选择 dns 托管商
  • 填入访问密钥,cloudflare 上为 Token,阿里云是 ak sk
  • 填入需要更新的域名

关于 cloudflare 和 阿里云如何分配访问密钥,可以参考站内文章:使用 acme 获取免费 https 证书

验证

在路由器上执行重新拨号,或者直接重启路由器。等待5~10分钟后,观察服务日志即可

systemctl status ddns-go.service 
Bash

端口映射配置

各家路由器基本都可以实现端口映射,将 公网ip:port​ 映射到家里的 内网ip:port​ 上。即实现服务对外提供访问。

我以我家的 华硕 ac5300​示例:

家宽建站的几种方式

补充配置 nginx 301跳转

端口映射的时候,外部端口是不能使用 80 443 等web端口的。而使用 65432 这种非标端口很难记忆。

我们可以在公网 vps 的 nginx 上配置 301 跳转,例如我想以 plex.com 对外提供服务,可以在nginx上配置如下规则,跳转到 media.plex.com 的 65432上去。

记忆 plex.com​ 比 media.plex.com:65432​ ,要简单的多,降低了记忆 url 的心智成本。

# vim test.conf
server {
  listen        80;
  server_name  plex.com ;
  satisfy any;

  return 301 https://media.plex.com:65432$request_uri;
}

server {
  listen 443 ssl http2;
  server_name plex.com;
  satisfy any;

  return 301 https://media.plex.com:65432$request_uri;
}

Bash

CDN

frp 和 ddns 方式,各有长短。上文已经讨论了它们的使用场景。

那么如何综合它们的优点呢,例如我即希望能够使用家宽的 30Mbps上行,又希望以 80 443 端口提供公开的 web 服务。

使用 cdn 方式可以解决。

我们还是需要用到 ddns + 端口映射​,将服务暴露在公网出来。然后使用cdn,配置暴露出来的 域名:端口​作为源站,让 cdn 进行回源。

cdn 本身是可以提供 80 和 443 端口的,并且可以隐藏你的后端,除了 cdn 厂商,没人会知道你的源站是什么,提供了很好的保护能力。

这依赖于 cdn 在配置源站时,可以自定义端口,并不是每家cdn厂商都可以做到,经过我实际验证较为知名的cdn厂商发现:

可以自定义源站端口的厂商有:

  • 腾讯云
  • 阿里云

不支持自定义源站端口的厂商有

  • 华为云
  • 七牛云
  • 火山引擎

而目前我使用的是腾讯云,因为它对比阿里云的优点有:可以实现 QPS限流,带宽阈值限制,总流量限制。这样可以很大避免被攻击产生高额费用。

并且腾讯云提供了半年免费的100GB流量包,已经足够本站使用了。

这里不详述如何进行 cdn 配置,各家 cdn 厂商都会有详细的文档和专业的客服,贴几张图参考下即可:

​​家宽建站的几种方式​​

家宽建站的几种方式

家宽建站的几种方式

家宽建站的几种方式

结论

不同的网络方案没有高低之别,我详细说明了每种方案的优缺点和适用场景。针对不同的需求选择合适的方式即可。

引用链接

正文完
 1
pengyinwei
版权声明:本站原创文章,由 pengyinwei 2023-08-23发表,共计9020字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处:https://www.opshub.cn
评论(2条评论)
2024-06-05 11:29:20 回复

家用带宽建站不会被请喝茶吗

 Windows  Chrome  中国移动
    2024-06-07 22:34:12 回复

    不会的,因为并没有直接将家宽提供的ip暴露在公网。实际的网络入口在云服务器上。

     Android  Chrome