【问题标题】:faraday code for HTTPS request over HTTPS proxy通过 HTTPS 代理进行 HTTPS 请求的法拉第代码
【发布时间】:2021-04-06 02:49:38
【问题描述】:

我们准备了代理服务器,它使用自签名证书在 proxy.foo.com 的端口 13128 上侦听 HTTPS,并希望通过该代理请求 https://target-site.com

curl 请求curl -v --proxy-cacert /path/to/proxy-cert.pem https://target-site.com/ -x https://user:pass@proxy.foo.com:13128 > /dev/null 通过。

对应的 ruby​​ 代码是什么样的?我们使用 faraday 0.12.2,但也欢迎使用 net/http。

此代码不起作用

cert = OpenSSL::X509::Certificate.new(<<PEM)
-----BEGIN CERTIFICATE-----
# this is our self signed cert
-----END CERTIFICATE-----
PEM
cert_store = OpenSSL::X509::Store.new
cert_store.add_cert(cert)
conn = Faraday.new(url: "https://target-site.com/", ssl: { cert_store: cert_store }, proxy: 'https://user:pass@proxy.foo.com:13128')
p "conn is #{conn.inspect}"
p conn.get()

部分输出为:

"conn is #<Faraday::Connection:0x007fb7e7d40520 @parallel_manager=nil, @headers={\"User-Agent\"=>\"Faraday v0.12.2\"}, @params={}, @options=#<Faraday::RequestOptions (empty)>, @ssl=#<Faraday::SSLOptions (empty)>, @default_parallel_manager=nil, @builder=#<Faraday::RackBuilder:0x007fb7ea143f08 @handlers=[Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp]>, @url_prefix=#<URI::HTTPS https://target-site.com/>, @proxy=#<Faraday::ProxyOptions uri=#<URI::HTTPS https://user:pass@proxy.foo.com:13128>, user=\"user\", password=\"pass\">>"
<internal:prelude>:78:in `__read_nonblock': Connection reset by peer (Faraday::ConnectionFailed)
    from <internal:prelude>:78:in `read_nonblock'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/2.4.0/net/protocol.rb:172:in `rbuf_fill'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/2.4.0/net/protocol.rb:154:in `readuntil'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/2.4.0/net/protocol.rb:164:in `readline'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/2.4.0/net/http/response.rb:40:in `read_status_line'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/2.4.0/net/http/response.rb:29:in `read_new'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/2.4.0/net/http.rb:925:in `connect'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/2.4.0/net/http.rb:887:in `do_start'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/2.4.0/net/http.rb:876:in `start'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/2.4.0/net/http.rb:1407:in `request'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/2.4.0/net/http.rb:1165:in `get'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/faraday-0.12.2/lib/faraday/adapter/net_http.rb:78:in `perform_request'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/faraday-0.12.2/lib/faraday/adapter/net_http.rb:38:in `block in call'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/faraday-0.12.2/lib/faraday/adapter/net_http.rb:85:in `with_net_http_connection'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/faraday-0.12.2/lib/faraday/adapter/net_http.rb:33:in `call'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/faraday-0.12.2/lib/faraday/request/url_encoded.rb:15:in `call'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/faraday-0.12.2/lib/faraday/rack_builder.rb:141:in `build_response'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/faraday-0.12.2/lib/faraday/connection.rb:386:in `run_request'
    from /Users/yskkin/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/faraday-0.12.2/lib/faraday/connection.rb:149:in `get'

【问题讨论】:

    标签: ruby https http-proxy faraday


    【解决方案1】:

    我已将 net/http 用于基于证书的请求。我忘记了我在哪里找到了这个补丁,但它有助于我们附加多个证书。

    
    
    class NetHttpPatch < Net::HTTP
      SSL_IVNAMES << :@extra_chain_cert unless SSL_IVNAMES.include?(:@extra_chain_cert)
      SSL_ATTRIBUTES << :extra_chain_cert unless SSL_ATTRIBUTES.include?(:extra_chain_cert)
    
      # Sets the rest of the cert chain if there is one by adding an array of OpenSSL::X509::Certificate objects
      attr_accessor :extra_chain_cert
    
    end
    

    至于net/http的实际实现,我按照步骤附上一个证书

    uri = URI.parse(url)
    http = NetHttpPatch.new(uri.host, uri.port)
    http.use_ssl = true
    http.cert = certificate(<CERT STRING>)
    http.key = OpenSSL::PKey::RSA.new(<PRIVATE KEY>)
    
    # Here is the usage of the patch
    http.extra_chain_cert = cert_chain([<EXTRA CERTS>])
    
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER
    
    request = Net::HTTP::<WHATEVER METHOD YOU NEED HERE>
    request.body = body
    request.content_type = ...
    request['Authorization'] = ...
    
    http.request(request)
    

    【讨论】:

      猜你喜欢
      • 2018-07-16
      • 2015-10-16
      • 1970-01-01
      • 2017-07-28
      • 2015-04-15
      • 2014-08-25
      • 1970-01-01
      • 2017-06-27
      • 1970-01-01
      相关资源
      最近更新 更多