Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connection to Lets Encrypt secured server fails #445

Open
corny opened this issue Sep 30, 2021 · 14 comments
Open

Connection to Lets Encrypt secured server fails #445

corny opened this issue Sep 30, 2021 · 14 comments

Comments

@corny
Copy link

corny commented Sep 30, 2021

OMG this library uses a built-in list of CA certificates from 2015: 💩 🤦‍♂️

##
## Bundle of CA Root Certificates
##
## Certificate data from Mozilla as of: Wed Oct 28 04:12:04 2015

My quick fix for Debian/Ubuntu:

ln -sf /etc/ssl/certs/ca-certificates.crt  $rubydir/2.7.0/gems/httpclient-2.8.3/lib/httpclient/cacert.pem
@jhollinger
Copy link

jhollinger commented Sep 30, 2021

Yeah, pretty crazy that it's doing that. Our fix was the following mokeypatch:

require 'httpclient'

class HTTPClient
  alias original_initialize initialize

  def initialize(*args, &block)
    original_initialize(*args, &block)
    # Force use of the default system CA certs (instead of the 6 year old bundled ones)
    @session_manager&.ssl_config&.set_default_paths
  end
end

@jessebs
Copy link

jessebs commented Sep 30, 2021

Building off of @jhollinger, just calling client.ssl_config.set_default_paths without overriding the constructor seems to work

client = HTTPClient.new
client.ssl_config.set_default_paths

@jdongelmans
Copy link

Just an FYI: this gem is a dependency for Rack::OAuth2 and broke our production, so we added an initializer basically doing the same as mentioned above:

Rack::OAuth2.http_config do |c|
  c.ssl_config.clear_cert_store
  c.ssl_config.cert_store.set_default_paths
end

@willtcarey
Copy link

Our application also uses Webfinger in our OAuth stack. The process of getting it to use the system certs was similar to Rack::OAuth2.

WebFinger.http_config do |c|
  c.ssl_config.clear_cert_store
  c.ssl_config.cert_store.set_default_paths
end

@jamesyale
Copy link

jamesyale commented Sep 30, 2021

Thanks all, based on @jhollinger 's suggestion we hacked the library directly: livelink@c1b97a7#diff-2a6765023b9beb8295399d5c04286045360ce90aabfffead2dba5c2c3ef71173

@essjayhch
Copy link

Just FYI, the monkey patch is an ruby 2.3+ feature set.

Not that I'm suggesting httpclient should specifically support ancient versions of ruby out there, it is worth noting that this gem has been fundamental since the days or rails 2, which love it or hate it still exist out there in the wild.

For those coming across this and looking to fix a certificate error on an unsupported version of ruby, the problem you will be tripping over will be the &. (safe operator) littered through the patch.

Yeah, pretty crazy that it's doing that. Our fix was the following mokeypatch:

require 'httpclient'

class HTTPClient
  alias original_initialize initialize

  def initialize(*args, &block)
    original_initialize(*args, &block)
    # Force use of the default system CA certs (instead of the 6 year old bundled ones)
    @session_manager&.ssl_config&.set_default_paths
  end
end

