我已经多次更改了服务器和客户端上的端口号,但服务器总是收到错误的端口号。
当我执行客户端时,服务器将记录此信息:
2017/05/07 15:06:07 grpc: Server.Serve failed to complete security handshake from "127.0.0.1:32763": remote error: tls: bad certificate
在客户端,我得到了这个:
2017/05/07 15:06:07 Failed to dial localhost:8070: connection error: desc = "transport: x509: certificate is not valid for any names, but wanted to match localhost:8070"; please retry.
rpc error: code = Internal desc = connection error: desc = "transport: x509: certificate is not valid for any names, but wanted to match localhost:8070"
我有这个代码用于server.go
func serve() {
addr := "localhost:8070"
crt, key := certificate.CreatePemKey()
certificate, err := tls.X509KeyPair(crt, key)
if err != nil {
fmt.Println(err)
}
certPool := x509.NewCertPool()
ca, err := ioutil.ReadFile("F:/GIAG3.crt")
if err != nil {
fmt.Println(err)
}
if ok := certPool.AppendCertsFromPEM(ca); !ok {
fmt.Println("unable to append certificate")
}
lis, err := net.Listen("tcp", addr)
if err != nil {
fmt.Println("could not list on %s: %s", addr, err)
}
// Create the TLS credentials
creds := credentials.NewTLS(&tls.Config{
ClientAuth: tls.RequireAndVerifyClientCert,
Certificates: []tls.Certificate{certificate},
ClientCAs: certPool,
})
srv := grpc.NewServer(grpc.Creds(creds))
pb.RegisterPingerServer(srv, &server{})
if err := srv.Serve(lis); err != nil {
fmt.Println("grpc serve error: %s", err)
}
}
这是针对client.go
func testDial2() {
addr := "localhost:8070"
crt, key := certificate.CreatePemKey()
certificate, err := tls.X509KeyPair(crt, key)
if err != nil {
fmt.Println(err)
}
certPool := x509.NewCertPool()
ca, err := ioutil.ReadFile("F:/GIAG3.crt")
if err != nil {
fmt.Println(err)
}
if ok := certPool.AppendCertsFromPEM(ca); !ok {
fmt.Println("unable to append certificate")
}
creds := credentials.NewTLS(&tls.Config{
ServerName: addr,
Certificates: []tls.Certificate{certificate},
RootCAs: certPool,
})
conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(creds))
if err != nil {
fmt.Println(err)
}
defer conn.Close()
c := pb.NewPingerClient(conn)
r, err := c.Ping(context.Background(), &pb.Payload{Message: "Ping"})
if err != nil {
fmt.Println(err)
}
log.Printf("%s", r.Message)
}
这是针对CreatePemKey的,它基于此示例https://golang.org/src/crypto/tls/generate_cert.go
func publicKey(priv interface{}) interface{} {
switch k := priv.(type) {
case *rsa.PrivateKey:
return &k.PublicKey
case *ecdsa.PrivateKey:
return &k.PublicKey
default:
return nil
}
}
func pemBlockForKey(priv interface{}) *pem.Block {
switch k := priv.(type) {
case *rsa.PrivateKey:
return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
case *ecdsa.PrivateKey:
b, err := x509.MarshalECPrivateKey(k)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to marshal ECDSA private key: %v", err)
os.Exit(2)
}
return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
default:
return nil
}
}
func CreatePemKey() (certpem, keypem []byte) {
priv, _ := rsa.GenerateKey(rand.Reader, 2048)
notBefore := time.Now()
notAfter := notBefore.AddDate(1, 0, 0)
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, _ := rand.Int(rand.Reader, serialNumberLimit)
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"Acme Co"},
},
NotBefore: notBefore,
NotAfter: notAfter,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}
// template.IPAddresses = append(template.IPAddresses, net.ParseIP("localhost"))
template.IsCA = true
derbytes, _ := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)
certpem = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derbytes})
keypem = pem.EncodeToMemory(pemBlockForKey(priv))
return certpem, keypem
}
BTW GIAG3.crt来自这里https://pki.goog/
请帮助我,谢谢
答案 0 :(得分:0)
如果您在journalctl -u docker
中找到了此日志:
mai 29 10:33:04 ca275nt dockerd[1523]: time="2019-05-29T10:33:04.454362399-03:00" level=warning msg="grpc: Server.Serve failed to complete security handshake from \"192.168.0.45:58392\": remote error: tls: bad certificate" module=grpc
这可能与另一个群集集群节点主机发出的docker swarm
请求试图使用无效令牌连接到docker swarm主节点有关。
您可以使用以下方法发现无效的群集节点主机名:
nslookup 192.168.0.45
45.0.168.192.in-addr.arpa name = hostabc.domain.com.
45.0.168.192.in-addr.arpa name = hostabc.
Authoritative answers can be found from:
通过在报告的主机上运行docker swarm leave
,解决此问题。
我知道这与主要问题无关,但是我在搜索:
docker "grpc: Server.Serve failed to complete security handshake from"
,这是第一个问题。那么我认为将疑难解答放在这里很有用,以节省其他时间。