Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

smartdns作为tls服务端指派证书链,签发者证书被丢弃 #1324

Closed
PikuZheng opened this issue Mar 13, 2023 · 20 comments
Closed

smartdns作为tls服务端指派证书链,签发者证书被丢弃 #1324

PikuZheng opened this issue Mar 13, 2023 · 20 comments

Comments

@PikuZheng
Copy link
Contributor

问题现象
smartdns tls 服务作为 smartdns 的上游,服务端配置有效证书(阿里云购买)。其中主域名(common name)是www.(some domain).com,备用域名(subjet alt name)是(some domain).com。
域名注册商配置服务端IP指向(some domain).com(www.(some domain).com 指向其他的IP)。
客户端配置 server-tls (some domain).com:853 -tls-host-verify (some domain).com 时报错 verify failed
由于服务端使用nginx反代需要识别TLS SNI,不能将 -tls-host-verify 配置为 www.(some domain).com。

运行环境
无关

  1. smartdns来源以及版本
    最新版自编译

  2. 涉及的配置(注意去除个人相关信息)
    服务端

bind-tls [::]:853
bind-cert-file /etc/smartdns/cert.pem
bind-cert-key-file /etc/smartdns/cert.key
server ......

客户端

server-tls (some domain).com:853 -tls-host-verify (some domain).com

重现步骤

信息收集
日志

[2023-03-13 11:48:41,433][DEBUG][     dns_client.c:2913] tls server (ip) connected.
[2023-03-13 11:48:41,433][DEBUG][     dns_client.c:2918] new session
[2023-03-13 11:48:41,433][ WARN][     dns_client.c:2776] peer server  (ip)  certificate verify failed, ret = 20
[2023-03-13 11:48:41,433][ WARN][     dns_client.c:2777] peer CN: www.(some domain).com
[2023-03-13 11:48:41,433][ WARN][     dns_client.c:2927] peer  (ip)  verify failed.
[2023-03-13 11:48:41,434][DEBUG][     dns_client.c:1191] server  (ip)  closed.
@PikuZheng
Copy link
Contributor Author

#343 可能也是这个问题,服务端 subjet alt name 是通配符域名

@pymumu
Copy link
Owner

pymumu commented Mar 13, 2023

CN是IP地址吗?

@PikuZheng
Copy link
Contributor Author

common name 不能是IP,IP记录在subjet alt name中的IP Address=

@pymumu
Copy link
Owner

pymumu commented Mar 14, 2023

举个例子吧,访问域名,cn是什么

@PikuZheng
Copy link
Contributor Author

server-tls jpn2n.com:853 -tls-host-verify jpn2n.com
证书
Common Name=www.jpn2n.com
Subject Alt Name={
DNS=jpn2n.com
}

@pymumu
Copy link
Owner

pymumu commented Mar 14, 2023

错误码20:

X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate

the issuer certificate could not be found: this occurs if the issuer certificate of an untrusted certificate cannot be found.

@PikuZheng
Copy link
Contributor Author

错误码20:

X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate

the issuer certificate could not be found: this occurs if the issuer certificate of an untrusted certificate cannot be found.

怎么一夜之间问题更严重了?服务端也是smartdns的

@PikuZheng
Copy link
Contributor Author

换绑定口到835了。。。853会被打

@pymumu
Copy link
Owner

pymumu commented Mar 14, 2023

你给的那个log里面,错误码20
[2023-03-13 11:48:41,433][ WARN][ dns_client.c:2776] peer server (ip) certificate verify failed, ret = 20
这个表示证书不可信,可能你用了自签名证书,如果明确正确,那就要排除网络过程劫持问题。
或用SPKPIN

@PikuZheng
Copy link
Contributor Author

你给的那个log里面,错误码20
[2023-03-13 11:48:41,433][ WARN][ dns_client.c:2776] peer server (ip) certificate verify failed, ret = 20
这个表示证书不可信,可能你用了自签名证书,如果明确正确,那就要排除网络过程劫持问题。
或用SPKPIN