Thinking about this (as we've had to patch some pre ruby 2.3 legacy code), you shouldn't need the safe operator, as the @ssl_config attribute should already be setup by the time you get to the end of the constructor anyway.

ApCoder123 pushed a commit to 2factorauth/twofactorauth that referenced this issue Oct 1, 2021
* Workaround for old CAs in httpclient

See nahi/httpclient#445.

The default implementation uses a list of CAs from 2015, and resetting
it to use default paths uses CA certificates from the underlying OS.

* Refactor for rubocop/readability

* Set proxy argument to nil

Co-authored-by: Carlgo11 <Carlgo11@users.noreply.github.com>
@heinrichhanekom
Copy link

We had the same thing.
Thanks for the fixes:

OpenIDConnect.http_config do |c|
  c.ssl_config.clear_cert_store
  c.ssl_config.cert_store.set_default_paths
end

Rack::OAuth2.http_config do |c|
  c.ssl_config.clear_cert_store
  c.ssl_config.cert_store.set_default_paths
end

WebFinger.http_config do |c|
  c.ssl_config.clear_cert_store
  c.ssl_config.cert_store.set_default_paths
end

@jhollinger
Copy link

jhollinger commented Oct 1, 2021

Is this lib even actively maintained? There's not much commit activity at all. I've rarely seen anyone use httpclient directly in their apps; usually it's a transitive dependency (openid_connect, rack-oauth2, etc). Could we put pressure on those projects to reduce their dependencies? I'll grant that the stdlib's HTTP client doesn't have the cleanest API, but it works just fine. The community has kind of "left-padded" itself, here, IMHO.

@gareth
Copy link

gareth commented Oct 1, 2021

It might have got hidden in the references above, but thanks to @nov there are now new versions of webfinger, rack-oauth2, fb_graph2, swd and openid_connect that have these fixes incorporated.

@jfederico
Copy link

Something else brought me to here, but yeah, this is pretty bad.

It would be super hard to update properly. The dependency to version 2.8.3 comes from google-apis-core (0.3.0), but there are some other gems depending on even older versions. We are using omniauth_openid_connect 0.3.5 (June 7, 2020), which uses openid_connect ~> 1.1 (March 23, 2017), which uses webfinger >= 1.0.1 (December 22, 2014), which uses httpclient >= 2.4 (June 8, 2014).

The patch contributed here #2930 seems to be the best choice right now. Although it may need to be extended.

We are looking into it

Magisus added a commit to Magisus/dropsonde that referenced this issue Oct 8, 2021
The `httpclient` gem uses a CA certificate bundle from 2015 (as of
version 2.8.3), see nahi/httpclient#445. When
the Let's Encrypt root cert expired recently, this gem started failing
SSL handshakes, because the CA bundle it was using did not contain an
alternate trust path.

Calling `set_default_paths` on the client's SSL store causes it to load
the certs shipped with the Ruby runtime being used to execute dropsonde.
In most cases, these certs will be more up-to-date, and should allow the
connection to succeed. This is definitely true when running with
puppet-agent's Ruby.

With Windows system Ruby, this won't be sufficient. Recommended
workaourn is to use puppet-agent's Ruby on Windows if possible.
@RiverHeart
Copy link

This appears to have affected apt-listbugs as well, which in our case was preventing updates from going through. Fix is the same as the original, but uses the path to the system version /usr/lib/ruby/vendor_ruby/httpclient/cacert.pem

Thread first indicating the issue with apt-listbugs
https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1822839.html

Magisus added a commit to Magisus/dropsonde that referenced this issue Oct 8, 2021
The `httpclient` gem uses a CA certificate bundle from 2015 (as of
version 2.8.3), see nahi/httpclient#445. When
the Let's Encrypt root cert expired recently, this gem started failing
SSL handshakes, because the CA bundle it was using did not contain an
alternate trust path.

Calling `set_default_paths` on the client's SSL store causes it to load
the certs shipped with the Ruby runtime being used to execute dropsonde.
In most cases, these certs will be more up-to-date, and should allow the
connection to succeed. This is definitely true when running with
puppet-agent's Ruby.

With Windows system Ruby, this won't be sufficient. Recommended
workaround is to use puppet-agent's Ruby on Windows if possible.
kamaradclimber added a commit to kamaradclimber/bga_to_bgg that referenced this issue Oct 13, 2021
Change-Id: I0bd8e66a77ab0a9830a793f98ff39f89c6045dae
Reference: nahi/httpclient#445
matiasgarciaisaia added a commit to instedd/alto_guisso_rails that referenced this issue Oct 19, 2021
The HTTPClient gem has a really dated trust store, so we know
use the OS' default one.

See nahi/httpclient#445
@mbeijen
Copy link

mbeijen commented Nov 10, 2021

This issue was fixed in debians version of the package here, and like this: https://salsa.debian.org/ruby-team/ruby-httpclient/-/commit/542849f1b60e9c0cd24c328ad710b2a94cb42729

@jrochkind
Copy link
Contributor

@nahi no action on this in over ayear may lead me to abandon HTTPClient, when I otherwise rather like it. :(

jrochkind added a commit to traject/traject that referenced this issue Nov 30, 2022
If the host app is passing in a HTTPClient instance, this won't effect it. But that's probably a rarely used feature, and the host app is responsible for configuring the HTTPClient similarly in that case.

Otherwise, tell HTTPClient to _not_ do it's insane default of using a 6-year-old cert package, but just to use the cert package on the OS. The bundled with HTTPClient cert package no longer works with letsencrypt certs. This change should resolve that for people using standard defaults.

If someone really needs the old behavior, they can set setting `"solr_json_writer.use_packaged_certs"` to `true` or `"true"`. Just in case there's some edge case reason this change could break things and someone would need to go back to previous behavior.  I am comfortable releasing this change in a minor release, considering it a bugfix.

Ref #285

and nahi/httpclient#445
@kirsha2
Copy link

kirsha2 commented May 3, 2024

Is there any update or timeline when this issue can be released ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests