Allen's 碎碎念

Allen's 碎碎念

SNI 分流

1
2026-03-30

使用 SNI 分流(SNI Routing)的方式使得 VPS 上建站和 reality 公用 443 端口。

nginx proxy manager

services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      # These ports are in format <host-port>:<container-port>
      - '80:80' # Public HTTP Port
      - '127.0.0.1:4443:443' # Public HTTPS Port
      - '81:81' # Admin Web Port
      # Add any other Stream port you want to expose
      # - '21:21' # FTP
    environment:
      TZ: "Asia/Shanghai"
      # Mysql/Maria connection parameters:
      DB_MYSQL_HOST: "db"
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: "npm"
      DB_MYSQL_PASSWORD: "npm"
      DB_MYSQL_NAME: "npm"
      # Optional SSL (see section below)
      # DB_MYSQL_SSL: 'true'
      # DB_MYSQL_SSL_REJECT_UNAUTHORIZED: 'true'
      # DB_MYSQL_SSL_VERIFY_IDENTITY: 'true'
      # Uncomment this if IPv6 is not enabled on your host
      # DISABLE_IPV6: 'true'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    depends_on:
      - db

  db:
    image: 'jc21/mariadb-aria:latest'
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: 'npm'
      MYSQL_DATABASE: 'npm'
      MYSQL_USER: 'npm'
      MYSQL_PASSWORD: 'npm'
      MARIADB_AUTO_UPGRADE: '1'
    volumes:
      - ./mysql:/var/lib/mysql

nginx

docker-compose.yml

version: '3'
services:
  sni-router:
    image: nginx:alpine
    network_mode: "host"       # 关键!使用 host 网络模式,这样 127.0.0.1 就能直接和主机的 Xray/NPM 通信
    restart: always
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro

nginx.conf

user root;
worker_processes auto;

events {
    worker_connections 1024;
}

stream {
    # 核心:根据 SNI 域名进行分流
    map $ssl_preread_server_name $backend_name {
        # 这里填入你的 Reality 伪装域名(请替换成你实际使用的域名)
        www.microsoft.com     xray_backend;
        microsoft.com         xray_backend;

        # 其他所有无法匹配的域名,默认全部丢给 NPM 去处理
        default               npm_backend;
    }

    upstream xray_backend {
        server 127.0.0.1:8443; # 指向刚才配置的 Xray 端口
    }

    upstream npm_backend {
        server 127.0.0.1:4443; # 指向刚才配置的 NPM HTTPS 端口
    }

    server {
        listen 443;
        listen [::]:443;
        proxy_pass $backend_name;
        ssl_preread on; # 开启 SNI 预读功能
    }
}

3XUI

docker-compose.yml

services:
  3xui:
    image: ghcr.io/mhsanaei/3x-ui:latest
    container_name: 3xui_app
    # hostname: yourhostname <- optional
    ports:
      - "2053:2053"                 # 你的面板端口(保持原样即可)
      - "127.0.0.1:8443:8443"       # 关键:新增一行,给 Reality 使用
    volumes:
      - $PWD/db/:/etc/x-ui/
      - $PWD/cert/:/root/cert/
    environment:
      XRAY_VMESS_AEAD_FORCED: "false"
      XUI_ENABLE_FAIL2BAN: "true"
    tty: true
    network_mode: host
    restart: unless-stopped

reality 节点设置端口443。