:lock: acmetool, an automatic certificate acquisition tool for ACME (Let's Encrypt)

Overview

acmetool

[webchat: freenode #acmetool]
[download count] [version]
[ppa
debian/ubuntu] Build Status

acmetool is an easy-to-use command line tool for automatically acquiring certificates from ACME servers (such as Let's Encrypt). Designed to flexibly integrate into your webserver setup to enable automatic verification. Unlike the official Let's Encrypt client, this doesn't modify your web server configuration.

Zero-downtime autorenewal
Supports any webserver
Fully automatable
Single-file dependency-free binary
Idempotent
Fast setup

You can perform verifications using port 80 or 443 (if you don't yet have a server running on one of them); via webroot; by configuring your webserver to proxy requests for /.well-known/acme-challenge/ to a special port (402) which acmetool can listen on; or by configuring your webserver not to listen on port 80, and instead running acmetool's built in HTTPS redirector (and challenge responder) on port 80. This is useful if all you want to do with port 80 is redirect people to port 443.

You can run acmetool on a cron job to renew certificates automatically (acmetool --batch). The preferred certificate for a given hostname is always at /var/lib/acme/live/HOSTNAME/{cert,chain,fullchain,privkey}. You can configure acmetool to reload your webserver automatically when it renews a certificate.

acmetool is intended to be "magic-free". All of acmetool's state is stored in a simple, comprehensible directory of flat files. The schema for this directory is documented.

acmetool is intended to work like "make". The state directory expresses target domain names, and whenever acmetool is invoked, it ensures that valid certificates are available to meet those names. Certificates which will expire soon are renewed. acmetool is thus idempotent and minimises the use of state.

acmetool can optionally be used without running it as root. If you have existing certificates issued using the official client, acmetool can import those certificates, keys and account keys (acmetool import-le).

acmetool supports both RSA and ECDSA keys and certificates. acmetool's notification hooks system allows you to write arbitrary shell scripts to be executed when new certificates are obtained. By default, this is used to reload webservers automatically, but it can also be used to distribute certificates to other servers or for other purposes.

Getting Started

Binary releases: Binary releases are available.

Download the release appropriate for your platform and simply copy the acmetool binary to /usr/bin.

_cgo releases are preferred over non-_cgo releases where available, but non-_cgo releases may be more compatible with older OSes.

Ubuntu users: A binary release PPA, ppa:hlandau/rhea (package acmetool) is available.

$ sudo add-apt-repository ppa:hlandau/rhea
$ sudo apt-get update
$ sudo apt-get install acmetool

You can also download .deb files manually.

(Note: There is no difference between the .deb files for different Ubuntu release codenames; they are interchangeable and completely equivalent.)

Debian users: The Ubuntu binary release PPA also works with Debian:

# echo 'deb http://ppa.launchpad.net/hlandau/rhea/ubuntu xenial main' > /etc/apt/sources.list.d/rhea.list
# apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9862409EF124EC763B84972FF5AC9651EDB58DFA
# apt-get update
# apt-get install acmetool

You can also download .deb files manually.

(Note: There is no difference between the .deb files for different Ubuntu release codenames; they are interchangeable and completely equivalent.)

RPM-based distros: A copr RPM repository is available.

If you have dnf installed:

$ sudo dnf copr enable hlandau/acmetool
$ sudo dnf install acmetool

Otherwise use the .repo files on the repository page and use yum, or download RPMs and use rpm directly.

Void Linux users: acmetool is in the repositories:

$ sudo xbps-install acmetool

Arch Linux users: An AUR PKGBUILD for building from source is available.

$ wget https://aur.archlinux.org/cgit/aur.git/snapshot/acmetool-git.tar.gz
$ tar xvf acmetool-git.tar.gz
$ cd acmetool-git
$ makepkg -s
$ sudo pacman -U ./acmetool*.pkg.tar.xz

Alpine Linux users: An APKBUILD for building from source is available.

FreeBSD users: FreeBSD port is available.

Building from source: You will need Go installed to build from source.

If you are on Linux, you will need to make sure the development files for libcap are installed. This is probably a package for your distro called libcap-dev or libcap-devel or similar.

# This is necessary to work around a change in Git's default configuration
# which hasn't yet been accounted for in some places.
$ git config --global http.followRedirects true

$ git clone https://github.com/hlandau/acme
$ cd acme
$ make && sudo make install

  # (People familiar with Go with a GOPATH setup can alternatively use go get/go install:)
  $ git config --global http.followRedirects true
  $ go get github.com/hlandau/acme/cmd/acmetool

After installation

# Run the quickstart wizard. Sets up account, cronjob, etc.
# (If you want to use ECDSA keys or set RSA key size, pass "--expert".)
$ sudo acmetool quickstart

# Configure your webserver to serve challenges if necessary.
# See https://hlandau.github.io/acmetool/userguide#web-server-configuration
$ ...

# Request the hostnames you want:
$ sudo acmetool want example.com www.example.com

# Now you have certificates:
$ ls -l /var/lib/acme/live/example.com/

The quickstart subcommand is a recommended wizard which guides you through the setup of ACME on your system.

The want subcommand states that you want a certificate for the given hostnames. (If you want separate certificates for each of the hostnames, run the want subcommand separately for each hostname.)

The default subcommand, reconcile, is like "make" and makes sure all desired hostnames are satisfied by valid certificates which aren't soon to expire. want calls reconcile automatically.

If you run acmetool reconcile on a cronjob to facilitate automatic renewal, pass --batch to ensure it doesn't attempt to interact with a terminal.

You can increase logging severity for debugging purposes by passing --xlog.severity=debug.

Validation Options

[screenshot]

Webroot: acmetool can place challenge files in a given directory, allowing your normal web server to serve them. The files must be served from the path you specify at /.well-known/acme-challenge/.

Information on configuring your web server.

Proxy: acmetool can respond to validation challenges by serving them on port 402. In order for this to be useful, you must configure your webserver to proxy requests under /.well-known/acme-challenge/ to http://127.0.0.1:402/.well-known/acme-challenge.

Information on configuring your web server.

Stateless: You configure your webserver to respond statelessly to challenges for a given account key without consulting acmetool. This requires nothing more than a one-time web server configuration change and no "moving parts". Information on configuring stateless challenges.

Redirector: acmetool redirector starts an HTTP server on port 80 which redirects all requests to HTTPS, as well as serving any necessary validation responses. The acmetool quickstart wizard can set it up for you if you use systemd. Otherwise, you'll need to configure your system to run acmetool redirector --service.uid=USERNAME --service.daemon=1 as a service, where USERNAME is the username you want the daemon to drop to.

Make sure your web server is not listening on port 80.

Listen: If you are for some reason not running anything on port 80 or 443, acmetool will use those ports. Either port being available is sufficient. This is only really useful for development purposes.

Hook: You can write custom shell scripts (or binary executables) which acmetool invokes to provision challenge files at the desired location. For example, you could rsync challenge files to a directory on a remote server. More information.

Renewal

acmetool will try to renew certificates automatically once they are 30 days from expiry, or 66% through their validity period, whichever is lower. Note that Let's Encrypt currently issues 90 day certificates.

acmetool will exit with an error message with nonzero exit status if it cannot renew a certificate, so it is suitable for use in a cronjob. Ensure your system is configured so that you get notifications of failing cronjobs.

If a cronjob fails, you should intervene manually to see what went wrong by running acmetool (possibly with --xlog.severity=debug for verbose logging).

Library

The client library which these utilities use can be used independently by any Go code. README and source code. Godoc.

Comparison with...

certbot: A heavyweight Python implementation which is a bit too “magic” for my tastes. Tries to mutate your webserver configuration automatically.

acmetool is a single-file binary which only depends on basic system libraries (on Linux, these are libc, libpthread, libcap, libattr). It doesn't do anything to your webserver; it just places certificates at a standard location and can also reload your webserver (whichever webserver it is) by executing hook shell scripts.

acmetool isn't based around individual transactions for obtaining certificates; it's about satisfying expressed requirements by any means necessary. Its comprehensible, magic-free state directory makes it as stateless and idempotent as possible.

lego: Like acmetool, xenolf/lego provides a library and client utility. The utility provides commands for creating certificates, but doesn't provide a compelling system for managing the lifetime of the short-lived certificates offered by Let's Encrypt. The user is expected to generate and install all certificates manually.

gethttpsforfree: diafygi/gethttpsforfree provides an HTML file which uses JavaScript to make requests to an ACME server and obtain certificates. It's a functional user interface, but like lego it provides no answer for the automation issue, and is thus impractical given the short lifetime of certificates issued by Let's Encrypt.

Comparison, list of client implementations

acmetool certbot lego gethttpsforfree
Automatic renewal Yes Not yet No No
SAN support Yes Yes Yes Yes
ECC support Yes No No No
OCSP Must Staple support Yes No No No
Revocation support Yes Yes Yes No
State management Yes† Yes
Single-file binary Yes No Yes Yes
Quickstart wizard Yes Yes No No
Modifies webserver config No By default No No
Non-root support Optional Optional Optional
Supports Apache Yes Yes
Supports nginx Yes Experimental
Supports HAProxy Yes No
Supports Hitch Yes No
Supports any web server Yes Webroot‡
Authorization via webroot Yes Yes Manual
Authorization via port 80 redirector Yes No No No
Authorization via proxy Yes No No No
Authorization via listener§ Yes Yes Yes No
Authorization via DNS Hook only No Yes No
Authorization via custom hook Yes No No No
Import state from official client Yes
Windows (basic) support No No Yes
Windows integration support No No No

† acmetool has a different philosophy to state management and configuration to the Let's Encrypt client; see the beginning of this README.

‡ The webroot method does not appear to provide any means of reloading the webserver once the certificate has been changed, which means auto-renewal requires manual intervention.

§ Requires downtime.

This table is maintained in good faith; I believe the above comparison to be accurate. If notified of any inaccuracies, I will rectify the table and publish a notice of correction here:

  • This table previously stated that the official Let's Encrypt client doesn't support non-root operation. This was incorrect; it can be installed at user level and be configured to use user-writable directories.

Documentation & Support

For more documentation see:

If your question or issue isn't resolved by any of the above, file an issue.

IRC: #acmetool on Freenode (webchat).

Licence

© 2015—2019 Hugo Landau <[email protected]>    MIT License

Licenced under the licence with SHA256 hash fd80a26fbb3f644af1fa994134446702932968519797227e07a1368dea80f0bc, a copy of which can be found here.

Issues
  • Can't add more than one host

    Can't add more than one host

    I added a host and it works without any issues, when adding another one using acmetool want example.tv I got below errors:

    20160923144412 [ERROR] acme.storageops: could not obtain authorization for www.example.tv: failed all combinations 20160923144412 [ERROR] acme.storageops: Target(www.example.tv;https://acme-v01.api.letsencrypt.org/directory;0): failed to request certificate: failed all combinations 20160923144412 [ERROR] acme.storageops: error while processing targets: the following errors occurred: error satisfying Target(www.example.tv;https://acme-v01.api.letsencrypt.org/directory;0): failed all combinations 20160923144412 [ERROR] acme.storageops: failed to reconcile: the following errors occurred: error satisfying Target(www.example.tv;https://acme-v01.api.letsencrypt.org/directory;0): failed all combinations 20160923144412 [CRITICAL] acmetool: fatal: reconcile: the following errors occurred: error satisfying Target(www.example.tv;https://acme-v01.api.letsencrypt.org/directory;0): failed all combinations

    I made it again with debug and found got these:

    [email protected] [~]# acmetool --xlog.severity=debug want example.tv 20160923144117 [DEBUG] fdb: enforce permissions: tmp/symlink.258794367 0/0 0/0 20160923144117 [DEBUG] fdb: enforce permissions: desired/example.tv-yvblotgi6ncjfjzunqvbmtxzkm 0/0 0/0 20160923144117 [DEBUG] fdb: enforce permissions: tmp/symlink.876249810 0/0 0/0 20160923144117 [DEBUG] acme.storageops: Certificate(whlxskruvxedl6h7sdbadoxpppc4vc62uecsmtq6sbsi4zln7ibq) cannot satisfy Target(example.tv;https://acme-v01.api.letsencrypt.org/directory;0) because required hostname "example.tv" is not listed on it: []string{"example-main.com"} 20160923144117 [DEBUG] acme.storageops: Target(example.tv;https://acme-v01.api.letsencrypt.org/directory;0): best certificate satisfying is , err=Target(example.tv;https://acme-v01.api.letsencrypt.org/directory;0): no certificate satisfies this target 20160923144117 [DEBUG] acme.storageops: Target(example.tv;https://acme-v01.api.letsencrypt.org/directory;0): requesting certificate 20160923144117 [DEBUG] acme.api: request: https://acme-v01.api.letsencrypt.org/directory 20160923144118 [DEBUG] acme.api: response: &{200 OK 200 HTTP/1.1 1 1 map[Replay-Nonce:[O8928CVDZ97v0-uVuxPzvkQe_1iHF25314kc4Zdydl4] Expires:[Fri, 23 Sep 2016 14:41:30 GMT] Pragma:[no-cache] Connection:[keep-alive] X-Frame-Options:[DENY] Strict-Transport-Security:[max-age=604800] Cache-Control:[max-age=0, no-cache, no-store] Date:[Fri, 23 Sep 2016 14:41:30 GMT] Server:[nginx] Content-Type:[application/json] Content-Length:[280] Boulder-Request-Id:[Qi_YL9xNVUKYBtCpd56GuNASDZ674aCzz5QHynjcHZk]] 0xc420286040 280 [] false false map[] 0xc4201f8ff0 0xc4200b8630} 20160923144118 [DEBUG] acme.api: request: https://acme-v01.api.letsencrypt.org/acme/new-reg 20160923144118 [DEBUG] acme.api: response: &{409 Conflict 409 HTTP/1.1 1 1 map[Server:[nginx] Content-Type:[application/problem+json] Location:[https://acme-v01.api.letsencrypt.org/acme/reg/4548967] Replay-Nonce:[kuqTMiptLGxAtl7iBWfY3mgNtFO6z4IntkbCCFXMic8] Expires:[Fri, 23 Sep 2016 14:41:31 GMT] Cache-Control:[max-age=0, no-cache, no-store] Content-Length:[107] Boulder-Request-Id:[Ac7un8dNHog6mAq04HkALXrCQ9d1icK5849NmCMxh-c] Boulder-Requester:[4548967] Pragma:[no-cache] Date:[Fri, 23 Sep 2016 14:41:31 GMT]] 0xc420187340 107 [] true false map[] 0xc4201f85a0 0xc4200b8630} 20160923144118 [DEBUG] acme.api: request: https://acme-v01.api.letsencrypt.org/acme/reg/4548967 20160923144118 [DEBUG] acme.api: response: &{202 Accepted 202 HTTP/1.1 1 1 map[Connection:[keep-alive] Boulder-Request-Id:[tqqYNzMHx0dObSLC-MfpXkfYpQ5Ymwp_MrxqEEyp-SM] Boulder-Requester:[4548967] Link:[https://acme-v01.api.letsencrypt.org/acme/new-authz;rel="next" https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf;rel="terms-of-service"] Replay-Nonce:[vuPVSHJllL12QZJQWWhhplTv4FnnZUAGJmQsZroCEpI] Cache-Control:[max-age=0, no-cache, no-store] Date:[Fri, 23 Sep 2016 14:41:31 GMT] Server:[nginx] Content-Type:[application/json] Content-Length:[631] Expires:[Fri, 23 Sep 2016 14:41:31 GMT] Pragma:[no-cache]] 0xc4203b4080 631 [] false false map[] 0xc4201f8c30 0xc4201d8000} 20160923144118 [DEBUG] acme.storageops: trying to obtain authorization for "example.tv" 20160923144118 [DEBUG] acme.api: request: https://acme-v01.api.letsencrypt.org/acme/new-authz 20160923144118 [DEBUG] acme.api: response: &{201 Created 201 HTTP/1.1 1 1 map[Expires:[Fri, 23 Sep 2016 14:41:31 GMT] Cache-Control:[max-age=0, no-cache, no-store] Date:[Fri, 23 Sep 2016 14:41:31 GMT] Connection:[keep-alive] Boulder-Request-Id:[w5hmbvNF4lgfhFoMgHIUVfH2OMEYu3JXeYKbo9FMfzo] X-Frame-Options:[DENY] Link:[https://acme-v01.api.letsencrypt.org/acme/new-cert;rel="next"] Content-Type:[application/json] Content-Length:[999] Boulder-Requester:[4548967] Strict-Transport-Security:[max-age=604800] Pragma:[no-cache] Server:[nginx] Replay-Nonce:[HCrvZnPl1oMHTgZUqxLYoRpvduEO9vLTbo4a0Vbfr2c] Location:[https://acme-v01.api.letsencrypt.org/acme/authz/dWfR6ySQHavmStNagQzJNkSgDl_GV4ZapWmu1wPQ4M8]] 0xc42000d540 999 [] false false map[] 0xc4201f92c0 0xc4201d8000} 20160923144118 [DEBUG] acme.solver: attempting challenge type tls-sni-01 20160923144118 [DEBUG] acme.responder: failed to start TLS-SNI listener: listen tcp :443: listen: address already in use 20160923144118 [DEBUG] acme.hooks: calling hook script: /usr/libexec/acme/hooks/haproxy 20160923144118 [DEBUG] acme.hooks: calling hook script: /usr/libexec/acme/hooks/reload 20160923144118 [DEBUG] acme.responder: tls-sni-01 self-test failed: remote error: tls: internal error 20160923144118 [DEBUG] acme.hooks: calling hook script: /usr/libexec/acme/hooks/haproxy 20160923144118 [DEBUG] acme.hooks: calling hook script: /usr/libexec/acme/hooks/reload 20160923144118 [DEBUG] acme.solver: challenge start failed: remote error: tls: internal error 20160923144118 [DEBUG] acme.solver: attempting challenge type http-01 20160923144118 [DEBUG] acme.responder: failed to listen on [::]:80: listen tcp [::]:80: bind: address already in use 20160923144118 [DEBUG] acme.responder: failed to listen on :80: listen tcp :80: bind: address already in use 20160923144118 [DEBUG] acme.responder: listening on [::1]:4402 20160923144118 [DEBUG] acme.responder: listening on 127.0.0.1:4402 20160923144118 [DEBUG] acme.responder: listening on [::1]:402 20160923144118 [DEBUG] acme.responder: listening on 127.0.0.1:402 20160923144118 [DEBUG] acme.responder: writing 1 webroot challenge files 20160923144118 [DEBUG] acme.responder: writing webroot file /var/run/acme/acme-challenge/aqicqpddAgRuDJos_i9T4g2TfgPsddNYj7-JxlRYQ6U 20160923144118 [DEBUG] acme.hooks: calling hook script: /usr/libexec/acme/hooks/haproxy 20160923144118 [DEBUG] acme.hooks: calling hook script: /usr/libexec/acme/hooks/reload 20160923144118 [DEBUG] acme.responder: http-01 self test 20160923144119 [INFO] acme.responder: http-01 self test failed: got 200 response when doing self-test, but with the wrong data 20160923144119 [DEBUG] acme.responder: removing webroot file /var/run/acme/acme-challenge/aqicqpddAgRuDJos_i9T4g2TfgPsddNYj7-JxlRYQ6U 20160923144119 [DEBUG] acme.hooks: calling hook script: /usr/libexec/acme/hooks/haproxy 20160923144119 [DEBUG] acme.hooks: calling hook script: /usr/libexec/acme/hooks/reload 20160923144119 [DEBUG] acme.solver: challenge start failed: got 200 response when doing self-test, but with the wrong data 20160923144119 [DEBUG] acme.solver: attempting challenge type dns-01 20160923144119 [DEBUG] acme.hooks: calling hook script: /usr/libexec/acme/hooks/haproxy 20160923144119 [DEBUG] acme.hooks: calling hook script: /usr/libexec/acme/hooks/reload 20160923144119 [DEBUG] acme.solver: challenge start failed: could not install DNS challenge, no hooks succeeded 20160923144119 [ERROR] acme.storageops: could not obtain authorization for example.tv: failed all combinations 20160923144119 [ERROR] acme.storageops: Target(example.tv;https://acme-v01.api.letsencrypt.org/directory;0): failed to request certificate: failed all combinations 20160923144119 [DEBUG] acme.storageops: Certificate(whlxskruvxedl6h7sdbadoxpppc4vc62uecsmtq6sbsi4zln7ibq) satisfies Target(example-main.com;https://acme-v01.api.letsencrypt.org/directory;0) 20160923144119 [DEBUG] acme.storageops: Target(example-main.com;https://acme-v01.api.letsencrypt.org/directory;0): best certificate satisfying is Certificate(whlxskruvxedl6h7sdbadoxpppc4vc62uecsmtq6sbsi4zln7ibq), err= 20160923144119 [DEBUG] acme.storageops: Certificate(whlxskruvxedl6h7sdbadoxpppc4vc62uecsmtq6sbsi4zln7ibq) needsRenewing=false notAfter=2016-12-22 12:55:00 +0000 UTC 20160923144119 [DEBUG] acme.storageops: Target(example-main.com;https://acme-v01.api.letsencrypt.org/directory;0): have best certificate which does not need renewing, skipping target 20160923144119 [DEBUG] acme.storageops: done processing targets, reconciliation complete, 1 errors occurred 20160923144119 [ERROR] acme.storageops: error while processing targets: the following errors occurred: error satisfying Target(example.tv;https://acme-v01.api.letsencrypt.org/directory;0): failed all combinations 20160923144119 [ERROR] acme.storageops: failed to reconcile: the following errors occurred: error satisfying Target(example.tv;https://acme-v01.api.letsencrypt.org/directory;0): failed all combinations 20160923144119 [DEBUG] fdb: enforce permissions: tmp/symlink.108478473 0/0 0/0 20160923144119 [DEBUG] acme.storageops: disjoint hostname mapping: example.tv -> Target(example.tv;https://acme-v01.api.letsencrypt.org/directory;0) 20160923144119 [DEBUG] acme.storageops: disjoint hostname mapping: example-main.com -> Target(example-main.com;https://acme-v01.api.letsencrypt.org/directory;0) 20160923144119 [DEBUG] acme.storageops: Certificate(whlxskruvxedl6h7sdbadoxpppc4vc62uecsmtq6sbsi4zln7ibq) cannot satisfy Target(example.tv;https://acme-v01.api.letsencrypt.org/directory;0) because required hostname "example.tv" is not listed on it: []string{"example-main.com"} 20160923144119 [DEBUG] acme.storageops: could not find certificate satisfying Target(example.tv;https://acme-v01.api.letsencrypt.org/directory;0): Target(example.tv;https://acme-v01.api.letsencrypt.org/directory;0): no certificate satisfies this target 20160923144119 [DEBUG] acme.storageops: Certificate(whlxskruvxedl6h7sdbadoxpppc4vc62uecsmtq6sbsi4zln7ibq) satisfies Target(example-main.com;https://acme-v01.api.letsencrypt.org/directory;0) 20160923144119 [CRITICAL] acmetool: fatal: reconcile: the following errors occurred: error satisfying Target(example.tv;https://acme-v01.api.letsencrypt.org/directory;0): failed all combinations

    example-main (is the first host I added and is working) example.tv (is the new one I'm trying to add)

    Any suggestions?

    I'm working on CentOS 7, Varnish 5 with Hitch and HTTP 2.

    Best regards,

    help wanted 
    opened by mmagdy88 28
  • License out of date?

    License out of date?

    Getting the below when trying to request any cert

    { "type": "urn:acme:error:malformed", "detail": "Provided agreement URL [https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf] does not match current agreement URL [https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf]", "status": 400 }

    opened by ConnorLinfoot 27
  • acmetool's HTTP self-test parameters differ from those used by boulder

    acmetool's HTTP self-test parameters differ from those used by boulder

    I am a new user to acmetool, while I am running letsencrypt certificates already. My problem seems to be related to acmetool not writing the challenge file to the setup webroot. Using the tool I receive the following output:

    sudo acmetool want iepenbierferfier.frl www.iepenbierferfier.frl
    20160827000257 [ERROR] acme.storageops: could not obtain authorization for iepenbierferfier.frl: failed all combinations
    20160827000257 [ERROR] acme.storageops: Target(iepenbierferfier.frl,www.iepenbierferfier.frl;https://acme-v01.api.letsencrypt.org/directory;0): failed to request certificate: failed all combinations
    20160827000257 [ERROR] acme.storageops: error while processing targets: the following errors occurred:
    error satisfying Target(iepenbierferfier.frl,www.iepenbierferfier.frl;https://acme-v01.api.letsencrypt.org/directory;0): failed all combinations
    20160827000257 [ERROR] acme.storageops: failed to reconcile: the following errors occurred:
    error satisfying Target(iepenbierferfier.frl,www.iepenbierferfier.frl;https://acme-v01.api.letsencrypt.org/directory;0): failed all combinations
    20160827000257 [CRITICAL] acmetool: fatal: reconcile: the following errors occurred:
    error satisfying Target(iepenbierferfier.frl,www.iepenbierferfier.frl;https://acme-v01.api.letsencrypt.org/directory;0): failed all combinations
    
    acmetool status
    Settings:
      ACME_STATE_DIR: /var/lib/acme
      ACME_HOOKS_DIR: /usr/lib/acme/hooks
      Default directory URL: https://acme-v01.api.letsencrypt.org/directory
      Preferred key type: rsa-2048
      Additional webroots:
        /opt/cherokee/var/www/.well-known/acme-challenge
    
    Available accounts:
      Account(acme-v01.api.letsencrypt.org%2fdirectory/a3n2fi3vvxvlkvnehrdaadxildvuhhqsgbgoxq6wihvzsxuggiya)
        thumbprint: wHdGj50hMqTQj2oE7KsqXMxeQ8ofB_4luUyLRiIdZUk
    
    Target(iepenbierferfier.frl,www.iepenbierferfier.frl;https://acme-v01.api.letsencrypt.org/directory;0)
      error: Target(iepenbierferfier.frl,www.iepenbierferfier.frl;https://acme-v01.api.letsencrypt.org/directory;0): no certificate satisfies this target
    

    Using a small shell script I am monitoring the webfolder, but it remains empty. I also notice that the challenges itself do come in via the webserver:

    2001:bc8:3020:300::1 - - [27/Aug/2016:00:02:57 +0200] "GET /.well-known/acme-challenge/1bFyh5fDOAZvX5juOzW7ssDqUbW4UamNN_0eQ8DOs98 HTTP/1.1" 404 672 "http://iepenbierferfier.frl/.well-known/acme-challenge/1bFyh5fDOAZvX5juOzW7ssDqUbW4UamNN_0eQ8DOs98" "Go-http-client/1.1"
    

    Any advises what I can do to monitor that the file itself is written... somewhere?

    Additionally I have attempted the proxy configuration, which also didn't complete.

    bug 
    opened by skinkie 27
  • Update ToS agreement verification logic when ACME protocol is clarified

    Update ToS agreement verification logic when ACME protocol is clarified

    Currently acmetool asks for UniqueID: "acme-agreement:" + e.URI (or looks for the anwser) to TOS agreement, but why isn't there a way to auto accept the TOS (e.g. for use in a cron job)?

    enhancement acme-v2 
    opened by rgl 25
  • The `want` command won’t work if LE limit is reached for *any* domains

    The `want` command won’t work if LE limit is reached for *any* domains

    I’m trying Let’s Encrypt via your tool since two days now and it works great. But yesterday I hit the beta limit after generating 5 certificates for subdomains of belfalas.eu (my domain). The problem is that now when I want to generate certificates for other unrelated domains, I got this error:

    20151209140116 [CRITICAL] acmetool: fatal: reconcile: HTTP error: 429 Unknown
    map[Server:[nginx] Replay-Nonce:[kfgpHwkR70jXVF8yD9gLEdvA86ieMJUP1Vxv3-leBo8] Expires:[Wed, 09 Dec 2015 13:01:11 GMT] Date:[Wed, 09 Dec 2015 13:01:11 GMT] Content-Type:[application/problem+json] Content-Length:[142] Cache-Control:[max-age=0, no-cache, no-store] Pragma:[no-cache]]
    {"type":"urn:acme:error:rateLimited","detail":"Error creating new cert :: Too many certificates already issued for: belfalas.eu","status":429}
    

    I tried with the official client, I could generate the wanted certificate without any problem, so there’s a bug in your client I think. In the error it seems it tries to do a reconcile and I think this is the problem. The cron job this night didn’t work either and output the same error.

    opened by Flink 21
  • FreeBSD: hooks/reload fails because bash path is nonexistent

    FreeBSD: hooks/reload fails because bash path is nonexistent

    I'm running acmetool on Freebsd:

    # freebsd-version
    10.2-RELEASE-p12
    

    The reload hook fails:

    # /usr/libexec/acme/hooks/reload
    /usr/libexec/acme/hooks/reload: Command not found.
    

    because the script looks for /bin/bash in the shebang line:

    #!/bin/bash
    ## This file was installed by acmetool. Any updates to this script will
    ## overwrite changes you make. If you don't want acmetool to manage
    ## this file, remove the following line.
    

    Since bash is only available as a port (in /usr/local/bin/bash) I would recommend to use /bin/sh. A quick test revealed that the script seems to be working using #!/bin/sh. I am not aware of the consequences on other systems.

    bug 
    opened by gonium 15
  • End of Life Plan for ACMEv1

    End of Life Plan for ACMEv1

    Now that the ACME protocol is an IETF standard[1], Let's Encrypt have announced an end-of-life plan[2] for the ACMEv1 endpoints. The first date of significance is Nov 2019 when new account creation will stop working.

    I'd really like to continue using acme-tool as it suits my workflow perfectly.

    Is anyone working on a fork to get the ACMEv2 protocol stuff to completion?

    Have people migrated to different tools, if so what?

    Thanks.

    [1] https://letsencrypt.org/2019/03/11/acme-protocol-ietf-standard.html [2] https://community.letsencrypt.org/t/end-of-life-plan-for-acmev1/88430

    opened by ronnyadsetts 15
  • Figure out what to do about pinning

    Figure out what to do about pinning

    Currently, a new private key is always generated for each new certificate. This causes issues if using HPKP to pin end entity certificates rather than CA certificates. Should probably find a workable solution for that for people that want to use HPKP.

    enhancement 
    opened by hlandau 13
  • webroot request hanging

    webroot request hanging

    Hi, I am trying to request a test certificate and while I see letsencrypt accessing my well-known URL, I get no answer:

    20151206105359 [DEBUG] acme.api: request: https://acme-v01.api.letsencrypt.org/directory
    20151206105400 [DEBUG] acme.api: response: &{200 OK 200 HTTP/1.1 1 1 map[Connection:[keep-alive] Server:[nginx] Content-Length:[263] Strict-Transport-Security:[max-age=604800] Expires:[Sun, 06 Dec 2015 09:54:00 GMT] Cache-Control:[max-age=0, no-cache, no-store] Content-Type:[application/json] Replay-Nonce:[2YAuMdK60eFTRP3gAD4Ypaui2MD-M2R0Ff_bcbHpRew] X-Frame-Options:[DENY] Pragma:[no-cache] Date:[Sun, 06 Dec 2015 09:54:00 GMT]] 0xc820340d80 263 [] false map[] 0xc820309420 0xc82021a9a0} <nil>
    20151206105400 [DEBUG] acme.api: request: https://acme-v01.api.letsencrypt.org/acme/new-reg
    20151206105400 [DEBUG] acme.api: response: &{409 Conflict 409 HTTP/1.1 1 1 map[Content-Length:[94] Cache-Control:[max-age=0, no-cache, no-store] Pragma:[no-cache] Date:[Sun, 06 Dec 2015 09:54:00 GMT] Expires:[Sun, 06 Dec 2015 09:54:00 GMT] Server:[nginx] Content-Type:[application/problem+json] Location:[https://acme-v01.api.letsencrypt.org/acme/reg/48696] Replay-Nonce:[Gor7ZLBKqlFHmyT7wBP0a4Qav_ZeZKAKdFp6Zj2PyA8]] 0xc82024e100 94 [] true map[] 0xc82024d880 0xc82021a9a0} <nil>
    20151206105400 [DEBUG] acme.api: request: https://acme-v01.api.letsencrypt.org/acme/reg/48696
    20151206105400 [DEBUG] acme.api: response: &{202 Accepted 202 HTTP/1.1 1 1 map[Pragma:[no-cache] Server:[nginx] Content-Length:[576] Cache-Control:[max-age=0, no-cache, no-store] Expires:[Sun, 06 Dec 2015 09:54:00 GMT] Date:[Sun, 06 Dec 2015 09:54:00 GMT] Connection:[keep-alive] Content-Type:[application/json] Link:[<https://acme-v01.api.letsencrypt.org/acme/new-authz>;rel="next" <https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf>;rel="terms-of-service"] Replay-Nonce:[vtsqaFSHLAaa1wAk66yRfJacCRBHZ084B6SI41IX5Fc]] 0xc8202e0100 576 [] false map[] 0xc8200d7ea0 0xc82016d290} <nil>
    20151206105400 [DEBUG] acme.api: request: https://acme-v01.api.letsencrypt.org/directory
    20151206105400 [DEBUG] acme.api: response: &{200 OK 200 HTTP/1.1 1 1 map[Server:[nginx] X-Frame-Options:[DENY] Pragma:[no-cache] Date:[Sun, 06 Dec 2015 09:54:00 GMT] Content-Type:[application/json] Content-Length:[263] Replay-Nonce:[GO4clmMvNX5hGr12udwIL4JZawg97_yk3QIfcLBGkIA] Strict-Transport-Security:[max-age=604800] Expires:[Sun, 06 Dec 2015 09:54:00 GMT] Cache-Control:[max-age=0, no-cache, no-store] Connection:[keep-alive]] 0xc8202e04c0 263 [] false map[] 0xc8202bc1c0 0xc82016d290} <nil>
    20151206105400 [DEBUG] acme.api: request: https://acme-v01.api.letsencrypt.org/acme/new-authz
    20151206105400 [DEBUG] acme.api: response: &{201 Created 201 HTTP/1.1 1 1 map[Content-Length:[569] Link:[<https://acme-v01.api.letsencrypt.org/acme/new-cert>;rel="next"] Location:[https://acme-v01.api.letsencrypt.org/acme/authz/qXCrJhNlZupNvU29A-JewLDN7zUVCr8NfiLKBjyJzIM] Replay-Nonce:[QQTKkLXXIPVOAmiKUwxCFrbrWNHpGPNKGdWBKqzNwRI] X-Frame-Options:[DENY] Strict-Transport-Security:[max-age=604800] Expires:[Sun, 06 Dec 2015 09:54:00 GMT] Date:[Sun, 06 Dec 2015 09:54:00 GMT] Connection:[keep-alive] Server:[nginx] Content-Type:[application/json] Cache-Control:[max-age=0, no-cache, no-store] Pragma:[no-cache]] 0xc8204e8280 569 [] false map[] 0xc82055a0e0 0xc82016d290} <nil>
    20151206105400 [DEBUG] acme.solver: attempting challenge type tls-sni-01
    20151206105400 [DEBUG] acme.solver: challenge start failed: listen tcp :443: bind: address already in use
    20151206105400 [DEBUG] acme.solver: attempting challenge type http-01
    20151206105400 [DEBUG] acme.responder: http-01 self test
    20151206105401 [DEBUG] acme.responder: http-01 started
    20151206105401 [DEBUG] acme.api: request: https://acme-v01.api.letsencrypt.org/acme/challenge/qXCrJhNlZupNvU29A-JewLDN7zUVCr8NfiLKBjyJzIM/1031567
    20151206105401 [DEBUG] acme.api: response: &{202 Accepted 202 HTTP/1.1 1 1 map[Content-Length:[312] Location:[https://acme-v01.api.letsencrypt.org/acme/challenge/qXCrJhNlZupNvU29A-JewLDN7zUVCr8NfiLKBjyJzIM/1031567] Expires:[Sun, 06 Dec 2015 09:54:01 GMT] Pragma:[no-cache] Content-Type:[application/json] Link:[<https://acme-v01.api.letsencrypt.org/acme/authz/qXCrJhNlZupNvU29A-JewLDN7zUVCr8NfiLKBjyJzIM>;rel="up"] Replay-Nonce:[Ku79VytL_dm71iwa8q5uaX8hW1Ygi7TQqn37ejpABCM] Cache-Control:[max-age=0, no-cache, no-store] Date:[Sun, 06 Dec 2015 09:54:01 GMT] Connection:[keep-alive] Server:[nginx]] 0xc82024e0c0 312 [] false map[] 0xc820523420 0xc82016d290} <nil>
    20151206105406 [DEBUG] acme.api: request: https://acme-v01.api.letsencrypt.org/acme/challenge/qXCrJhNlZupNvU29A-JewLDN7zUVCr8NfiLKBjyJzIM/1031567
    20151206105406 [DEBUG] acme.api: response: &{202 Accepted 202 HTTP/1.1 1 1 map[Connection:[keep-alive] Link:[<https://acme-v01.api.letsencrypt.org/acme/authz/qXCrJhNlZupNvU29A-JewLDN7zUVCr8NfiLKBjyJzIM>;rel="up"] Replay-Nonce:[YY0xW99e6Lp2Kf9aGW87p1SgIuALmI5flC0kat0wvEE] Cache-Control:[max-age=0, no-cache, no-store] Date:[Sun, 06 Dec 2015 09:54:06 GMT] Expires:[Sun, 06 Dec 2015 09:54:06 GMT] Pragma:[no-cache] Server:[nginx] Content-Type:[application/json] Content-Length:[548] Location:[https://acme-v01.api.letsencrypt.org/acme/challenge/qXCrJhNlZupNvU29A-JewLDN7zUVCr8NfiLKBjyJzIM/1031567]] 0xc820340bc0 548 [] false map[] 0xc8202c8000 0xc82016d290} <nil>
    

    at this point nothing happens anymore…

    the access log shows:

    185.11.136.221 - - [06/Dec/2015:10:54:01 +0100] "GET /.well-known/acme-challenge/SlmxjpPu7MxyVRQvvoY-id-iQ0UksEfbBot02rYoR7k HTTP/1.1" 200 275 "-" "Go-http-client/1.1"
    66.133.109.36 - - [06/Dec/2015:10:54:01 +0100] "GET /.well-known/acme-challenge/SlmxjpPu7MxyVRQvvoY-id-iQ0UksEfbBot02rYoR7k HTTP/1.1" 200 294 "-" "Mozilla/5.0 (compatible; Let's Encrypt validation server; +https://www.letsencrypt.org)"
    

    Any hints?

    opened by apollo13 12
  • Configured webroot path not being used

    Configured webroot path not being used

    Hello,

    After updating the acmetool binary I noticed that the webroot config file is no longer used. The directory structure doc tells me that the option is deprecated, acmetool logs pointed me to new location in /var/run.

    Readme still says that webroot is a configurable path, but it looks like that's no longer the case? Please update documentation on how this should be used. Also: could you mention breaking changes like these on the release page, in the future? Thanks!

    opened by sorcix 11
  • Adding flock() support

    Adding flock() support

    I am automating seamless DANE support after acmetool, and this process triggers a sequence of simple atomic and idempotent actions with its own timing. This raises concerns about atomicity of the /var/lib/acme/live directory contents. Multiple files cannot be written all at the same time, and concurrent programs might interact and see half-way results.

    I therefore started wrapping acmetool with a voluntary lock, using flock(). I use the same lock for the scripts that work with /var/lib/acme.

    I think it is generally a good idea to use flock() in the tool itself, precisely because it is a command that runs as a cronjob and occasionally at the user's request. There should be no interference between any two calls of the tool and, given the neat documentation of the /var/lib/acme directory, it would be good if any other tools could follow a compatible practice.

    opened by vanrein 0
  • staging URL in defaultconf with live URL in desired files makes for a lot of accounts

    staging URL in defaultconf with live URL in desired files makes for a lot of accounts

    I haven't debugged this fully but if you put the staging URL in the defaultconf and a live URL in every desired file AND when you start with a clean acmetool state directory (as an upgrade cleared out my state dir) you'll walk into the max 10 accounts/3 hours rate limit.

    Fix was easy: make defaultconf have the live URL.

    opened by Mrten 0
  • PKCS #11 support request

    PKCS #11 support request

    Would you consider adding PKCS #11 support to acmetool? Though it would be possible to import the generated keys afterwards, it beats the purpose of using this private-key-protective API.

    Apache supports use of PKCS #11 private keys and even certificates via PKCS #11, which generally is helpful to avoid that private keys are ever revealed. It remains an operational choice what implementation of the PKCS #11 API to use; it could be a software implementation, a simple USB token or a more advanced rack-mounted redundant key management solution for tens of thousands of dollars. With PKCS #11, key management quality is a choice.

    This range of operational choices is why we use it in our TLS Pool project, which additionally separates TLS handling from the application process via file descriptor passing and reduces TLS implementation to one API call, fd = starttls_client (fd, ...). We intend to use that in security/privacy projects like Keyful Identity Protocol and Realm Crossover for Kerberos.

    Just ask if you want to learn more about PKCS #11. These are a few speciication links that you might find interesting:

    opened by vanrein 1
  • Binary installed under directory name

    Binary installed under directory name

    I installed on a disk (actually, in a DESTDIR) without /usr/local/bin directory. In that case, acmetool installs itself as an executable program named /usr/local/bin :-)

    Easily remedied, but perhaps good to avoid by copying to the full name (or perhaps with a slash at the end of the target directory).

    Other than that, the tool looks very useful. Thank you very much.

    opened by vanrein 0
  • acmetool v0.2.1 failing getting certificate (ACMEv2)

    acmetool v0.2.1 failing getting certificate (ACMEv2)

    Good afternoon, after upgrading to the most recent verion acmetool won't get any certificates. Previous version was v.0.0.67 among others, which have been serving for a long time just fine. After upgrading, a quickstart has been done. This is the base configuration:

    #> acmetool status
    Settings:
      ACME_STATE_DIR: /var/db/acme
      ACME_HOOKS_DIR: /usr/local/libexec/acme/hooks
      Default directory URL: https://acme-v02.api.letsencrypt.org/directory
      Preferred key type: rsa-4096
      Additional webroots:
        /var/run/acme/acme-challenge
    
    Available accounts:
      Account(acme-v02.api.letsencrypt.org%2fdirectory/01234567890abcdefghijklmnopqrst)
        thumbprint: c_mnopqrstuvwxyzmnopqrstuvwxyz
    
    Target(example.com;https://acme-v02.api.letsencrypt.org/directory;0)
      error: Target(example.com;https://acme-v02.api.letsencrypt.org/directory;0): no certificate satisfies this target
    

    ACMEv2 is set everywhere, as challenge completion method webroot has been set (as it was the choice over the last couple years). For webroot, nginx is configured according to Hugo's user guide by including a server location block to have no redundancies across several domains and their corresponding (virtual) servers. This method has been working over dozens of renewals over the years, and it proves working by dropping an arbitrary file in there (/var/run/acme/acme-challenge/) and subsequentally fetching it (wget, browser). No problem.

    The problem is, acmetool would not fetch any certificate:

    #> acmetool --version
    go version go1.15.6 freebsd/amd64 gc cgo=true
    acmetool-v0.2.1-freebsd-ports
    #> acmetool --xlog.syslog --xlog.facility=local7 --xlog.severity=debug reconcile
    20210202150310 [DEBUG] acmetool.storageops: Target(example.com;https://acme-v02.api.letsencrypt.org/directory;0): best certificate satisfying is <nil>, err=Target(example.com;https://acme-v02.api.letsencrypt.org/directory;0): no certificate satisfies this target
    20210202150310 [DEBUG] acmetool.storageops: Target(example.com;https://acme-v02.api.letsencrypt.org/directory;0): requesting certificate
    20210202150349 [DEBUG] fdb: enforce permissions: keys/1234567890abcdefghij/privkey 0/0 0/0
    20210202150349 [DEBUG] acmetool.storageops: Target(example.com;https://acme-v02.api.letsencrypt.org/directory;0): ordering certificate
    20210202150350 [DEBUG] acmetool.reshttp: acquire port "[::]:80" "abcdefghijklmn--my--challenge--abcdefghijklmn"
    20210202150350 [DEBUG] acmetool.reshttp: listening on [::]:80
    20210202150350 [DEBUG] acmetool.reshttp: acquire port ":80" "abcdefghijklmn--my--challenge--abcdefghijklmn"
    20210202150350 [DEBUG] acmetool.reshttp: failed to listen on :80: listen tcp :80: bind: address already in use
    20210202150350 [DEBUG] acmetool.reshttp: acquire port "[::1]:402" "abcdefghijklmn--my--challenge--abcdefghijklmn"
    20210202150350 [DEBUG] acmetool.reshttp: listening on [::1]:402
    20210202150350 [DEBUG] acmetool.reshttp: acquire port "127.0.0.1:402" "abcdefghijklmn--my--challenge--abcdefghijklmn"
    20210202150350 [DEBUG] acmetool.reshttp: listening on 127.0.0.1:402
    20210202150350 [DEBUG] acmetool.reshttp: acquire port "[::1]:4402" "abcdefghijklmn--my--challenge--abcdefghijklmn"
    20210202150350 [DEBUG] acmetool.reshttp: listening on [::1]:4402
    20210202150350 [DEBUG] acmetool.reshttp: acquire port "127.0.0.1:4402" "abcdefghijklmn--my--challenge--abcdefghijklmn"
    20210202150350 [DEBUG] acmetool.reshttp: listening on 127.0.0.1:4402
    20210202150350 [DEBUG] acme.responder: writing 1 webroot challenge files
    20210202150350 [DEBUG] acme.responder: writing webroot file /var/run/acme/acme-challenge/abcdefghijklmn--my--challenge--abcdefghijklmn
    20210202150350 [DEBUG] acme.hooks: calling hook script: /usr/local/libexec/acme/hooks/haproxy
    20210202150350 [DEBUG] acme.hooks: calling hook script: /usr/local/libexec/acme/hooks/reload
    20210202150350 [DEBUG] acme.responder: http-01 self test for "example.com"
    20210202150355 [INFO] acme.responder: http-01 self test failed: example.com: Get "http://example.com/.well-known/acme-challenge/abcdefghijklmn--my--challenge--abcdefghijklmn": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
    20210202150355 [DEBUG] acme.responder: removing webroot file /var/run/acme/acme-challenge/abcdefghijklmn--my--challenge--abcdefghijklmn
    20210202150355 [DEBUG] acme.hooks: calling hook script: /usr/local/libexec/acme/hooks/haproxy
    20210202150355 [DEBUG] acme.hooks: calling hook script: /usr/local/libexec/acme/hooks/reload
    20210202150355 [DEBUG] acmetool.solver: challenge start failed: Get "http://example.com/.well-known/acme-challenge/abcdefghijklmn--my--challenge--abcdefghijklmn": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
    20210202150355 [DEBUG] acme.hooks: calling hook script: /usr/local/libexec/acme/hooks/haproxy
    20210202150355 [DEBUG] acme.hooks: calling hook script: /usr/local/libexec/acme/hooks/reload
    20210202150355 [DEBUG] acmetool.solver: challenge start failed: could not install DNS challenge, no hooks succeeded
    20210202150355 [DEBUG] acmetool.solver: challenge instantiation failed: challenge type not supported
    20210202150356 [ERROR] acmetool.storageops: Target(example.com;https://acme-v02.api.letsencrypt.org/directory;0): failed to request certificate: the following errors occurred:
    exhausted all possible challenges in authorization "https://acme-v02.api.letsencrypt.org/acme/authz-v3/0123456789" [due to inner error: the following errors occurred:
    Get "http://example.com/.well-known/acme-challenge/abcdefghijklmn--my--challenge--abcdefghijklmn": context deadline exceeded (Client.Timeout exceeded while awaiting headers);
    could not install DNS challenge, no hooks succeeded;
    challenge type not supported]
    20210202150356 [DEBUG] acmetool.storageops: done processing targets, reconciliation complete, 1 errors occurred
    20210202150356 [ERROR] acmetool.storageops: error while processing targets: the following errors occurred:
    error satisfying Target(example.com;https://acme-v02.api.letsencrypt.org/directory;0): the following errors occurred:
    exhausted all possible challenges in authorization "https://acme-v02.api.letsencrypt.org/acme/authz-v3/0123456789" [due to inner error: the following errors occurred:
    Get "http://example.com/.well-known/acme-challenge/abcdefghijklmn--my--challenge--abcdefghijklmn": context deadline exceeded (Client.Timeout exceeded while awaiting headers);
    could not install DNS challenge, no hooks succeeded;
    challenge type not supported]
    20210202150356 [ERROR] acmetool.storageops: failed to reconcile: the following errors occurred:
    error satisfying Target(example.com;https://acme-v02.api.letsencrypt.org/directory;0): the following errors occurred:
    exhausted all possible challenges in authorization "https://acme-v02.api.letsencrypt.org/acme/authz-v3/0123456789" [due to inner error: the following errors occurred:
    Get "http://example.com/.well-known/acme-challenge/abcdefghijklmn--my--challenge--abcdefghijklmn": context deadline exceeded (Client.Timeout exceeded while awaiting headers);
    could not install DNS challenge, no hooks succeeded;
    challenge type not supported]
    20210202150405 [DEBUG] acmetool.storageops: disjoint hostname mapping: "example.com" -> Target(example.com;https://acme-v02.api.letsencrypt.org/directory;0)
    20210202150405 [DEBUG] acmetool.storageops: could not find certificate satisfying Target(example.com;https://acme-v02.api.letsencrypt.org/directory;0): Target(example.com;https://acme-v02.api.letsencrypt.org/directory;0): no certificate satisfies this target
    20210202150405 [CRITICAL] acmetool: fatal: reconcile: the following errors occurred:
    error satisfying Target(example.com;https://acme-v02.api.letsencrypt.org/directory;0): the following errors occurred:
    exhausted all possible challenges in authorization "https://acme-v02.api.letsencrypt.org/acme/authz-v3/0123456789" [due to inner error: the following errors occurred:
    Get "http://example.com/.well-known/acme-challenge/abcdefghijklmn--my--challenge--abcdefghijklmn": context deadline exceeded (Client.Timeout exceeded while awaiting headers);
    could not install DNS challenge, no hooks succeeded;
    challenge type not supported]
    #>
    

    While running a reconcile, after generating a key pair for the hostname at hand, acmetool puts a challenge webroot file in that said directory. I simply can see it using ls -l. To me, this somewhat mismatches with log lines like could not install DNS challenge, no hooks succeeded;.

    I have also altered the challenge completion to proxy method for test, including nginx server configuration modifications, but to no success. Lastly I shut the web server down, releasing ports 80 and 443 to acmetool to do its thing. Still no success.

    Can anyone explain what's going on here? What's wrong? Any help is highly appreciated.

    opened by backstube 1
  • No Release File - ubuntu 20.04

    No Release File - ubuntu 20.04

    E: The repository 'http://ppa.launchpad.net/hlandau/rhea/ubuntu focal Release' does not have a Release file. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details.

    opened by jadeye 0
  • add --forceRenew flag

    add --forceRenew flag

    To use: ./acmetool want --forceRenew <domain>

    Also, maybe the usage of --forceRenew should be noted in DEBUG/TRACE output?

    Fixes: #274

    opened by jtl999 0
  • Make reconcile Linear - should solve partially #282

    Make reconcile Linear - should solve partially #282

    Basically,

    loops a first time over certificates to create a map name => certs[], this allows for lookup of the possible certificates, which allows way faster matching.

    opened by xdecock 1
  • certrequest is failing with api-v2

    certrequest is failing with api-v2

    I have compile the current version of acmetool on an ubuntu18

    acmetool quickstart works fine but when I run acmetool want <domain> I get the following error message:

    20200408071127 [ERROR] acmetool.storageops: Target(<domain>;https://acme-v02.api.letsencrypt.org/directory;0): failed to request certificate: the following errors occurred:
    exhausted all possible challenges in authorization "https://acme-v02.api.letsencrypt.org/acme/authz-v3/xxxxx" [due to inner error: the following errors occurred:
    Get "http://<domain>/.well-known/acme-challenge/xxxxxxxxxxxxxx": dial tcp 1<ip>:80: connect: connection refused; 
    could not install DNS challenge, no hooks succeeded; 
    challenge type not supported]
    

    In the tcpdump I can see, that noone is trying to connect to my host on port 80. From an other host I can access to http://<domain>/.well-known/acme-challenge/xxxxxxxxxxxxxx.

    Has anybody an idea wants going wrong? Thanks.

    opened by kaikrueger 7
  • cli: fix dropped error

    cli: fix dropped error

    This picks up a dropped error in the cli package.

    opened by alrs 1
Releases(v0.0.67)
Let's Encrypt client and ACME library written in Go

Let's Encrypt client and ACME library written in Go. Features ACME v2 RFC 8555 Register with CA Obtain certificates, both from scratch or with an exis

null 4.9k Oct 23, 2021
Automatic HTTPS for any Go program: fully-managed TLS certificate issuance and renewal

Easy and Powerful TLS Automation The same library used by the Caddy Web Server Caddy's automagic TLS features—now for your own Go programs—in one powe

Caddy 3.8k Oct 21, 2021
androidqf (Android Quick Forensics) helps quickly gathering forensic evidence from Android devices, in order to identify potential traces of compromise.

androidqf androidqf (Android Quick Forensics) is a portable tool to simplify the acquisition of relevant forensic data from Android devices. It is the

Nex 11 Oct 10, 2021
SourcePoint is a C2 profile generator for Cobalt Strike command and control servers designed to ensure evasion.

SourcePoint SourcePoint is a polymorphic C2 profile generator for Cobalt Strike C2s, written in Go. SourcePoint allows unique C2 profiles to be genera

Tylous 429 Oct 17, 2021
A tool to check for vulnerabilities in your Golang dependencies, powered by Sonatype OSS Index

Nancy nancy is a tool to check for vulnerabilities in your Golang dependencies, powered by Sonatype OSS Index, and as well, works with Nexus IQ Server

Sonatype Community 328 Oct 21, 2021
An opinionated helper for generating tls certificates

Certificates helper This is an opinionated helper for generating tls certificates. It outputs only in PEM format but this enables you easily generate

Martijn van Maasakkers 21 Jul 9, 2021
Go package to embed the Mozilla Included CA Certificate List

rootcerts Package rootcerts provides an embedded copy of the Mozilla Included CA Certificate List, more specifically the PEM of Root Certificates in M

Lucas Bremgartner 55 Oct 15, 2021
✒ A self-hosted, cross-platform service to sign iOS apps using any CI as a builder

iOS Signer Service A self-hosted, cross-platform service to sign iOS apps using any CI as a builder Introduction There are many reasons to install app

null 482 Oct 17, 2021
Cossack Labs 807 Oct 15, 2021
Secure Boot certificates from the Framework Laptop

Framework Laptop UEFI Secure Boot Certificates Source: Extracted from a live machine (FRANBMCP08) Date: 2021-10-21 KEK (Key Exchange Key) This certifi

Dustin L. Howett 5 Oct 24, 2021
A scalable overlay networking tool with a focus on performance, simplicity and security

What is Nebula? Nebula is a scalable overlay networking tool with a focus on performance, simplicity and security. It lets you seamlessly connect comp

Slack 8.2k Oct 16, 2021
HTTP/HTTPS MITM proxy and recorder.

Hyperfox Hyperfox is a security auditing tool that proxies and records HTTP and HTTPS traffic between two points. Installation You can install the lat

null 1.5k Oct 13, 2021
A simple, modern and secure encryption tool (and Go library) with small explicit keys, no config options, and UNIX-style composability.

age age is a simple, modern and secure file encryption tool, format, and library. It features small explicit keys, no config options, and UNIX-style c

Filippo Valsorda 8.8k Oct 23, 2021
How to systematically secure anything: a repository about security engineering

How to Secure Anything Security engineering is the discipline of building secure systems. Its lessons are not just applicable to computer security. In

Veeral Patel 6.4k Oct 17, 2021
Simple PKI for developers.

SimpleCA Have you ever been working with a technology and needed TLS certificates quickly? Perhaps you wanted to set up a PKI infrastructure for testi

Eamon Bauman 2 Sep 22, 2021
Encrypt your files or notes by your GPG key and save to MinIO or Amazon S3 easily!

Super Dollop Super Dollop can encrypt your files and notes by your own GPG key and save them in S3 or minIO to keep them safe and portability, also yo

Nedim AKAR 55 Oct 6, 2021
Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.

Themis provides strong, usable cryptography for busy people General purpose cryptographic library for storage and messaging for iOS (Swift, Obj-C), An

Cossack Labs 1.4k Oct 22, 2021
Encrypt embedded go files using age.

encembed Encrypt embedded resource in compiled binary using age. Meant for usage with go generate. This tool will generate a go source file that embed

C_Sto 20 Oct 12, 2021
2FA (Two-Factor Authentication) application for CLI terminal with support to import/export andOTP files.

zauth zauth is a 2FA (Two-Factor Authentication) application for terminal written in Go. Features Supports both TOTP and HOTP codes. Add new entries d

Rijul Gulati 67 Oct 16, 2021