meshplus/bitxhub

json-rpc supports https

DiyiWi opened this issue · 1 comments

赛题5:网关接入中继链证书准入机制
在联盟链场景下,需要对接入的成员有相应的准入许可。在跨链场景下也是类似,网关代表应用链接入到跨链系统中时,必须获取到中继链联盟的许可,才可以获取相应的跨链交易数据。

解题思路:

  1. 增加准入机制时,主要涉及到两个部分:客户端SDK和中继链。跨链网关在中继模式启动时需要向中继链请求许可,中继链收到SDK/跨链网关的请求时,也必须检查相应的许可是否正确。这里许可机制一般采用证书来实现。
  1. 参考grpc-gateway-tls-server 实现方式:

./api/gateway/gateway.go

if config.Security.EnableTLS {
		g.certFile = filepath.Join(config.RepoRoot, config.Security.PemFilePath)
		g.keyFile = filepath.Join(config.RepoRoot, config.Security.ServerKeyPath)
		g.gatewayCertFile = filepath.Join(config.RepoRoot, config.Security.GatewayCertPath)
		g.gatewayKeyFile = filepath.Join(config.RepoRoot, config.Security.GatewayKeyPath)
		clientCaCert, _ := ioutil.ReadFile(g.certFile)
		clientCaCertPool := x509.NewCertPool()
		clientCaCertPool.AppendCertsFromPEM(clientCaCert)
		g.server = &http.Server{
			Addr:    fmt.Sprintf(":%d", config.Port.Gateway),
			Handler: wsproxy.WebsocketProxy(handler),
			TLSConfig: &tls.Config{
				//MinVersion: tls.VersionTLS12,
				ClientCAs:  clientCaCertPool,
				ClientAuth: tls.RequireAndVerifyClientCert,
			},
		}
	} else {
func (g *Gateway) Start() error {
	g.logger.WithField("port", g.config.Port.Gateway).Info("Gateway service started")
	if g.certFile != "" || g.keyFile != "" {
		cert, err := tls.LoadX509KeyPair(g.gatewayCertFile, g.gatewayKeyFile)
		cred := credentials.NewTLS(&tls.Config{
			Certificates: []tls.Certificate{cert}, InsecureSkipVerify: true})

		conn, err := grpc.DialContext(g.ctx, g.endpoint, grpc.WithTransportCredentials(cred))
		if err != nil {
			return err
		}
		err = pb.RegisterChainBrokerHandler(g.ctx, g.mux, conn)
		if err != nil {
			return err
		}

		go func() {
			err := g.server.ListenAndServeTLS(g.certFile, g.keyFile)
			if err != nil {
				g.logger.Error(err)
			}
		}()

  1. 在jsonrpc服务下,添加TLS配置

./api/jsonrpc/broker.go

func (cbs *ChainBrokerService) Start() error {
	router := mux.NewRouter()
	router.Handle("/", cbs.server)

	go func() {
		cbs.logger.WithFields(logrus.Fields{
			"port": cbs.config.Port.JsonRpc,
		}).Info("JSON-RPC service started")

		if err := http.ListenAndServe(fmt.Sprintf(":%d", cbs.config.Port.JsonRpc), router); err != nil {
			cbs.logger.WithFields(logrus.Fields{
				"error": err.Error(),
			}).Error("Failed to start JSON_RPC service")
			return
		}
	}()

	return nil
}