-
Notifications
You must be signed in to change notification settings - Fork 436
/
backend.go
130 lines (113 loc) · 3.91 KB
/
backend.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
125
126
127
128
129
130
package main
import (
"crypto/tls"
"crypto/x509"
"io/ioutil"
"github.com/mwitkow/grpc-proxy/proxy"
"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
var (
flagBackendHostPort = pflag.String(
"backend_addr",
"",
"A host:port (IP or hostname) of the gRPC server to forward it to.")
flagBackendIsUsingTls = pflag.Bool(
"backend_tls",
false,
"Whether the gRPC server of the backend is serving in plaintext (false) or over TLS (true).",
)
flagBackendTlsNoVerify = pflag.Bool(
"backend_tls_noverify",
false,
"Whether to ignore TLS verification checks (cert validity, hostname). *DO NOT USE IN PRODUCTION*.",
)
flagBackendTlsClientCert = pflag.String(
"backend_client_tls_cert_file",
"",
"Path to the PEM certificate used when the backend requires client certificates for TLS.")
flagBackendTlsClientKey = pflag.String(
"backend_client_tls_key_file",
"",
"Path to the PEM key used when the backend requires client certificates for TLS.")
flagMaxCallRecvMsgSize = pflag.Int(
"backend_max_call_recv_msg_size",
1024*1024*4, // The current maximum receive msg size per https://github.com/grpc/grpc-go/blob/v1.8.2/server.go#L54
"Maximum receive message size limit. If not specified, the default of 4MB will be used.",
)
flagBackendTlsCa = pflag.StringSlice(
"backend_tls_ca_files",
[]string{},
"Paths (comma separated) to PEM certificate chains used for verification of backend certificates. If empty, host CA chain will be used.",
)
flagBackendDefaultAuthority = pflag.String(
"backend_default_authority",
"",
"Default value to use for the HTTP/2 :authority header commonly used for routing gRPC calls through a backend gateway.",
)
flagBackendBackoffMaxDelay = pflag.Duration(
"backend_backoff_max_delay",
grpc.DefaultBackoffConfig.MaxDelay,
"Maximum delay when backing off after failed connection attempts to the backend.",
)
)
func dialBackendOrFail() *grpc.ClientConn {
if *flagBackendHostPort == "" {
logrus.Fatalf("flag 'backend_addr' must be set")
}
opt := []grpc.DialOption{}
opt = append(opt, grpc.WithCodec(proxy.Codec()))
if *flagBackendDefaultAuthority != "" {
opt = append(opt, grpc.WithAuthority(*flagBackendDefaultAuthority))
}
if *flagBackendIsUsingTls {
opt = append(opt, grpc.WithTransportCredentials(credentials.NewTLS(buildBackendTlsOrFail())))
} else {
opt = append(opt, grpc.WithInsecure())
}
opt = append(opt,
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(*flagMaxCallRecvMsgSize)),
grpc.WithBackoffMaxDelay(*flagBackendBackoffMaxDelay),
)
cc, err := grpc.Dial(*flagBackendHostPort, opt...)
if err != nil {
logrus.Fatalf("failed dialing backend: %v", err)
}
return cc
}
func buildBackendTlsOrFail() *tls.Config {
tlsConfig := &tls.Config{}
tlsConfig.MinVersion = tls.VersionTLS12
if *flagBackendTlsNoVerify {
tlsConfig.InsecureSkipVerify = true
} else {
if len(*flagBackendTlsCa) > 0 {
tlsConfig.RootCAs = x509.NewCertPool()
for _, path := range *flagBackendTlsCa {
data, err := ioutil.ReadFile(path)
if err != nil {
logrus.Fatalf("failed reading backend CA file %v: %v", path, err)
}
if ok := tlsConfig.RootCAs.AppendCertsFromPEM(data); !ok {
logrus.Fatalf("failed processing backend CA file %v", path)
}
}
}
}
if *flagBackendTlsClientCert != "" || *flagBackendTlsClientKey != "" {
if *flagBackendTlsClientCert == "" {
logrus.Fatal("flag 'backend_client_tls_cert_file' must be set when 'backend_client_tls_key_file' is set")
}
if *flagBackendTlsClientKey == "" {
logrus.Fatal("flag 'backend_client_tls_key_file' must be set when 'backend_client_tls_cert_file' is set")
}
cert, err := tls.LoadX509KeyPair(*flagBackendTlsClientCert, *flagBackendTlsClientKey)
if err != nil {
logrus.Fatalf("failed reading TLS client keys: %v", err)
}
tlsConfig.Certificates = append(tlsConfig.Certificates, cert)
}
return tlsConfig
}