Debian 13 纯净安装 Xray 并配置 VLESS + Reality 与 BBR

by 落墨in 技术

Debian 13 (trixie)从零开始、不依赖任何面板(纯净安装)的 Xray 部署流程:装系统依赖 → 安装 Xray-core → 配置 VLESS + Reality → 开启 BBR。

说明:本文用于技术学习与个人合规用途。请在你所在地区法律允许的前提下使用,并仅用于访问你有权访问的资源。

一、系统准备

先用 root 登录,更新软件源并升级:

apt update
apt upgrade -y

装几个后续会用到的工具:

apt install -y curl wget gnupg2 lsb-release ca-certificates

确认系统版本(应显示 trixie / 13):

cat /etc/os-release | grep -E "VERSION|PRETTY"

Reality 对内核版本没有硬性要求,但 Debian 13 自带 6.x 内核,BBR 原生支持,无需换内核。确认一下:

uname -r

二、纯净安装 Xray-core

官方推荐的方式是用 XTLS 提供的安装脚本,它会把二进制放到 /usr/local/bin/xray、配置目录放到 /usr/local/etc/xray/,并注册 systemd 服务,不污染系统包管理器。

bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install

安装完成后查看版本,确认成功:

xray version

如果 GitHub 访问不畅,可改用镜像(二选一,注意替换为可信镜像源):

# 例如 jsdelivr 镜像
bash -c "$(curl -L https://cdn.jsdelivr.net/gh/XTLS/Xray-install@main/install-release.sh)" @ install

安装脚本同时创建了 xray 用户与 /etc/systemd/system/xray.service。检查服务状态:

systemctl status xray --no-pager

此时服务是 inactive,因为我们还没放配置。
安装后的文件位置(官方 FHS 布局):

用途 路径
主程序 /usr/local/bin/xray
配置文件 /usr/local/etc/xray/config.json
geo 数据 /usr/local/share/xray/geoip.dat、geosite.dat
systemd 服务 /etc/systemd/system/xray.service
日志目录 /var/log/xray/

三、生成密钥与 UUID

Reality 使用 X25519 密钥对做身份验证,公钥给客户端、私钥留服务器。执行:

xray x25519

输出形如:

Private key: <你的私钥>
Public key:  <你的公钥>

再生成一个 UUID 作为客户端 ID:

xray uuid
<你的-uuid>

把这两个值记下来,下面配置要用。

四、配置 VLESS + Reality(服务端)

编辑配置文件:

nano /usr/local/etc/xray/config.json

写入以下内容(注意替换 <...> 占位符):

{
  "inbounds": [
    {
      "listen": "0.0.0.0",
      "port": 443,
      "protocol": "vless",
      "settings": {
        "clients": [
          {
            "id": "<你的-uuid>",
            "flow": "xtls-rprx-vision"
          }
        ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "tcp",
        "security": "reality",
        "realitySettings": {
          "show": false,
          "dest": "www.microsoft.com:443",
          "xver": 0,
          "serverNames": ["www.microsoft.com", "www.apple.com"],
          "privateKey": "<你的私钥>",
          "minClientVer": "",
          "maxClientVer": "",
          "maxTimeDiff": 0,
          "shortIds": ["", "abcd1234"],
          "spiderX": "/"
        }
      },
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls", "quic"]
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "tag": "direct"
    },
    {
      "protocol": "blackhole",
      "tag": "blocked"
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "blocked"
      }
    ]
  }
}

字段说明:

  • port: 443:复用标准 HTTPS 端口,配合 Reality 伪装成正常 TLS 流量,最难被识别。
  • flow: xtls-rprx-vision:VLESS 的高性能流控,必须客户端一致。(一定要配置,影响速度)
  • dest / serverNames:Reality 会“借用”一个真实站点的 TLS 握手。这里借用 www.microsoft.com,无需你持有证书或域名。
  • privateKey:上一步生成的 X25519 私钥。
  • shortIds:留空串 "" 和一个自定义值均可,客户端需与之对应。

校验配置语法:

xray run -test -config /usr/local/etc/xray/config.json

看到 Configuration OK 即可启动:

systemctl enable --now xray
systemctl status xray --no-pager

