The other day I wanted to try out Rails 7’s import maps on my new M1 MacBook, but I was blocked by an error telling me that Ruby couldn’t make any SSL requests.
I’ll go through how I fixed this.
The command I tried that gave me an error was:
bin/importmap pin @picocss/pico
I got the following error about SSL:
/Users/abuisman/.asdf/installs/ruby/3.1.0/lib/ruby/3.1.0/net/protocol.rb:46:in `connect_nonblock': SSL_connect returned=1 errno=0 peeraddr=220.127.116.11:443 state=error: certificate verify failed (unable to get local issuer certificate) (OpenSSL::SSL::SSLError)
from /Users/abuisman/.asdf/installs/ruby/3.1.0/lib/ruby/3.1.0/net/protocol.rb:46:in `ssl_socket_connect'
from /Users/abuisman/.asdf/installs/ruby/3.1.0/lib/ruby/3.1.0/net/http.rb:1048:in `connect'
from /Users/abuisman/.asdf/installs/ruby/3.1.0/lib/ruby/3.1.0/net/http.rb:976:in `do_start'
from /Users/abuisman/.asdf/installs/ruby/3.1.0/lib/ruby/3.1.0/net/http.rb:965:in `start'
from /Users/abuisman/.asdf/installs/ruby/3.1.0/lib/ruby/3.1.0/net/http.rb:1530:in `request'
from (irb):25:in `<main>'
from /Users/abuisman/.asdf/installs/ruby/3.1.0/lib/ruby/gems/3.1.0/gems/irb-1.4.1/exe/irb:11:in `<top (required)>'
from /Users/abuisman/.asdf/installs/ruby/3.1.0/bin/irb:25:in `load'
from /Users/abuisman/.asdf/installs/ruby/3.1.0/bin/irb:25:in `<main>'
I could reproduce this in a Ruby console with this code:
url = URI("https://duckduckgo.com/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
I’ve seen this error before and usually it happens when you haven’t compiled ruby properly with openssl. So I first reinstalled firstname.lastname@example.org and openssl@3 and a few times again and again, but I couldn’t fix it.
I was ducking around for some info and I sort of picked up in my searching that this could mean that my CA certificates were outdated.
I’ll start with the fix:
brew uninstall email@example.com --force --ignore-dependencies
brew install firstname.lastname@example.org
--force --ignore-dependencies is critical. I just ran
uninstall without it the first 10 times or so and I didn't notice that nothing was really being removed because of dependencies. It could be that it was clear from the command output but I do not remember seeing anything relating to dependencies.
--force --ignore-dependencies was the thing that made a difference for me.
With the following
.zshrc configuration for compilation related things:
# openssl config
export PATH="/email@example.com:$PATH" # Might be overkill
Then install ruby. For example with
asdf install ruby 3.1.0
Oh and how do we know it works?
A colleague of mine pointed me to the bundler documentation and there they mention a nice command:
curl -Lks 'https://git.io/rg-ssl' | ruby
Before the fix the output looked like this:
Afterwards it looks like this:
This means we have a quick way to test the config without having to boot up a ruby console.
have to could go deeper
In my recent migration from an i7 MacBook to this new M1 Pro I moved over my dotfiles with my
.zshrc config. I figured it was wrong at some point so I had a critical look. I must admit looked ridiculous:
# openssl config
So many of these variables are being overwritten in every section. It seems like this stuff accumulated while I was trying out things over time or as I was installing libraries. Who knows. Git shows many of these lines as new since moving to the new Mac.
What is the problem? For example
LDFLAGS gets overwritten like so:
So in the end the value is just
-L/opt/homebrew/opt/libffi/lib. You can see above that I corrected this by appending
:$LDFLAGS" each time. This means that it will add things to the
LDFLAGS variable instead of overwriting it. It turns out this cleanup didn't do much, or at least reverting it didn't break openssl again.
Interestingly, I had already built Ruby 2.7.4 already and it was showing the same issues. After fixing 3.1.0, 2.7.4 was also fixed. I believe this has something to do with new certificate files being downloaded as I mentioned earlier. My general idea is that reinstalling openssl properly also updated some certificate.
If you look here:
You can see that there is a certificate directory and a certificate file:
SSL_CERT_FILE: /firstname.lastname@example.org/cert.pem SSL_CERT_DIR: /email@example.com/certs
When I look around in the directory it doesn't contain anything and when I open the certificate file I see the following:
I have no clue what this certificate's role is to be honest. I might find out and update here.
The fix was for me as described above. I ran into several github issues, stack overflows, etc. that allowed me to piece together these instructions. I hope my gathering of these solutions will be the real fix for you, or for me when I run into this again and forget.