Getting Started
This guide explains how to use localhost
for provisioning local TLS certificates for development.
Installation
Add the gem to your project:
$ bundle add localhost
Then, generate an issuer certificate and install it:
$ bundle exec bake localhost:install
You may be prompted for a password to install the certificate. This is the password for your local keychain.
Purging your certificates
If you have an existing installation which does not use the issuer certificate, you can remove the existing certificates and start over:
$ bundle exec bake localhost:purge
Note this will remove all certificates in the $XDG_STATE_HOME/localhost.rb/
directory, but it won't remove the issuer certificate that was installed in your keychain.
Core Concepts
localhost
has two core concepts:
- A
class Localhost::Issuer
instance which represents a certificate authority (CA) that can be used to sign certificates for localhost. - A
class Localhost::Authority
instance which represents a public and private key pair that can be used for both clients and servers.
Files
The certificate and private key are stored in $XDG_STATE_HOME/localhost.rb/
(typically ~/.local/state/localhost.rb/
). You can delete them and they will be regenerated. If you added the certificate to your computer's certificate store/keychain, you'll you'd need to update it.
Usage
In general, you won't need to do anything at all. The application server you are using will automatically provision a self-signed certificate for localhost. That being said, if you want to implement your own self-signed secure server, the following example demonstrates how to use the class Localhost::Authority
:
require 'socket'
require 'thread'
require 'localhost/authority'
# Get the self-signed authority for localhost:
authority = Localhost::Authority.fetch
ready = Thread::Queue.new
# Start a server thread:
server_thread = Thread.new do
server = OpenSSL::SSL::SSLServer.new(TCPServer.new("localhost", 4050), authority.server_context)
server.listen
ready << true
peer = server.accept
peer.puts "Hello World!"
peer.flush
peer.close
end
ready.pop
client = OpenSSL::SSL::SSLSocket.new(TCPSocket.new("localhost", 4050), authority.client_context)
# Initialize SSL connection:
client.connect
# Read the encrypted message:
puts client.read(12)
client.close
server_thread.join