XTLS / Xray-core

Xray, Penetrates Everything. Also the best v2ray-core, with XTLS support. Fully compatible configuration.
https://t.me/projectXray
Mozilla Public License 2.0
24.59k stars 3.84k forks source link

XTLS-REALITY 自己偷自己时,serverName填的域名与实际SSL证书包含的域名不一致时,也能连接 #1681

Closed chika0801 closed 1 year ago

chika0801 commented 1 year ago

使用的Xray-core版本是 https://github.com/XTLS/Xray-core/actions/runs/4209833887

环境是: Chrome用 SwitchyOmega 设置http代理,127.0.0.1 10809端口进v2rayN。

配置过程:

1、将客户端配置和服务器配置的serverName填同一个,与SSL证书中包含的域名不一样,可以连通。

2、将客户端配置和服务器配置的serverName填不一样的,且保持与SSL证书中包含的域名不一样,客户端连不通。

补充:

如果不是自己偷自己的情况,没有以上问题。

chika0801 commented 1 year ago

服务器配置

{
    "inbounds": [
        {
            "listen": "0.0.0.0",
            "port": 443,
            "protocol": "vless",
            "settings": {
                "clients": [
                    {
                        "id": "chika",
                        "flow": "xtls-rprx-vision"
                    }
                ],
                "decryption": "none"
            },
            "streamSettings": {
                "network": "tcp",
                "security": "reality",
                "realitySettings": {
                    "show": false,
                    "dest": "8003",
                    "xver": 1,
                    "serverNames": [
                        "SSL证书包含的域名"
                    ],
                    "privateKey": "私钥",
                    "shortIds": [
                        ""
                    ]
                }
            },
            "sniffing": {
                "enabled": true,
                "destOverride": [
                    "http",
                    "tls"
                ]
            }
        }
    ],
    "outbounds": [
        {
            "protocol": "freedom",
            "tag": "direct"
        },
        {
            "protocol": "blackhole",
            "tag": "block"
        }
    ],
    "policy": {
        "levels": {
            "0": {
                "handshake": 2,
                "connIdle": 120,
                "uplinkOnly": 1,
                "downlinkOnly": 1
            }
        }
    }
}

nginx配置

user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    log_format main '[$time_local] $remote_addr "$http_referer" "$http_user_agent"';
    access_log /var/log/nginx/access.log main;

    server {
        listen 80;
        return 301 https://$host$request_uri;
    }

    server {
        listen 127.0.0.1:8003 ssl http2 proxy_protocol;
        set_real_ip_from 127.0.0.1;

        ssl_certificate /etc/ssl/private/fullchain.cer;
        ssl_certificate_key /etc/ssl/private/private.key;

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers TLS13_AES_128_GCM_SHA256:TLS13_AES_256_GCM_SHA384:TLS13_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305;
        ssl_prefer_server_ciphers on;

        ssl_stapling on;
        ssl_stapling_verify on;

        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

        location / {
            resolver 1.1.1.1;
            set $example https://www.lovelive-anime.jp;
            proxy_pass $example;
            proxy_ssl_server_name on;
        }
    }
}
chika0801 commented 1 year ago

客户端配置

{
    "log": {
        "loglevel": "warning"
    },
    "inbounds": [
        {
            "listen": "127.0.0.1",
            "port": 10808,
            "protocol": "socks",
            "settings": {
                "udp": true
            },
            "sniffing": {
                "enabled": true,
                "destOverride": [
                    "http",
                    "tls"
                ]
            }
        },
        {
            "listen": "127.0.0.1",
            "port": 10809,
            "protocol": "http",
            "sniffing": {
                "enabled": true,
                "destOverride": [
                    "http",
                    "tls"
                ]
            }
        }
    ],
    "outbounds": [
        {
            "protocol": "vless",
            "settings": {
                "vnext": [
                    {
                        "address": "VPS的IP",
                        "port": 443,
                        "users": [
                            {
                                "id": "chika",
                                "flow": "xtls-rprx-vision",
                                "encryption": "none"
                            }
                        ]
                    }
                ]
            },
            "streamSettings": {
                "network": "tcp",
                "security": "reality",
                "realitySettings": {
                    "show": false,
                    "fingerprint": "chrome",
                    "serverName": "SSL证书包含的域名",
                    "publicKey": "公钥",
                    "shortId": "",
                    "spiderX": "/chika"
                }
            },
            "tag": "proxy"
        },
        {
            "protocol": "freedom",
            "tag": "direct"
        },
        {
            "protocol": "blackhole",
            "tag": "block"
        }
    ]
}
RPRX commented 1 year ago

配置如下,测试时将客户端配置和服务器配置的serverName填同一个,与SSL证书中包含的域名不一样,也可以连通。

其实只要 dest 有默认证书,REALITY 客户端就可以用其它 SNI 连接,REALITY 服务端响应符合 dest 返回默认证书时的特征

所以 REALITY 服务端必填 serverNames 限制可选范围,这是服务端的责任去填好它,防止客户端乱填 SNI,除非故意里应外合

举个例子,真想的话,你填个 xyz.cn 都行,它可能更便于实现某些目标,但主动探测返回的是 dest 的默认证书,有利有弊

chika0801 commented 1 year ago

感谢解答。 虽然不懂。