googleapis / google-cloud-ruby

Google Cloud Client Library for Ruby
https://googleapis.github.io/google-cloud-ruby/
Apache License 2.0
1.35k stars 543 forks source link

Ruby SDK doesn't send port on CONNECT via http_proxy #8189

Open KennyCCK opened 3 years ago

KennyCCK commented 3 years ago

Environment details

Steps to reproduce

  1. install & run pproxy [1] ("pproxy -v -d")
  2. $ export http_proxy=http://localhost:8080
  3. $ strace -f -s 9999 ruby secrets.rb |& grep -i '"CONNECT ' | grep " send"

Code example

secrets.rb

# To run this script
#
#     gem install google-cloud-secret_manager
#     export GOOGLE_PROJECT=your-project-id
#     Run with: ruby secrets.rb
#

require "google-cloud-secret_manager"

secret_manager_service = Google::Cloud::SecretManager.secret_manager_service
project_id = ENV['GOOGLE_PROJECT'] || raise("GOOGLE_PROJECT env variable is not set. It's required.")
puts "testing secret_manager_service.list_secrets for google project #{project_id}"
parent = "projects/#{project_id}"
resp = secret_manager_service.list_secrets(parent: parent)
puts "resp.count #{resp.count}"

Full backtrace

The proxy would display an error display an error about not being able to split "host:port" (host_name, port = path.rsplit(':', 1))

Part of the trace shows the following CONNECT:

CONNECT secretmanager.googleapis.com HTTP/1.0
Host: secretmanager.googleapis.com
User-Agent: grpc-httpcli/0.0

Any additional information below

Is it possible to fix the SDK so that the CONNECT includes port and uses HTTP/1.1? (If it is using a common library, it might be possible that the problem is not limited to this secrets manager API)

Thanks!

*Note: A related bug issue has also been raised internally

[1] https://pypi.org/project/pproxy/ [2] https://tools.ietf.org/html/rfc7231#section-4.3.6

dazuma commented 3 years ago

The SecretManager client (and indeed most of the Ruby clients in this repo, with a few notable exceptions) use gRPC and HTTP/2 as the transport (not HTTP/1.1 or 1.0). Is it possible your proxy doesn't recognize that protocol?

KennyCCK commented 3 years ago

it was reproduced with pproxy and Zscaler proxy, if we look into the trace logs we can find that HTTP/1.0 was indeed specified on CONNECT

I1111 16:26:08.287403000 123145569693696 http_connect_handshaker.cc:329] Connecting to server secretmanager.googleapis.com via HTTP proxy ipv4:15x.xx.xxx.xx:80
I1111 16:26:08.287419000 123145569693696 tcp_posix.cc:1569]            WRITE 0x7f8ef8d576c0 (peer=ipv4:15x.xx.xxx.xx:80)
D1111 16:26:08.287430000 123145569693696 tcp_posix.cc:1573]            DATA: 43 4f 4e 4e 45 43 54 20 73 65 63 72 65 74 6d 61 6e 61 67 65 72 2e 67 6f 6f 67 6c 65 61 70 69 73 2e 63 6f 6d 20 48 54 54 50 2f 31 2e 30 0d 0a 48 6f 73 74 3a 20 73 65 63 72 65 74 6d 61 6e 61 67 65 72 2e 67 6f 6f 67 6c 65 61 70 69 73 2e 63 6f 6d 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 67 72 70 63 2d 68 74 74 70 63 6c 69 2f 30 2e 30 0d 0a 0d 0a 'CONNECT secretmanager.googleapis.com HTTP/1.0..Host: secretmanager.googleapis.com..User-Agent: grpc-httpcli/0.0....'
...
...
...
D1111 16:26:08.490937000 123145569693696 tcp_posix.cc:692]             DATA: 48 54 54 50 2f 31 2e 30 20 34 30 30 20 42 61 64 20 52 65 71 75 65 73 74 0d 0a 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 35 34 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 74 65 78 74 2f 68 74 6d 6c 3b 20 63 68 61 72 73 65 74 3d 55 54 46 2d 38 0d 0a 44 61 74 65 3a 20 54 68 75 2c 20 31 32 20 4e 6f 76 20 32 30 32 30 20 30 30 3a 32 36 3a 30 38 20 47 4d 54 0d 0a 0d 0a 3c 68 74 6d 6c 3e 3c 74 69 74 6c 65 3e 45 72 72 6f 72 20 34 30 30 20 28 42 61 64 20 52 65 71 75 65 73 74 29 21 21 31 3c 2f 74 69 74 6c 65 3e 3c 2f 68 74 6d 6c 3e 'HTTP/1.0 400 Bad Request..Content-Length: 54..Content-Type: text/html; charset=UTF-8..Date: Thu, 12 Nov 2020 00:26:08 GMT....<html><title>Error 400 (Bad Request)!!1</title></html>'
E1111 16:26:08.491005000 123145569693696 ssl_transport_security.cc:1439] Handshake failed with fatal error SSL_ERROR_SSL: error:100000f7:SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER.
D1111 16:26:08.491036000 123145569693696 security_handshaker.cc:184]   Security handshake failed: {"created":"@1605140768.491021000","description":"Handshake failed","file":"src/core/lib/security/transport/security_handshaker.cc","file_line":307,"tsi_code":10,"tsi_error":"TSI_PROTOCOL_FAILURE"}

The above does indicate the use of gRPC but without specifying the port as required by the RFC. The error reported is "Handshake failed" with HTTP 400