Skip to content

Instantly share code, notes, and snippets.

@etozzato
Last active January 28, 2024 20:12
Show Gist options
  • Save etozzato/0ba2140ea3c6125d4839373309fe733a to your computer and use it in GitHub Desktop.
Save etozzato/0ba2140ea3c6125d4839373309fe733a to your computer and use it in GitHub Desktop.
A section of config/puma.rb that will automatically generate a self-signed X509 certificate and provide https in development
if Rails.env.development?
FileUtils.mkdir_p(Rails.root.join('config', 'certs'))
key_path = Rails.root.join('config', 'certs', 'development.key')
crt_path = Rails.root.join('config', 'certs', 'development.crt')
unless File.exist?(key_path) && File.exist?(crt_path)
def cert_domain
'localhost' # Setting[:cookie_domain] || 'localhost'
end
def generate_cert(key, subject)
cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = 0x0
cert.subject = cert.issuer = subject
cert.public_key = key.public_key
cert.not_before = Time.now
cert.not_after = Time.now + 2.years
extend_and_sign(cert, key)
end
def extend_and_sign(cert, key)
ef = OpenSSL::X509::ExtensionFactory.new
ef.subject_certificate = ef.issuer_certificate = cert
cert.add_extension(ef.create_extension('keyUsage', 'digitalSignature', true))
cert.add_extension(ef.create_extension('extendedKeyUsage', 'serverAuth', true))
cert.add_extension(ef.create_extension('subjectAltName', "DNS.1:#{cert_domain},DNS.2:*.#{cert_domain}", true))
cert.sign(key, OpenSSL::Digest.new('SHA256'))
end
begin
subject = OpenSSL::X509::Name.parse("/L=Los Angeles/C=US/O=AINZ/OU=TOP/ST=CA/CN=#{cert_domain}")
key = OpenSSL::PKey::RSA.new(2048)
FileUtils.rm key_path, force: true
file = File.new(key_path, 'wb')
file.write(key)
file.close
cert = generate_cert(key, subject)
FileUtils.rm crt_path, force: true
file = File.new(crt_path, 'wb')
file.write(cert)
file.close
rescue StandardError => e
Rails.logger.warn "An error occurred creating the SSL certificate in development: #{e.message}.. Skipping SSL!"
FileUtils.rm key_path, force: true
FileUtils.rm crt_path, force: true
end
end
if File.exist?(key_path) && File.exist?(crt_path)
ssl_bind '0.0.0.0', '3001', {
key: key_path,
cert: crt_path
}
end
end
@TheNotary
Copy link

This approach allows me to delete a ton of setup documentation, thanks for doing this in pure ruby!

@etozzato
Copy link
Author

This approach allows me to delete a ton of setup documentation, thanks for doing this in pure ruby!

I am happy to help!

I noticed that on deploy, some stacks will error out at Rails.env.development?, and I changed that to a safer RAILS_ENV check

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment