Giter Site home page Giter Site logo

chef-acme's Introduction

ACME cookbook

Build Status Cookbook Version

Automatically get/renew free and trusted certificates from Let's Encrypt (letsencrypt.org). ACME is the Automated Certificate Management Environment protocol used by Let's Encrypt.

Starting with v4.0.0 of the acme cookbook the acme_ssl_certificate provider has been removed! The TLS-SNI-01 validation method used by this provider been disabled by Let's Encrypt due to security concerns. Please switch to the acme_certificate provider in this cookbook to request and renew your certificate using the supported HTTP-01 validation method.

Attributes

Attribute Description Default
contact Contact information, default empty. Set to mailto:[email protected] []
dir ACME server endpoint, Set to https://acme-staging-v02.api.letsencrypt.org/directory if you want to use the Let's Encrypt staging environment and corresponding certificates. https://acme-v02.api.letsencrypt.org/directory
renew Days before the certificate expires at which the certificate will be renewed 30
source_ips IP addresses used by Let's Encrypt to verify the TLS certificates, it will change over time. This attribute is for firewall purposes. Allow these IPs for HTTP (tcp/80). ['66.133.109.36']
private_key Private key content of registered account. Private keys identify the ACME client with the endpoint and are not transferable between staging and production endpoints. nil
private_key_file Filename where private key will be saved. If this file exists, the contents take precedence over the value set in private_key. /etc/acme/account_private_key.pem
key_size Default private key size used when resource property is not. Must be one out of: 2048, 3072, 4096. 2048

Recipes

default

Installs the required acme-client rubygem.

Usage

Use the acme_certificate resource to request a certificate with the http-01 challenge. The webserver for the domain for which you are requesting a certificate must be running on the local server. This resource only supports the http validation method. To use the tls-sni-01 challenge, please see the resource below. Provide the path to your wwwroot for the specified domain.

acme_certificate 'test.example.com' do
  crt               '/etc/ssl/test.example.com.crt'
  key               '/etc/ssl/test.example.com.key'
  wwwroot           '/var/www'
end

If your webserver needs an existing certificate already when installing a new server, you will have a bootstrap problem: The web server cannot start without a certificate, but the certificate cannot be requested without the running web server. To overcome this, a temporary self-signed certificate can be generated with the acme_selfsigned resource, allowing the web server to start.

acme_selfsigned 'test.example.com' do
  crt     '/etc/ssl/test.example.com.crt'
  chain   '/etc/ssl/test.example.com-chain.crt'
  key     '/etc/ssl/test.example.com.key'
end

A working example can be found in the included acme_client test cookbook.

Providers

certificate

Property Type Default Description
cn string name The common name for the certificate
alt_names array [] The common name for the certificate
crt string nil File path to place the certificate
key string nil File path to place the private key
key_size integer 2048 Private key size. Must be one out of: 2048, 3072, 4096
owner string,integer root Owner of the created files
group string,integer root Group of the created files
wwwroot string /var/www Path to the wwwroot of the domain
ignore_failure boolean false Whether to continue chef run if issuance fails
retries integer 0 Number of times to catch exceptions and retry
retry_delay integer 2 Number of seconds to wait between retries
endpoint string nil The Let's Encrypt endpoint to use
contact array [] The contact to use

selfsigned

Property Type Default Description
cn string name The common name for the certificate
crt string nil File path to place the certificate
key string nil File path to place the private key
key_size integer 2048 Private key size. Must be one out of: 2048, 3072, 4096
chain string nil File path to place the certificate chain
owner string,integer root Owner of the created files
group string,integer root Group of the created files

Example

To generate a certificate for an apache2 website you can use code like this:

# Include the recipe to install the gems
include_recipe 'acme'

# Set up contact information. Note the mailto: notation
node.override['acme']['contact'] = ['mailto:[email protected]']
# Real certificates please...
node.override['acme']['endpoint'] = 'https://acme-v01.api.letsencrypt.org'

site = "example.com"
sans = ["www.#{site}"]

# Generate a self-signed if we don't have a cert to prevent bootstrap problems
acme_selfsigned "#{site}" do
  crt     "/etc/httpd/ssl/#{site}.crt"
  key     "/etc/httpd/ssl/#{site}.key"
  chain    "/etc/httpd/ssl/#{site}.pem"
  owner   "apache"
  group   "apache"
  notifies :restart, "service[apache2]", :immediate
end

# Set up your web server here...

# Get and auto-renew the certificate from Let's Encrypt
acme_certificate "#{site}" do
  crt               "/etc/httpd/ssl/#{site}.crt"
  key               "/etc/httpd/ssl/#{site}.key"
  wwwroot           "/var/www/#{site}/htdocs/"
  notifies :restart, "service[apache2]"
  alt_names sans
end

DNS verification

Letsencrypt supports DNS validation. Depending on the setup there may be different ways to deploy an acme challenge to your infrastructure. If you want to use DSN validation, you have to provide two block arguments to the acme_certificate resource.

Implement 2 methods in a library in your cookbook, each returning a Proc object. The following example uses a HTTP API to provide challenges to the DNS infrastructure.

# my_cookbook/libraries/acme_dns.rb

class Chef
  class Recipe
    def install_dns_challenge(apitoken)
      Proc.new do |authorization, new_resource|
        # use DNS authorization
        authz = authorization.dns
        fqdn = authorization.identifier['value']
        r = Net::HTTP.post(URI("https://my_awesome_dns_api/#{fqdn}"), authz.record_content, {'Authorization' => "Token #{apitoken}"})
        if r.code != '200'
          fail "DNS API does not want to install Challenge for #{fqdn}"
        else
          # do some validation that the challenge has propagated to the infrastructure
        end
        # it is important that the authz and fqdn is passed back, so it can be passed to the remove_dns_challenge method
        [authz, fqdn]
      end
    end
    def remove_dns_challenge(apitoken)
      Proc.new do |authz, fqdn|
        uri = URI("https://my_awesome_dns_api/#{fqdn}")
        Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme=='https') do |http|
          http.delete(uri, {'Authorization' => "Token #{apitoken}"})
        end
      end
    end
  end
end

Use it in your recipe the following way:

apitoken = chef_vault_item(vault, item)['dns_api_token']
acme_certificate node['fqdn'] do
  key '/path/to/key'
  crt '/path/to/crt'
  install_authz_block install_dns_challenge(apitoken)
  remove_authz_block remove_dns_challenge(apitoken)
end

Testing

The kitchen includes a pebble server to run the integration tests with, so testing can run locally without interaction with the online APIs.

Contributing

  1. Fork the repository on Github
  2. Create a named feature branch (like add_component_x)
  3. Write your change
  4. Write tests for your change (if applicable)
  5. Run the tests, ensuring they all pass
  6. Submit a Pull Request using Github

License and Authors

Authors: Thijs Houtenbos [email protected]

Credits

Let’s Encrypt is a trademark of the Internet Security Research Group. All rights reserved.

chef-acme's People

Contributors

