Skip to content

Commit 2e0779d

Browse files
authored
feat: add TLS for gRPC server endpoint (#477)
1 parent dd90d1e commit 2e0779d

File tree

4 files changed

+519
-5
lines changed

4 files changed

+519
-5
lines changed

cmd/server.go

+30-4
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import (
5555
"github.com/spf13/cobra"
5656
"golang.org/x/oauth2"
5757
"google.golang.org/grpc"
58+
"google.golang.org/grpc/credentials"
5859
"google.golang.org/grpc/credentials/insecure"
5960
"google.golang.org/grpc/metadata"
6061
"google.golang.org/grpc/reflection"
@@ -98,6 +99,10 @@ func createServerCmd(execer fakeruntime.Execer, httpServer server.HTTPServer) (c
9899

99100
// gc related flags
100101
flags.IntVarP(&opt.gcPercent, "gc-percent", "", 100, "The GC percent of Go")
102+
//grpc_tls
103+
flags.BoolVarP(&opt.tls, "tls-grpc", "", false, "Enable TLS mode. Set to true to enable TLS. Alow SAN certificates")
104+
flags.StringVarP(&opt.tlsCert, "cert-file", "", "","The path to the certificate file, Alow SAN certificates")
105+
flags.StringVarP(&opt.tlsKey, "key-file", "", "", "The path to the key file, Alow SAN certificates")
101106

102107
c.Flags().MarkHidden("dry-run")
103108
c.Flags().MarkHidden("gc-percent")
@@ -139,6 +144,9 @@ type serverOption struct {
139144

140145
// inner fields, not as command flags
141146
provider oauth.OAuthProvider
147+
tls bool
148+
tlsCert string
149+
tlsKey string
142150
}
143151

144152
func (o *serverOption) preRunE(cmd *cobra.Command, args []string) (err error) {
@@ -170,7 +178,15 @@ func (o *serverOption) preRunE(cmd *cobra.Command, args []string) (err error) {
170178

171179
grpcOpts = append(grpcOpts, oauth.NewAuthInterceptor(o.oauthGroup))
172180
}
173-
181+
if o.tls {
182+
if o.tlsCert != "" && o.tlsKey != "" {
183+
creds, err := credentials.NewServerTLSFromFile(o.tlsCert, o.tlsKey)
184+
if err != nil {
185+
return fmt.Errorf("failed to load credentials: %v", err)
186+
}
187+
grpcOpts = append(grpcOpts, grpc.Creds(creds))
188+
}
189+
}
174190
if o.dryRun {
175191
o.gRPCServer = &fakeGRPCServer{}
176192
} else {
@@ -269,9 +285,19 @@ func (o *serverOption) runE(cmd *cobra.Command, args []string) (err error) {
269285
gRPCServerAddr := fmt.Sprintf("127.0.0.1:%s", gRPCServerPort)
270286

271287
mux := runtime.NewServeMux(runtime.WithMetadata(server.MetadataStoreFunc))
272-
err = errors.Join(
273-
server.RegisterRunnerHandlerFromEndpoint(ctx, mux, gRPCServerAddr, []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}),
274-
server.RegisterMockHandlerFromEndpoint(ctx, mux, gRPCServerAddr, []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}))
288+
if o.tls {
289+
creds,err:=credentials.NewClientTLSFromFile(o.tlsCert,"localhost")
290+
if err!=nil{
291+
return fmt.Errorf("failed to load credentials: %v", err)
292+
}
293+
err = errors.Join(
294+
server.RegisterRunnerHandlerFromEndpoint(ctx, mux, gRPCServerAddr, []grpc.DialOption{grpc.WithTransportCredentials(creds)}),
295+
server.RegisterMockHandlerFromEndpoint(ctx, mux, gRPCServerAddr, []grpc.DialOption{grpc.WithTransportCredentials(creds)}))
296+
}else{
297+
err = errors.Join(
298+
server.RegisterRunnerHandlerFromEndpoint(ctx, mux, gRPCServerAddr, []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}),
299+
server.RegisterMockHandlerFromEndpoint(ctx, mux, gRPCServerAddr, []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}))
300+
}
275301
if err == nil {
276302
mux.HandlePath(http.MethodGet, "/", frontEndHandlerWithLocation(o.consolePath))
277303
mux.HandlePath(http.MethodGet, "/assets/{asset}", frontEndHandlerWithLocation(o.consolePath))

docs/grpc-TLS.md

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# gRPC TLS verification
2+
3+
If you want to enable gRPC TLS, you need to generate your certificates in the workspace, or you can use an absolute path
4+
5+
**1. 生成私钥**
6+
7+
```shell
8+
openssl genrsa -out server.key 2048
9+
```
10+
11+
**2. 生成证书(会提示即可,不必填写)**
12+
13+
```shell
14+
openssl req -new -x509 -key server.key -out server.crt -days 36500
15+
国家名字
16+
Country Name (2 letter code) [AU]:CN
17+
省份全名
18+
State or Province Name (full name) [Some-State]:GuangDong
19+
城市名
20+
Locality Name (eg, city) []:Meizhou
21+
组织名
22+
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Xuexiangban
23+
组织单位名
24+
Organizational Unit Name (eg, section) []:go
25+
服务器or用户的名字
26+
Common Name (e.g. server FQDN or YOUR name) []:kuangstudy
27+
邮箱地址
28+
Email Address []:[email protected]
29+
```
30+
31+
**3.生成csr**
32+
33+
```shell
34+
openssl req -new -key server.key -out server.csr
35+
```
36+
37+
**4.配置openssl.cfg**
38+
39+
```shell
40+
1) 查找openssl在服务器的安装目录并且找到openssl.cnf
41+
2) 编辑[ CA_default ] ,打开 copy_extensions = copy #取消注释
42+
3) 找到[ req ],打开 req_extensions = v3.req #取消注释
43+
4) 找到[ v3_req ],添加字段 subjectAltName = @alt_names
44+
5) 添加新的标签在最底部 [ alt_names ]和标签字段
45+
DNS.1 = localhost
46+
```
47+
48+
**5.生成本地私钥test.key**
49+
50+
```shell
51+
openssl genpkey -algorithm RSA -out test.key
52+
```
53+
54+
**6.根据私钥生成csr请求文件test.csr**
55+
56+
```shell
57+
openssl req -new -nodes -key test.key -out test.csr -days 3650 \
58+
-subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" \
59+
-config ./openssl.cnf -extensions v3_req
60+
```
61+
62+
**7.生成ca证书 pem**
63+
64+
```shell
65+
openssl x509 -req -days 365 -in test.csr \
66+
-out test.pem -CA server.crt -CAkey server.key \
67+
-CAcreateserial -extfile ./openssl.cnf -extensions v3_req
68+
```
69+

e2e/entrypoint.sh

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,30 @@
11
#!/bin/bash
22
set -e
33

4+
SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
45
mkdir -p /root/.config/atest
56
mkdir -p /var/data
7+
cd "/var/data"
8+
# Generate private key
9+
openssl genrsa -out server.key 2048
10+
# Generate self-signed certificate
11+
openssl req -new -x509 -key server.key -out server.crt -days 36500 \
12+
-subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com"
13+
# Generate Certificate Signing Request (CSR)
14+
openssl req -new -key server.key -out server.csr \
15+
-subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com"
16+
# Generate a new private key
17+
openssl genpkey -algorithm RSA -out test.key
18+
# Generate a new CSR
19+
openssl req -new -nodes -key test.key -out test.csr -days 3650 \
20+
-subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" \
21+
-config "$SCRIPT_DIR/openssl.cnf" -extensions v3_req
22+
# Sign the new CSR with the self-signed certificate
23+
openssl x509 -req -days 365 -in test.csr \
24+
-out test.pem -CA server.crt -CAkey server.key \
25+
-CAcreateserial -extfile "$SCRIPT_DIR/openssl.cnf" -extensions v3_req
626

7-
nohup atest server&
27+
nohup atest server --tls-grpc --cert-file /var/data/test.pem --key-file /var/data/test.key&
828
cmd="atest run -p test-suite-common.yaml --report github --report-github-identity e2e-testing --report-file /var/data/report.json --report-github-repo linuxsuren/api-testing --report-github-pr ${PULL_REQUEST:-0}"
929

1030
echo "start to run testing: $cmd"

0 commit comments

Comments
 (0)