You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ti...@apache.org on 2021/08/11 04:29:36 UTC

[servicecomb-kie] branch master updated: Feature: support tls (#195)

This is an automated email from the ASF dual-hosted git repository.

tianxiaoliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-kie.git


The following commit(s) were added to refs/heads/master by this push:
     new 5252092  Feature: support tls (#195)
5252092 is described below

commit 52520923f3d6b5015bc2c9e3c4655de1c662e6d6
Author: little-cui <su...@qq.com>
AuthorDate: Wed Aug 11 12:29:33 2021 +0800

    Feature: support tls (#195)
---
 examples/dev/kie-conf.yaml                 |  3 ++
 examples/dev/ssl/cert_pwd                  |  1 +
 examples/dev/ssl/server.cer                | 13 ++++++
 examples/dev/ssl/server_key.pem            | 18 ++++++++
 examples/dev/ssl/trust.cer                 | 13 ++++++
 go.mod                                     |  2 +-
 go.sum                                     |  2 +
 server/datasource/etcd/init.go             |  1 +
 server/datasource/mongo/session/session.go |  5 ++-
 server/datasource/options.go               | 15 ++++---
 server/datasource/tlsutil/tlsutil.go       | 36 +++++++++-------
 server/datasource/tlsutil/tlsutil_test.go  | 67 ++++++++++++++++++++++++++++++
 12 files changed, 152 insertions(+), 24 deletions(-)

diff --git a/examples/dev/kie-conf.yaml b/examples/dev/kie-conf.yaml
index 58e806c..7f57ab2 100644
--- a/examples/dev/kie-conf.yaml
+++ b/examples/dev/kie-conf.yaml
@@ -9,6 +9,9 @@ db:
   timeout: 5m
   sslEnabled: false
   rootCAFile: /opt/kie/ca.crt
+  certFile: /opt/kie/server.cer
+  keyFile: /opt/kie/server_key.pem
+  certPwdFile: /opt/kie/cert_pwd
 rbac:
   enabled: false
   rsaPublicKeyFile: ./examples/dev/public.key
\ No newline at end of file
diff --git a/examples/dev/ssl/cert_pwd b/examples/dev/ssl/cert_pwd
new file mode 100644
index 0000000..0a783b7
--- /dev/null
+++ b/examples/dev/ssl/cert_pwd
@@ -0,0 +1 @@
+Changeme_123
\ No newline at end of file
diff --git a/examples/dev/ssl/server.cer b/examples/dev/ssl/server.cer
new file mode 100644
index 0000000..c29eb6a
--- /dev/null
+++ b/examples/dev/ssl/server.cer
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIICATCCAWoCCQDmvlmfua/ThTANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
+VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
+cyBQdHkgTHRkMB4XDTE3MTIwNTA5MzA0NloXDTE4MTIwNTA5MzA0NlowRTELMAkG
+A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
+IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtu5H
+L8mlCL6n+BrQ71eJgJJJ427/DgovzHBqLTYuk/It987wNJFmTMgdWRXHujwe4bFt
+G78d7OJteXcR7a68sIxWrytWeAwG88M62duS+DCUke1YuQ6hrfIADvE2ZgYEuVxz
+5UxOTYYIjtSxCGKDuxmlvkJgO6lE0zIhtFxz1WcCAwEAATANBgkqhkiG9w0BAQsF
+AAOBgQCq89sMPmhVS5+Mh+FvnNC9qOnsnqWhyAEc5XEmqtCTAe1XpO3CvPH7DdHz
+Ss0FVqpBRqmxUR0sQo6t/S0kW7uwDgjm7nIy67wtTLOLclYW2Yw+d3ApwBVMhVBp
+yhDpV90YZF7QM9uhdsEgLpbTqs4hvPB1pUWH6oXdtjnEkp6lFQ==
+-----END CERTIFICATE-----
diff --git a/examples/dev/ssl/server_key.pem b/examples/dev/ssl/server_key.pem
new file mode 100644
index 0000000..c0b907e
--- /dev/null
+++ b/examples/dev/ssl/server_key.pem
@@ -0,0 +1,18 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-128-CBC,22C64A026937643A490027AC7931D19A
+
+FdV2dDDn5l767Ulha9IMxiwvyMu6BziFCjXbfsHB1aHdBfuFWV8uJ5lEYiWPWdj3
+QIeK79QH8i6N0n2f1VfXtW7RJKS+6Gg9m1dttxGXY/6sEIkFJRPiWrNrzeHaXAoI
+38CBZli2nvtZMLo8oBj/iuQ0qlkh00Mm2RW1SgJx2I6FJZLS8xb9kKUhPL/SlBYd
+EboWXpKtubg5DhvQd8MKIaTJDf3L1Iqc7OMnLs64ONvfylYy39uv8yGsimHNItQh
+ylHjUhmqOjCwnogO1Nh2wsjQCODRPEJzpu2fJ1lb2+xqwbTg3ygVwzLoK2ScXND4
+DIo8YOa9jBCR9/Yg1IzqOIUD+UzQWhBqDejMHVXAGQb5e2AldLdFnGwx1Yz4FCIl
+nULP8lcMDeYRK0sS4N5/I4nqfvlVPyj96Nj4F3D68Q8oQXl1rTSbKXmWILxIIlHm
+tBf+NA16p9A9TegHr/qn3L3NRCxyY7gLwL+cNG2uZ9NqmxnSmWhL9UQgWYPeGr8Z
+Z9nqqshfzIMoBjZ4QP1pifKhEvb0w2MpjKtiAR3hmwn8SJDp7CPTlb7nm5e5fjZb
+nkzsTXYaJiYYiuEjiIsxJY/6ptWeYq9kqTT/3Hmy0MdkcqeDbcLwqo6jbAJxcPFf
+C0SCJ+woIZJeHpZZjmH/qsZUKq2UEDsLqGruNMDzxarmme67lwPIDG2pZ90EIcNx
+BR0ZU4owv9N+dO2sFsMNHae9X8mHWynUJ2V3ISxshvS3WJmq+YkeYTjYljeIZ28x
++UBhUrmikzx/CrIFd9irnkVhPIqJ+uUZEiMNEnT7VxCpHZHDU+ujweChUzaLkh0x
+-----END RSA PRIVATE KEY-----
diff --git a/examples/dev/ssl/trust.cer b/examples/dev/ssl/trust.cer
new file mode 100644
index 0000000..8fb3139
--- /dev/null
+++ b/examples/dev/ssl/trust.cer
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIICATCCAWoCCQCu7pAj81WabjANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
+VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
+cyBQdHkgTHRkMB4XDTE3MTIwNTA5MTMzNVoXDTE4MTIwNTA5MTMzNVowRTELMAkG
+A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
+IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyDpT
+In6x3H0HEGOXzJMByOnvzD4rL0B4wyE9K2Nng0Ev0pS0dlPQK67fZJ6e2KDcA72d
+dSps61YQ6tWnBbssCZat0qI2g3Kh4wKgEoCv/0Wm9J+c9gHO9VXyRd91FkJNFDB4
+Lsh4EF4kMVsdLfvP98LkQQAfjg621Yqa1bEu5RUCAwEAATANBgkqhkiG9w0BAQsF
+AAOBgQCbURtlhZMNUN8W2EQJVqgEbZmtNriI1VpKvfU4b8d05PwaoL3qV8tx6p5/
+2p/+diRH8XWkPMm0Ix+c7752ebWSVb8WoQL40ZBd4PIuy6RlS7/45VeMUk7LvxBG
+iPXnB72OzQmBiPhVNiINVumQWJ62NPlbYaJsG/WsZdaWYMDeww==
+-----END CERTIFICATE-----
diff --git a/go.mod b/go.mod
index 30eab51..6a9b868 100644
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,7 @@ require (
 	github.com/coreos/etcd v3.3.25+incompatible
 	github.com/emicklei/go-restful v2.12.0+incompatible
 	github.com/go-chassis/cari v0.5.0
-	github.com/go-chassis/foundation v0.3.1-0.20210806081520-3bd92d1ef787
+	github.com/go-chassis/foundation v0.3.1-0.20210811025651-7f4d2b2b906c
 	github.com/go-chassis/go-archaius v1.5.2-0.20210301074935-e4694f6b077b
 	github.com/go-chassis/go-chassis/v2 v2.2.1-0.20210810140748-7274d2228000
 	github.com/go-chassis/openlog v1.1.3
diff --git a/go.sum b/go.sum
index fd83238..96a03cc 100644
--- a/go.sum
+++ b/go.sum
@@ -178,6 +178,8 @@ github.com/go-chassis/foundation v0.3.1-0.20210602072914-a580bed505d0 h1:bWvRZc0
 github.com/go-chassis/foundation v0.3.1-0.20210602072914-a580bed505d0/go.mod h1:6NsIUaHghTFRGfCBcZN011zl196F6OR5QvD9N+P4oWU=
 github.com/go-chassis/foundation v0.3.1-0.20210806081520-3bd92d1ef787 h1:XWbUjex+ge+rnmSeNumU+oRewcscXWLvcfGNFEtlK0o=
 github.com/go-chassis/foundation v0.3.1-0.20210806081520-3bd92d1ef787/go.mod h1:6NsIUaHghTFRGfCBcZN011zl196F6OR5QvD9N+P4oWU=
+github.com/go-chassis/foundation v0.3.1-0.20210811025651-7f4d2b2b906c h1:6ooUyysnayGgoJHV++NLEcnnnXzsw3ud4VydjISGBqI=
+github.com/go-chassis/foundation v0.3.1-0.20210811025651-7f4d2b2b906c/go.mod h1:6NsIUaHghTFRGfCBcZN011zl196F6OR5QvD9N+P4oWU=
 github.com/go-chassis/go-archaius v1.3.6-0.20201210061741-7450779aaeb8/go.mod h1:j8vJX5c455N0cN5rzeC1dm9T5kyOI8ZvIjaSJ+rZjwc=
 github.com/go-chassis/go-archaius v1.4.0/go.mod h1:j8vJX5c455N0cN5rzeC1dm9T5kyOI8ZvIjaSJ+rZjwc=
 github.com/go-chassis/go-archaius v1.5.0/go.mod h1:QPwvvtBxvwiC48rmydoAqxopqOr93RCQ6syWsIkXPXQ=
diff --git a/server/datasource/etcd/init.go b/server/datasource/etcd/init.go
index ef48f85..fdd7596 100644
--- a/server/datasource/etcd/init.go
+++ b/server/datasource/etcd/init.go
@@ -21,6 +21,7 @@ import (
 	"crypto/tls"
 	"fmt"
 
+	// support embedded etcd
 	_ "github.com/little-cui/etcdadpt/embedded"
 	_ "github.com/little-cui/etcdadpt/remote"
 
diff --git a/server/datasource/mongo/session/session.go b/server/datasource/mongo/session/session.go
index fc9dc99..94a4ce9 100644
--- a/server/datasource/mongo/session/session.go
+++ b/server/datasource/mongo/session/session.go
@@ -20,6 +20,7 @@ package session
 
 import (
 	"context"
+	"crypto/tls"
 	"errors"
 	"reflect"
 	"strings"
@@ -31,7 +32,6 @@ import (
 	"github.com/apache/servicecomb-kie/server/datasource"
 	"github.com/apache/servicecomb-kie/server/datasource/tlsutil"
 	"github.com/go-chassis/openlog"
-
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/bson/bsoncodec"
 	"go.mongodb.org/mongo-driver/mongo"
@@ -91,7 +91,8 @@ func Init(c *datasource.Config) error {
 		uri := cipherutil.TryDecrypt(c.URI)
 		clientOps := []*options.ClientOptions{options.Client().ApplyURI(uri)}
 		if c.SSLEnabled {
-			tc, err := tlsutil.Config(c)
+			var tc *tls.Config
+			tc, err = tlsutil.Config(c)
 			if err != nil {
 				return
 			}
diff --git a/server/datasource/options.go b/server/datasource/options.go
index 60e53fa..05f2653 100644
--- a/server/datasource/options.go
+++ b/server/datasource/options.go
@@ -22,12 +22,15 @@ import (
 )
 
 type Config struct {
-	URI        string        `yaml:"uri"`
-	PoolSize   int           `yaml:"poolSize"`
-	SSLEnabled bool          `yaml:"sslEnabled"`
-	RootCA     string        `yaml:"rootCAFile"`
-	Timeout    time.Duration `yaml:"timeout"`
-	VerifyPeer bool          `yaml:"verifyPeer"`
+	URI         string        `yaml:"uri"`
+	PoolSize    int           `yaml:"poolSize"`
+	SSLEnabled  bool          `yaml:"sslEnabled"`
+	VerifyPeer  bool          `yaml:"verifyPeer"`
+	RootCA      string        `yaml:"rootCAFile"`
+	CertFile    string        `yaml:"certFile"`
+	KeyFile     string        `yaml:"keyFile"`
+	CertPwdFile string        `yaml:"certPwdFile"`
+	Timeout     time.Duration `yaml:"timeout"`
 }
 
 //NewDefaultFindOpts return default options
diff --git a/server/datasource/tlsutil/tlsutil.go b/server/datasource/tlsutil/tlsutil.go
index 8ced719..d857dad 100644
--- a/server/datasource/tlsutil/tlsutil.go
+++ b/server/datasource/tlsutil/tlsutil.go
@@ -19,33 +19,39 @@ package tlsutil
 
 import (
 	"crypto/tls"
-	"crypto/x509"
 	"errors"
-	"fmt"
 	"io/ioutil"
 
+	"github.com/apache/servicecomb-kie/pkg/cipherutil"
 	"github.com/apache/servicecomb-kie/server/datasource"
+	"github.com/go-chassis/foundation/stringutil"
+	"github.com/go-chassis/foundation/tlsutil"
 	"github.com/go-chassis/openlog"
 )
 
 var ErrRootCAMissing = errors.New("rootCAFile is empty in config file")
 
 func Config(c *datasource.Config) (*tls.Config, error) {
+	var password string
+	if c.CertPwdFile != "" {
+		pwdBytes, err := ioutil.ReadFile(c.CertPwdFile)
+		if err != nil {
+			openlog.Error("read cert password file failed: " + err.Error())
+			return nil, err
+		}
+		password = cipherutil.TryDecrypt(stringutil.Bytes2str(pwdBytes))
+	}
 	if c.RootCA == "" {
 		openlog.Error(ErrRootCAMissing.Error())
 		return nil, ErrRootCAMissing
 	}
-	pool := x509.NewCertPool()
-	caCert, err := ioutil.ReadFile(c.RootCA)
-	if err != nil {
-		openlog.Error(fmt.Sprintf("read ca cert file %s failed", caCert))
-		return nil, err
-	}
-	pool.AppendCertsFromPEM(caCert)
-	// #nosec
-	tc := &tls.Config{
-		RootCAs:            pool,
-		InsecureSkipVerify: !c.VerifyPeer,
-	}
-	return tc, nil
+	opts := append(tlsutil.DefaultClientTLSOptions(),
+		tlsutil.WithVerifyPeer(c.VerifyPeer),
+		tlsutil.WithVerifyHostName(false),
+		tlsutil.WithKeyPass(password),
+		tlsutil.WithCA(c.RootCA),
+		tlsutil.WithCert(c.CertFile),
+		tlsutil.WithKey(c.KeyFile),
+	)
+	return tlsutil.GetClientTLSConfig(opts...)
 }
diff --git a/server/datasource/tlsutil/tlsutil_test.go b/server/datasource/tlsutil/tlsutil_test.go
new file mode 100644
index 0000000..3e7c962
--- /dev/null
+++ b/server/datasource/tlsutil/tlsutil_test.go
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tlsutil_test
+
+import (
+	"testing"
+
+	_ "github.com/go-chassis/go-chassis/v2/security/cipher/plugins/plain"
+
+	"github.com/apache/servicecomb-kie/server/datasource"
+	"github.com/apache/servicecomb-kie/server/datasource/tlsutil"
+	"github.com/go-chassis/go-archaius"
+	"github.com/go-chassis/go-chassis/v2/security/cipher"
+	"github.com/stretchr/testify/assert"
+)
+
+const sslRoot = "./../../../examples/dev/ssl/"
+
+func init() {
+	archaius.Init()
+	cipher.Init()
+}
+
+func TestConfig(t *testing.T) {
+	t.Run("normal scene, should return ok", func(t *testing.T) {
+		cfg, err := tlsutil.Config(&datasource.Config{
+			RootCA:      sslRoot + "trust.cer",
+			CertFile:    sslRoot + "server.cer",
+			KeyFile:     sslRoot + "server_key.pem",
+			CertPwdFile: sslRoot + "cert_pwd",
+			VerifyPeer:  false,
+		})
+		assert.NoError(t, err)
+		assert.NotNil(t, cfg)
+	})
+	t.Run("without ca file, should return false", func(t *testing.T) {
+		cfg, err := tlsutil.Config(&datasource.Config{})
+		assert.ErrorIs(t, tlsutil.ErrRootCAMissing, err)
+		assert.Nil(t, cfg)
+	})
+	t.Run("set not exist pwd file, should return false", func(t *testing.T) {
+		cfg, err := tlsutil.Config(&datasource.Config{
+			RootCA:      sslRoot + "trust.cer",
+			CertFile:    sslRoot + "server.cer",
+			KeyFile:     sslRoot + "server_key.pem",
+			CertPwdFile: sslRoot + "xxx",
+			VerifyPeer:  false,
+		})
+		assert.Error(t, err)
+		assert.Nil(t, cfg)
+	})
+}