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

bug: 3.7.0 版本通过apisix-dashboard 创建的证书,会报找不到SNI #2915

Open
lan11 opened this issue Dec 25, 2023 · 11 comments
Open

Comments

@lan11
Copy link

lan11 commented Dec 25, 2023

Current Behavior

通过apisix-dashboard 页面导入证书(泛域名证书),会保找不到对应域名SNI, 将证书内容复制出来,通过 http://127.0.0.1:9180/apisix/admin/ssls/1 导入,可以正常使用. 同时发现版本下降到3.6.0 ,上述dashboard 页面操作没有发现该问题

Expected Behavior

No response

Error Logs

[error] 48#48: 737 [lua] init.lua:213: http_ssl_client_hello_phase(): failed to match any SSL certificate by SNI: test.ydact.cn, context: ssl_client_hello_by_lua, client: 192.168.205.100, server: 0.0.0.0:443

Steps to Reproduce

1.运行docker
2.通过dashboard 页面导入泛域名证书
3.访问域名会报错,查看apisix日志会报找到证书SNI
4.将证书通过管理接口导入,访问域名正常
5.将apisix版本下降到3.6.0.页面导入证书,访问网站正常

Environment

docker 运行 apache/apisix:3.7.0-debian 和 apache/apisix-dashboard:3.0.1-alpine,bitnami/etcd:3.4.15

@shreemaan-abhishek
Copy link

please use english in your issue description and title.

@shreemaan-abhishek shreemaan-abhishek added the wait for update 1. Solution 2. Due date 3. Assignees if needed label Dec 26, 2023
@hanqingwu
Copy link

i have reproduce , i will try to debug it .

@hanqingwu
Copy link

hanqingwu commented Dec 27, 2023

i get the root cause, because apisix v3.7.0 remove validity_end and validity_start
apache/apisix#10323

so if you import ssl cert at apisix v3.6.0 then ssl cert save to etcd contain properties : validity_end and validity_start .
but when you upgrade to 3.7.0 , it load config from etcd will report err like this ,

2023/12/27 08:39:23 [error] 87#87: *14 [lua] config_etcd.lua:520: load_full_data(): failed to check item data of [/apisix/ssls] err:additional properties forbidden, found validity_end ,val:

so i suggest you reimport ssl cert at apisix v3.7.0 and make sure no properties validity_end and validity_start store in etcd.
@lan11

@shreemaan-abhishek shreemaan-abhishek removed the wait for update 1. Solution 2. Due date 3. Assignees if needed label Dec 29, 2023
@shreemaan-abhishek
Copy link

shreemaan-abhishek commented Dec 29, 2023

@hanqingwu thanks for the insight. @lan11 could you please check if the above solution helps?

@shreemaan-abhishek shreemaan-abhishek transferred this issue from apache/apisix Jan 23, 2024
@jzin-v2
Copy link

jzin-v2 commented Feb 2, 2024

Hope to identify in all> = 3.7 documents

@xuelangos
Copy link

apisix 3.2.0 and 3.2.2,dashboard 3.0.1 have same question。
Causing business to go down all。

@xuruidong
Copy link

apache/apisix#10233

@johnxiaohe
Copy link

can we support this change? The question is how to make it compatible with 3.7 and below or launch a new version?

@fatihusta
Copy link

Here is quick fix.
This patch compatible with new apisix ssls api endpoint.

Tested with apisix-3.9.1

diff -waur a/api/internal/handler/ssl/ssl.go b/api/internal/handler/ssl/ssl.go
--- a/api/internal/handler/ssl/ssl.go	2023-03-24 03:11:19.000000000 +0300
+++ b/api/internal/handler/ssl/ssl.go	2024-05-23 19:49:51.161372590 +0300
@@ -198,6 +198,9 @@
 	for _, item := range ret.Rows {
 		ssl := &entity.SSL{}
 		_ = utils.ObjectClone(item, ssl)
+		x509_validity, _ := x509CertValidity(ssl.Cert)
+		ssl.ValidityStart = x509_validity.NotBefore
+		ssl.ValidityEnd = x509_validity.NotAfter
 		ssl.Key = ""
 		ssl.Keys = nil
 		list = append(list, ssl)
@@ -327,6 +330,35 @@
 	return nil, nil
 }

