Skip to content

Commit

Permalink
tls support: dubbo/dubbo3/grpc protocol (#2073)
Browse files Browse the repository at this point in the history
* tls support for grpc protocol

* tls support for grpc protocol
  • Loading branch information
ZLBer authored Nov 8, 2022
1 parent bb20754 commit 9ca9bae
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 11 deletions.
8 changes: 8 additions & 0 deletions common/constant/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ const (
MaxServerRecvMsgSize = "max-server-recv-msg-size"
)

//tls constant
const (
TLSKey = "tls_key"
TLSCert = "tls_cert"
CACert = "ca_cert"
TLSServerNAME = "tls_server_name"
)

const (
ServiceFilterKey = "service.filter"
ReferenceFilterKey = "reference.filter"
Expand Down
9 changes: 5 additions & 4 deletions config/protocol_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ import (

// ProtocolConfig is protocol configuration
type ProtocolConfig struct {
Name string `default:"dubbo" validate:"required" yaml:"name" json:"name,omitempty" property:"name"`
Ip string `yaml:"ip" json:"ip,omitempty" property:"ip"`
Port string `default:"20000" yaml:"port" json:"port,omitempty" property:"port"`
Params interface{} `yaml:"params" json:"params,omitempty" property:"params"`
Name string `default:"dubbo" validate:"required" yaml:"name" json:"name,omitempty" property:"name"`
Ip string `yaml:"ip" json:"ip,omitempty" property:"ip"`
Port string `default:"20000" yaml:"port" json:"port,omitempty" property:"port"`
Params interface{} `yaml:"params" json:"params,omitempty" property:"params"`
TLSConfig *TLSConfig `yaml:"tls_config" json:"tls_config,omitempty" property:"tls_config"`
}

// Prefix dubbo.config-center
Expand Down
19 changes: 14 additions & 5 deletions config/reference_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,12 @@ type ReferenceConfig struct {
Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"`
invoker protocol.Invoker
urls []*common.URL
Generic string `yaml:"generic" json:"generic,omitempty" property:"generic"`
Sticky bool `yaml:"sticky" json:"sticky,omitempty" property:"sticky"`
RequestTimeout string `yaml:"timeout" json:"timeout,omitempty" property:"timeout"`
ForceTag bool `yaml:"force.tag" json:"force.tag,omitempty" property:"force.tag"`
TracingKey string `yaml:"tracing-key" json:"tracing-key,omitempty" propertiy:"tracing-key"`
Generic string `yaml:"generic" json:"generic,omitempty" property:"generic"`
Sticky bool `yaml:"sticky" json:"sticky,omitempty" property:"sticky"`
RequestTimeout string `yaml:"timeout" json:"timeout,omitempty" property:"timeout"`
ForceTag bool `yaml:"force.tag" json:"force.tag,omitempty" property:"force.tag"`
TracingKey string `yaml:"tracing-key" json:"tracing-key,omitempty" propertiy:"tracing-key"`
TLSConfig *TLSConfig `yaml:"tls_config" json:"tls_config,omitempty" property:"tls_config"`

rootConfig *RootConfig
metaDataType string
Expand Down Expand Up @@ -137,6 +138,14 @@ func (rc *ReferenceConfig) Refer(srv interface{}) {
common.WithParamsValue(constant.BeanNameKey, rc.id),
common.WithParamsValue(constant.MetadataTypeKey, rc.metaDataType),
)
//client tls client
if rc.TLSConfig != nil {
cfgURL.AddParam(constant.SslEnabledKey, "true")
cfgURL.AddParam(constant.TLSCert, rc.TLSConfig.TLSCertFile)
cfgURL.AddParam(constant.TLSKey, rc.TLSConfig.TLSKeyFile)
cfgURL.AddParam(constant.CACert, rc.TLSConfig.CACertFile)
cfgURL.AddParam(constant.TLSServerNAME, rc.TLSConfig.TLSServerName)
}

SetConsumerServiceByInterfaceName(rc.InterfaceName, srv)
if rc.ForceTag {
Expand Down
8 changes: 8 additions & 0 deletions config/service_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,14 @@ func (s *ServiceConfig) Export() error {
common.WithToken(s.Token),
common.WithParamsValue(constant.MetadataTypeKey, s.metadataType),
)
//server tls config
if proto.TLSConfig != nil {
ivkURL.AddParam(constant.SslEnabledKey, "true")
ivkURL.AddParam(constant.TLSCert, proto.TLSConfig.TLSCertFile)
ivkURL.AddParam(constant.TLSKey, proto.TLSConfig.TLSKeyFile)
ivkURL.AddParam(constant.CACert, proto.TLSConfig.CACertFile)
ivkURL.AddParam(constant.TLSServerNAME, proto.TLSConfig.TLSServerName)
}
if len(s.Tag) > 0 {
ivkURL.AddParam(constant.Tagkey, s.Tag)
}
Expand Down
93 changes: 93 additions & 0 deletions config/tls_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* 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 config

import (
"crypto/tls"
"crypto/x509"
"io/ioutil"
)

// TLSConfig tls config
type TLSConfig struct {
CACertFile string `yaml:"ca_cert_file" json:"ca_cert_file" property:"ca_cert_file"`
TLSCertFile string `yaml:"tls_cert_file" json:"tls_cert_file" property:"tls_cert_file"`
TLSKeyFile string `yaml:"tls_key_file" json:"tls_key_file" property:"tls_key_file"`
TLSServerName string `yaml:"tls_server_name" json:"tls_server_name" property:"tls_server_name"`
}

// GetServerTlsConfig build server tls config from TLSConfig
func GetServerTlsConfig(opt *TLSConfig) (*tls.Config, error) {
//no TLS
if opt.TLSCertFile == "" && opt.TLSKeyFile == "" {
return nil, nil
}
var ca *x509.CertPool
cfg := &tls.Config{}
//need mTLS
if opt.CACertFile != "" {
ca = x509.NewCertPool()
caBytes, err := ioutil.ReadFile(opt.CACertFile)
if err != nil {
return nil, err
}
if ok := ca.AppendCertsFromPEM(caBytes); !ok {
return nil, err
}
cfg.ClientAuth = tls.RequireAndVerifyClientCert
cfg.ClientCAs = ca
}
cert, err := tls.LoadX509KeyPair(opt.TLSCertFile, opt.TLSKeyFile)
if err != nil {
return nil, err
}
cfg.Certificates = []tls.Certificate{cert}
cfg.ServerName = opt.TLSServerName

return cfg, nil
}

// GetClientTlsConfig build client tls config from TLSConfig
func GetClientTlsConfig(opt *TLSConfig) (*tls.Config, error) {
//no TLS
if opt.CACertFile == "" {
return nil, nil
}
cfg := &tls.Config{
ServerName: opt.TLSServerName,
}
ca := x509.NewCertPool()
caBytes, err := ioutil.ReadFile(opt.CACertFile)
if err != nil {
return nil, err
}
if ok := ca.AppendCertsFromPEM(caBytes); !ok {
return nil, err
}
cfg.RootCAs = ca
//need mTls
if opt.TLSCertFile != "" {
var cert tls.Certificate
cert, err = tls.LoadX509KeyPair(opt.TLSCertFile, opt.TLSKeyFile)
if err != nil {
return nil, err
}
cfg.Certificates = []tls.Certificate{cert}
}
return cfg, err
}
17 changes: 16 additions & 1 deletion protocol/grpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import (
"github.com/opentracing/opentracing-go"

"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"

"gopkg.in/yaml.v2"
)
Expand Down Expand Up @@ -65,7 +67,6 @@ func NewClient(url *common.URL) (*Client, error) {
//connectTimeout := config.GetConsumerConfig().ConnectTimeout

dialOpts = append(dialOpts,
grpc.WithInsecure(),
grpc.WithBlock(),
// todo config network timeout
grpc.WithTimeout(time.Second*3),
Expand All @@ -77,6 +78,20 @@ func NewClient(url *common.URL) (*Client, error) {
grpc.MaxCallSendMsgSize(1024*1024*maxMessageSize),
),
)
if url.GetParam(constant.SslEnabledKey, "false") == "true" {
cfg, err := config.GetClientTlsConfig(&config.TLSConfig{
CACertFile: url.GetParam(constant.CACert, ""),
TLSCertFile: url.GetParam(constant.TLSCert, ""),
TLSKeyFile: url.GetParam(constant.TLSKey, ""),
TLSServerName: url.GetParam(constant.TLSServerNAME, ""),
})
if err != nil {
return nil, err
}
dialOpts = append(dialOpts, grpc.WithTransportCredentials(credentials.NewTLS(cfg)))
} else {
dialOpts = append(dialOpts, grpc.WithTransportCredentials(insecure.NewCredentials()))
}

conn, err := grpc.Dial(url.Location, dialOpts...)
if err != nil {
Expand Down
24 changes: 23 additions & 1 deletion protocol/grpc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package grpc

import (
"crypto/tls"
"fmt"
"net"
"sync"
Expand All @@ -32,11 +33,14 @@ import (
"github.com/opentracing/opentracing-go"

"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/reflection"
)

import (
"dubbo.apache.org/dubbo-go/v3/common"
"dubbo.apache.org/dubbo-go/v3/common/constant"
"dubbo.apache.org/dubbo-go/v3/config"
"dubbo.apache.org/dubbo-go/v3/protocol"
)
Expand Down Expand Up @@ -81,12 +85,30 @@ func (s *Server) Start(url *common.URL) {
// If global trace instance was set, then server tracer instance
// can be get. If not, will return NoopTracer.
tracer := opentracing.GlobalTracer()
server := grpc.NewServer(
var serverOpts []grpc.ServerOption
serverOpts = append(serverOpts,
grpc.UnaryInterceptor(otgrpc.OpenTracingServerInterceptor(tracer)),
grpc.StreamInterceptor(otgrpc.OpenTracingStreamServerInterceptor(tracer)),
grpc.MaxRecvMsgSize(1024*1024*s.bufferSize),
grpc.MaxSendMsgSize(1024*1024*s.bufferSize),
)

if url.GetParam(constant.SslEnabledKey, "false") == "true" {
var cfg *tls.Config
cfg, err = config.GetServerTlsConfig(&config.TLSConfig{
CACertFile: url.GetParam(constant.CACert, ""),
TLSCertFile: url.GetParam(constant.TLSCert, ""),
TLSKeyFile: url.GetParam(constant.TLSKey, ""),
TLSServerName: url.GetParam(constant.TLSServerNAME, ""),
})
if err != nil {
return
}
serverOpts = append(serverOpts, grpc.Creds(credentials.NewTLS(cfg)))
} else {
serverOpts = append(serverOpts, grpc.Creds(insecure.NewCredentials()))
}
server := grpc.NewServer(serverOpts...)
s.grpcServer = server

go func() {
Expand Down

0 comments on commit 9ca9bae

Please sign in to comment.