acoulton avatar alex-tan avatar arr-dev avatar axos88 avatar bugoff avatar chr4 avatar dawnflash avatar detjensrobert avatar faucct avatar funzoneq avatar hrak avatar ibaum avatar jeffbyrnes avatar kiwidream avatar mattrobenolt avatar miguelaferreira avatar mrseccubus avatar notapatch avatar obazoud avatar patcon avatar petracvv avatar ramereth avatar rmoriz avatar sawanoboly avatar seansith avatar thoutenbos avatar twk3 avatar wndhydrnt avatar zakame avatar zedtux avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chef-acme's Issues

Certificate is not updated when common name / alternate names changed

The letsencrypt provider only creates a new certificate if the certificate file does not exist or if the certificate is approaching expiry. If there is a valid non-expired certificate on disk at the specified path then the provider does nothing.

I think it should also check that the common name and alternate names on the existing certificate match those declared on the resource, and provision a new certificate if any of those have changed?

Chef 11

Curious if this cookbook is compatible with Chef 11? After digging it looks like the 1.0 releases were but they are not available on chef supermarket, any reason for that?

Recommended workflow for certificate renewal

Hi Thijs,

thanks for your great work with this cookbook. Since renewal should be automated, what would be your recommended workflow?
I'm using chef-solo, so I could run chef-solo once a month in a cron job. However, since there is a lot going on during a chef run I'd be more comfortable only running a single script. Would you recommend this or does anything come to mind that goes against this?

Thank you!

Tim

Doesn't fail provisioning when validation fails

Thanks for this cookbook.

I was just stubbing out a recipe for this on a local vagrant box, and realised that although validation fails (and there's an error in the log) the letsencrypt_certificate resource appears to complete successfully. I would have expected the resource and the overall chef run to fail in this case - without triggering any delayed notifications - which is generally the convention with other chef resources.

Is this intentional, and/or am I doing something wrong?

==> default: * letsencrypt_certificate[{name}] action create
==> default:
==> default: * file[{name} SSL key] action create_if_missing
==> default:  (up to date)
==> default:
==> default: * directory[{docroot}/.well-known/acme-challenge] action create
==> default: [2016-02-26T23:01:14+00:00] INFO: directory[{docroot}/.well-known/acme-challenge] owner changed to 0
==> default: [2016-02-26T23:01:14+00:00] INFO: directory[{docroot}/.well-known/acme-challenge] group changed to 0
==> default: [2016-02-26T23:01:14+00:00] INFO: directory[{docroot}/.well-known/acme-challenge] mode changed to 755
==> default:
==> default: - change mode from '0777' to '0755'
==> default:
==> default: - change owner from 'vagrant' to 'root'
==> default:
==> default: - change group from 'vagrant' to 'root'
==> default:
==> default: * file[{docroot}/.well-known/acme-challenge/{token}] action create
==> default: [2016-02-26T23:01:14+00:00] INFO: file[{docroot}/.well-known/acme-challenge/{token}] created file /var/www/sciswiper/current/h
docs/.well-known/acme-challenge/{token}
==> default:
==> default: - create new file {docroot}/.well-known/acme-challenge/{token}
==> default: [2016-02-26T23:01:14+00:00] INFO: file[{docroot}/.well-known/acme-challenge/{token}] updated file contents /var/www/sciswiper/
urrent/htdocs/.well-known/acme-challenge/{token}

# {skipped other resource output}

==> default: [2016-02-26T23:01:14+00:00] INFO: file[{docroot}/.well-known/acme-challenge/{token}] owner changed to 0
==> default: [2016-02-26T23:01:14+00:00] INFO: file[{docroot}/.well-known/acme-challenge/{token}] group changed to 0
==> default: [2016-02-26T23:01:14+00:00] INFO: file[{docroot}/.well-known/acme-challenge/{token}] mode changed to 644
==> default:
==> default: - change mode from '' to '0644'
==> default:
==> default: - change owner from '' to 'root'
==> default:
==> default: - change group from '' to 'root'
==> default: [2016-02-26T23:01:25+00:00] ERROR: [{name}] Validation failed for domain {name}
==> default:
==> default: * file[{name} SSL key] action nothing
==> default:  (skipped due to action :nothing)
==> default:
==> default: * directory[{docroot}/.well-known/acme-challenge] action create
==> default:  (up to date)
==> default:
==> default: * file[{docroot}/.well-known/acme-challenge/{token}] action create
==> default:  (up to date)
==> default:
==> default: * ruby_block[create certificate for {name}] action run
==> default: [2016-02-26T23:01:25+00:00] **ERROR: [{name}] Validation failed, unable to request certificate**

# {skipped other resource output}

==> default: [2016-02-26T23:01:43+00:00] INFO: letsencrypt_certificate[{name}] sending reload action to service[apache2] (delayed)
==> default: Recipe: project::app-server
==> default:
==> default: * service[apache2] action reload
==> default: [2016-02-26T23:01:43+00:00] INFO: service[apache2] reloaded
==> default:
==> default:     - reload service service[apache2]

# {skipped other resource output}

==> default: [2016-02-26T23:01:55+00:00] INFO: letsencrypt_certificate[{name}] not queuing delayed action reload on service[apache2] (delayed), as it's already been queued
==> default: [2016-02-26T23:01:55+00:00] INFO: Chef Run complete in 45.600917319 seconds
==> default: [2016-02-26T23:01:55+00:00] INFO: Skipping removal of unused files from the cache
==> default: Running handlers:
==> default: [2016-02-26T23:01:55+00:00] INFO: Running report handlers
==> default: Running handlers complete
==> default: [2016-02-26T23:01:55+00:00] INFO: Report handlers complete
==> default: Chef Client finished, 24/226 resources updated in 46.651249508 seconds

test kitchen not running

on ubuntu the server does not start up correcly, due to a wrong passowrd (and etchosts file too)
on centos it doesn't find the box.

      
       
       These processes exited early (check above for their output):
        'GORACE="halt_on_error=1" exec ./bin/boulder-sa --config test/boulder-config.json' with pid 25461 exited 1
       started exec listenbuddy -listen :5673 -speak boulder-rabbitmq:5672 with pid 24823
       export GO15VENDOREXPERIMENT=1
       GOBIN=/opt/go/src/github.com/letsencrypt/boulder/bin go install  ./...
       started GORACE="halt_on_error=1" exec ./bin/boulder-wfe --config test/boulder-config.json with pid 25457
       started GORACE="halt_on_error=1" exec ./bin/boulder-ra --config test/boulder-config.json with pid 25458
       started GORACE="halt_on_error=1" exec ./bin/boulder-sa --config test/boulder-config.json with pid 25461
       started GORACE="halt_on_error=1" exec ./bin/boulder-ca --config test/boulder-config.json with pid 25464
       started GORACE="halt_on_error=1" exec ./bin/boulder-va --config test/boulder-config.json with pid 25470
       I212423 boulder-wfe Versions: boulder-wfe=(Unspecified Unspecified) Golang=(go1.5) BuildHost=(Unspecified)
       started GORACE="halt_on_error=1" exec ./bin/boulder-publisher --config test/boulder-config.json with pid 25473
       I212423 boulder-ra Versions: boulder-ra=(Unspecified Unspecified) Golang=(go1.5) BuildHost=(Unspecified)
       started GORACE="halt_on_error=1" exec ./bin/ocsp-updater --config test/boulder-config.json with pid 25476
       started GORACE="halt_on_error=1" exec ./bin/ocsp-responder --config test/boulder-config.json with pid 25482
       I212424 boulder-sa Versions: boulder-sa=(Unspecified Unspecified) Golang=(go1.5) BuildHost=(Unspecified)
       I212424 boulder-wfe WFE using key policy: goodkey.KeyPolicy{AllowRSA:true, AllowECDSANISTP256:true, AllowECDSANISTP384:true, AllowECDSANISTP521:false}
       I212424 boulder-wfe Server running, listening on 0.0.0.0:4000...
       
       I212424 boulder-ra loading hostname policy, sha256: 3ddc932620e3f59623af52971fcc3cf38c9759f64575fd018a7097875427ea5e
       started GORACE="halt_on_error=1" exec ./bin/ct-test-srv --config test/boulder-config.json with pid 25484
       started GORACE="halt_on_error=1" exec ./bin/dns-test-srv --config test/boulder-config.json with pid 25487
       I212424 boulder-ca Versions: boulder-ca=(Unspecified Unspecified) Golang=(go1.5) BuildHost=(Unspecified)
       I212424 boulder-ca loading hostname policy, sha256: 3ddc932620e3f59623af52971fcc3cf38c9759f64575fd018a7097875427ea5e
       started GORACE="halt_on_error=1" exec ./bin/mail-test-srv --config test/boulder-config.json with pid 25489
       E212424 boulder-sa [AUDIT] Couldn't connect to SA database: Error 1045: Access denied for user 'sa'@'localhost' (using password: NO)
       Couldn't connect to SA database: Error 1045: Access denied for user 'sa'@'localhost' (using password: NO)
       started GORACE="halt_on_error=1" exec ./bin/ocsp-responder --config test/issuer-ocsp-responder.json with pid 25493
       I212424 boulder-va Versions: boulder-va=(Unspecified Unspecified) Golang=(go1.5) BuildHost=(Unspecified)
       I212424 boulder-publisher Versions: boulder-publisher=(Unspecified Unspecified) Golang=(go1.5) BuildHost=(Unspecified)
       started GORACE="halt_on_error=1" exec ./bin/caa-checker --config cmd/caa-checker/test-config.yml with pid 25499
       
       
       These processes exited early (check above for their output):
        'GORACE="halt_on_error=1" exec ./bin/boulder-sa --config test/boulder-config.json' with pid 25461 exited 1

akos@akos-ui ~/projects/freelancer/chef/chef-acme $ kitchen converge ssl-centos-7
Expected array default value for '--driver'; got "kitchen-vagrant" (string)
-----> Starting Kitchen (v1.14.0)
-----> Creating <ssl-centos-7>...
       Bringing machine 'default' up with 'virtualbox' provider...
       ==> default: Box 'opscode-centos-7.1' could not be found. Attempting to find and install...
           default: Box Provider: virtualbox
           default: Box Version: >= 0
       ==> default: Box file was not detected as metadata. Adding it directly...
       ==> default: Adding box 'opscode-centos-7.1' (v0) for provider: virtualbox
           default: Downloading: opscode-centos-7.1
An error occurred while downloading the remote file. The error
       message, if any, is reproduced below. Please fix this error and try
       again.
       
       Couldn't open file /home/akos/projects/freelancer/chef/chef-acme/.kitchen/kitchen-vagrant/kitchen-chef-acme-ssl-centos-7/opscode-centos-7.1
>>>>>> ------Exception-------
>>>>>> Class: Kitchen::ActionFailed
>>>>>> Message: 1 actions failed.
>>>>>>     Failed to complete #create action: [Expected process to exit with [0], but received '1'
---- Begin output of vagrant up --no-provision --provider virtualbox ----
STDOUT: Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'opscode-centos-7.1' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
==> default: Box file was not detected as metadata. Adding it directly...
==> default: Adding box 'opscode-centos-7.1' (v0) for provider: virtualbox
    default: Downloading: opscode-centos-7.1

STDERR: An error occurred while downloading the remote file. The error
message, if any, is reproduced below. Please fix this error and try
again.

Couldn't open file /home/akos/projects/freelancer/chef/chef-acme/.kitchen/kitchen-vagrant/kitchen-chef-acme-ssl-centos-7/opscode-centos-7.1
---- End output of vagrant up --no-provision --provider virtualbox ----
Ran vagrant up --no-provision --provider virtualbox returned 1] on ssl-centos-7
>>>>>> ----------------------
>>>>>> Please see .kitchen/logs/kitchen.log for more details
>>>>>> Also try running `kitchen diagnose --all` for configuration