考虑这一行下面一行的错误,还是怀疑服务端用的subject alt name,但是只识别了common name。
证书证实是可信CA签发的,那个2777行正确识别出来Common name

@pymumu
Copy link
Owner

pymumu commented Mar 14, 2023

这个错误是openssl返回的。你最好用openssl命令远程链接下看看是否正常。

@pymumu
Copy link
Owner

pymumu commented Mar 14, 2023

还有,你本地的CA证书路径是否正确设置到smartdns中,最新代码增加了subject alt name的处理。
但你的问题,应该不是这个导致的。

@PikuZheng
Copy link
Contributor Author

更新后似乎无改善。
首先证实服务端证书正确

localhost:~# openssl s_client -showcerts -connect jpn2n.com:835 </dev/null 2>/dev/null | openssl x509 -noout -text | grep DNS:
                DNS:www.jpn2n.com, DNS:jpn2n.com

客户端报错行变化了,但内容没有变化

[2023-03-15 22:47:50,561][DEBUG][     dns_client.c:2969] tls server 45.32.229.227 connected.
[2023-03-15 22:47:50,561][DEBUG][     dns_client.c:2974] new session
[2023-03-15 22:47:50,561][ WARN][     dns_client.c:2836] peer server 45.32.229.227 certificate verify failed, unable to get local issuer certificate
[2023-03-15 22:47:50,561][ WARN][     dns_client.c:2838] peer CN: www.jpn2n.com
[2023-03-15 22:47:50,561][ WARN][     dns_client.c:2983] peer 45.32.229.227 verify failed.

证书是可信CA签发的,已经更新了本地 ca-certificates 包

@pymumu
Copy link
Owner

pymumu commented Mar 16, 2023

我说了,不是san问题

unable to get local issuer certificate

这个错误导致证书校验失败

看看本地证书安装是否正确吧

apt-get install ca-certificates

@pymumu
Copy link
Owner

pymumu commented Mar 16, 2023

curl https://jpn2n.com:835
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

感觉是服务端的证书问题

@PikuZheng
Copy link
Contributor Author

那么问题就变成,smartdns指定证书,但客户端报错的问题了。

@PikuZheng PikuZheng changed the title 不识别上游证书的 subjet alt name? smartdns作为tls服务端指派证书链,签发者证书被丢弃 Mar 16, 2023
@PikuZheng
Copy link
Contributor Author

localhost:~# openssl s_client -showcerts -connect jpn2n.com:835 </dev/null
CONNECTED(00000003)
depth=0 CN = www.jpn2n.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = www.jpn2n.com
verify error:num=21:unable to verify the first certificate
verify return:1
depth=0 CN = www.jpn2n.com
verify return:1

smartdns没有把这个证书作为证书链处理,而当成是CA证书了

@pymumu
Copy link
Owner

pymumu commented Mar 16, 2023

if (ssl_cert_file[0] != '\0' && SSL_CTX_use_certificate_file(ssl_ctx, ssl_cert_file, SSL_FILETYPE_PEM) <= 0) {

替换为

if (ssl_cert_file[0] != '\0' && SSL_CTX_use_certificate_chain_file(ssl_ctx, ssl_cert_file) <= 0) {

@pymumu
Copy link
Owner

pymumu commented Mar 16, 2023

还有一个修改验证点是,保留原有代码6671行,增加加载CA中介证书
用这个函数
SSL_CTX_use_certificate_chain_file

@PikuZheng
Copy link
Contributor Author

if (ssl_cert_file[0] != '\0' && SSL_CTX_use_certificate_file(ssl_ctx, ssl_cert_file, SSL_FILETYPE_PEM) <= 0) {

替换为

if (ssl_cert_file[0] != '\0' && SSL_CTX_use_certificate_chain_file(ssl_ctx, ssl_cert_file) <= 0) {

这个可行,一切都正常了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants