-
Notifications
You must be signed in to change notification settings - Fork 47
/
setup.go
124 lines (101 loc) · 3.56 KB
/
setup.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT License was not distributed with this
// file, you can obtain one at https://opensource.org/licenses/MIT.
//
// Copyright (c) DUSK NETWORK. All rights reserved.
// This package represents the GRPC server exposing functions to interoperate
// with the node components as well as the wallet
package server
import (
"os"
"time"
"github.com/dusk-network/dusk-blockchain/pkg/config"
"github.com/dusk-network/dusk-protobuf/autogen/go/node"
"github.com/sirupsen/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
var log = logrus.WithField("process", "grpc_s")
// Setup is a configuration struct to setup the GRPC with.
type Setup struct {
SessionDurationMins uint
RequireSession bool
EnableTLS bool
CertFile string
KeyFile string
Network string
Address string
}
// FromCfg creates a Setup from the configuration. This is handy when a
// configuration should be used (i.e. outside of tests).
func FromCfg() Setup {
rpc := config.Get().RPC
return Setup{
SessionDurationMins: rpc.SessionDurationMins,
CertFile: rpc.CertFile,
KeyFile: rpc.KeyFile,
Network: rpc.Network,
Address: rpc.Address,
RequireSession: rpc.RequireSession,
}
}
// SetupGRPC will create a new gRPC server with the correct authentication
// and TLS settings. This server can then be used to register services.
// Note that the server still needs to be turned on (`Serve`).
func SetupGRPC(conf Setup) (*grpc.Server, error) {
// creating the JWT token manager
jwtMan, err := NewJWTManager(time.Duration(conf.SessionDurationMins) * time.Minute)
if err != nil {
return nil, err
}
if conf.Network == "unix" {
// Remove obsolete unix socket file
_ = os.Remove(conf.Address)
}
// Add default interceptors to provide jwt-based session authentication and error logging
// for both unary and stream RPC calls
serverOpt := make([]grpc.ServerOption, 0)
// Enable TLS if configured
opt, tlsVer := loadTLSFiles(conf.EnableTLS, conf.CertFile, conf.KeyFile, conf.Network)
if opt != nil {
serverOpt = append(serverOpt, opt)
}
log.WithField("tls", tlsVer).Info("HTTP server TLS configured")
grpc.EnableTracing = false
if conf.RequireSession {
// instantiate the auth service and the interceptor
auth, authInterceptor := NewAuth(jwtMan)
// serverOpt = append(serverOpt, grpc.StreamInterceptor(streamInterceptor))
serverOpt = append(serverOpt, grpc.UnaryInterceptor(authInterceptor.Unary()))
grpcServer := grpc.NewServer(serverOpt...)
// hooking up the Auth service
node.RegisterAuthServer(grpcServer, auth)
return grpcServer, nil
}
return grpc.NewServer(serverOpt...), nil
}
func loadTLSFiles(enable bool, certFile, keyFile, network string) (grpc.ServerOption, string) {
tlsVersion := "disabled"
if !enable {
if network != "unix" {
// Running gRPC over tcp would require TLS
log.Warn("running over insecure HTTP")
}
return nil, tlsVersion
}
creds, err := credentials.NewServerTLSFromFile(certFile, keyFile)
if err != nil {
// If TLS is explicitly enabled, any error here should cause panic
log.WithError(err).Panic("could not enable TLS")
}
i := creds.Info()
if i.SecurityProtocol == "ssl" {
log.WithError(err).Panic("SSL is insecure")
}
recommendedVer := "1.3"
if i.SecurityVersion != recommendedVer { //nolint
log.Warnf("Recommended TLS version is %s", recommendedVer)
}
tlsVersion = i.SecurityVersion //nolint
return grpc.Creds(creds), tlsVersion
}