Files
Private-Proxy/server_config/README.md
T
RRRosmontis 20d2532e8f server_config: 重写为完整部署规范(BBR/nginx CONNECT/sing-box/mtg)
- 新增完整 README.md 部署规范:架构、端口规划、BBR 跨境优化、
  nginx 源码编译+CONNECT 隧道、sing-box(VLESS+REALITY/SS)、mtg(MTProto)、
  本机 IP 自动识别、systemd、启动顺序与验证清单
- nginx/nginx.conf:占位符版,proxy_connect_allow all + 回环保护
- sing-box/config.json:占位符版,VLESS+REALITY + SS
- systemd/:nginx/sing-box/mtg 服务文件
- scripts/sync-nginx-local-ips.sh:去除真实域名,占位符版
- fake-site/index.html:伪装页(清除真实品牌域名)
- 移除过时:traffic-monitor/、pac/、conf.d 具体站点配置
- 所有敏感值(IP/域名/端口/密钥)均以 <占位符> 表示
2026-09-10 00:22:03 +08:00

14 KiB
Raw Blame History

RRPP 服务端部署规范

一套统一的跨境代理节点部署流程,适用于 Debian/Ubuntu 系 Linux。 每台节点运行相同的服务栈:BBR 拥塞控制 + nginx CONNECT 隧道 + sing-box(VLESS+REALITY / Shadowsocks) + mtg(MTProto)。

本文档为通用规范,所有 IP / 域名 / 端口 / 密钥均以占位符表示,部署时替换为实际值。 凡标注 <...> 的均为占位符,不要原样照抄。


目录


0. 架构总览

客户端 ──► nginx(443/<nginx端口>) ──┬─► CONNECT 隧道(任意端口, 全端口放行)
        │                          └─► 伪装页面(直接访问/IP访问)
        │
        ├─► sing-box(<vless端口>) ──► VLESS+REALITY(vision)
        ├─► sing-box(<ss端口>)    ──► Shadowsocks(aes-256-gcm)
        └─► mtg(<mtproto端口>)    ──► MTProto(Fake TLS, Telegram 内置代理)

四层代理各司其职:

层 组件 协议 适用场景
HTTP 隧道 nginx CONNECT + Basic Auth 浏览器/curl/系统代理,全端口 WebSocket 透传
通用代理 sing-box VLESS+REALITY Shadowrocket/Clash/v2rayN 客户端
兼容旧客户端 sing-box Shadowsocks Shadowrocket 2.x 等不支持 REALITY 的客户端
Telegram 专用 mtg MTProto Fake TLS Telegram 内置代理,抗封锁

核心密钥体系(全套节点共用一套):

  • VLESS+REALITY:统一 UUID、统一 REALITY 私钥/short_id/SNI(SNI 用 <伪装SNI域名>,选一个高流量、TLS 指纹稳定的知名站点域名)
  • Shadowsocks:统一密码,方法 aes-256-gcm
  • MTProto:每台独立 secret(Fake TLS 类型,fronting 到 <伪装SNI域名>)

1. 端口与服务规划

端口全部落在同一区段便于防火墙管理(示例用 1200–1220,可按需调整):

端口 服务 说明
<nginx端口> nginx HTTPS 站点 + CONNECT 隧道(示例 1205)
<vless端口> sing-box VLESS+REALITY(示例 1206)
<ss端口> sing-box Shadowsocks(示例 1207)
<mtproto端口> mtg MTProto(示例 1210)

节点 A 用 80xx 区段、节点 B 用 120xx 区段皆可,只要同节点内不冲突、且运营商/防火墙放行。 防火墙放行:iptables -A INPUT -p tcp -m multiport --dports <nginx端口>,<vless端口>,<ss端口>,<mtproto端口> -j ACCEPT

域名规划: 每个节点一个独立域名 <节点域名>(如 node1.example.com),A 记录指向节点公网 IP。acme.sh 用 DNS-01 签证书,无需 80 端口可达。


