title: go-go-micro安全tls
categories: Go
tags: [go, 微服務, tls, 安全]
date: 2019-10-11 17:42:57
comments: false
go-go-micro安全tls
前篇
a
內置的 tls 證書
是用 micro 默認的 tls 非常簡單, 只需要 transport.Secure(true)
即可
func main() {
service := micro.NewService(
...
micro.Transport(
transport.NewTransport(
transport.Secure(true),
),
),
)
}
自定義 tls 證書
參考: https://studygolang.com/articles/15331
生成 CA 根證書
爲了保證證書的可靠性和有效性,在這裏可引入 CA 頒發的根證書的概念。其遵守 X.509 標準
根證書(root certificate)是屬於根證書頒發機構(CA)的公鑰證書。我們可以通過驗證 CA 的簽名從而信任 CA ,任何人都可以得到 CA 的證書(含公鑰),用以驗證它所簽發的證書(客戶端、服務端)
-
生成 Key:
ca.key
$ openssl genrsa -out ca.key 2048
-
生成密鑰:
ca.pem
$ openssl req -new -x509 -days 7200 -key ca.key -out ca.pem Country Name (2 letter code) [AU]:aa // // 填一堆信息 State or Province Name (full name) [Some-State]:bb Locality Name (eg, city) []:cc Organization Name (eg, company) [Internet Widgits Pty Ltd]:dd Organizational Unit Name (eg, section) []:ee Common Name (e.g. server FQDN or YOUR name) []:ff Email Address []:gg
生成 Server 證書
-
生成 Key:
server.key
$ openssl ecparam -genkey -name secp384r1 -out server.key
-
生成 CSR:
server.csr
$ openssl req -new -key server.key -out server.csr Country Name (2 letter code) [AU]:aa // 填一堆信息 State or Province Name (full name) [Some-State]:bb Locality Name (eg, city) []:cc Organization Name (eg, company) [Internet Widgits Pty Ltd]:dd Organizational Unit Name (eg, section) []:ee Common Name (e.g. server FQDN or YOUR name) []:ff Email Address []:gg Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:helloworld An optional company name []:aa
-
生成 ip 白名單文件:
extfile.cnf
$ echo subjectAltName = IP:192.168.1.190 > extfile.cnf
-
extfile.cnf
文件內容subjectAltName = IP:192.168.1.190
如果有多個 ip,用
,
分割subjectAltName = IP:192.168.1.191,IP:192.168.1.190,IP:192.168.1.192
-
-
基於 CA 簽發:
server.pem
$ openssl x509 -req -sha256 -CA ca.pem -CAkey ca.key -CAcreateserial -days 3650 -in server.csr -out server.pem -extfile extfile.cnf Signature ok subject=C = aa, ST = bb, L = cc, O = dd, OU = ee, CN = ff, emailAddress = gg Getting CA Private Key
- 如果少了訪問的 ip 白名單文件 (
-extfile extfile.cnf
) , 客戶端請求報錯:doesn't contain any IP SANs
- 如果少了訪問的 ip 白名單文件 (
最後生成一堆東西
├─conf
│ ca.key
│ ca.pem
│ ca.srl
│ extfile.cnf
│ server.csr
│ server.key
│ server.pem
代碼
參考: test_secure_tls
客戶端 和 服務器 都是用相同的證書即可 server.pem
, server.key
server
func loadTlsConfig() *tls.Config {
cert, err := tls.LoadX509KeyPair("../conf/server.pem", "../conf/server.key")
if err != nil {
log.Fatalf("tls.LoadX509KeyPair err: %v", err)
}
certPool := x509.NewCertPool()
ca, err := ioutil.ReadFile("../conf/ca.pem")
if err != nil {
log.Fatalf("ioutil.ReadFile err: %v", err)
}
if ok := certPool.AppendCertsFromPEM(ca); !ok {
log.Fatalf("certPool.AppendCertsFromPEM err")
}
tlsCfg := &tls.Config{
Certificates: []tls.Certificate{cert},
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: certPool,
InsecureSkipVerify: false,
}
return tlsCfg
}
func main() {
service := micro.NewService(
...
micro.Transport(
transport.NewTransport(
transport.TLSConfig(loadTlsConfig()),
),
),
)
}
client
func loadTlsConfig() *tls.Config {
cert, err := tls.LoadX509KeyPair("../conf/server.pem", "../conf/server.key")
if err != nil {
log.Fatalf("tls.LoadX509KeyPair err: %v", err)
}
certPool := x509.NewCertPool()
ca, err := ioutil.ReadFile("../conf/ca.pem")
if err != nil {
log.Fatalf("ioutil.ReadFile err: %v", err)
}
if ok := certPool.AppendCertsFromPEM(ca); !ok {
log.Fatalf("certPool.AppendCertsFromPEM err")
}
tlsCfg := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: certPool,
InsecureSkipVerify: false,
}
return tlsCfg
}
func init() {
client.DefaultClient.Init(
client.Transport(
transport.NewTransport(
transport.TLSConfig(loadTlsConfig()),
),
),
)
}
func main() {
cl := hello.NewSayService("go.micro.srv.greeter", client.DefaultClient)
rsp, err := cl.Hello(context.TODO(), &hello.Request{
Name: "John",
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println("--- recv srv, msg:", rsp.Msg)
}
踩坑
-
客戶端請求報錯:
doesn't contain any IP SANs
參考: https://codeday.me/bug/20190105/485233.html
是因爲 [生成 Server 證書](#生成 Server 證書) 中的 第4步 中沒有指定可訪問的 ip 白名單文件. (
-extfile extfile.cnf
)