确认 443 在监听:

ss -tlnp | grep 443

五、客户端配置(VLESS + Reality)

客户端同样需要 Xray-core(Windows/macOS/Linux 均可用对应的安装包或 GUI 客户端,内核配置同理)。一份 Linux 客户端的 config.json 示例:

{
  "inbounds": [
    {
      "port": 10808,
      "listen": "127.0.0.1",
      "protocol": "socks",
      "settings": { "udp": true }
    },
    {
      "port": 10809,
      "listen": "127.0.0.1",
      "protocol": "http"
    }
  ],
  "outbounds": [
    {
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "<服务器IP>",
            "port": 443,
            "users": [
              {
                "id": "<你的-uuid>",
                "flow": "xtls-rprx-vision",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "reality",
        "realitySettings": {
          "serverName": "www.microsoft.com",
          "fingerprint": "chrome",
          "publicKey": "<你的公钥>",
          "shortId": "abcd1234",
          "spiderX": "/"
        }
      }
    }
  ]
}

客户端要填的是上一步的 Public key(不是私钥),serverName 与 shortId 必须与服务端 serverNames / shortIds 中的某一项一致,fingerprint 填 chrome 或 firefox 等浏览器指纹以模拟真实客户端。

六、与网站共存:把 Xray 端口从 443 改到 8443

如果这台机器上还跑了网站(Nginx / Caddy / Apache 等),它们默认会占用 443 端口。而上面的 Xray 入站也监听 443,两者会端口冲突,只能有一个能起来。

解决办法:把 Xray 的入站端口改到 8443(或其他未占用端口),网站继续独占 443,各走各的。

1. 修改服务端配置

编辑 config.json,把入站 port 由 443 改为 8443:

{
  "listen": "0.0.0.0",
  "port": 8443,
  "protocol": "vless",
  "settings": { ... }
}

实际改动只有一行:"port": 443 → "port": 8443。注意 Reality 的 dest 仍借用 www.microsoft.com:443,那是目标站地址,不是本机监听端口,因此无需改动。

2. 修改客户端配置

客户端 vnext 里的 port 同样改成 8443:

"vnext": [
  {
    "address": "<服务器IP>",
    "port": 8443,
    "users": [ ... ]
  }
]

3. 防火墙放行 8443

如果用了 ufw,放行新端口(443 留给网站,无需再为 Xray 放行):

ufw allow 8443/tcp
ufw reload

4. 重启 Xray 并验证

systemctl restart xray
ss -tlnp | grep 8443

看到 8443 在监听、且 systemctl status xray 正常,说明 Xray 与网站各占 8443 / 443,互不干扰。

5. 进阶:用 Nginx / Caddy 回落,让客户端仍走 443

如果你嫌客户端要记 8443 麻烦,想要客户端只填标准 443、外观上和正常 HTTPS 网站完全一致,可以用 Web 服务器在 443 入口做 SNI 分流(即“回落 / fallback”):

  • 443 交给 Nginx(或 Caddy)统一监听;
  • 用 SNI(客户端 Hello 里携带的域名)判断:是代理流量 → 转发给本机 Xray(127.0.0.1:8443);是普通访客 → 转发给网站;
  • 客户端 port 改回 443,不用再记特殊端口。

5.1 准备你自己的域名与证书

回落方案需要你自己的一个域名(如 proxy.yourdomain.com),解析到服务器 IP,并用 Let’s Encrypt 等签发证书,让 Nginx 能在该域名上提供正常的 HTTPS 站点。这个站点既是给访客看的,也同时充当 Reality 的 dest 目标。

5.2 改 Xray:借用你自己的域名

Xray 入站仍监听 8443(见上一节),但把 dest / serverNames 改成你自己的域名:

"realitySettings": {
  "show": false,
  "dest": "proxy.yourdomain.com:443",
  "xver": 0,
  "serverNames": ["proxy.yourdomain.com"],
  "privateKey": "<你的私钥>",
  "shortIds": ["", "abcd1234"],
  "spiderX": "/"
}

dest 现在是你自己的站点,Xray 会借用它的 TLS 做 Reality 握手,因此该域名必须证书有效、Nginx 能正常响应(正好由下面的网站 server 提供)。

5.3 Nginx:stream + ssl_preread 按 SNI 分流

在 nginx.conf 里加一个与 http 块同级的 stream 块,用 ssl_preread 读取 SNI 后转发:

stream {
    # 按 SNI 选择后端:代理域名 → Xray,其它 → 网站
    map $ssl_preread_server_name $backend {
        proxy.yourdomain.com   127.0.0.1:8443;   # 代理流量给 Xray
        default                127.0.0.1:8444;   # 普通访客给网站
    }

    server {
        listen 443 reuseport;
        ssl_preread on;
        proxy_pass $backend;
    }
}

注意:stream 和 http 不能在同一端口上同时监听,所以把原本在 443 的网站 server 挪到 8444(由上面的 default 转发过去):

# /etc/nginx/sites-enabled/yourdomain.conf
server {
    listen 8444 ssl;
    server_name yourdomain.com proxy.yourdomain.com;

    ssl_certificate     /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    root /var/www/html;
    index index.html;
}

改完重载:nginx -t && systemctl reload nginx。

5.4 客户端:改回 443

客户端 vnext 的 port 改回 443,serverName 填你自己的域名,其余不变:

"vnext": [
  {
    "address": "<服务器IP>",
    "port": 443,
    "users": [ { "id": "<你的-uuid>", "flow": "xtls-rprx-vision", "encryption": "none" } ]
  }
],
"streamSettings": {
  "network": "tcp",
  "security": "reality",
  "realitySettings": {
    "serverName": "proxy.yourdomain.com",
    "fingerprint": "chrome",
    "publicKey": "<你的公钥>",
    "shortId": "abcd1234",
    "spiderX": "/"
  }
}

5.5 Caddy 用户

思路相同,只是用 Caddy 实现 SNI 分流:可用 reverse_proxy 配合 tls 的 sni 匹配,或更干净地用 layer4 插件 在四层按 SNI 路由(代理域名 → 127.0.0.1:8443,其余 → 本地 HTTPS 站点)。

5.6 关键点回顾

  • 443 入口只能有一个监听者,所以用 Nginx stream 统一收口再分流;
  • Reality 的 dest / serverNames 必须指向你自己有证书的域名;
  • 客户端 serverName 与 port 要与之一致(这里是 proxy.yourdomain.com + 443);
  • 此方案对外完全像“一个普通 HTTPS 网站”,隐蔽性最好,但配置比直接换端口复杂,按需选择。

七、启用 BBR 拥塞控制

VLESS + Reality 跑在 TCP 上,开启 BBR 能显著改善高延迟、高丢包链路下的吞吐。Debian 13 内核已自带 BBR 模块,无需编译。

写入 sysctl 配置:

echo 'net.core.default_qdisc = fq' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_congestion_control = bbr' >> /etc/sysctl.conf
sysctl -p

验证是否生效:

sysctl net.ipv4.tcp_congestion_control
# 期望输出:net.ipv4.tcp_congestion_control = bbr

再从内核模块侧确认:

lsmod | grep bbr
# 或
cat /proc/sys/net/ipv4/tcp_available_congestion_control
# 期望能看到 bbr

若 tcp_available_congestion_control 里没有 bbr,通常是模块未加载,手动加载即可:

modprobe tcp_bbr

BBR 立即生效,无需重启;重启后由 /etc/sysctl.conf 自动应用。

八、防火墙与收尾

若开启了 ufw,放行 Xray 所用端口:单用途场景放行默认的 443,若按「第六节」改了端口则放行 8443(网站自身需要的 443 由 Web 服务器自己处理):

# 单用途(Xray 在 443)
ufw allow 443/tcp

# 与网站共存(Xray 已改到 8443)
ufw allow 8443/tcp

ufw reload

最后做一次端到端验证:客户端连接后,浏览器或 curl -x socks5://127.0.0.1:10808 https://www.google.com 能正常返回即大功告成。

小结

整套下来核心就三步:用官方脚本纯净装 Xray → 写好 Reality 入站(借用真实站点 TLS,免证书)、客户端填公钥 → 开 BBR。