Administrator
发布于 2026-10-01 / 0 阅读
0
0

frp + nginx:把家里的 NAS 服务安全地暴露到公网

家里 NAS 上跑着一堆自建服务,但没有公网 IP。这篇文章讲怎么用 frp 把它们安全地暴露出去,以及我在这个过程中踩的坑。

架构

公网用户
   │ HTTPS :443
   ▼
云服务器 nginx ──按 server_name 分流──┬─→ 127.0.0.1:19951 ─frp TLS─→ NAS frpc → 服务 A
                                      └─→ 127.0.0.1:19953 ─frp TLS─→ NAS frpc → 服务 B

关键设计:

  • 公网服务器只跑 nginx + frps,不跑业务
  • 所有业务服务都在内网 NAS 上,通过 frp 反向隧道暴露到 ECS 的回环端口
  • nginx 做 TLS 终结和域名分流,按 server_name 决定转发给哪个服务
  • 回环端口整段放行(frps 的 allowPorts),新增服务不用改 frps、不用重启

坑 1:frp 的端口是"客户端声明、服务端照做"

frps 的 allowPorts 只是白名单,它不会主动开端口。真正决定"暴露哪些端口"的是 frpc 的 [[proxies]] 配置。

如果某个端口不通,先别查服务端,去看客户端是否在线:

# 采两次,看数字是否增长 —— 增长说明客户端在线
grep -c 'client login info' /var/log/frps.log

坑 2:改 frpc 配置,必须重建容器

如果 NAS 上的 frpc 是跑在 Docker 里的,改完配置点"重启"是没用的。

原因:很多 frpc 镜像把配置通过环境变量注入,而环境变量在容器创建时就固化了。docker restart 只是重启进程,环境变量还是旧的。

正确做法:删除并重建容器(docker compose down && up -d,或面板上的"重建")。

这一条和"改 Docker 挂载必须重建"是同一个道理。

坑 3:frps 日志按天轮转,统计别只看一个文件

frps.log 会滚动成 frps.log.2026-09-30 等等。如果你用

grep -c 'timeout' /var/log/frps.log

统计"有没有超时",会漏掉历史文件里的记录。

正确做法:跨所有轮转文件统计:

cat /var/log/frps*.log | grep -c 'timeout'

nginx 侧:为什么用 443 + server_name 而不是多开端口

早期我在 ECS 上开了 8443、9443 给不同服务用——因为域名还没备案,只能用 IP 直连。

备案通过后,正确的收敛方式是:只留 443,按 server_name 分流。

# 站点 A:博客
server {
    listen 443 ssl;
    server_name blog.example.com;
    ssl_certificate     /etc/letsencrypt/live/blog/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/blog/privkey.pem;
    location / { proxy_pass http://127.0.0.1:19953; }
}

# 站点 B:代码托管
server {
    listen 443 ssl;
    server_name git.example.com;
    ssl_certificate     /etc/letsencrypt/live/git/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/git/privkey.pem;
    location / { proxy_pass http://127.0.0.1:19951; }
}

# 兜底:IP 直连 / 未声明域名(自签证书)
server {
    listen 443 ssl default_server;
    server_name _;
    ssl_certificate     /etc/pki/self-signed/fullchain.pem;
    ssl_certificate_key /etc/pki/self-signed/privkey.pem;
    location / { proxy_pass http://127.0.0.1:19951; }
}

好处:

  • 对外只需开放 443(一个端口),攻击面最小
  • 加新服务 = 加一个 server 块 + 签一张证书,不动 frps、不动客户端
  • 每个域名独立证书,互不影响

记得把 return 301(HTTP→HTTPS)下沉到 location /,否则 ACME 校验请求会被 301 跳走。

安全组:最小化开放

公网机器的安全组,最终只留:

端口用途
443HTTPS(nginx)
80HTTP(仅用于 ACME 校验 + 301)
22SSH(建议同时上 2FA)
7000frps 控制面(token + TLS)
ICMPping 诊断

备案期用的临时端口(8443 等),域名上线后立刻删掉——安全组规则和 nginx 站点都要收。

小结

frp + nginx 这套组合的价值在于:把"暴露服务"变成一次配置,而不是一次架构变更。

  • 内网服务只管跑,不关心公网
  • ECS 只管转发,不存业务数据
  • 新服务接入 = 一行 frpc 配置 + 一个 nginx server 块

代价是链路变长了一层。排查问题时要有顺序:客户端在线 → 隧道通 → nginx 分流 → 证书,从后往前一段段查。


评论