-
Notifications
You must be signed in to change notification settings - Fork 43
/
tls.go
150 lines (135 loc) · 3.93 KB
/
tls.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package database
import (
"crypto/tls"
"crypto/x509"
"errors"
"os"
"github.com/go-sql-driver/mysql"
"github.com/pilinux/gorest/config"
)
// InitTLSMySQL registers a custom tls.Config
//
// Tutorial: How to configure MySQL instance and enable TLS support
//
// 1.0 generate CA's private key and certificate
//
// to omit password: `-nodes -keyout`
//
// `openssl req -x509 -sha512 -newkey rsa:4096 -days 10950 -keyout ca-key.pem -out ca.pem`
//
// 2.0 generate web server's private key and certificate signing request (CSR)
//
// to omit password: `-nodes -keyout`
//
// Common Name (e.g. server FQDN or YOUR name) must be different for CA and web server certificates
//
// `openssl req -sha512 -newkey rsa:4096 -nodes -keyout server-key.pem -out server-req.pem`
//
// 2.1 config file
//
// IP: server's public or local IPs of the interfaces
//
// `echo "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:172.17.0.1,IP:x.x.x.x,IP:y.y.y.y" > "server-ext.cnf"`
//
// 2.2 use CA's private key to sign web server's CSR and get back the signed certificate
//
// `openssl x509 -sha512 -req -in server-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile server-ext.cnf`
//
// 2.3 verify the certificate
//
// `openssl verify -CAfile ca.pem server-cert.pem`
//
// 3.0 convert PKCS#8 format key into PKCS#1 format
//
// `openssl rsa -in server-key.pem -out server-key.pem`
//
// 4.0 replace existing files located at /var/lib/mysql
//
// 5.0 set ownership and r/w permissions
//
// ```bash
// sudo chown -R mysql:mysql ca-key.pem ca.pem server-key.pem server-cert.pem
// sudo chmod -R 600 ca-key.pem server-key.pem
// sudo chmod -R 644 ca.pem server-cert.pem
// ```
//
// 6.0 restart mysql service
//
// `sudo service mysql restart`
//
// 7.0 optional:
//
// 7.1 generate client's private key and certificate signing request (CSR)
//
// `openssl req -sha512 -newkey rsa:4096 -nodes -keyout client-key.pem -out client-req.pem`
//
// 7.2 config file
//
// IP: server's public or local IPs of the interfaces
//
// `echo "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:172.17.0.1,IP:x.x.x.x,IP:y.y.y.y" > "client-ext.cnf"`
//
// 7.3 use CA's private key to sign client's CSR and get back the signed certificate
//
// `openssl x509 -sha512 -req -in client-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -extfile client-ext.cnf`
//
// 7.4 verify the certificate
//
// `openssl verify -CAfile ca.pem client-cert.pem`
//
// 7.5 convert PKCS#8 format key into PKCS#1 format
//
// `openssl rsa -in client-key.pem -out client-key.pem`
func InitTLSMySQL() (err error) {
configureDB := config.GetConfig().Database.RDBMS
minTLS := configureDB.Ssl.MinTLS
rootCA := configureDB.Ssl.RootCA
serverCert := configureDB.Ssl.ServerCert
clientCert := configureDB.Ssl.ClientCert
clientKey := configureDB.Ssl.ClientKey
rootCertPool := x509.NewCertPool()
var pem []byte
if rootCA != "" {
pem, err = os.ReadFile(rootCA)
if err != nil {
return
}
} else {
if serverCert == "" {
err = errors.New("missing server certificate")
return
}
pem, err = os.ReadFile(serverCert)
if err != nil {
return
}
}
if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
err = errors.New("failed to parse PEM encoded certificates")
return
}
tlsConfig := tls.Config{}
tlsConfig.MinVersion = tls.VersionTLS12 // default: TLS 1.2
if minTLS == "1.1" {
tlsConfig.MinVersion = tls.VersionTLS11
}
if minTLS == "1.2" {
tlsConfig.MinVersion = tls.VersionTLS12
}
if minTLS == "1.3" {
tlsConfig.MinVersion = tls.VersionTLS13
}
tlsConfig.RootCAs = rootCertPool
if clientCert != "" && clientKey != "" {
clientCertificate := make([]tls.Certificate, 0, 1)
var certs tls.Certificate
certs, err = tls.LoadX509KeyPair(clientCert, clientKey)
if err != nil {
return
}
clientCertificate = append(clientCertificate, certs)
tlsConfig.Certificates = clientCertificate
}
err = mysql.RegisterTLSConfig("custom", &tlsConfig)
return
}