The cause of

Question 1

RPC error: code = Unavailable DESC = Connection error: desc = "Transport: authentication Handshake failed: X509: certificate is not validforAny names, but wanted to match XXX"Copy the code

This is because GRPC has not been connected for a long time, restart can be

Question 2

Normal self-signed certificates on Golang 1.15 + use gRPC TLS to report an error

rpc error: rpc error: code = Unavailable desc = connection error: desc = "transport: authentication handshake failed: x509: certificate is not valid for any names, but wanted to match SANs"
Copy the code

You need to turn on something called a SAN extension, otherwise there’s no way to link

1. Create a CA private key (root certificate)

openssl genrsa -out ca.key 4096
Copy the code

2. Create a conf to generate the CSR (request signing certificate file)

touch ca.conf
vi ca.conf
Copy the code

Writing a CONF file

CommonName_default: If there is a domain name, write the domain name and localhost

[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name

[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CN
stateOrProvinceName = State or Province Name (2 letter code)
stateOrProvinceName_default = Shanghai
localityName = Locality Name (eg, city)
localityName_default = Shanghai
organizationName = Organization Name (eg, company)
organizationName_default = nsqk.com
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
commonName_default = localhost
Copy the code

Generating a CSR File

openssl req \
-new \
-sha256 \
-out ca.csr \
-key ca.key \
-config ca.conf
Copy the code

3. Generate the CRT certificate file

openssl x509 \
-req \
-days 365 \
-in ca.csr \
-signkey ca.key \
-out ca.crt
Copy the code

4. Generate the server certificate

The new server.conf commonName_default client matches this field

[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name

[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CN
stateOrProvinceName = State or Province Name (2 letter code)
stateOrProvinceName_default = Shanghai
localityName = Locality Name (eg, city)
localityName_default = Shanghai
organizationName = Organization Name (eg, company)
organizationName_default = nsqk.com
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
commonName_default = localhost
[ req_ext ]
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP  = 127.0.0.1
Copy the code

Generate server. The key

openssl genrsa -out server.key 2048
Copy the code

Generate server. The CSR

openssl req \
-new \
-sha256 \
-out server.csr \
-key server.key \
-config server.conf
Copy the code

Generate server. The CRT/pem

openssl x509 \
-req \
-days 365 \
-CA ca.crt \
-CAkey ca.key \
-CAcreateserial \
-in server.csr \
-out server.pem \
-extensions req_ext \
-extfile server.conf
Copy the code

Generate the client. The key

openssl ecparam -genkey -name secp384r1 -out client.key
Copy the code

Generate the client. The CSR

openssl req -new -key client.key -out client.csr -config server.conf
Copy the code

Generate client. Pem

openssl x509 -req -sha256 -CA ca.pem -CAkey ca.key -CAcreateseria
l -days 3650 -in client.csr -out client.pem -extensions req_ext -extfile server.conf
Copy the code

5. GRPC use

The server side

// Use TLS to load the key pair
	cert, err := tls.LoadX509KeyPair("cert/server.pem"."cert/server.key")
	iferr ! =nil {
		log.Println("TLS failed to load X509 certificate", err)
	}
	// Create a certificate pool
	certPool := x509.NewCertPool()

	// Add a certificate to the certificate pool
	cafileBytes, err := ioutil.ReadFile("cert/ca.pem")
	iferr ! =nil {
		log.Println("Failed to read ca.pem certificate", err)
	}
	// Load the client certificate
	//certPool.AddCert()

	// Load the certificate from the pem file
	certPool.AppendCertsFromPEM(cafileBytes)

	// Create the Credentials object
	creds := credentials.NewTLS(&tls.Config{
		Certificates: []tls.Certificate{cert},        // Server certificate
		ClientAuth:   tls.RequireAndVerifyClientCert, // The client certificate is required and verified
		ClientCAs:    certPool,                       // Client certificate pool

	})

	lis, err := net.Listen("tcp".": 2333")
	iferr ! =nil {
		fmt.Println("Listening on port failed to err:", err)
	}
	s := grpc.NewServer(grpc.Creds(creds))
	services.RegisterHelloWorldServer(s, new(services.HelloService))

	reflection.Register(s)

	err = s.Serve(lis)
	fmt.Println("gRPC starting")
	iferr ! =nil {
		fmt.Println("Failed to start GRPC err:", err)
	} else {
		fmt.Println("gRPC started")}Copy the code

The client side

// Create a certificate pool as on the server
	cert, err := tls.LoadX509KeyPair("cert/client.pem"."cert/client.key")
	iferr! =nil{
		log.Println("Failed to load client PEM key",err)
	}

	certPool := x509.NewCertPool()
	caFile ,err :=  ioutil.ReadFile("cert/ca.pem")
	iferr! =nil{
		log.Println("Failed to load ca",err)
	}
	certPool.AppendCertsFromPEM(caFile)

	creds := credentials.NewTLS(&tls.Config{
		Certificates: []tls.Certificate{cert},// Add the client certificate
		ServerName: "localhost".// commonName in the certificate
		RootCAs: certPool, / / certificates pool
	})

	conn, err := grpc.Dial(": 2333", grpc.WithTransportCredentials(creds))
	iferr ! =nil {
		log.Fatal(err)
	}
	defer conn.Close()

	client := services.NewHelloWorldClient(conn)
	replay, err := client.HelloRPC(context.Background(), &services.SayHelloRequest{
		Name: "hello world name",})iferr ! =nil {
		fmt.Println("rpc error:", err)
	} else {
		fmt.Println("result message :", replay.Message)
	}
Copy the code