2. 系统基础优化(BBR 跨境丢包优化)

BBR(Bottleneck Bandwidth and RTT)+ fq 队列,显著改善跨境 TCP 丢包/高延迟下的吞吐。

2.1 启用 BBR

写入 /etc/sysctl.d/99-bbr.conf:

net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr

应用并验证:

modprobe tcp_bbr 2>/dev/null || true   # 部分内核需手动加载模块
sysctl --system
sysctl net.ipv4.tcp_congestion_control net.core.default_qdisc
# 期望输出: bbr / fq

内核要求:BBR 需 Linux 4.9+。default_qdisc=fq 在部分新内核(6.12+ cloud 内核)可能无此参数,仅保留 tcp_congestion_control=bbr 即可,不影响 BBR 生效。

2.2 文件描述符

nginx worker 高并发需要提高 limit,在 /etc/security/limits.conf 追加:

* soft nofile 65535
* hard nofile 65535

2.3 时区与 NTP

代理证书校验、日志排障都依赖准确时间:

timedatectl set-timezone Asia/Shanghai
apt install -y chrony && systemctl enable --now chrony

3. 伪装站点页面

直接访问节点/IP 时返回一个普通网页(而非代理错误),降低被探测的特征。

放置一个静态 index.html 到 /var/www/html/index.html:

  • 任意抓取的合法 HTML 页面(博客/门户首页快照均可)
  • 所有节点用同一份(md5 一致),避免逐节点特征差异
mkdir -p /var/www/html
# index.html 为本仓库 fake-site/index.html 的拷贝
cp fake-site/index.html /var/www/html/index.html

4. HTTPS 证书(acme.sh DNS-01)

nginx 站点与 CONNECT 隧道共用一张证书。用 acme.sh + DNS-01(以阿里云 DNS 为例,其他 DNS 商同理):

curl https://get.acme.sh | sh -s email=<你的邮箱>
export Ali_Key="<阿里云AccessKey>"
export Ali_Secret="<阿里云Secret>"

~/.acme.sh/acme.sh --issue --dns dns_ali -d <节点域名> --keylength ec-256

# 安装到 nginx 读取路径
mkdir -p /etc/nginx/ssl/<节点域名>
~/.acme.sh/acme.sh --install-cert -d <节点域名> --ecc \
  --fullchain-file /etc/nginx/ssl/<节点域名>/fullchain.pem \
  --key-file       /etc/nginx/ssl/<节点域名>/privkey.pem

acme.sh 自带 cron 自动续期。证书路径固定为 /etc/nginx/ssl/<节点域名>/{fullchain,privkey}.pem。


5. nginx 源码编译 + CONNECT 隧道

标准 nginx 不自带 CONNECT 方法支持,需打 ngx_http_proxy_connect_module 补丁后源码编译。

5.1 编译

apt install -y build-essential libssl-dev libpcre3-dev zlib1g-dev curl wget

NGINX_VER=1.26.3
cd /usr/local/src
curl -LO http://nginx.org/download/nginx-$NGINX_VER.tar.gz
tar xzf nginx-$NGINX_VER.tar.gz

git clone https://github.com/chobits/ngx_http_proxy_connect_module.git
cd nginx-$NGINX_VER
patch -p1 < ../ngx_http_proxy_connect_module/patch/proxy_connect_rewrite_102101.patch

./configure \
  --prefix=/usr/local/nginx \
  --conf-path=/etc/nginx/nginx.conf \
  --pid-path=/var/run/nginx.pid \
  --error-log-path=/var/log/nginx/error.log \
  --http-log-path=/var/log/nginx/access.log \
  --with-http_ssl_module \
  --with-http_v2_module \
  --with-http_realip_module \
  --with-http_stub_status_module \
  --with-http_gzip_static_module \
  --add-module=../ngx_http_proxy_connect_module
make -j$(nproc) && make install

