p4gefau1t / trojan-go

Go实现的Trojan代理,支持多路复用/路由功能/CDN中转/Shadowsocks混淆插件,多平台,无依赖。A Trojan proxy written in Go. An unidentifiable mechanism that helps you bypass GFW. https://p4gefau1t.github.io/trojan-go/
GNU General Public License v3.0
7.65k stars 1.66k forks source link

[BUG] 使用自签名证书(域名为IP地址)时不能显示页面/trojan-go客户端不能连接网络 #219

Open siwind opened 3 years ago

siwind commented 3 years ago

原版trojan使用自签名证书(域名为IP地址)是可以正常运行的,但是替换为trojan-go以后会存在如下问题。具体说明如下:

服务器和客户端环境信息

服务器Centos8, trojan, trojan-go, nginx(以root用户运行) 客户端: windows10.

附trojan配置文件:

自签名证书生成:

1) 通过openssl生成私钥
openssl genrsa -out server.key 2048

2) 根据私钥生成证书申请文件csr
openssl req -new -key server.key -out server.csr
这里根据命令行向导来进行信息输入:其中“Common Name(FQDN Name)”处输入域名(IP地址)
ps.Common Name可以输入:*.yourdomain.com,这种方式生成通配符域名证书
注: **这里是输入的真实的IP地址。例如 132.15.xx.xx**

3) 使用私钥对证书申请进行签名从而生成证书
openssl x509 -req -in server.csr -out server.crt -signkey server.key -days 3650
这样就生成了有效期为:10年的证书文件,对于自己内网服务使用足够。
文件"server.crt" 同时用于服务端和客户端。

trojan配置文件

客户端config.json:

