postmodern / ruby-install

Installs Ruby, JRuby, TruffleRuby, or mruby
MIT License
1.89k stars 250 forks source link

Use OpenSSL 3 by default #461

Closed semaperepelitsa closed 5 months ago

semaperepelitsa commented 11 months ago

With Ruby 3.1.4 I would get the following error when trying to install latest "puma" gem.

``` Installing puma 6.3.1 with native extensions Gem::Ext::BuildError: ERROR: Failed to build gem native extension. current directory: /Users/sema/.gem/ruby/3.1.0/gems/puma-6.3.1/ext/puma_http11 /Users/sema/.rubies/ruby-3.1.4/bin/ruby -I /Users/sema/.rubies/ruby-3.1.4/lib/ruby/3.1.0 extconf.rb using OpenSSL pkgconfig (openssl.pc) checking for openssl/bio.h... yes checking for DTLS_method() in openssl/ssl.h... yes checking for SSL_CTX_set_session_cache_mode(NULL, 0) in openssl/ssl.h... yes checking for TLS_server_method() in openssl/ssl.h... yes checking for SSL_CTX_set_min_proto_version(NULL, 0) in openssl/ssl.h... yes checking for X509_STORE_up_ref()... yes checking for SSL_CTX_set_ecdh_auto(NULL, 0) in openssl/ssl.h... yes checking for SSL_CTX_set_dh_auto(NULL, 0) in openssl/ssl.h... yes checking for SSL_get1_peer_certificate() in openssl/ssl.h... no checking for Random.bytes... yes creating Makefile current directory: /Users/sema/.gem/ruby/3.1.0/gems/puma-6.3.1/ext/puma_http11 make DESTDIR\= sitearchdir\=./.gem.20230829-62642-3qoc84 sitelibdir\=./.gem.20230829-62642-3qoc84 clean current directory: /Users/sema/.gem/ruby/3.1.0/gems/puma-6.3.1/ext/puma_http11 make DESTDIR\= sitearchdir\=./.gem.20230829-62642-3qoc84 sitelibdir\=./.gem.20230829-62642-3qoc84 compiling http11_parser.c compiling mini_ssl.c compiling puma_http11.c linking shared-object puma/puma_http11.bundle Undefined symbols for architecture arm64: "_SSL_get1_peer_certificate", referenced from: _engine_peercert in mini_ssl.o ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [puma_http11.bundle] Error 1 make failed, exit code 2 ```

This is because Ruby is compiled with OpenSSL 1.1 instead of the latest OpenSSL 3. I had to reinstall Ruby with OpenSSL 3 to make it work:

ruby-install ruby 3.1.4 -- --with-openssl-dir=/opt/homebrew/opt/openssl@3

According to https://github.com/puma/puma/issues/2790#issuecomment-1009044847 OpenSSL 3 is fully supported since Ruby 3.1. Should ruby-install just use the latest OpenSSL by default?

postmodern commented 11 months ago

I am all for ditching OpenSSL 1.x support in favor of 3.x. However, Ruby 3.0 was the last Ruby version that still use OpenSSL 1.1. Ruby 3.0 reaches EoL next March, 2024. Do we prematurely switch to OpenSSL 3.x now, or wait until next year? Considering there are still developers trying to install Ruby 2.7 for older Rails apps, I worry doing a hard-switch to openssl@3 would break things for developers still using Ruby 3.0.x.

The other option is to dynamically switch between openssl@3 and openssl@1.1 based on the Ruby version. However, homebrew seems to be the only package manager to provides both version families.

svoop commented 11 months ago

Considering there are still developers trying to install Ruby 2.7 for older Rails apps, I worry doing a hard-switch to openssl@3 would break things for developers still using Ruby 3.0.x.

Dynamically switching the OpenSSL version is certainly the least surprising solution for developers.

However, if this is not a solution with reasonable effort, wouldn't it be better if installing EOL (< Ruby 3.0) or near-EOL (Ruby 3.0) require workarounds and not installing current versions?

havenwood commented 11 months ago

It seems like it might be nice to go ahead and make the jump since Ruby 3.0 lost regular maintenance on 2023-04-01.

havenwood commented 11 months ago

Or 2024-03-31 is expected EOL for 3.0.

postmodern commented 11 months ago

Tagging this for 0.10.0 and merged into the 0.10.0 branch.

postmodern commented 11 months ago

OpenSSL 1.1.1 has officially reached EoL. https://www.openssl.org/blog/blog/2023/03/28/1.1.1-EOL/

postmodern commented 8 months ago

I have recently added some logic to dynamically install the openssl@1.1 or openssl@3 homebrew package depending on the version of Ruby. See a37e332e055da91db5fb053a3d94ebb0f219043d This will be released shortly in ruby-install 0.9.3.

However, this comes with a few caveats:

  1. This is risky, because openssl-1.1 has reached End-of-Life. It will not receive anymore security updates. While I understand people have legacy apps they must maintain, running old unmaintained versions of software is risky. I strongly recommend that people upgrade to at least Ruby 3.1, which uses openssl-3.0.
  2. This only works for homebrew users. Linux and other BSD package managers only provide one version of openssl, and that's most likely openssl-3.0, as openssl-1.1 has reached End-of-Life.
  3. I will eventually remove this complex logic after Ruby 3.0 reaches End-of-Life, which was the last Ruby version to use openssl-1.1. After that point, if users still need to install Ruby 2.7 or 3.0, they will have to specify -- --with-openssl-dir=/path/to/openssl@1.1 themselves.

So sometime after March 31st, 2024, I will be removing the code and switching to OpenSSL 3.0 as the default homebrew/MacPorts openssl version.

postmodern commented 5 months ago

Decided to change directions on this and keep the openssl@3 vs. openssl@1.1 logic based on the ruby version for a while longer. I also decided to convert the dependencies.txt into dependencies.sh files to allow for dynamic dependencies based on the ruby version or OS version. https://github.com/postmodern/ruby-install/issues/477