若发行版 nginx 已自带 proxy_connect 补丁(极少见),可用 apt install nginx 跳过编译,但源码编译是通用做法。

5.2 Basic Auth 凭据

CONNECT 代理需要 Basic Auth(用户名/密码),生成 htpasswd:

apt install -y apache2-utils
htpasswd -bc /etc/nginx/.htpasswd <代理用户名> '<代理密码>'
chmod 644 /etc/nginx/.htpasswd   # worker 以 nobody 运行,必须可读

5.3 nginx.conf

完整配置见 nginx/nginx.conf。关键设计:

  • 两个 server 块共用 <nginx端口>:
    • 主块 server_name <节点域名>:证书站点 + location / 返回伪装页;非本域名一律 rewrite 到 /__proxy 转发
    • fallback 块 default_server:其他 SNI 也接受 CONNECT 代理;本机/私网/公网 IP 直连返回伪装页,其余走 /__proxy
  • proxy_connect_allow all;:全端口 CONNECT 放行(codex/WebSocket 走任意端口均通)。若需限制,改回 proxy_connect_allow 443 563;
  • auth_basic:仅 CONNECT/正向代理需要认证,location / 伪装页 auth_basic off
  • 自代理回环保护:/__proxy 转发时带 X-Proxy-Loop-Guard 头,二次进入返回 508 防死循环
  • /__local:本机 IP 直连时剥前缀返回伪装页
  • map $host $is_local:私网/回环段判定;公网 IP 由 cron 脚本动态写入 local_ip_rules.conf

5.4 自代理回环保护说明

正向代理转发目标若指向本机自己(如域名公网 IP 变更、或代理目标就是本节点),会无限循环。两层防护:

  1. map 判定私网/回环段 + cron 维护的本机公网 IP 规则 → 直连伪装页
  2. /__proxy 的 Loop-Guard 头兜底 → 二次进入返回 508

6. sing-box(VLESS+REALITY / Shadowsocks)

6.1 安装

SINGBOX_VER=1.13.19
curl -LO https://github.com/SagerNet/sing-box/releases/download/v$SINGBOX_VER/sing-box-$SINGBOX_VER-linux-amd64.tar.gz
tar xzf sing-box-*.tar.gz
install -m 755 sing-box-$SINGBOX_VER-linux-amd64/sing-box /usr/local/bin/sing-box

6.2 配置

完整配置见 sing-box/config.json。要点:

  • VLESS+REALITY:统一 UUID、统一私钥/short_id/SNI,flow xtls-rprx-vision;REALITY handshake server 用 <伪装SNI域名>:443
  • Shadowsocks:aes-256-gcm + 统一密码,独立端口(兼容不支持 REALITY 的老客户端)
  • 无 SOCKS5 inbound(已按需移除;如需可在 inbounds 追加 type: socks)

6.3 REALITY 密钥生成

首次部署生成一套(全套节点共用):

# 生成私钥/公钥(sing-box 1.13+ 内置 reality 密钥生成)
sing-box generate reality-keypair
# 输出 private_key / public_key,记录备用
# short_id 用 8 字节随机 hex:
openssl rand -hex 8
# UUID:
sing-box generate uuid

私钥只放服务端配置;公钥给客户端订阅。UUID/short_id 全节点一致。


7. mtg(MTProto 代理)

Telegram 内置代理,Fake TLS 模式抗封锁。用 mtg(Go 单二进制):

7.1 安装

MTG_VER=2.2.8
curl -LO https://github.com/9seconds/mtg/releases/download/v$MTG_VER/mtg-$MTG_VER-linux-amd64.tar.gz
tar xzf mtg-*.tar.gz
install -m 755 mtg-$MTG_VER-linux-amd64/mtg /usr/local/bin/mtg

7.2 生成 secret(每台独立)

mtg generate-secret --hex <伪装SNI域名>
# 输出 ee<32hex><域名hex>,以 ee 开头 = Fake TLS 类型

7.3 运行

