-
-
Save technion/f299433f42dd3ae5dd96 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby | |
# We're going to need a private key. | |
require 'openssl' | |
# Initialize the client | |
require 'acme/client' | |
# We need an ACME server to talk to, see github.com/letsencrypt/boulder | |
ENDPOINT = 'https://acme-v01.api.letsencrypt.org/' | |
#ENDPOINT = 'https://acme-staging.api.letsencrypt.org' | |
ACCOUNT_FILE = 'account_key.pem' | |
NAMES = { 'lolware.net' => '/var/www/html', | |
'erlvulnscan.lolware.net' => '/home/technion/erlvulnscan/frontend/build', | |
'ctadvisor.lolware.net' => '/home/technion/ct_advisor_int/public', | |
'www.lolware.net' => '/var/www/html' | |
} | |
unless File.exist?(ACCOUNT_FILE) | |
puts "Creating new account file" | |
private_key = OpenSSL::PKey::RSA.new(2048) | |
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'll may need to agree to the term (that's up the to the server to require i | |
t or not but boulder does by default) | |
registration.agree_terms | |
NAMES.each do |subject, path| | |
authorization = client.authorize(domain: subject) | |
challenge = authorization.http01 | |
# Save the file. We'll create a public directory to serve it from, and we'll cre | |
ating the challenge directory. | |
FileUtils.mkdir_p( File.join( path, File.dirname( challenge.filename ) ) ) | |
# Then writing the file | |
File.write( File.join( path, challenge.filename), challenge.file_content ) | |
# Wait a bit for the server to make the request, or really just blink, it should | |
be fast. | |
sleep(5) | |
puts "Verification status: " + challenge.verify_status # => 'pending' | |
end | |
open ACCOUNT_FILE, 'w' do |io| | |
io.write private_key.to_pem | |
end | |
puts "New account written" | |
end | |
private_key = OpenSSL::PKey::RSA.new(File.read ACCOUNT_FILE) | |
client = Acme::Client.new(private_key: private_key, endpoint: ENDPOINT) | |
# 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: NAMES.keys) | |
# 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 a | |
# OpenSSL::X509::Request too. | |
certificate = client.new_certificate(csr) # => #<Acme::Client::Certificate ....> | |
# Save the certificate and key | |
File.write("privkey.pem", certificate.request.private_key.to_pem) | |
File.write("fullchain.pem", certificate.fullchain_to_pem) | |
I have corrected the syntax issue - there appeared to be a paste error uploading this gist originally.
Unauthorized error would suggest you have not had that particular domain approved for the Lets Encrypt beta program. This issue will resolve itself when you come out of beta.
Note this now an updated release, which includes subjectAltNames support.
I have the same problem as @solisoft above. My domain is explicitly in the whitelist (At least, it's in the list in the email I received notifying me that I'm in the Beta....
@andrewkendall You will receive such an error, if your verify_status
will be 'invalid'. It can be, for example, if you not started your server, or it is unavailable and LetsEncrypt can't read your verification file
Note there has been an overhauled API in the acme-client gem. This gist is now obsolete.
I did modify the script to handle both errors ...
Now I have Error creating new cert :: Authorizations for these names not found or expired: solisoft.net (Acme::Error::Unauthorized) I guess I need a trial account (doable ? )
Here my modified script : https://gist.github.com/solisoft/4fa9643ea7eab9bdb378