SSL connection options seemingly being ignored
andrewhamon opened this issue · comments
I'm trying to use Pebble to perform integration tests that don't rely on the Let's Encrypt staging server.
In order to get this to work, I need to either disable SSL verification, or add the Pebble CA. Neither seems to be working.
If I make a Faraday connection directly, though, using identical connection options as what I used for acme-client, I do not get SSL errors (as expected).
Example:
require 'openssl'
private_key = OpenSSL::PKey::RSA.new(4096)
# Local Pebble endpoint
endpoint = "https://0.0.0.0:14000/"
connection_options = { ssl: { verify: false }, request: { open_timeout: 5, timeout: 5 } }
client = Acme::Client.new(private_key: private_key, endpoint: endpoint, connection_options: connection_options)
client.connection.get
# Traceback (most recent call last):
# 1: from (irb):35
# Faraday::SSLError (SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate))
But it works when using a plain old Faraday connection with no middleware:
connection = Faraday.new endpoint, **connection_options
connection.get
#<Faraday::Response:0x00007f84e45c8508 @on_complete_callbacks=[], @env=#<Faraday::Env @method=:get @body="404 page not found\n" @url=#<URI::HTTPS https://0.0.0.0:14000/> @request=#<Faraday::RequestOptions timeout=5, open_timeout=5> @request_headers={"User-Agent"=>"Faraday v0.14.0"} @ssl=#<Faraday::SSLOptions (empty)> @response=#<Faraday::Response:0x00007f84e45c8508 ...> @response_headers={"content-type"=>"text/plain; charset=utf-8", "x-content-type-options"=>"nosniff", "date"=>"Sat, 10 Feb 2018 20:19:37 GMT", "content-length"=>"19", "connection"=>"close"} @status=404 @reason_phrase="Not Found">>
The only difference between the two is the middleware used:
acme-client/lib/acme/client.rb
Lines 100 to 105 in 552f4a1
I tried replicating this with a dummy middleware, which still works fine:
class DummyMiddleware < Faraday::Middleware
def call(env)
@app.call(env)
end
end
connection = Faraday.new endpoint, **connection_options do |configuration|
configuration.use DummyMiddleware
configuration.adapter Faraday.default_adapter
end
connection.get
#<Faraday::Response:0x00007f84e45c8508 @on_complete_callbacks=[], @env=#<Faraday::Env @method=:get @body="404 page not found\n" @url=#<URI::HTTPS https://0.0.0.0:14000/> @request=#<Faraday::RequestOptions timeout=5, open_timeout=5> @request_headers={"User-Agent"=>"Faraday v0.14.0"} @ssl=#<Faraday::SSLOptions (empty)> @response=#<Faraday::Response:0x00007f84e45c8508 ...> @response_headers={"content-type"=>"text/plain; charset=utf-8", "x-content-type-options"=>"nosniff", "date"=>"Sat, 10 Feb 2018 20:19:37 GMT", "content-length"=>"19", "connection"=>"close"} @status=404 @reason_phrase="Not Found">>
My next idea is to try to slowly build up the dummy middleware until it is identical to the middleware used here, but I figured I would gather my thoughts and leave them here first, and see if anyone can even reproduce this.
It seems as though my attempt to use Pebble may be misguided as I think it implements the newer ACME standard 🙂
Still, the issue is perplexing.
Hey @andrewhamon,
You are right. Pebble implement (partially) the newer ACME spec.
I'm developing a new version of the client for ACME v2 on this branch. I write my test against Pebble whenever possible.
To skip the certificate check I do OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
in my spec helper.
I'm not too sure why Faraday seem to not pass the connection options properly. I'll have to investigate that.
I experience a failure to validate the certificate when I talk to the LetsEncrypt staging server.
I would suspect that Faraday is using a different (or no?) set of certificate anchors?
I experience a failure to validate the certificate when I talk to the LetsEncrypt staging server.
I would suspect that Faraday is using a different (or no?) set of certificate anchors?
This problem is solved by setting the connection_options when creating the client:
Acme::Client.new(private_key: acmeprivkey,
directory: server,
connection_options: {
:ssl => {
:ca_file => '/usr/lib/ssl/certs/ca-certificates.crt',
:ca_path => "/usr/lib/ssl/certs"
}
})