# In your Gemfile
gem "localhost"
# Then, depending on your desired server
gem "falcon"
gem "puma"
# Start your server, so that "localhost" will create your default ssl cert in ~/.local/state/localhost.rb/localhost.crt
bundle exec falcon serve --port 3000
# or
bundle exec puma -b 'ssl://localhost:3000'
# Load the "localhost" gem cert into your Keychain
# -d -> "trust domain" certificate
# -r trustRoot -> trusted as root certificate
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ~/.local/state/localhost.rb/localhost.crt
# Find the cert, and output it as a .pem file using PEM (-p) format
security find-certificate -c "localhost" -p > localhost.pem
# Find your default cert file for ruby openssl
# With openssl@3 installed w/ homebrew, the default is /opt/homebrew/etc/openssl@3/cert.pem
ruby -ropenssl -e "puts OpenSSL::X509::DEFAULT_CERT_FILE"
# Backup your default cert file
sudo cp /opt/homebrew/etc/openssl@3/cert.pem /opt/homebrew/etc/openssl@3/cert.pem.bak
# Add the "localhost" gem .pem to the default cert file
# Pipe "localhost.pem" into `tee`
# -a append to the file
cat localhost.pem | sudo tee -a /opt/homebrew/etc/openssl@3/cert.pem
# verify the output
openssl crl2pkcs7 -nocrl -certfile /opt/homebrew/etc/openssl@3/cert.pem | openssl pkcs7 -print_certs -text -noout
# Run Falcon
bundle exec falcon serve --port 3000
# Or run Puma
bundle exec puma -b 'ssl://localhost:3000'
# 1. Each should validate properly in your browser - no warnings
# 2. Calling w/ a Ruby library, like HTTParty, should also validate correctly without ignorning SSL verification
HTTParty.get("https://localhost:3000/") # Works!
We should make a bake task to do this so you don't have to do it by hand.
We already have https://github.com/socketry/localhost/blob/main/bake/localhost.rb - we just need to add a task for creating a named certificate.
I'd also be open to adding a bake task (might need to be OS specific, e.g.
bake localhost:macos:trust
andlocalhost:linux:trust
etc) to add the certificate to the trust store. Automating this will make it easier for users.