Frp打洞后内网Nginx反代

Frp打洞后内网Nginx反代

Photo by Alex Cheung / Unsplash

家里这台NAS从24年10月开组,系统用的飞牛OS,最开始用无线网卡出过几次问题,后来换成有限网卡后趋于稳定。不过官方最近报了个0day漏洞出来炸了锅,不过我情绪还算比较稳定,在期初系统选型时就在黑裙、OMV、truenas、飞牛之间犹豫了很久,最后还是选择了拿安全换方便。

机器从最开始的3D打印机箱+闲置硬盘上手,到后面的疾风知N52机箱+两块4T硬盘上手,后续为了「一步到位」换了10盘位的机箱+陆续上到了7块硬盘,那时的我还不知道短短一年多时间,当时买的这些硬盘能翻上好几倍变成了理财产品。

因为电信不给申请公网服务,所以选择了Frp+中继服务器打洞,当时图方便直接使用了Frp自带的转发服务,但随着玩机的深入,部署的容器服务也从此前的几个增长到了几十个,Frp转发服务的一些问题逐渐暴露出来,如:

  1. 个别服务需要用到WebSocket服务,但是Frp转发服务没法自定义这些配置,
  2. 不能对域名下的不同路径转发做处理
  3. 性能较差,我的体验是看影视资源经常要等个四五秒才能开始播放
  4. 每个服务一个配置项,管理不方便

所以昨天花了一两个小时从原来的Frp转发服务切换到了Nginx反代。

Frp的修改

原来Frps上设置了vHost相关配置需要取消掉

bindAddr = "0.0.0.0"
bindPort = 8010
quicBindPort = 8010
subDomainHost="test.com"

auth.method = "token"
auth.token = ""


transport.tls.certFile = ""
transport.tls.keyFile = ""
transport.tls.trustedCaFile = ""

Frpc部分的修改则是备份一下原来的配置文件,把所有转发都删除掉,只留下一个TCP通道

serverAddr = "frpsip"
serverPort = 8010
auth.method = "token"
auth.token = ""
transport.protocol = "tcp"

transport.tls.certFile = "client.crt"
transport.tls.keyFile = "client.key"
transport.tls.trustedCaFile = "ca.crt"


[[proxies]]
name = "web-raw"
type = "tcp"
localIP  = "192.168.0.12"      # NAS 本机 Nginx 监听地址
localPort = 14433           # NAS 本机 Nginx 监听端口
remotePort = 4433           # 对应请求 frps 的附带的 remote_port

Nginx配置

因为站点比较多,希望用一个简短好管理的方式来维护站点,所以这里和AI搏斗了很久,最后用一个map来管理服务列表,一个通用server来代理所有服务,如果有特殊设置的服务则单独写一个server块明确指定ServerName来进行设置。

# 2. 核心路由映射 (已去重并分类)
map $host $upstream {
    hostnames; # 启用主机名匹配模式,性能更好

    # 常用服务
    1.test.com          https://192.168.0.12:31111;
    2.test.com           http://192.168.0.12:31112;
    aria.test.com           http://192.168.0.12:31113;
    
    default                http://192.168.0.12:31110;
}

# 4. 特殊配置:是否开启代理缓冲 (解决 SSE 或长连接卡顿)
map $host $proxy_buff {
    hostnames;
    ~^deeplx\.  off;    # 流式翻译建议关闭缓冲
    default     on;
}

# --------------------------------------------------
# 独立 Server 通过明确指定server_name提高优先级
# --------------------------------------------------
server {
    listen 14433 ssl http2;
    listen 4433  ssl http2;
    server_name aria.test.com;

    ssl_certificate     frp.crt;
    ssl_certificate_key frp.key;
    include             ssl_security.conf;  #独立的ssl配置文件

    client_max_body_size 0;          # 允许 BT 大文件
    proxy_request_buffering off;     # 实时上传进度
    proxy_buffering off;             # SSE / WebSocket 不缓冲

    # ---------- 公共头 ----------
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_read_timeout 86400s;

    # ---------- JSON-RPC 入口 ----------
    location = /jsonrpc {
        proxy_pass http://192.168.0.12:6800/jsonrpc;
    }

    # ---------- AriaNg 等静态面板 ----------
    location / {
        proxy_pass http://192.168.0.12:31113;
    }
}


# --------------------------------------------------
# 兜底 Server
# --------------------------------------------------
server {
    listen 14433 ssl;
    listen 4433 ssl;
    http2 on;
    server_name *.test.com;

    ssl_certificate     frp.crt;
    ssl_certificate_key frp.key;
    include ssl_security.conf;

    # 应用动态变量
    client_max_body_size 0;
	proxy_buffering on;         # 默认开启缓冲提升性能
    proxy_request_buffering off; # 建议关闭请求缓冲,方便大文件上传进度实时显示

    # 公共 Proxy 配置模板
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_read_timeout 86400s;

    # 通用路由
    location / {
        proxy_pass $upstream;
    }
}

且因为使用了Nginx,可以回家在连局域网时搭配Smartdns直接将解析指向NAS服务器,Nginx上同时监听4433实现局域网访问。

目前可以通过一个比较简短的conf文件维护二十几个docker服务,还算是比较方便,性能也更好。

这个方法如果有什么问题希望各位大佬指正。

来自联邦宇宙的回应

加入评论