+// validity allows unmarshaling the certificate validity date range
+type validity struct {
+	NotBefore, NotAfter int64
+}
+
+func x509CertValidity(crt string) (*validity, error) {
+	if crt == "" {
+		return nil, consts.ErrSSLCertificate
+	}
+
+	certDERBlock, _ := pem.Decode([]byte(crt))
+	if certDERBlock == nil {
+		return nil, consts.ErrSSLCertificateResolution
+	}
+
+	x509Cert, err := x509.ParseCertificate(certDERBlock.Bytes)
+
+	if err != nil {
+		return nil, consts.ErrSSLCertificateResolution
+	}
+
+	val := validity{}
+
+	val.NotBefore = x509Cert.NotBefore.Unix()
+	val.NotAfter = x509Cert.NotAfter.Unix()
+
+	return &val, nil
+}
+
 func ParseCert(crt, key string) (*entity.SSL, error) {
 	if crt == "" || key == "" {
 		return nil, consts.ErrSSLCertificate
@@ -383,8 +415,6 @@

 	ssl.Snis = snis
 	ssl.Key = key
-	ssl.ValidityStart = x509Cert.NotBefore.Unix()
-	ssl.ValidityEnd = x509Cert.NotAfter.Unix()
 	ssl.Cert = crt

 	return &ssl, nil
@@ -424,6 +454,10 @@
 		return nil, err
 	}

+	x509_validity, _ := x509CertValidity(input.Cert)
+	ssl.ValidityStart = x509_validity.NotBefore
+	ssl.ValidityEnd = x509_validity.NotAfter
+
 	return ssl, nil
 }

@wangchao732
Copy link

Here is quick fix. This patch compatible with new apisix ssls api endpoint.

Tested with apisix-3.9.1

diff -waur a/api/internal/handler/ssl/ssl.go b/api/internal/handler/ssl/ssl.go
--- a/api/internal/handler/ssl/ssl.go	2023-03-24 03:11:19.000000000 +0300
+++ b/api/internal/handler/ssl/ssl.go	2024-05-23 19:49:51.161372590 +0300
@@ -198,6 +198,9 @@
 	for _, item := range ret.Rows {
 		ssl := &entity.SSL{}
 		_ = utils.ObjectClone(item, ssl)
+		x509_validity, _ := x509CertValidity(ssl.Cert)
+		ssl.ValidityStart = x509_validity.NotBefore
+		ssl.ValidityEnd = x509_validity.NotAfter
 		ssl.Key = ""
 		ssl.Keys = nil
 		list = append(list, ssl)
@@ -327,6 +330,35 @@
 	return nil, nil
 }

+// validity allows unmarshaling the certificate validity date range
+type validity struct {
+	NotBefore, NotAfter int64
+}
+
+func x509CertValidity(crt string) (*validity, error) {
+	if crt == "" {
+		return nil, consts.ErrSSLCertificate
+	}
+
+	certDERBlock, _ := pem.Decode([]byte(crt))
+	if certDERBlock == nil {
+		return nil, consts.ErrSSLCertificateResolution
+	}
+
+	x509Cert, err := x509.ParseCertificate(certDERBlock.Bytes)
+
+	if err != nil {
+		return nil, consts.ErrSSLCertificateResolution
+	}
+
+	val := validity{}
+
+	val.NotBefore = x509Cert.NotBefore.Unix()
+	val.NotAfter = x509Cert.NotAfter.Unix()
+
+	return &val, nil
+}
+
 func ParseCert(crt, key string) (*entity.SSL, error) {
 	if crt == "" || key == "" {
 		return nil, consts.ErrSSLCertificate
@@ -383,8 +415,6 @@

 	ssl.Snis = snis
 	ssl.Key = key
-	ssl.ValidityStart = x509Cert.NotBefore.Unix()
-	ssl.ValidityEnd = x509Cert.NotAfter.Unix()
 	ssl.Cert = crt

 	return &ssl, nil
@@ -424,6 +454,10 @@
 		return nil, err
 	}

+	x509_validity, _ := x509CertValidity(input.Cert)
+	ssl.ValidityStart = x509_validity.NotBefore
+	ssl.ValidityEnd = x509_validity.NotAfter
+
 	return ssl, nil
 }

Do you mean for me to use apisix version 3.9.1?

@fatihusta
Copy link

Do you mean for me to use apisix version 3.9.1?

No, I only tested with 3.9.1. But I think this patch also can be works with apisix-3.6 or new versions.
Apply this patch apisix-dashboard and compile new apisix-dashboard. Remove old certificates and re-add using dashboard.

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

9 participants