Recommended approach for apache

Not sure whether this is too opinionated, but as someone who just worked through how to get this working with apache, I thought perhaps it might be useful to bring some bits into this cookbook:

https://github.com/parallels-cookbooks/confluence/pull/93/files

Any thoughts? Mostly thinking the "letencrypt.conf" apache config fragment approach. Seems like it might be nice to add and create a test for, so that the current test goes a little bit further in explaining how to get things working

(I'm aware that some apps might get confused by being proxied, but seems to be working fine in our situation)

Centos 7 Error with LWRP

I'm trying to use your cookbook on Centos 7 with httpd:

Recipe: letsencrypt::default

  • chef_gem[acme-client] action install (up to date)
    Converging 56 resources

Running handlers:
[2016-04-20T07:57:21+00:00] ERROR: Running exception handlers
Running handlers complete
[2016-04-20T07:57:21+00:00] ERROR: Exception handlers complete
Chef Client failed. 0 resources updated in 08 seconds
[2016-04-20T07:57:22+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
[2016-04-20T07:57:22+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2016-04-20T07:57:22+00:00] ERROR: resource letsencrypt_certificate[performance.fanatics-it.de] is configured to notify resource service[httpd] with action reload, but service[httpd] cannot be found in the resource collection. letsencrypt_certificate[performance.fanatics-it.de] is defined in /var/chef/cache/cookbooks/zabbix3-server/recipes/default.rb:17:in `from_file'

HTTPD is of course installed and running.

New release causes ruby syntax error when installed from supermarket

variations on

[2016-07-11T16:02:49-04:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2016-07-11T16:02:49-04:00] ERROR: /tmp/gocd-chef-botstrap_06LYSPjH/.chef/local-mode-cache/cache/cookbooks/letsencrypt/libraries/PaxHeader/acme.rb:1: syntax error, unexpected tIDENTIFIER, expecting end-of-input
17 gid=450652656
      ^
[2016-07-11T16:02:50-04:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

Googling suggests this is to do with running the package step on OS X with extended attributes accidentally set? (e.g. sous-chefs/redisio#147 )

Changing policyfile to point to github fixes it for now, but I'd prefer to use supermarket overall

Private key stored in node attributes

Does the private key need to persist on the node attributes, since it can be read from disk? It would be nice to be able to remove it.

(btw -- thanks for all of your great work on this)

Validation failed, unable to request certificate

I'm using a recipe very much based on acme-client, but with my own server name. I cannot get it to work. Every time, I get:

aws_instance.ciserver (remote-exec):     * ruby_block[create certificate for jenkins.aws.3wi.io] action run[2016-03-10T17:25:59+00:00] ERROR: [jenkins.aws.3wi.io] Validation failed, unable to request certificate

I have checked that the challenge is accessible (e.g. I can browse http://jenkins.aws.3wi.io/.well-known/acme-challenge/NSbcKRWllRkBCtWS0Ot-C1lNOJqXQxusdNciend-g0c and get the response). There's nothing in the nginx log. I've tried both staging and live.

Any ideas? Been beating my head against this for a couple of days and have to admit I am stuck.

This is my nginx conf:

server {
  listen   80;
  server_name jenkins.aws.3wi.io;
  access_log /var/log/nginx/localhost.access.log;
  error_log /var/log/nginx/localhost.error.log;
  location / {
    default_type "text/plain";
    root   /var/www/nginx-default;
    index  index.html;
  }
}

server {
  listen   443;
  ssl    on;
  ssl_certificate    /etc/ssl/jenkins.aws.3wi.io.crt;
  ssl_certificate_key    /etc/ssl/jenkins.aws.3wi.io.key;
  server_name jenkins.aws.3wi.io;
  access_log /var/log/nginx/localhost.access.log;
  error_log /var/log/nginx/localhost.error.log;
  location / {
    root   /var/www/nginx-default;
    index  index.html;
  }
}

This is my recipe:

include_recipe 'letsencrypt'

# Generate selfsigned certificate so nginx can start
letsencrypt_selfsigned 'jenkins.aws.3wi.io' do
  crt     '/etc/ssl/jenkins.aws.3wi.io.crt'
  key     '/etc/ssl/jenkins.aws.3wi.io.key'
end

include_recipe 'nginx'

cookbook_file "#{node['nginx']['dir']}/sites-available/test" do
  source 'nginx-test.conf'
end

directory node['nginx']['default_root'] do
  owner 'root'
  group 'root'
  recursive true
end

cookbook_file "#{node['nginx']['default_root']}/index.html" do
  source 'index.html'
end

nginx_site 'test' do
  timing :immediately
end

# Request the real certificate
letsencrypt_certificate 'jenkins.aws.3wi.io' do
  fullchain '/etc/ssl/jenkins.aws.3wi.io.crt'
  chain     '/etc/ssl/jenkins.aws.3wi.io-chain.crt'
  key       '/etc/ssl/jenkins.aws.3wi.io.key'
  method    'http'
  wwwroot   node['nginx']['default_root']
  notifies  :reload, 'service[nginx]'
end

Error use recipe letsencript

I used your recipe and return error bellow:

================================================================================�[0m
�[31mRecipe Compile Error in /var/chef/cookbooks/empresa/recipes/letsencript.rb�[0m
================================================================================�[0m
�[0mNoMethodError�[0m
-------------�[0m
undefined method compile_time' for Chef::Resource::ChefGem�[0m �[0mCookbook Trace:�[0m ---------------�[0m /var/chef/cookbooks/letsencrypt/recipes/default.rb:24:inblock in from_file'
�[0m /var/chef/cookbooks/letsencrypt/recipes/default.rb:21:in from_file' �[0m /var/chef/cookbooks/empresa/recipes/letsencript.rb:2:infrom_file'�[0m

�[0mRelevant File Content:�[0m ----------------------�[0m
/var/chef/cookbooks/letsencrypt/recipes/default.rb:
�[0m
�[0m 17: # See the License for the specific language governing permissions and
�[0m 18: # limitations under the License.
�[0m 19: #
�[0m 20:
�[0m 21: chef_gem 'acme-client' do
�[0m 22: action :install
�[0m 23: version '0.2.2'
�[0m 24>> compile_time true
�[0m 25: end
�[0m 26:
�[0m 27: require 'acme-client'
�[0m 28: �[0m

�[0m[2016-06-06T14:45:53-03:00] ERROR: Running exception handlers
[2016-06-06T14:45:53-03:00] ERROR: Exception handlers complete
[2016-06-06T14:45:53-03:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
[2016-06-06T14:45:53-03:00] ERROR: undefined method `compile_time' for Chef::Resource::ChefGem
[2016-06-06T14:45:53-03:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
Build step 'Execute shell' marked build as failure
Notifying upstream projects of job completion
Finished: FAILURE

Ambient description:
System: ubuntu 14.04
Ruby versions tested: 1.9, 2.1 and 2.2
I installed this gem manually with 'gem install acme-client -v 0.2.4' continue the error.

uninitialized constant Acme

Added the following to Berksfile

cookbook 'letsencrypt', '~> 1.0.0'

Added the following to metadata.rb

depends 'letsencrypt'

Created a recipe similar to the following:

letsencrypt_certificate 'test.example.com' do
  crt      '/etc/ssl/test.example.com.crt'
  key      '/etc/ssl/test.example.com.key'
  method   'http'
  wwwroot  '/var/www'
end

When running a converge on this node it's throwing the error below. Any insight would be appreciated

           NameError
           ---------
           uninitialized constant Acme
           
           Cookbook Trace:
           ---------------
           /tmp/kitchen/cache/cookbooks/letsencrypt/libraries/acme.rb:37:in `acme_client'
           /tmp/kitchen/cache/cookbooks/letsencrypt/libraries/acme.rb:49:in `acme_authz'
           /tmp/kitchen/cache/cookbooks/letsencrypt/providers/certificate.rb:54:in `block (2 levels) in class_from_file'
           /tmp/kitchen/cache/cookbooks/letsencrypt/providers/certificate.rb:53:in `map'
           /tmp/kitchen/cache/cookbooks/letsencrypt/providers/certificate.rb:53:in `block in class_from_file'
           /tmp/kitchen/cache/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/runner.rb:41:in `run_action'

Reloading web server configuration

Hi,

This looks very good, but have any thought been given to how to best make sure that the web servers configuration is reloaded when the certificate is updated?

Intermediate certificates

Does this client library support full certificate chains?
The certificates I get are missing the intermediate certificates of letsencrypt, therefore not being trusted on many clients.

Is there an option I didn't find, or is this an issue? Unfortunately, as there's X1 X2 X3 X4, it's not as simple as simply appending the certificate chain to the generated certificate.

Did I miss something?

Fix for chef-client v11 compatibility

Download v.1.0.0.
I used chef-client v.11.16.4
And have this error:

[2016-06-15T07:24:26+00:00] INFO: Processing chef_gem[acme-client] action install (letsencrypt::default line 21)
[2016-06-15T07:24:51+00:00] ERROR: Running exception handlers
[2016-06-15T07:24:51+00:00] ERROR: Exception handlers complete
[2016-06-15T07:24:51+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
[2016-06-15T07:24:51+00:00] INFO: Sending resource update report (run-id: 6c22f109-dba0-4d33-823d-ee7c9cb14a89)
[2016-06-15T07:24:52+00:00] ERROR: /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/acme-client-0.2.4/lib/acme/client/certificate_request.rb:28: syntax error, unexpected tLABEL, expecting ')'
  def initialize(common_name: nil,
                             ^
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/acme-client-0.2.4/lib/acme/client/certificate_request.rb:28: Can't assign to nil
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/acme-client-0.2.4/lib/acme/client/certificate_request.rb:32: syntax error, unexpected ')', expecting keyword_end
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/acme-client-0.2.4/lib/acme/client/certificate_request.rb:115: syntax error, unexpected keyword_end, expecting $end
[2016-06-15T07:24:52+00:00] ERROR: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

Help please, how to fix?

Ubuntu 14.04 support

Is there any reason why v4.0.0 only support Ubuntu 16.04? So far the cookbook has worked fine on 14.04 as well.

Can't install from Cheffile

Am I doing something wrong? I updated my Cheffile with the following:

cookbook "letsencrypt", "~> 0.1.4"

And then install the cookbooks like so:

$ librarian-chef install
/Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-chef-0.0.4/lib/librarian/chef/source/site.rb:309:in `unpack_package!': The package archive has too many children! (
RuntimeError)
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-chef-0.0.4/lib/librarian/chef/source/site.rb:224:in `cache_version_uri_unpacked!'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-chef-0.0.4/lib/librarian/chef/source/site.rb:93:in `block in version_uri_manifest'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-chef-0.0.4/lib/librarian/chef/source/site.rb:381:in `memo'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-chef-0.0.4/lib/librarian/chef/source/site.rb:92:in `version_uri_manifest'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-chef-0.0.4/lib/librarian/chef/source/site.rb:88:in `version_manifest'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-chef-0.0.4/lib/librarian/chef/source/site.rb:54:in `version_dependencies'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-chef-0.0.4/lib/librarian/chef/source/site.rb:462:in `fetch_dependencies'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/manifest.rb:125:in `fetch_dependencies!'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/manifest.rb:117:in `fetched_dependencies'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/manifest.rb:81:in `dependencies'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:117:in `block in check_manifest_for_cycles'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:117:in `each'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:117:in `map'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:117:in `check_manifest_for_cycles'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:64:in `block in recursive_resolve'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:154:in `block (3 levels) in resolving_dependency_map_fi
nd_manifests'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:187:in `block in scope_checking_manifest'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:223:in `scope'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:186:in `scope_checking_manifest'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:153:in `block (2 levels) in resolving_dependency_map_fi
nd_manifests'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:211:in `block in map_find'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:210:in `each'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:210:in `map_find'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:152:in `block in resolving_dependency_map_find_manifest
s'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:165:in `block (2 levels) in scope_resolving_dependency'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:179:in `block in scope_checking_manifests'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:223:in `scope'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:178:in `scope_checking_manifests'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:164:in `block in scope_resolving_dependency'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:223:in `scope'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:163:in `scope_resolving_dependency'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:151:in `resolving_dependency_map_find_manifests'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:62:in `recursive_resolve'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver/implementation.rb:50:in `resolve'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/resolver.rb:23:in `resolve'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/action/resolve.rb:26:in `run'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/cli.rb:169:in `resolve!'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-chef-0.0.4/lib/librarian/chef/cli.rb:41:in `install'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/command.rb:27:in `run'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in `invoke_command'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor.rb:359:in `dispatch'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/base.rb:440:in `start'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/cli.rb:26:in `block (2 levels) in bin!'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/cli.rb:31:in `returning_status'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/cli.rb:26:in `block in bin!'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/cli.rb:47:in `with_environment'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-0.1.2/lib/librarian/cli.rb:26:in `bin!'
        from /Users/achan/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/librarian-chef-0.0.4/bin/librarian-chef:7:in `<top (required)>'
        from /Users/achan/.rbenv/versions/2.1.5/bin/librarian-chef:23:in `load'

Any suggestions / directions? When I remove the cookbook, the others can be installed properly.

Ruby version block

Hello. Since today I have problems using this cookbook because of the ACME client.

Mixlib::ShellOut::ShellCommandFailed
------------------------------------
chef_gem[acme-client] (letsencrypt::default line 21) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit with [0], but received '1'
---- Begin output of /opt/chef/embedded/bin/gem install acme-client -q --no-rdoc --no-ri -v "0.2.4" ----
STDOUT: 
STDERR: ERROR:    Error installing acme-client:
  activesupport requires Ruby version >= 2.2.2.
---- End output of /opt/chef/embedded/bin/gem install acme-client -q --no-rdoc --no-ri -v "0.2.4" ----
Ran /opt/chef/embedded/bin/gem install acme-client -q --no-rdoc --no-ri -v "0.2.4" returned 1`

Chef is using this Ruby version (Ubuntu 14.04):

/opt/chef/embedded/bin/ruby -v
ruby 2.1.8p440 (2015-12-16 revision 53160) [x86_64-linux]

Do you know any way how to resolve this? This is a really, really big problem for me :(

Thanks!

Compile / Converge issues

It seems like there are some problems with generating the private key and requesting a new certificate, as the key is not generated and available in the same phase. I'm sure there are lots of ways to fix this, one of them being generating self-signed key for the same domain first.

Load Error: cannot load such file -- acme-client

I am using:

Chef Development Kit Version: 2.4.17
chef-client version: 13.6.4
berks version: 6.3.1
kitchen version: 1.19.2
inspec version: 1.45.13

And I get the following error with ChefSpec:

      LoadError:
        cannot load such file -- acme-client
      # /var/folders/2j/k1y8bp_53xz84ss2y5wn337w0000gp/T/chefspec20180313-89745-13lh3hofile_cache_path/cookbooks/acme/recipes/default.rb:27:in `from_file'
      # /var/folders/2j/k1y8bp_53xz84ss2y5wn337w0000gp/T/chefspec20180313-89745-13lh3hofile_cache_path/cookbooks/mail-processor/recipes/default.rb:113:in `from_file'
      # ./spec/unit/recipes/default_spec.rb:37:in `block (3 levels) in <top (required)>'
      # ./spec/unit/recipes/default_spec.rb:154:in `block (3 levels) in <top (required)>'

Am I missing something?

Thank you.

No registration exists matching provided key

Hi there,

I am trying to get your acme_client code to run. It works with the staging server, but when I try to use the real endpoint I get the error:

Acme::Client::Error::Unauthorized
---------------------------------
No registration exists matching provided key

My code is pretty much the same as yours, this are my attributes:

default['letsencrypt']['contact'] = 'mailto:[email protected]'
default['letsencrypt']['endpoint'] = 'https://acme-v01.api.letsencrypt.org'

I am running Ubuntu 14.04. Do you have any idea why this could happen?

Thanks!

Contact method is not supported

I try to use letsencrypt cookbook.
But I got the following error.
Any ideas ?

    Error executing action `create` on resource 'letsencrypt_certificate[xxxxxxx]'
    ================================================================================

    Acme::Error::Malformed
    ----------------------
    Error creating new registration :: Contact method  is not supported

    Cookbook Trace:
    ---------------
    /var/chef/cache/cookbooks/letsencrypt/libraries/acme.rb:40:in `acme_client'
    /var/chef/cache/cookbooks/letsencrypt/libraries/acme.rb:49:in `acme_authz'
    /var/chef/cache/cookbooks/letsencrypt/providers/certificate.rb:55:in `block in class_from_file'

    Resource Declaration:
    ---------------------
    # In /var/chef/cache/cookbooks/ogury-jira/recipes/default.rb

     21:   letsencrypt_certificate node['jira']['apache2']['virtual_host_name'] do
     22:     crt      "/etc/ssl/#{node['jira']['apache2']['virtual_host_name']}.crt"
     23:     key      "/etc/ssl/#{node['jira']['apache2']['virtual_host_name']}.key"
     24:     method   'http'
     25:     wwwroot  "#{node['jira']['install_path']}/atlassian-jira"
     26:     notifies :reload, 'service[apache2]'
     27:   end
     28: end

Invalid character in DNS name

Hi,

I'm using version 1.0.3 and have a problem with creating certificate:

this is how I use this recipe :

letsencrypt_certificate "kmspace cert" do
  alt_names ['console.k-m.space', 'devel.k-m.space']
  fullchain "/etc/ssl/k-m.space.crt"
  key       "/etc/ssl/k-m.space.key"
  chain     "/etc/ssl/k-m.space.pem"
  method    "http"
  wwwroot   "/var/www/letsencrypt/"
  notifies  :restart, "service[nginx]"
end

And the error is like this:

   ================================================================================
    Error executing action `create` on resource 'letsencrypt_certificate[kmspace cert]'
    ================================================================================

    Acme::Client::Error::Malformed
    ------------------------------
    Invalid character in DNS name

    Cookbook Trace:
    ---------------
    /var/chef/cache/cookbooks/letsencrypt/libraries/acme.rb:45:in `acme_authz'
    /var/chef/cache/cookbooks/letsencrypt/providers/certificate.rb:54:in `block (2 levels) in class_from_file'
    /var/chef/cache/cookbooks/letsencrypt/providers/certificate.rb:53:in `map'
    /var/chef/cache/cookbooks/letsencrypt/providers/certificate.rb:53:in `block in class_from_file'
    /var/chef/cache/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/runner.rb:41:in `run_action'

    Resource Declaration:
    ---------------------
    # In /var/chef/cache/cookbooks/kmspace_nginx/recipes/default.rb

     48: letsencrypt_certificate "kmspace cert" do
     49:   alt_names ['console.k-m.space', 'devel.k-m.space']
     50:   fullchain "/etc/ssl/k-m.space.crt"
     51:   key       "/etc/ssl/k-m.space.key"
     52:   chain     "/etc/ssl/k-m.space.pem"
     53:   method    "http"
     54:   wwwroot   "/var/www/letsencrypt/"
     55:   notifies  :restart, "service[nginx]"
     56: end
     57:


    Compiled Resource:
    ------------------
    # Declared in /var/chef/cache/cookbooks/kmspace_nginx/recipes/default.rb:48:in `from_file'

    letsencrypt_certificate("kmspace cert") do
      action [:create]
      retries 0
      retry_delay 2
      default_guard_interpreter :default
      declared_type :letsencrypt_certificate
      cookbook_name "hmspace_nginx"
      recipe_name "default"
      alt_names ["console.k-m.space", "devel.k-m.space"]
      fullchain "/etc/ssl/k-m.space.crt"
      key "/etc/ssl/k-m.space.key"
      chain "/etc/ssl/k-m.space.pem"
      method "http"
      wwwroot "/var/www/letsencrypt/"
      cn "kmspace cert"
      owner "root"
      group "root"
    end

Any idea what goes wrong? I can see that alt_names has proper domain list

undefined method `file' for Chef::Resource::RubyBlock

i am getting the following ruby error with chef 12.3.0 -- am i missing something?
the certificate request seems to have worked as can be seen in the faraday client dump. (i removed sensitive data.)

================================================================================
      Error executing action `run` on resource 'ruby_block[create certificate for www.example.com]'
      ================================================================================

      NoMethodError
      -------------
      undefined method `file' for Chef::Resource::RubyBlock

      Cookbook Trace:
      ---------------
      /root/chef-solo/cookbooks-2/letsencrypt/providers/certificate.rb:104:in `block (3 levels) in class_from_file'

      Resource Declaration:
      ---------------------
      # In /root/chef-solo/cookbooks-2/letsencrypt/providers/certificate.rb

       96:     ruby_block "create certificate for #{new_resource.cn}" do
       97:       block do
       98:         if (all_validations.map { |authz| authz.status == 'valid' }).all?
       99:           begin
      100:             newcert = acme_cert(new_resource.cn, mykey, new_resource.alt_names)
      101:           rescue Acme::Client::Error => e
      102:             fail "[#{new_resource.cn}] Certificate request failed: #{e.message}"
      103:           else
      104:             file "#{new_resource.cn} SSL new crt" do
      105:               path    new_resource.crt || new_resource.fullchain
      106:               owner   new_resource.owner
      107:               group   new_resource.group
      108:               content new_resource.crt.nil? ? newcert.fullchain_to_pem : newcert.to_pem
      109:               mode    00644
      110:               action  :create
      111:             end
      112:
      113:             file "#{new_resource.cn} SSL new chain" do
      114:               path    new_resource.chain
      115:               owner   new_resource.owner
      116:               group   new_resource.group
      117:               content newcert.chain_to_pem
      118:               not_if  { new_resource.chain.nil? }
      119:               mode    00644
      120:               action  :create
      121:             end
      122:           end
      123:         else
      124:           fail "[#{new_resource.cn}] Validation failed, unable to request certificate"
      125:         end
      126:       end

      Compiled Resource:
      ------------------
      # Declared in /root/chef-solo/cookbooks-2/letsencrypt/providers/certificate.rb:96:in `block in class_from_file'

      ruby_block("create certificate for www.example.com") do
        action "run"
        retries 0
        retry_delay 2
        default_guard_interpreter :default
        block_name "create certificate for www.example.com"
        declared_type :ruby_block
        cookbook_name :example
        block #<Proc:0x0000000886d7d0@/root/chef-solo/cookbooks-2/letsencrypt/providers/certificate.rb:97>
        client #<Acme::Client:0x000000088557c0 @directory_uri=nil, @private_key=#<OpenSSL::PKey::RSA:0x00000008855860>, @endpoint="https://acme-staging.api.letsencrypt.org", @nonces=[FILTERED], @operation_endpoints={"new-authz"=>"/acme/new-authz", "new-cert"=>"/acme/new-cert", "new-reg"=>"/acme/new-reg", "revoke-cert"=>"/acme/revoke-cert"}, @connection=#<Faraday::Connection:0x00000008855360 @parallel_manager=nil, @headers={"User-Agent"=>"Faraday v0.9.2"}, @params={}, @options=#<Faraday::RequestOptions (empty)>, @ssl=#<Faraday::SSLOptions verify=true>, @default_parallel_manager=nil, @builder=#<Faraday::RackBuilder:0x00000008854f50 @handlers=[Acme::Client::FaradayMiddleware, Faraday::Adapter::NetHttp], @app=#<Acme::Client::FaradayMiddleware:0x00000008854118 @app=#<Faraday::Adapter::NetHttp:0x00000008854168 @app=#<Proc:0x00000008854230@/opt/chef/embedded/lib/ruby/gems/2.1.0/gems/faraday-0.9.2/lib/faraday/rack_builder.rb:152 (lambda)>>, @client=#<Acme::Client:0x000000088557c0 ...>, @env=#<Faraday::Env @method=:get @body=[FILTERED]

Provide account details in certificate provider attributes for already registered accounts

I have multiple domains on the same node, so I want to use separate ACME accounts for each domain,
but that doesn't seem possible now, since it's set as node attribute.

I can see why it's needed for private_key to be set on node so it can be registered and stored,
but for already registered accounts, it would be useful to provide separate credentials.

Would you be interested in a PR?

chef13 deprecation warning

  • property method of resource acme_certificate overwrites an existing method. Please use a different property name. This will raise an exception in Chef 13. at 1 location:
  • /var/chef/cache/cookbooks/acme/resources/certificate.rb:36:in `class_from_file'

This is intentionally caused by a check in https://github.com/chef/chef/blob/master/lib/chef/property.rb#L610
and tracks probably down to https://ruby-doc.org/core-2.4.1/Object.html#method-i-method

I suggest we change this property (attribute) into something like verification_method?

Undefined method "acme_ssl_certificate"

I noticed a discrepancy between the README here on GitHub and the README on https://supermarket.chef.io/cookbooks/acme.

I want to create a certificate to use on my Nginx server using acme_ssl_certificate. But when I try to use the acme_ssl_certificate resource in my recipe I get the following error when I run kitchen converge:

       Recipe: acme::default
         * chef_gem[acme-client] action install (up to date)

         ================================================================================
         Recipe Compile Error in /tmp/kitchen/cache/cookbooks/LEMPChefCookbook/recipes/default.rb
         ================================================================================

         NoMethodError
         -------------
         undefined method `acme_ssl_certificate' for cookbook: LEMPChefCookbook, recipe: default :Chef::Recipe

         Cookbook Trace:
         ---------------
           /tmp/kitchen/cache/cookbooks/LEMPChefCookbook/recipes/default.rb:27:in `from_file'

         Relevant File Content:
         ----------------------
         /tmp/kitchen/cache/cookbooks/LEMPChefCookbook/recipes/default.rb:

          20:  include_recipe 'LEMPChefCookbook::nginx'
          21:  include_recipe 'acme::default'
          22:
          23:  secrets = Chef::EncryptedDataBagItem.load('secrets', 'secrets')
          24:
          25:  node.default['acme']['contact'] = [secrets['acme_contact']]
          26:
          27>> acme_ssl_certificate '/etc/ssl/budw.in.crt' do
          28:    cn 'budw.in'
          29:    output :fullchain
          30:    key '/etc/ssl/private/budw.in.key.pem'
          31:    min_validity 30
          32:    webserver :nginx
          33:  end
          34:
          35:  include_recipe 'composer::default'
          36:

         System Info:
         ------------
         chef_version=13.1.31
         platform=ubuntu
         platform_version=16.04
         ruby=ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]
         program_name=chef-client worker: ppid=3020;start=23:09:46;
         executable=/opt/chef/bin/chef-client


         Running handlers:
       [2017-06-16T23:09:52+00:00] ERROR: Running exception handlers
       [2017-06-16T23:09:52+00:00] ERROR: Running exception handlers
         Running handlers complete
       [2017-06-16T23:09:52+00:00] ERROR: Exception handlers complete
       [2017-06-16T23:09:52+00:00] ERROR: Exception handlers complete
         Chef Client failed. 2 resources updated in 05 seconds
       [2017-06-16T23:09:52+00:00] FATAL: Stacktrace dumped to /tmp/kitchen/cache/chef-stacktrace.out
       [2017-06-16T23:09:52+00:00] FATAL: Stacktrace dumped to /tmp/kitchen/cache/chef-stacktrace.out
       [2017-06-16T23:09:52+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
       [2017-06-16T23:09:52+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
       [2017-06-16T23:09:52+00:00] ERROR: undefined method `acme_ssl_certificate' for cookbook: LEMPChefCookbook, recipe: default :Chef::Recipe
       [2017-06-16T23:09:52+00:00] ERROR: undefined method `acme_ssl_certificate' for cookbook: LEMPChefCookbook, recipe: default :Chef::Recipe
       [2017-06-16T23:09:52+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
       [2017-06-16T23:09:52+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
>>>>>> ------Exception-------
>>>>>> Class: Kitchen::ActionFailed
>>>>>> Message: 1 actions failed.
>>>>>>     Converge failed on instance <default-ubuntu-1604>.  Please see .kitchen/logs/default-ubuntu-1604.log for more details
>>>>>> ----------------------
>>>>>> Please see .kitchen/logs/kitchen.log for more details
>>>>>> Also try running `kitchen diagnose --all` for configuration

False positive Chefspec matcher `create_acme_certificate()`

describe 'site-proxy::letsencrypt' do
  context 'When all attributes are default, on debian 8.7' do
    let(:chef_run) { ChefSpec::SoloRunner.new(DEBIAN_OPTS).converge(described_recipe) }

    it 'includes `acme` recipe' do
      expect(chef_run).to include_recipe('acme')
    end

    it 'creates a self signed certificate with attributes' do
      expect(chef_run).to create_acme_selfsigned('my-site.com')
      expect(chef_run).to_not create_acme_certificate('/etc/nginx/ssl/my-site.com.crt')
    end
  end

  context 'When configured for live, on debian 8.7' do
    let(:chef_run) {
      ChefSpec::SoloRunner.new(DEBIAN_OPTS) do |node|
        node.normal['site']['lets_encrypt']['enabled'] = true
      end.converge(described_recipe)
    }

    it 'creates a ca certificate' do
      expect(chef_run).to create_acme_certificate('/etc/nginx/ssl/my-site.com.crt')
      expect(chef_run).to_not create_acme_selfsigned('my-site.com')
    end
  end
end

The output is:

Failures:

  1) site-proxy::letsencrypt When configured for live, on debian 8.7 creates a ca certificate with attributes
     Failure/Error: expect(chef_run).to create_acme_certificate('/etc/nginx/ssl/my-site.com.crt')

       expected "acme_certificate[/etc/nginx/ssl/my-site.com.crt]" with action :create to be in Chef run. Other acme_certificate resources:

I'm really confused with this failure despite having a match. Am I missing something?

chef13 compat

Looks like chef-acme needs a few chef13 compatibility updates.

[2017-04-26T18:16:45-08:00] WARN: Acme library dependency 'acme-client' not loaded: cannot load such file -- acme-client
[2017-04-26T18:16:45-08:00] WARN: Property method of resource acme_certificate overwrites an existing method. Please use a different property name. This will raise an exception in Chef 13. (CHEF-11)/tmp/chefspec20170426-3728-xy9n5rfile_cache_path/cookbooks/acme/resources/certificate.rb:36:in class_from_file'. Please see https://docs.chef.io/deprecations_property_name_collision.html for further details and information on how to correct this problem. at /opt/chefdk/embedded/lib/ruby/gems/2.3.0/gems/chef-12.19.36/lib/chef/event_dispatch/dispatcher.rb:43:in call'

New certificate request at each update ?

Hello,
Is the cookbook requesting a new certificate every time I run chef-client on my server ?
If yes, is it a problem ?
If no, how do you renew existing certificates using this cookbook ?
Thanks

Cached node private key causes error when switching to production endpoint

First of all, thanks for the cookbook. It works great!

I ran into a problem yesterday when testing a node with multiple new LE certificates while using the staging endpoint for ACME. After I was able to get those certificates working, I switched the ACME endpoint in the node attributes to the production endpoint. Then the chef client run failed with the error:

Acme::Client::Error::Unauthorized: No registration exists matching provided key

It took me a few hours to figure out but when the chef client ran with the staging endpoint, a private key was stored in the node attributes. Then switching to the production endpoint would mean chef would try to register LE certificates using the staging endpoint's private key, which doesn't work with the production endpoint. (For clarification, this private key is not the same as the certificate private key, it is the private key for communication with the ACME endpoint.)

I fixed it by removing the node['letsencrypt']['private_key'] attribute from the node — I am using Chef Zero, so editing nodes/<nodename>.json was enough to clear it. For Chef Server users I would think using $ knife node edit would work.

This isn't really a bug, but perhaps it would be helpful to note this either here or in the README for anyone else who runs into the problem.

Renewal problem

Hey there, I tried to test the renewal process by specifying

node.default['acme']['renew'] = 89

The first certificate I got had was issued on:
Monday, 13. February 2017 at 09:52:00
And had an expiry date of:
Sunday, 14. May 2017 at 10:52:00

So I supposed, that if I waited one day, I would get a new certificate, but this did not happen.

Am I getting something wrong, or is this a problem with the renewal process?

Thanks in advance for any help!

japel

Deprecated features used - nil is an invalid value for path of resource file.

I'm creating a self signed certificate using the Letsencrypt cookbook. The Certificates are generating perfectly fine but I'm getting a warning that I have set the Property path as nil. Could someone provide any insight on what needs to be tweaked to eliminate the warning?

$ chef -v
Chef Development Kit Version: 0.11.2
chef-client version: 12.9.41
berks version: 4.2.0
kitchen version: 1.5.0
include_recipe 'letsencrypt'

letsencrypt_selfsigned node['apache']['fqdn'] do
  crt     "/etc/ssl/#{node['apache']['fqdn']}.crt" 
  key     "/etc/ssl/#{node['apache']['fqdn']}.key"
end

When converging, I'm getting the following Warnings that are shown below in the console and logs.

Deprecated features used!

         nil is an invalid value for path of resource file. In Chef 13, this warning will change to an error. Error: Property path must be one of: String!  You passed nil. at 1 location:
           - /tmp/kitchen/cache/cookbooks/letsencrypt/providers/selfsigned.rb:44:in `block (2 levels) in class_from_file'

Acme Client reports Malformed error - algorithm 'none' in JWS header not acceptable

Acme::Client::Error::Malformed: algorithm 'none' in JWS header not acceptable

================================================================================
     Error executing action `create` on resource 'letsencrypt_certificate[run.storj.io]'
     ================================================================================

     Acme::Client::Error::Malformed
     ------------------------------
     algorithm 'none' in JWS header not acceptable

     Cookbook Trace:
     ---------------
     /var/chef/cache/cookbooks/letsencrypt/libraries/acme.rb:40:in `acme_client'
     /var/chef/cache/cookbooks/letsencrypt/libraries/acme.rb:49:in `acme_authz'
     /var/chef/cache/cookbooks/letsencrypt/providers/certificate.rb:54:in `block (2 levels) in class_from_file'
     /var/chef/cache/cookbooks/letsencrypt/providers/certificate.rb:53:in `map'
     /var/chef/cache/cookbooks/letsencrypt/providers/certificate.rb:53:in `block in class_from_file'
     /var/chef/cache/cookbooks/compat_resource/files/lib/chef_compat/monkeypatches/chef/runner.rb:41:in `run_action'

Happy to provide more info if needed. I've been using this same setup to get my certs and it is now broken... I updated my letsencrypt cookbook to latest and berks installed and uploaded again to ensure I have latest from everywhere.

authz.send returns nil

validation = authz.send(new_resource.validation_method)

This call is returning nil rather than a legitimate validation instance. The object and the parameters look ok and the code did run in the past several months ago.

Did the acme-client gem change such that the send method is no longer working?

Disallow defining `crt` without `chain`

I got bit by this when I was generating certificates without any chains. Oddly, they worked in some browsers but not others, so it went unnoticed for a bit. I definitely intended to use fullchain, but instead had a bunch of certificates with no root attached with no way to even fix without re-issuing new certificates.

I likely would have caught this if the provider yelled at me for declaring crt without a chain. It seems hazardous to allow one without the other unless I'm missing any scenario where that'd be acceptable.

Validation failure/increase logging

Is it possible to increase the logging in some way as I keep getting Validation failures but with little info as to what is the cause:

       ================================================================================
       Error executing action `create` on resource 'acme_certificate[test.xxx]'
       ================================================================================
       
       RuntimeError
       ------------
       [test.xxx] Validation failed for domain test.xxx
       
       Cookbook Trace:
       ---------------
       /tmp/kitchen/cache/cookbooks/acme/providers/certificate.rb:85:in `block (2 levels) in class_from_file'
       /tmp/kitchen/cache/cookbooks/acme/providers/certificate.rb:53:in `map'
       /tmp/kitchen/cache/cookbooks/acme/providers/certificate.rb:53:in `block in class_from_file'

chefspec

We should get chefspec tests added. Integration tests are taking ages (in VMware) and seem to fail in Docker (due to some rabbitmq issue).

acme_client does not appear to be a valid cookbook

I'm sure there is something basic I am doing wrong here and it isnt related to chef-acme specifically but every attempt at running berks or kitchen I get the following error:

Resolving cookbook dependencies...
Fetching 'acme' from source at .
Fetching 'acme_client' from source at test/fixtures/cookbooks/acme_client
The resource at '~/chef-repo/cookbooks/acme/test/fixtures/cookbooks/acme_client' does not appear to be a valid cookbook. Does it have a metadata.rb?

What am I doing wrong??

Multiple SAN support

Hi,

I'd like to be able to use multiple hostnames in my certificate. For example:

letsencrypt_certificate 'test.example.com' do
  crt      '/etc/ssl/test.example.com.crt'
  key      '/etc/ssl/test.example.com.key'
  method   'http'
  wwwroot  '/var/www'
  domains ['example.example.com', 'www.example.com', 'example.com']
end

See example for generating the X509 cert here: https://gist.github.com/arusso/d5a3195773c2ca3717d4

Undeclared dependency on nginx cookbook

This cookbook appears to (justifiably) depend on the nginx cookbook, but this is not listed in the dependencies. Attempting to use the acme_ssl_certificate resource without having a compatible nginx cookbook in the Chef run results in an error like this one.

[2017-07-27T19:27:31+00:00] INFO: Setting up verification...

================================================================================
Error executing action `create` on resource 'acme_ssl_certificate[/etc/ssl/mysite.com.crt]'
================================================================================

NoMethodError
-------------
No resource or method named `nginx_site' for `Chef::Provider::SSLCertificate::Nginx ""'

Cookbook Trace:
---------------
/tmp/kitchen/cache/cookbooks/acme/libraries/ssl_certificate/nginx.rb:52:in `setup_challanges'
/tmp/kitchen/cache/cookbooks/acme/libraries/ssl_certificate.rb:105:in `block (3 levels) in action_create'
/tmp/kitchen/cache/cookbooks/acme/libraries/ssl_certificate.rb:105:in `block (2 levels) in action_create'
/tmp/kitchen/cache/cookbooks/acme/libraries/ssl_certificate.rb:91:in `map'
/tmp/kitchen/cache/cookbooks/acme/libraries/ssl_certificate.rb:91:in `block in action_create'
/tmp/kitchen/cache/cookbooks/acme/libraries/ssl_certificate.rb:90:in `action_create'

It seems like this should be stated in the dependencies.

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.