mtg simple-run --prefer-ip=prefer-ipv4 0.0.0.0:<mtproto端口> <上面生成的secret>

--prefer-ip=prefer-ipv4:强制 IPv4 出站,避免容器/双栈环境下 IPv6 不可达导致回退失败。

7.4 Telegram 客户端参数

  • 服务器:<节点域名>
  • 端口:<mtproto端口>
  • Secret:上面生成的 hex(Telegram 自动识别 Fake TLS)

8. 本机公网 IP 自动识别(防自代理回环)

正向代理转发时,若目标 Host 是本机公网 IP,会被识别为"本机直连"返回伪装页(而非经代理转发本机,造成回环)。公网 IP 可能变动,用 cron 脚本每 5 分钟自动维护。

脚本见 scripts/sync-nginx-local-ips.sh,cron 见 cron/sync-nginx-local-ips:

*/5 * * * * root /usr/local/sbin/sync-nginx-local-ips.sh >/dev/null 2>&1

脚本逻辑:取 api.ipify.org 出站 IP + 节点域名 A 记录,比对重写 /etc/nginx/local_ip_rules.conf,仅变更时 nginx -t && systemctl reload nginx。


9. systemd 服务文件

服务 文件
nginx systemd/nginx.service
sing-box systemd/sing-box.service
mtg systemd/mtg.service
cp systemd/*.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now nginx sing-box mtg

10. 启动顺序与验证清单

启动顺序

sysctl --system                      # 1. BBR
systemctl start sing-box             # 2. VLESS/SS
systemctl start mtg                  # 3. MTProto
systemctl start nginx                # 4. nginx(最后,依赖证书/伪装页/规则文件)

验证清单

# BBR
sysctl net.ipv4.tcp_congestion_control   # => bbr

# sing-box
sing-box check -c /etc/sing-box/config.json
systemctl is-active sing-box

# mtg(Fake TLS:非法 ClientHello 应返回 TLS alert 0x15)
timeout 8 python3 -c "
import socket,os,struct
s=socket.connect(('<节点域名>',<mtproto端口>)) if False else socket.create_connection(('<节点域名>',<mtproto端口>),timeout=6)
s.sendall(b'\x16\x03\x01'+struct.pack('>H',100)+os.urandom(100))
print('resp:',s.recv(8).hex())"   # 期望首字节 15 (TLS alert)

# nginx CONNECT(带 Basic Auth,B64 = base64('<代理用户名>:<代理密码>'))
B64=$(printf '<代理用户名>:<代理密码>' | base64 -w0)
curl -sk --proxy-insecure -x https://<节点域名>:<nginx端口> \
  --proxy-header "Authorization: Basic $B64" \
  -o /dev/null -w '%{http_code}\n' http://example.com/    # => 200

# 伪装页(直连 IP/域名,无认证)
curl -sk https://<节点域名>:<nginx端口>/ -o /dev/null -w '%{http_code}\n'   # => 200

11. 目录结构与文件索引

server_config/
├── README.md                        ← 本文档
├── nginx/
│   ├── nginx.conf                   ← 完整 nginx 配置(占位符版)
│   ├── local_ip_rules.conf.example  ← 本机 IP 规则文件示例(cron 自动生成,勿手改)
│   └── conf.d/                      ← 预留:额外站点配置
├── sing-box/
│   └── config.json                  ← sing-box 配置(VLESS+REALITY + SS,占位符版)
├── systemd/
│   ├── nginx.service
│   ├── sing-box.service
│   └── mtg.service
├── scripts/
│   └── sync-nginx-local-ips.sh      ← 本机公网 IP 规则自动维护
├── cron/
│   └── sync-nginx-local-ips         ← cron 定义(每 5 分钟)
└── fake-site/
    └── index.html                   ← 伪装站点页面(所有节点共用同一份)

旧的 traffic-monitor/、pac/、conf.d/*.conf 已下线或迁移,不再维护,已从本目录移除。