Giter Site home page Giter Site logo

acme-client's Introduction

Acme::Client

Build Status

acme-client is a client implementation of the ACME protocol in Ruby.

You can find the ACME reference implementations of the server in Go and the client in Python.

ACME is part of the Letsencrypt project, which goal is to provide free SSL/TLS certificates with automation of the acquiring and renewal process.

Installation

Via Rubygems:

$ gem install acme-client

Or add it to a Gemfile:

gem 'acme-client'

Usage

Register client

In order to authenticate our client, we have to create an account for it.

# We're going to need a private key.
require 'openssl'
private_key = OpenSSL::PKey::RSA.new(4096)

# We need an ACME server to talk to, see github.com/letsencrypt/boulder
# WARNING: This endpoint is the production endpoint, which is rate limited and will produce valid certificates.
# You should probably use the staging endpoint for all your experimentation:
# endpoint = 'https://acme-staging.api.letsencrypt.org/'
endpoint = 'https://acme-v01.api.letsencrypt.org/'

# Initialize the client
require 'acme/client'
client = Acme::Client.new(private_key: private_key, endpoint: endpoint)

# If the private key is not known to the server, we need to register it for the first time.
registration = client.register(contact: 'mailto:[email protected]')

# You may need to agree to the terms of service (that's up the to the server to require it or not but boulder does by default)
registration.agree_terms

Authorize for domain

Before you are able to obtain certificates for your domain, you have to prove that you are in control of it.

authorization = client.authorize(domain: 'example.org')

# This example is using the http-01 challenge type. Other challenges are dns-01 or tls-sni-01.
challenge = authorization.http01

# The http-01 method will require you to respond to a HTTP request.

# You can retrieve the challenge token
challenge.token # => "some_token"

# You can retrieve the expected path for the file.
challenge.filename # => ".well-known/acme-challenge/:some_token"

# You can generate the body of the expected response.
challenge.file_content # => 'string token and JWK thumbprint'

# You are not required to send a Content-Type. This method will return the right Content-Type should you decide to include one.
challenge.content_type

# Save the file. We'll create a public directory to serve it from, and inside it we'll create the challenge file.
FileUtils.mkdir_p( File.join( 'public', File.dirname( challenge.filename ) ) )

# We'll write the content of the file
File.write( File.join( 'public', challenge.filename), challenge.file_content )

# Optionally save the challenge for use at another time (eg: by a background job processor)
File.write('challenge', challenge.to_h.to_json)

# The challenge file can be served with a Ruby webserver.
# You can run a webserver in another console for that purpose. You may need to forward ports on your router.
#
# $ ruby -run -e httpd public -p 8080 --bind-address 0.0.0.0

# Load a saved challenge. This is only required if you need to reuse a saved challenge as outlined above.
challenge = client.challenge_from_hash(JSON.parse(File.read('challenge')))

# Once you are ready to serve the confirmation request you can proceed.
challenge.request_verification # => true
challenge.verify_status # => 'pending'

# Wait a bit for the server to make the request, or just blink. It should be fast.
sleep(1)

challenge.verify_status # => 'valid'

Obtain a certificate

Now that your account is authorized for the domain, you should be able to obtain a certificate for it.

# We're going to need a certificate signing request. If not explicitly
# specified, the first name listed becomes the common name.
csr = Acme::Client::CertificateRequest.new(names: %w[example.org www.example.org])

# We can now request a certificate. You can pass anything that returns
# a valid DER encoded CSR when calling to_der on it. For example an
# OpenSSL::X509::Request should work too.
certificate = client.new_certificate(csr) # => #<Acme::Client::Certificate ....>

# Save the certificate and the private key to files
File.write("privkey.pem", certificate.request.private_key.to_pem)
File.write("cert.pem", certificate.to_pem)
File.write("chain.pem", certificate.chain_to_pem)
File.write("fullchain.pem", certificate.fullchain_to_pem)

# Start a webserver, using your shiny new certificate
# ruby -r openssl -r webrick -r 'webrick/https' -e "s = WEBrick::HTTPServer.new(
#   :Port => 8443,
#   :DocumentRoot => Dir.pwd,
#   :SSLEnable => true,
#   :SSLPrivateKey => OpenSSL::PKey::RSA.new( File.read('privkey.pem') ),
#   :SSLCertificate => OpenSSL::X509::Certificate.new( File.read('cert.pem') )); trap('INT') { s.shutdown }; s.start"

Not implemented

  • Recovery methods are not implemented.
  • proofOfPossession-01 is not implemented.

Requirements

Ruby >= 2.1

Development

All the tests use VCR to mock the interaction with the server but if you need to record new interation against the server simply clone boulder and run it normally with ./start.py.

Pull request?

Yes.

License

MIT License

acme-client's People

Contributors

unixcharles avatar jhass avatar ajacques avatar technion avatar weppos avatar 0x7466 avatar sawanoboly avatar nikita-v avatar orthographic-pedant avatar felixfkrull avatar will-in-wi avatar mjtko avatar louim avatar blackjid avatar itspriddle avatar saltsa avatar dnsco avatar dkam avatar kintner avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.