"ssl": {
        "verify": true,
        "verify_hostname": true,
        "cert": "./server.crt",

服务端config.json:

"log_level": 1,
    "ssl": {
        "cert": "/usr/local/etc/trojan/server.crt",
        "key":  "/usr/local/etc/trojan/server.key",

服务端和客户端日志

客户端日志:

[INFO]  2020/12/26 22:27:21 trojan-go v0.8.2 initializing
[INFO]  2020/12/26 22:27:21 adapter listening on tcp/udp: 127.0.0.1:1080
[INFO]  2020/12/26 22:27:21 tls fingerprint firefox applied
[INFO]  2020/12/26 22:27:21 using custom cert
[INFO]  2020/12/26 22:27:21 geoip info {CN 1} loaded
[INFO]  2020/12/26 22:27:21 geoip info {PRIVATE 1} loaded
[INFO]  2020/12/26 22:27:22 geosite info {GEOLOCATION-!CN 0} loaded
[INFO]  2020/12/26 22:27:22 geosite info {CN 1} loaded
[INFO]  2020/12/26 22:27:22 geosite info {GEOLOCATION-CN 1} loaded
[INFO]  2020/12/26 22:27:22 geosite info {CATEGORY-ADS 2} loaded
[INFO]  2020/12/26 22:27:22 router client created
[INFO]  2020/12/26 22:27:34 socks connection from 127.0.0.1:1905 metadata www.youtube.com:443
[INFO]  2020/12/26 22:27:34 socks connection from 127.0.0.1:1906 metadata fonts.googleapis.com:443
[INFO]  2020/12/26 22:27:34 socks connection from 127.0.0.1:1907 metadata fonts.gstatic.com:443
[INFO]  2020/12/26 22:27:34 socks connection from 127.0.0.1:1909 metadata www.youtube.com:443
[ERROR] 2020/12/26 22:27:34 github.com/p4gefau1t/trojan-go/proxy.(*Proxy).relayConnLoop.func1.1:proxy.go:66 proxy failed to dial connection | simplesocks failed to dial using underlying tunnel | no available mux client found | mux failed to dial | tls failed to handshake with remote server | x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0
[INFO]  2020/12/26 22:27:34 socks connection from 127.0.0.1:1911 metadata www.youtube.com:443
[INFO]  2020/12/26 22:27:34 socks connection from 127.0.0.1:1912 metadata www.gstatic.com:443
[INFO]  2020/12/26 22:27:34 socks connection from 127.0.0.1:1913 metadata ssl.gstatic.com:443
[INFO]  2020/12/26 22:27:34 socks connection from 127.0.0.1:1914 metadata apis.google.com:443
[ERROR] 2020/12/26 22:27:35 github.com/p4gefau1t/trojan-go/proxy.(*Proxy).relayConnLoop.func1.1:proxy.go:66 proxy failed to dial connection | simplesocks failed to dial using underlying tunnel | no available mux client found | mux failed to dial | tls failed to handshake with remote server | x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0

服务端日志:

Dec 06 22:27:38 racknerd trojan-go[878]: [INFO]  2020/12/20 22:27:38 tcp connection from 2xx.x.xx.xxx:36189
Dec 06 22:27:39 racknerd trojan-go[878]: [ERROR] 2020/12/20 22:27:39 github.com/p4gefau1t/trojan-go/tunnel/tls.(*Server
).acceptLoop.func1:server.go:135 tls handshake failed | remote error: tls: bad certificate
Dec 06 22:27:39 racknerd trojan-go[878]: [INFO]  2020/12/20 22:27:39 tcp connection from 2xx.x.xx.xxx:18812
Dec 06 22:27:39 racknerd trojan-go[878]: [ERROR] 2020/12/20 22:27:39 github.com/p4gefau1t/trojan-go/tunnel/tls.(*Server
).acceptLoop.func1:server.go:135 tls handshake failed | remote error: tls: bad certificate
Dec 06 22:27:39 racknerd trojan-go[878]: [INFO]  2020/12/20 22:27:39 tcp connection from 2xx.x.xx.xxx:36191
Dec 06 22:27:40 racknerd trojan-go[878]: [ERROR] 2020/12/20 22:27:40 github.com/p4gefau1t/trojan-go/tunnel/tls.(*Server
).acceptLoop.func1:server.go:135 tls handshake failed | remote error: tls: bad certificate
Dec 06 22:27:40 racknerd trojan-go[878]: [INFO]  2020/12/20 22:27:40 tcp connection from 2xx.x.xx.xxx:18814
Dec 06 22:27:40 racknerd trojan-go[878]: [ERROR] 2020/12/20 22:27:40 github.com/p4gefau1t/trojan-go/tunnel/tls.(*Server
).acceptLoop.func1:server.go:135 tls handshake failed | remote error: tls: bad certificate
Dec 06 22:27:40 racknerd trojan-go[878]: [INFO]  2020/12/20 22:27:40 tcp connection from 2xx.x.xx.xxx:36192
Dec 06 22:27:40 racknerd trojan-go[878]: [ERROR] 2020/12/20 22:27:40 github.com/p4gefau1t/trojan-go/tunnel/tls.(*Server
).acceptLoop.func1:server.go:135 tls handshake failed | remote error: tls: bad certificate
Dec 06 22:28:17 racknerd trojan-go[878]: [INFO]  2020/12/20 22:28:17 tcp connection from 2xx.x.xx.xxx:18844
Dec 06 22:28:17 racknerd trojan-go[878]: [ERROR] 2020/12/20 22:28:17 github.com/p4gefau1t/trojan-go/tunnel/tls.(*Server
).acceptLoop.func1:server.go:135 tls handshake failed | remote error: tls: bad certificate
Dec 06 22:28:17 racknerd trojan-go[878]: [INFO]  2020/12/20 22:28:17 tcp connection from 2xx.x.xx.xxx:36220
Dec 06 22:28:17 racknerd trojan-go[878]: [ERROR] 2020/12/20 22:28:17 github.com/p4gefau1t/trojan-go/tunnel/tls.(*Server
).acceptLoop.func1:server.go:135 tls handshake failed | remote error: tls: bad certificate
KazamaSion commented 3 years ago

我并没有完整按照你的做法完整从 trojan-gfw 到 trojan-go 实验操作,但是从结论来说,自签证书可以在 trojan-go 使用(客户端也为 trojan-go)。但无法按照你生成证书的方法使用。同时我这里的报错提示也和你的不一样。

同时由于我没有在你提供的配置文件中发现有配置 SNI 字段。可能你把对应的功能塞进 Nginx 里而我并不知道。如果没有配置,也请加上。

请尝试按照以下方法生成证书。并将 example.com 替换为自己的域名。

cat > csrconfig.txt <<-EOF
[ req ]
default_md = sha256
prompt = no
req_extensions = req_ext
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
commonName = example.com
countryName = US
[ req_ext ]
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=critical,serverAuth,clientAuth
subjectAltName = @alt_names
[ alt_names ]
DNS.0 = example.com
EOF

cat > certconfig.txt <<-EOF
[ req ]
default_md = sha256
prompt = no
req_extensions = req_ext
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
commonName = example.com
[ req_ext ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=critical,serverAuth,clientAuth
subjectAltName = @alt_names
[ alt_names ]
DNS.0 = example.com
EOF

openssl genpkey -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out cert.key
openssl req -new -nodes -key cert.key -config csrconfig.txt -out cert.csr
openssl req -x509 -nodes -in cert.csr -days 365 -key cert.key -config certconfig.txt -extensions req_ext -out cert.crt
siwind commented 3 years ago

感谢回复。 不好意思,这里我漏了一点,就是生成证书时, 输入的域名其实是真实的VPS的IP地址,例如: 12.34.xx.xx。 因为没有时间/精力去申请域名,直接用IP地址代替了。 这样时, 原版的trojan服务端和客户端都是可以使用的,而且没问题~

附浏览器访问时,展示的证书: (域名处为真实的IP地址)

a

yufeiluo commented 3 years ago

我也发现同样的问题

kalagxw commented 2 years ago

any update?