用Xray实现域前置直连GitHub
背景
众所周知,GitHub时不时会被GFW阻断,非常影响日常使用。其本质原因是握手的时候SNI为明文,可以被防火墙检测。
SNI (服务器名称指示) 是TLS的一个扩展协议,在该协议下,在握手过程开始时客户端告诉它正在连接的服务器要连接的主机名称。
那么能不能发送请求的时候伪装SNI,以避免干扰?域前置技术干的就是这个。
原理
我们可以借助Xray的MITIM中间人攻击实现这一点,具体来说就是,我们先把传入的正常的网站流量解密,然后修改TLS的serverName,再重新发送出去,得到结果返回,这样就形成了一条代理链。
而实现这个的第一步,解密流量,就是需要自签一个CA证书,并让系统信任。
之后再编写Xray的配置,本地做一个socks的入站,和修改serverName后发送流量的出站。
最后让GitHub的流量经过这个socks代理就可以了。
自签证书生成和信任
这里用到openssl,Linux系统下自带,Windows系统下需要下载并安装。
先生成RSA 2048位私钥:
openssl genrsa -out ca.key 2048
接下来生成CA证书,会要求输入一些信息 (比如说国家、组织名称等),随便填一填就行。
openssl req -new -sha256 -key ca.key -out ca.csr
openssl x509 -req -sha256 -days 36500 -in ca.csr -signkey ca.key -out ca.crt
我们希望生成一个时效比较长的,这里有效期天数是36500就大概是100年,设大一点没有问题。
在Windows环境下双击ca.crt文件,点击安装证书,在导入向导中选择"受信任的根证书颁发机构",导入完成后这个证书就会被系统信任了 (如果密钥泄露,签发的证书都会被你的电脑信任)。

然后我们保存好ca.key和ca.crt文件,后面要用。
编写Xray配置
总体来说就是通过socks入站的流量转发到unpacker解包,再用repacker出站发送,一个简易示例配置如下:
{
"log": {
"loglevel": "warning"
},
"routing": {
"domainStrategy": "IPOnDemand",
"rules": [
{
"ip": [
"geoip:private"
],
"outboundTag": "freedom"
},
{
"inboundTag": [
"tls_unpacker_nosni"
],
"outboundTag": "tls_repacker_nosni"
},
{
"inboundTag": [
"socks"
],
"outboundTag": "redirector_nosni"
}
]
},
"inbounds": [
{
"tag": "socks",
"listen": "127.0.0.1",
"port": 10811, // 本地10811端口的socks入站
"protocol": "socks",
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
}
},
{
"tag": "tls_unpacker_nosni",
"listen": "127.0.0.1",
"port": 10010,
"protocol": "tunnel",
"settings": {
"port": 443,
"network": "tcp",
"followRedirect": true
},
"streamSettings": {
"security": "tls",
"tlsSettings": {
"alpn": [
"http/1.1",
"h2"
],
"certificates": [
{
"usage": "issue",
"certificateFile": "D:\\ca.crt", // 文件路径按实际填写
"keyFile": "D:\\ca.key"
}
]
}
}
}
],
"outbounds": [
{
"tag": "tls_repacker_nosni",
"protocol": "freedom",
"settings": {
"domainStrategy": "ForceIPv6"
},
"streamSettings": {
"security": "tls",
"tlsSettings": {
"serverName": "0.0.0.0", // 随便填
"verifyPeerCertInNames": [
"FromMitm"
],
"alpn": [
"FromMitm"
],
"fingerprint": "chrome"
}
}
},
{
"tag": "redirector_nosni",
"protocol": "freedom",
"settings": {
"redirect": "127.0.0.1:10010" // 转发到unpacker
}
},
{
"tag": "freedom",
"protocol": "freedom",
"settings": {
"domainStrategy": "ForceIP"
}
}
]
}
运行起来后让GitHub分流经过socks代理127.0.0.1:10811就行了,在没有dns污染的情况下应该是可以稳定直连。
除此之外,类似的,Xray的MITM还可以实现ech repacker。
Xray后台运行
另外一提,在Windows下如果想让这个在后台跑起来,可以使用nssm工具快速创建和管理服务,虽然软件比较古老但还挺好用的,只需要在命令行下执行:
nssm.exe install
在弹出的窗口里选择Xray-core的Path,填入一个Service name后install就能完成一个服务的注册。

之后可以通过nssm.exe start <servicename>启动服务,nssm.exe status <servicename>查看服务运行状态。
总结
当然直接用国外代理访问GitHub可能更快,本文只是讨论使用域前置直连GitHub的方法。
在特定场景下,比如说国内大学申请GitHub学生包时,可能需要IP一致性。