I tried to test gRPC communication with mTLS, but the following error occurred.
error message
grpc._channel._MultiThreadedRendezvous: <_MultiThreadedRendezvous of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = "failed to connect to all addresses"
debug_error_string = "{"created":"@1659422447.426000000","description":"Failed to pick subchannel","file":"src/core/ext/filters/client_channel/client_channel.cc","file_line":3151,"referenced_errors":[{"created":"@1659422447.426000000","description":"failed to connect to all addresses","file":"src/core/lib/transport/error_utils.cc","file_line":165,"grpc_status":14}]}"
I run the server.py on my server, and then use the client.py to try to connect on localhost.
The following information may be useful:
When I run the same client.py in the same network environment(just on the same server), I can connect to the server.py .
I make sure that the server network environment is unblocked and the port(5060) is open to connetion.I even shut down the firewall.
The gRPC without mTLS from localhost to my server is successful. Just this gRPC with mTLS failed.
I unseted the http/https proxy.
"sample.com" is the domain name of the server. I have added it to the hosts file.
I run the same server.py on another server, and I can connect to it on localhost with the same client.py.So I guess there is something wrong with my server,but I don't konw what it is on details.
I use "export GRPC_VERBOSITY=debug" "export GRPC_TRACE=all" to get more error message.
The following is some potentially useful pieces of debug information I intercepted
I0802 15:57:33.591844400 125 tcp_posix.cc:699] READ 0x7f62cc018920 (peer=ipv4:[MYHOST]:5060) error={"created":"@1659427053.591576600","description":"Socket closed","fd":5,"file":"src/core/lib/iomgr/tcp_posix.cc","file_line":796,"grpc_status":14,"target_address":"ipv4:[MYHOST]:5060"}
D0802 15:57:33.592397300 125 security_handshaker.cc:181] Security handshake failed: {"created":"@1659427053.592378500","description":"Handshake read failed","file":"src/core/lib/security/transport/security_handshaker.cc","file_line":466,"referenced_errors":[{"created":"@1659427053.591576600","description":"Socket closed","fd":5,"file":"src/core/lib/iomgr/tcp_posix.cc","file_line":796,"grpc_status":14,"target_address":"ipv4:[MYHOST]:5060"}]}
I0802 15:57:33.593177800 125 handshaker.cc:93] handshake_manager 0x7f62cc007510: error={"created":"@1659427053.592378500","description":"Handshake read failed","file":"src/core/lib/security/transport/security_handshaker.cc","file_line":466,"referenced_errors":[{"created":"@1659427053.591576600","description":"Socket closed","fd":5,"file":"src/core/lib/iomgr/tcp_posix.cc","file_line":796,"grpc_status":14,"target_address":"ipv4:[MYHOST]:5060"}]} shutdown=0 index=3, args={endpoint=(nil), args=(nil) {size=0: {}}, read_buffer=(nil) (length=0), exit_early=0}
I0802 15:57:33.593884200 125 handshaker.cc:126] handshake_manager 0x7f62cc007510: handshaking complete -- scheduling on_handshake_done with error={"created":"@1659427053.592378500","description":"Handshake read failed","file":"src/core/lib/security/transport/security_handshaker.cc","file_line":466,"referenced_errors":[{"created":"@1659427053.591576600","description":"Socket closed","fd":5,"file":"src/core/lib/iomgr/tcp_posix.cc","file_line":796,"grpc_status":14,"target_address":"ipv4:[MYHOST]:5060"}]}
I0802 15:57:33.594520400 125 timer_generic.cc:447] TIMER 0x7f62cc007578: CANCEL pending=true
I0802 15:57:33.595084000 125 subchannel.cc:956] subchannel 0x7f62cc006c10 {address=ipv4:[MYHOST]:5060, args={grpc.client_channel_factory=0x12fd870, grpc.default_authority=sample.com:5060,
grpc.http2_scheme=https, grpc.internal.channel_credentials=0x10cc3e0, grpc.internal.security_connector=0x7f62cc002230, grpc.internal.subchannel_pool=0x131c430, grpc.max_receive_message_length=536870912, grpc.primary_user_agent=grpc-python/1.47.0, grpc.resource_quota=0x12b9020, grpc.server_uri=dns:///sample.com:5060}}: connect failed ({"created":"@1659427053.592378500","description":"Handshake read failed","file":"src/core/lib/security/transport/security_handshaker.cc","file_line":466,"referenced_errors":[{"created":"@1659427053.591576600","description":"Socket closed","fd":5,"file":"src/core/lib/iomgr/tcp_posix.cc","file_line":796,"grpc_status":14,"target_address":"ipv4:[MYHOST]:5060"}]}), backing off for 847 ms
- The following is the source code of the client.py, server.py and the process of generating SSL certificate
server.py
import time
from concurrent import futures
from helloworld_pb2 import *
from helloworld_pb2_grpc import *
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
class Greeter(GreeterServicer):
def SayHello(self, request, context):
return HelloReply(message='Hello, %s!' % request.name)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
add_GreeterServicer_to_server(Greeter(), server)
with open('server.key', 'rb') as f:
private_key = f.read()
with open('server.crt', 'rb') as f:
certificate_chain = f.read()
with open('ca.crt', 'rb') as f:
root_certificates = f.read()
server_credentials = grpc.ssl_server_credentials(((private_key, certificate_chain),), root_certificates,True)
server.add_secure_port('[::]:5060', server_credentials)
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
serve()
client.py
from __future__ import print_function
from helloworld_pb2 import *
from helloworld_pb2_grpc import *
def run():
with open('client.key', 'rb') as f:
private_key = f.read()
with open('client.crt', 'rb') as f:
certificate_chain = f.read()
with open('ca.crt', 'rb') as f:
root_certificates = f.read()
creds = grpc.ssl_channel_credentials(root_certificates, private_key, certificate_chain)
channel = grpc.secure_channel('sample.com:5060', creds)
stub = GreeterStub(channel)
response = stub.SayHello(HelloRequest(name='world'))
print("Greeter client received: " + response.message)
if __name__ == '__main__':
run()
Process of generating SSL certificate
openssl genrsa -passout pass:1234 -des3 -out ca.key 4096
openssl req -passin pass:1234 -new -x509 -days 365 -key ca.key -out ca.crt -subj "/C=SP/ST=Italy/L=Ornavasso/O=Test/OU=Test/CN=Root CA"
openssl genrsa -passout pass:1234 -des3 -out server.key 4096
openssl genrsa -passout pass:1234 -des3 -out client.key 4096
openssl req -passin pass:1234 -new -key server.key -out server.csr -subj "/C=SP/ST=Italy/L=Ornavasso/O=Test/OU=Server/CN=sample.com"
openssl req -passin pass:1234 -new -key client.key -out client.csr -subj "/C=SP/ST=Italy/L=Ornavasso/O=Test/OU=Client/CN=localhost"
openssl x509 -req -passin pass:1234 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
openssl x509 -req -passin pass:1234 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
openssl rsa -passin pass:1234 -in server.key -out server.key
openssl rsa -passin pass:1234 -in client.key -out client.key
I have tried many ways but failed to solve the problem. I hope someone can provide a solution。
Thank you in advance!