释放小七猫的分享欲

公网访问方案介绍及各类代理服务器的搭建

tags: NAS
@ 27/11/2025

公网访问方案介绍及各类代理服务器的搭建

NAS 如果不能公网访问,玩法直接少一半,但公网访问又挺复杂的,有很多方案可以选择,常见的有三种:

  1. DDNS + 反向代理

基本原理是把一个网络入口开放到公网,仅开放一个反向代理服务器的端口,通过不同的域名访问不同的服务。缺点是现在几乎没有公网 IPv4 地址,仅能通过 IPv6 访问。

  1. 内网穿透 + 反向代理

与 1 类似,但开放到公网的方式是内网穿透,而不是直接 IP 地址访问。这种方案的流量带宽取决于 frps 服务器的带宽,免费方案几乎跑不满家宽上行。

  1. 虚拟局域网

最安全的方式,缺点是每个客户端都需要安装一个虚拟局域网软件。

这些方案并不互斥,你完全可以将它们结合成更加灵活的方案。下面介绍一下我使用的结合了 1 和 2 的反向代理+DDNS+ 内网穿透实现双栈访问的方案。

路由器基本配置

  1. NAT 类型更改

NAT 默认为 NAT4,如果能改的话,最好改为 NAT1

  1. 防火墙

配置规则,禁用所有 IPv6 入站,然后放通 IPv6 反向代理端口,这里假设为 54321

然后放通所有的 IPv6 ping,如果有别的服务需求,按需放行即可

如果你没有公网 IPv4,那么设不设 IPv4 防火墙都无所谓了

内网穿透占坑

每个人选择部署反向代理的位置不同,有的人部署在 PVE 上,有的在 NAS 系统上,有的在路由器上,有的在单独的 LXC 容器里,所以后面我把部署的位置统称为“系统”(我部署在 NAS 上的)。

内网穿透(frps)服务器的端口往往由服务商那边指定,一般都是高位端口,为了结合方案 1、2,我们需要保证 fprs 端口与反向代理服务器的端口一致,大概如下

<frps>:54321 -> <NAS>:54321

所以你要先拿到服务商那边的端口号,再决定自己这边反向代理的端口号。

假设获取到了 54321 端口号

根据服务商的文档在系统上配置穿透即可。由于不同的服务商配置方法不同,这里就不赘述了。

配置 ddns-go

ddns-go

在系统上安装 ddns-go 服务:

sudo mkdir /opt/ddns-go/
sudo mv ./ddns-go /opt/ddns-go/
sudo /opt/ddns-go/ddns-go -s install

然后配置

  • IPv4 由内网穿透服务商固定,因此使用命令把 IP 打进去即可
  • IPv6 通过网卡检测的方式实现
  • IPv4 和 IPv6 的 Domains 一般应当一致,如非你有的服务希望仅 v4 或仅 v6 访问

Nginx 反向代理

模板:

server {
    listen 54321 ssl;
    listen [::]:54321 ssl;
    http2 on;

    # 服务域名
    server_name example.com;

    # 证书地址
    ssl_certificate     /etc/nginx/conf.d/certs/_.example.com.crt;
    ssl_certificate_key /etc/nginx/conf.d/certs/_.example.com.key;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    add_header Strict-Transport-Security "max-age=63072000" always;

    location / {
        # 后端服务地址
        proxy_pass http://192.168.31.211:7556;
        proxy_set_header Host $host;
        # 代理 WebSocket,一般都需要
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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;
    }
}

不同系统的 nginx 配置文件写法类似,但配置文件路径和重载方法不一样:

debian

配置文件放在 /etc/nginx/site-available,然后软链接到 /etc/nginx/site-enabled

例如:

sudo ln -s /etc/nginx/sites-available/mywebsite /etc/nginx/sites-enabled/

然后验证配置并重载:

sudo nginx -t
sudo systemctl reload/restart nginx

alpine

配置文件放在:/etc/nginx/http.d/

验证配置并重载:

sudo nginx -t
sudo rc-service nginx restart/reload

openwrt

配置文件放在:/etc/nginx/conf.d/

要麻烦一些,有些内容需要 uci 来配置(也可以改配置让 nginx 脱离 uci 的管理),例如:

# 去掉 _lan 区块中对 restrict_locally 的引用
uci del_list nginx._lan.include='restrict_locally'
# 设置一下证书路径:
uci set nginx._redirect2ssl.ssl_certificate='/etc/nginx/conf.d/_.Example.com.crt'
uci set nginx._redirect2ssl.ssl_certificate_key='/etc/nginx/conf.d/_.Example.com.key'

验证配置并重载

nginx -t # 这个命令好像不行,有点忘了,要加个什么
service nginx restart/reload

caddy 反向代理

配置比 nginx 简单很多,但性能要差一点,推荐用这个

这里以 fedora、debian 为例

sudo dnf install caddy
sudo apt install caddy

配置文件在 /etc/caddy/Caddyfile

模板:

# ========== 通用片段 ==========
(common) {
        header {
                # 隐藏 Caddy 版本号
                -Server
                # 强制浏览器以后只走 HTTPS
                Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
                # 禁止浏览器猜测响应内容类型
                X-Content-Type-Options "nosniff"
                # 防止你的页面被别人的站点用 <iframe> 嵌进去,启用会导致 PVE 无法看到终端
                # X-Frame-Options "DENY"
        }
        # 启用压缩传输
        encode gzip
}

# ========== 证书片段 ==========
(nas-cert) {
        tls /etc/caddy/certs/_.example.com.crt /etc/caddy/certs/_.example.com.key
}

# ========== NAS 站点 ==========
nas.550293.xyz:54321 {
        import common
        import nas-cert
        reverse_proxy 127.0.0.1:9090 {
                transport http {
                        tls_insecure_skip_verify
                }
        }
}

music.550293.xyz:56789 {
        import common
        import nas-cert
        reverse_proxy 127.0.0.1:4533
}


# ========== 其他内网服务(IP 不变) ==========
pve.550293.xyz:54321 {
        import common
        import nas-cert
        reverse_proxy 10.0.0.140:8006 {
                transport http {
                        tls_insecure_skip_verify
                }
        }
}

注意代理 https 和 http 写法略有不同,代理 https 需要加

{
        transport http {
                tls_insecure_skip_verify
        }
}

跳过 SSL 验证,因为内网的 https 服务一般都是自签名。

双栈方案原理

双栈访问方案的核心在于利用 IPv4 和 IPv6 的 DNS 解析特性,实现智能路由选择。其工作原理如下:

IPv4 访问路径

  1. 反向代理服务端口(如 54321)通过内网穿透服务映射到公网 IPv4 地址(如 11.22.33.44)
  2. 在 ddns-go 中,所有域名都同时解析到公网 IPv4 地址 11.22.33.44 和系统的 IPv6 地址
  3. IPv4 用户访问域名时,DNS 解析到 11.22.33.44,通过内网穿透服务访问到反向代理服务器

IPv6 访问路径

  1. IPv6 用户访问相同域名时,由于双栈优先使用 IPv6 的特性,DNS 直接解析到系统的 IPv6 地址
  2. IPv6 流量直接访问系统本地的反向代理端口,无需经过内网穿透服务

这种就是前面要求内网穿透的端口与反向代理端口保持一致的原因:确保无论通过哪种路径访问,都能到达同一个服务端口,从而实现无缝的双栈访问体验。