grpc/grpc

Python "Peer name x.x.x.x is not in peer certificate"

san213 opened this issue · 5 comments

I am trying to connect to nginx ingress remotely from my local through grpc python client. I am using self signed certificate. I want to use IP to connect to ingress. I do not have hostname or dns.

I generated the key and cert pair using the below command and attached the key and cert to ingress controller and using the same cert in the grpc client code.

Command to generate key and cert
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${KEY_FILE} -out ${CERT_FILE} -subj "/CN=${HOST}/O=${HOST}"

grpc client code

def generate_and_send_message(self):
cert = None
key = None
cacert = None
cert = open('client.cert', 'rb').read()
cred = grpc.ssl_channel_credentials(root_certificates=cert, private_key=None, certificate_chain=None)

Output:

I0225 00:43:48.395631000 123145309118464 subchannel.cc:964] Failed to connect to channel, retrying
I0225 00:43:49.943328000 123145308581888 ssl_transport_security.cc:217] HANDSHAKE START - TLS client start_connect - !!!!!!
I0225 00:43:49.943381000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client enter_early_data - !!!!!!
I0225 00:43:49.943393000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client read_server_hello - !!!!!!
I0225 00:43:50.454432000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client read_server_certifi - !!!!!!
I0225 00:43:50.454500000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client read_certificate_st - !!!!!!
I0225 00:43:50.454508000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client verify_server_certi - !!!!!!
I0225 00:43:50.454539000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client read_server_key_exc - !!!!!!
I0225 00:43:50.454664000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client read_certificate_re - !!!!!!
I0225 00:43:50.454676000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client read_server_hello_d - !!!!!!
I0225 00:43:50.454680000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client send_client_certifi - !!!!!!
I0225 00:43:50.454684000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client send_client_key_exc - !!!!!!
I0225 00:43:50.455099000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client send_client_certifi - !!!!!!
I0225 00:43:50.455113000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client send_client_finishe - !!!!!!
I0225 00:43:50.455196000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client finish_flight - !!!!!!
I0225 00:43:50.455217000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client read_session_ticket - !!!!!!
I0225 00:43:50.967219000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client process_change_ciph - !!!!!!
I0225 00:43:50.967272000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client read_server_finishe - !!!!!!
I0225 00:43:50.967312000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client finish_client_hands - !!!!!!
I0225 00:43:50.967338000 123145308581888 ssl_transport_security.cc:217] LOOP - TLS client done - !!!!!!
I0225 00:43:50.967349000 123145308581888 ssl_transport_security.cc:217] HANDSHAKE DONE - TLS client done - !!!!!!
D0225 00:43:50.967464000 123145308581888 security_handshaker.cc:186] Security handshake failed: {"created":"@1582571630.967438000","description":"Peer name x.x.x.x is not in peer certificate","file":"src/core/lib/security/security_connector/ssl/ssl_security_connector.cc","file_line":55}

Can you please suggest how to make this work?

I used this to generate key and cert
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${KEY_FILE} -out ${CERT_FILE} -subj "/CN=x.x.x.x/subjectAltName=IP:x.x.x.x"

The failure is due to hostname check.

There are two ways to address your issue

  1. Use GRPC_SSL_TARGET_NAME_OVERRIDE_ARG as channel arg.
  2. We have a new TLS credentials in gRPC (only in C++ for now). It has an option called GRPC_TLS_SKIP_HOSTNAME_VERIFICATION.

@ZhenLian or @yihuazhang can help you with details.

Can you please ping the steps on using towards the first approach with an example? I could not find any example. @ZhenLian @yihuazhang

I used the first approach - Use GRPC_SSL_TARGET_NAME_OVERRIDE_ARG as channel arg. This solved the issue.

I added localhost as CN and IP in the SAN and used the below in my python code to make it work.

cert_cn = "localhost" # or parse it out of the cert data
options = (('grpc.ssl_target_name_override', cert_cn,),)
grpc.secure_channel(self.opta_url, cred, options) as channel

@san213
Thanks for letting us know and sharing the solution. Feel free to reach out if you have any other questions :-)