Giter Club home page Giter Club logo

lego's Introduction

lego logo

Automatic Certificates and HTTPS for everyone.

Lego

Let's Encrypt client and ACME library written in Go.

Go Reference Build Status Docker Pulls

Features

  • ACME v2 RFC 8555
    • Support RFC 8737: TLS Application‑Layer Protocol Negotiation (ALPN) Challenge Extension
    • Support RFC 8738: certificates for IP addresses
    • Support draft-ietf-acme-ari-03: Renewal Information (ARI) Extension
  • Register with CA
  • Obtain certificates, both from scratch or with an existing CSR
  • Renew certificates
  • Revoke certificates
  • Robust implementation of all ACME challenges
    • HTTP (http-01)
    • DNS (dns-01)
    • TLS (tls-alpn-01)
  • SAN certificate support
  • CNAME support by default
  • Comes with multiple optional DNS providers
  • Custom challenge solvers
  • Certificate bundling
  • OCSP helper function

Installation

How to install.

Usage

Documentation

Documentation is hosted live at https://go-acme.github.io/lego/.

DNS providers

Detailed documentation is available here.

Akamai EdgeDNS Alibaba Cloud DNS all-inkl Amazon Lightsail
Amazon Route 53 ArvanCloud Aurora DNS Autodns
Azure (deprecated) Azure DNS Bindman Bluecat
Brandit Bunny Checkdomain Civo
Cloud.ru CloudDNS Cloudflare ClouDNS
CloudXNS ConoHa Constellix CPanel/WHM
Derak Cloud deSEC.io Designate DNSaaS for Openstack Digital Ocean
DNS Made Easy dnsHome.de DNSimple DNSPod (deprecated)
Domain Offensive (do.de) Domeneshop DreamHost Duck DNS
Dyn Dynu EasyDNS Efficient IP
Epik Exoscale External program freemyip.com
G-Core Gandi Live DNS (v5) Gandi Glesys
Go Daddy Google Cloud Google Domains Hetzner
Hosting.de Hosttech HTTP request http.net
Hurricane Electric DNS HyperOne IBM Cloud (SoftLayer) IIJ DNS Platform Service
Infoblox Infomaniak Internet Initiative Japan Internet.bs
INWX Ionos IPv64 iwantmyname
Joker Joohoi's ACME-DNS Liara Linode (v4)
Liquid Web Loopia LuaDNS Mail-in-a-Box
Manual Metaname MyDNS.jp MythicBeasts
Name.com Namecheap Namesilo NearlyFreeSpeech.NET
Netcup Netlify Nicmanager NIFCloud
Njalla Nodion NS1 Open Telekom Cloud
Oracle Cloud OVH plesk.com Porkbun
PowerDNS Rackspace RcodeZero reg.ru
RFC2136 RimuHosting Sakura Cloud Scaleway
Selectel v2 Selectel Servercow Shellrent
Simply.com Sonic Stackpath Tencent Cloud DNS
TransIP UKFast SafeDNS Ultradns Variomedia
VegaDNS Vercel Versio.[nl/eu/uk] VinylDNS
VK Cloud Vscale Vultr Webnames
Websupport WEDOS Yandex 360 Yandex Cloud
Yandex PDD Zone.ee Zonomi

If your DNS provider is not supported, please open an issue.

lego's People

Contributors

adriencarbonne avatar aebruno avatar beautifulentropy avatar beevik avatar cgroschupp avatar cpu avatar ddymko avatar deining avatar dmke avatar dstdfx avatar fuku2014 avatar fxposter avatar greut avatar jbrunink avatar ldez avatar lukehandle avatar mholt avatar mhoran avatar middelink avatar nmengin avatar pchanvallon avatar porjo avatar rekby avatar systemcrash avatar tommie avatar vancluever avatar weppos avatar willglynn avatar xenolf avatar yamamoto-febc 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  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

lego's Issues

DoS in GetOCSPForCert

The following line

issuerBytes, err := ioutil.ReadAll(resp.Body)

allows an an attacker in a network MiTM position to exhaust the memory of any application using lego and cause a runtime panic by holding the previously opened TCP connection open and forging garbage data. The call the ioutil.ReadAll ensures that the application will consume the garbage data until it runs out of memory.

Move DNS providers out of the lego executable

lego could grow indefinitely by supporting every DNS provider API ever made, but this seems less than ideal (#100). I'd like to discuss how to move DNS providers out of the lego executable.

It is fortunate that DNS-01 has a very small surface area in terms of what functions are required. There's basically just two operations:

  1. Create the record _acme-challenge.whatever IN TXT "abc123"
  2. Clean up

lego can monitor the authoritative DNS servers to watch and wait for success, so communication from the DNS provider back to lego can be as little as just signaling failure.

Go limits the mechanisms by which external code can interact with a project like lego. The most straightforward mechanism is to launch a child process and interact with it, and based on my understanding of the requirements, I think that model would work fine:

  1. lego does everything ACME-related, ultimately deciding that it needs to create _acme-challenge.whatever IN TXT "abc123".
  2. lego, having been invoked with --dns=foo, spawns lego-dns-foo "_acme-challenge.whatever" "abc123", passing on its environment variables.
  3. lego-dns-foo uses FOO_USERNAME and FOO_PASSWORD to create the record indicated by its arguments, then waits.
  4. lego spins and waits for a) _acme-challenge.whatever to show the correct value, b) lego-dns-foo to exit, or c) some configurable timeout.
  5. lego sees _acme-challenge.whatever get created and proceeds in its ACME dance, yielding a completed challenge and a certificate for whatever.
  6. lego no longer needs _acme-challenge.whatever, and indicates this by closing lego-dns-foo's stdin.
  7. lego-dns-foo sees its stdin close, removes the record, and terminates successfully.

This scheme avoids unnecessary complexity (it's simple enough that a provider could be implemented with a shell script) and platform dependence (i.e. signals don't really port well to Windows). lego-dns-foo could communicate back by printing to stdout/stderr and by exiting with a failure code, which seems like it's enough.

Some negatives of this approach are:

  • lego-dns-foo doesn't get run until late in the operation, which means DNS-related configuration errors aren't detected until late in the operation. This could be mitigated by launching lego-dns-foo with no arguments before doing anything else (i.e. "don't actually create any records, but do fail immediately if you would fail immediately"), or by adding a separate dns-test function which creates a TXT record and verifies its content outside an ACME exchange (#110).
  • go get github.com/xenolf/lego becomes insufficient. (That's sort of the point, though.) Would it be okay to make users say go get github.com/xenolf/lego-dns-foo? Do we want users to have a kitchen sink option?

Thoughts?

Certificate renewal drops Subject Alternative Name extension

Previously created a certificate:
lego --domains example.com --domains www.example.com [email protected] --path /etc/ssl/letsencrypt run

Then, tried to renew the certificate:

lego --domains example.com --domains www.example.com [email protected] run
2015/12/15 08:29:36 [INFO] acme: [example.com] Trying renewal with 2015 hours remaining
2015/12/15 08:29:36 [INFO] acme: Obtaining bundled certificates for example.com
2015/12/15 08:29:36 [INFO] acme: Trying to solve HTTP-01
2015/12/15 08:29:37 [INFO] Served key authentication
2015/12/15 08:29:38 The server validated our request
2015/12/15 08:29:38 [INFO] acme: Validations succeeded; requesting certificates
2015/12/15 08:29:40 [INFO] acme: Requesting issuer cert from https://acme-v01.api.letsencrypt.org/acme/issuer-cert
2015/12/15 08:29:41 [example.com] Server responded with a certificate.
2015/12/15 08:29:41 Error while loading the certificate for domain www.example.com
    open /etc/ssl/letsencrypt/certificates/www.example.com.crt: no such file or directory

Result is a certificate without the correct Subject Alternate Names:

X509v3 Subject Alternative Name: 
    DNS:example.com
X509v3 Certificate Policies: 
    Policy: 2.23.140.1.2.1
    Policy: 1.3.6.1.4.1.44947.1.1.1
      CPS: http://cps.letsencrypt.org
      User Notice:
        Explicit Text: This Certificate may only be relied upon by Relying Parties and only in accordance with the Certificate Policy found at https://letsencrypt.org/repository/

IPv6-only support

Pending Let's Encrypts's IPv6 support (IPv6-only hosts), I guess bootstrapping off a magic IPv4 DNS forwarder is going to be a problem...

/*  .../lego/acme/dns_challenge.go */
func checkDNS(domain, fqdn string) bool {
    // check if the expected DNS entry was created. If not wait for some time and try again.
    m := new(dns.Msg)
    m.SetQuestion(domain+".", dns.TypeSOA)
    c := new(dns.Client)
    in, _, err := c.Exchange(m, "8.8.8.8:53")  // <= ouch
    if err != nil {
        return false
    }
    // ...

There are systems out there that let only certain DNS forwarders through their firewalls (to mitigate cache poison attacks etc), so maybe it would be an idea to provide a configurable forwarder?

"The server returned an unexpected status code 200"

After pulling the latest tonight, I get this:

2015/10/17 21:08:01 [caddy.dev] The server returned an unexpected status code 200.

Then the program exits.

Based on logs, it seems to happen just after everything is done and the web server (not the lego one, but the one I'm getting the certs for) is already started. I suspect, though I am not sure, the behavior comes from caa6e78. None of the other changes tonight seem like they would cause this.

Ambiguous error messages

Caddy gives back a single failure message:

2015/12/06 03:51:44 [blog.coolaj86.com] failed to get certificate: The server could not validate our request.

while the python client gives back very detailed (and varied) error messages:

Failed authorization procedure. blog.coolaj86.com (tls-sni-01): urn:acme:error:unknownHost :: The server could not resolve a domain name :: No IPv4 addresses found for blog.coolaj86.com

Asking over at certbot/certbot#1855 as to how they pass error messages.

Add tests

Currently there are none... add some!

dns-01 support for DigitalOcean DNS

To piggyback off the excellent PR #38, it might be nice to see DigitalOcean support for the dns-01 challenge as well... I'll eventually do it but somebody else might beat me to it.

Doesn't work if server can't bind to DNS IP

I'm very possibly missing something, but I'm trying this running on a cloud server with a floating IP. I have set up DNS to resolve to this floating IP & then trying to do domain validation. This tries to bind to the IP that the domain resolves to which ends up with

Could not start HTTPS server for challenge -> listen tcp <IP>:5001: bind: cannot assign requested address

which is understandable because that IP is a floating IP, not bound to the host interfaces.

How about just listening on requested port rather than trying to use the requested domain IP?

`lego dns-test` feature request

I'd like to be able to run lego --dns=foo --domains=totally.legit.biz dns-test, which would:

  1. Use the foo DNS provider to create a _acme-challenge.totally.legit.biz record with a unique value for testing.
  2. Watch and wait for _acme-challenge.totally.legit.biz to report that value just like a normal DNS challenge, preferably with extra log output so I can see what it's doing.
  3. Clean up after itself.

This would allow users to test and troubleshoot their configuration without either a) pestering live ACME services or b) launching their own local ACME service for testing.

This would be safe to do even if someone else is concurrently answering challenges for the same name because identically-named TXT records can coexist and DNS-01 requires only one of them to match:

 To validate a DNS challenge, the server performs the following steps:

 1.  Compute the SHA-256 digest of the key authorization

 2.  Query for TXT records under the validation domain name

 3.  Verify that the contents of one of the TXT records matches the
     digest value

Imports & Dependencies

I sweat dependency trees, and really enjoy light libraries. One of the initial appeals to me of lego over hlandau/acme was how light this project was in terms of dependencies to accomplish what i needed. ❤️

Unfortunately, with the current code structure, the addition of support for multiple DNS providers to solve the dns-01 challenge has increased the dependency tree 🙈.

To import github.com/hlandau/acme the current dependency tree you need to support is

$ go list -f '{{join .Deps "\n"}}' |  xargs go list -f '{{if not .Standard}}{{.ImportPath}}{{end}}'
github.com/crackcomm/cloudflare
github.com/miekg/dns
github.com/mitchellh/goamz/aws
github.com/mitchellh/goamz/route53
github.com/square/go-jose
github.com/square/go-jose/cipher
github.com/vaughan0/go-ini
github.com/weppos/dnsimple-go/dnsimple
golang.org/x/crypto/ocsp
golang.org/x/crypto/sha3
golang.org/x/net/context

Of these, I'd love to skip 6 of them (vaughan0/go-ini is a sub dependency of mitchellh/goamz/route53), so I'd like to propose two options for refactoring the code structure to make these dependencies separate from the main acme package.

a) Move all providers into a single xenolf/lego/providers package
b) Move per-challenge pacakges (ie: xenolf/lego/providers/dns01 xenolf/lego/providers/http01 etc)
c) move to per-provider packages (ie: xenolf/lego/providers/dns/cloudflare, xenolf/lego/providers/dnsimple, ...)
d) some combination of the above?

(Note: i'm proposing structure, not specific naming). Since i personally don't care about the DNS providers, 2 and 3 are equal for me. I imagine others might feel differently, and the ideal case might change when more options w/ dependencies are added (like say #28).

The key is that the acme package doesn't import these packages (because that makes them all a dependency), the cli code would import them and set them as appropriate on the Client. Depending on the approach, the default http and tls-sni providers may or may not be moved.

thoughts @xenolf ?

Could not create client:decode directory: json: cannot unmarshal number into Go value of type acme.directory

Could not create client:decode directory: json: cannot unmarshal number into Go value of type acme.directory

Caddy errored out with this, but lego does the same:

gthomas@tequila:/home/gthomas$ sudo chpst -u www-data:ssl-cert /home/gthomas/bin/lego --path /var/www/.caddy/letsencrypt --server https://acme-v01.api.letsencrypt.org/directory --email [email protected] run
2015/11/10 18:04:13 No key found for account [email protected]. Generating a 2048 bit key.
2015/11/10 18:04:14 Saved key to /var/www/.caddy/letsencrypt/accounts/acme-v01.api.letsencrypt.org/[email protected]/keys/[email protected]
2015/11/10 18:04:15 Could not create client:decode directory: json: cannot unmarshal number into Go value of type acme.directory

Idea?

NAT port support?

This may or may not be something that one want to support, but I thought I could ask.

By NAT port support I mean having the ability to run with another parameter defining the public port which the Let's Encrypt server should query against. I imagine something like this.

./lego [other params...] --port=80 --natport=8888

Where lego would be listening on 80 in the local machine but tell the Let's Encrypt server to connect to 8888.

Add a Go web server+Lego tutorial to wiki?

Hi Legoers. I've been so impressed with Lego after discovering it a couple of days ago that I made a short tutorial describing my setup to try to help others. You can find it here:

https://github.com/xi2/lego/wiki/A-100%25-automated-Lego-setup-for-Go-web-servers

Sorry for creating a Github issue, but there doesn't seem to be pull requests for the wiki?

Is the tutorial worth adding the wiki? I didn't want to just dump it on there as that seemed a bit rude. If it's not the right sort of thing then I will probably stick it on my blog so that's OK too and there'd be no offence caused. :)

Best wishes

DNS challenge with Route 53 fails with "InvalidTXTRDATA encountered"

Continued from my comments in #2:

$ lego --email="[email protected]" --domains="example.com" --dns="route53" --exclude="http-01" --exclude="tls-sni-01" run
2016/01/29 23:06:03 [INFO][example.com] acme: Obtaining bundled SAN certificate
2016/01/29 23:06:03 [INFO][example.com] acme: Could not find solver for: http-01
2016/01/29 23:06:03 [INFO][example.com] acme: Could not find solver for: tls-sni-01
2016/01/29 23:06:03 [INFO] acme: Trying to solve DNS-01
2016/01/29 23:06:04 [example.com] Could not obtain certificates
    Error presenting token Request failed, got status code: 400. Response: <?xml version="1.0"?>
<ErrorResponse xmlns="https://route53.amazonaws.com/doc/2013-04-01/"><Error><Type>Sender</Type><Code>InvalidChangeBatch</Code><Message>Invalid Resource Record: FATAL problem: InvalidTXTRDATA encountered at hcpTWGxkPEGUMxJMPsXtsPE0TSflliWqAKH1FJ8crvg</Message></Error><RequestId>REDACTED</RequestId></ErrorResponse>

This is with lego built from source at commit 031c5b5 (HEAD as of right now).

ACME challenge route53 does not build on 32bit

den@abdim:lego$ git log -1
commit 5992793edd44b2adbf095c1bc70245bb2a440b2c
Author: xenolf <[email protected]>
Date:   Fri Jan 22 02:25:27 2016 +0100

    Refactor DNS precheck

den@abdim:lego$ go version
go version go1.5.3 linux/386

den@abdim:lego$ go build
# github.com/xenolf/lego/acme
acme/dns_challenge_route53.go:66: constant 9223372036854775807 overflows int

Provide autorenew command

I don't know if this is feasible or not as I have not too much experience with letsencrypt.

Would it be possible to have some kind of 'autorenew' command which renews all certificates it finds in the lego directory which require renewal within a given period of days (preferable configurable)?

So one has just to schedule a daily cronjob which calls autorenew. Failures should then be outputted to stderr and exit with != 0, so that it's easy to send a failure notice email just in case.

Need assistance in private beta...

Hi sorry if this is more of a stupid error by me, but I can't get lego to work on my server.

Running letsencryt-auto works and creates certificates:
/opt/letsencrypt/letsencrypt-auto --agree-dev-preview --server https://acme-v01.api.letsencrypt.org/directory auth -d sub.mydomain.com--standalone

Running lego:

./Go/bin/lego --domains=sub.mydomain.com -B 4096 --email="[email protected]" --port 10443 -s "https://acme-v01.api.letsencrypt.org/" run

gets me:

2015/11/20 16:24:52 [INFO] acme: Obtaining bundled SAN certificate for mydomain.com
2015/11/20 16:24:53 [INFO] acme: Trying to solve HTTP-01
2015/11/20 16:24:54 [mydomain.com] Could not obtain certificates
    The server could not validate our request.

Can you help me out here? I even tried the add-tls-sni-challenge branch, but with the same results.

Webroot authenticator

Do you plan to implement webroot authenticator? ACME challenge file can be written to a directory, while another webserver (eg. nginx) is configured to read from it.

Not only it allows to run the client LE application as non-root user, it is also possible to run multiple cert requests at once, because it doesn't block any incoming port.

OCSP syntax error

Usually when I call acme.GetOCSPForCert and pass in the PEM-encoded certificate bundle, I get this error:

asn1: syntax error: sequence truncated

This is on a 32-bit Windows VM. Here is the cert bundle - (from happy hacker fake CA):

-----BEGIN CERTIFICATE-----
MIIE4zCCA8ugAwIBAgITAPrCvQf6blNjag6FSzlxf3ZqtTANBgkqhkiG9w0BAQsF
ADAfMR0wGwYDVQQDDBRoYXBweSBoYWNrZXIgZmFrZSBDQTAeFw0xNTExMTgwMjA0
MDBaFw0xNjAyMTYwMjA0MDBaMBoxGDAWBgNVBAMTD2ZpbmVycGl4ZWxzLmNvbTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM0RTYoqnUWbeOzXrItwPxhx
Tq7zxlwj9BW3KJ07NjDpCjWWTYMB4bF0O3ipoVYzxkz/8Fd20yml8NbN+s/ajtR/
bKt1VoHersPu5Zt6sIT0BjcJrhvTUtGMnPHoKntP9Zya3aP0rTfC5+u8uzDtz+M3
636MzhcrciT1YH4ssewvhmqQnKJg27lhkRuTI300ffMzaphY4mqdmrMJN7iNwIca
XUwedz6f/SWTb6czCES4rRb4NFGfmxkdxCzrJ1bfpYrLtjYT6BodPb3yNA5C5G51
wbcHABpSI8+GuPr347Nj8aPwSfFuIdbWmigXWT0g26WesZWkfdq4nbgx5MGRx30C
AwEAAaOCAhswggIXMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcD
AQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU/HnLxTMWmlG7JSKi
tti92ApIDqQwHwYDVR0jBBgwFoAU+3hPEvlgFYMsnxd/NBmzLjbqQYkweAYIKwYB
BQUHAQEEbDBqMDMGCCsGAQUFBzABhidodHRwOi8vb2NzcC5zdGFnaW5nLXgxLmxl
dHNlbmNyeXB0Lm9yZy8wMwYIKwYBBQUHMAKGJ2h0dHA6Ly9jZXJ0LnN0YWdpbmct
eDEubGV0c2VuY3J5cHQub3JnLzAaBgNVHREEEzARgg9maW5lcnBpeGVscy5jb20w
ggEABgNVHSAEgfgwgfUwCgYGZ4EMAQIBMAAwgeYGCysGAQQBgt8TAQEBMIHWMCYG
CCsGAQUFBwIBFhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCBqwYIKwYBBQUH
AgIwgZ4MgZtUaGlzIENlcnRpZmljYXRlIG1heSBvbmx5IGJlIHJlbGllZCB1cG9u
IGJ5IFJlbHlpbmcgUGFydGllcyBhbmQgb25seSBpbiBhY2NvcmRhbmNlIHdpdGgg
dGhlIENlcnRpZmljYXRlIFBvbGljeSBmb3VuZCBhdCBodHRwczovL2xldHNlbmNy
eXB0Lm9yZy9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEABQOe88NEmuig
dWSpxUDThdEwlGXmo3V+JUuBpepojlBoPxI/lNn3iIFvPTM2pB384ZSDQ0LeIgW3
LoVws10zSEx1jFDzJmqdFv7K+/7pHmUXDEsH+KiwbTyAaawM+uoNL4P0lCqI0g7H
j3YgPBMWHZ+8udLBxbRvqjQC8RT0mUXZl2PdQbYo4/MnauCq21BAsUieCkTNz84w
hizziDazIhOnxY1U+F12uH/8n619Gm530y5MBaavLXWsrTTYfN4r8kEt3mTplXlW
UXJr1KMHxARHFIUQopKfd25vjzJyHIhJqF6tEeJgVvSdfqH08IfRUQ1wYMHLJ2ks
hmTQWMs2Mg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDETCCAfmgAwIBAgIJAJzxkS6o1QkIMA0GCSqGSIb3DQEBCwUAMB8xHTAbBgNV
BAMMFGhhcHB5IGhhY2tlciBmYWtlIENBMB4XDTE1MDQwNzIzNTAzOFoXDTI1MDQw
NDIzNTAzOFowHzEdMBsGA1UEAwwUaGFwcHkgaGFja2VyIGZha2UgQ0EwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCCkd5mgXFErJ3F2M0E9dw+Ta/md5i
8TDId01HberAApqmydG7UZYF3zLTSzNjlNSOmtybvrSGUnZ9r9tSQcL8VM6WUOM8
tnIpiIjEA2QkBycMwvRmZ/B2ltPdYs/R9BqNwO1g18GDZrHSzUYtNKNeFI6Glamj
7GK2Vr0SmiEamlNIR5ktAFsEErzf/d4jCF7sosMsJpMCm1p58QkP4LHLShVLXDa8
BMfVoI+ipYcA08iNUFkgW8VWDclIDxcysa0psDDtMjX3+4aPkE/cefmP+1xOfUuD
HOGV8XFynsP4EpTfVOZr0/g9gYQ7ZArqXX7GTQkFqduwPm/w5qxSPTarAgMBAAGj
UDBOMB0GA1UdDgQWBBT7eE8S+WAVgyyfF380GbMuNupBiTAfBgNVHSMEGDAWgBT7
eE8S+WAVgyyfF380GbMuNupBiTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUA
A4IBAQAd9Da+Zv+TjMv7NTAmliqnWHY6d3UxEZN3hFEJ58IQVHbBZVZdW7zhRktB
vR05Kweac0HJeK91TKmzvXl21IXLvh0gcNLU/uweD3no/snfdB4OoFompljThmgl
zBqiqWoKBJQrLCA8w5UB+ReomRYd/EYXF/6TAfzm6hr//Xt5mPiUHPdvYt75lMAo
vRxLSbF8TSQ6b7BYxISWjPgFASNNqJNHEItWsmQMtAjjwzb9cs01XH9pChVAWn9L
oeMKa+SlHSYrWG93+EcrIH/dGU76uNOiaDzBSKvaehG53h25MHuO1anNICJvZovW
rFo4Uv1EnkKJm3vJFe50eJGhEKlx
-----END CERTIFICATE-----

Sometimes it works though. For example, I just re-ran the client for the same hostname (after deleting the cert file from last time) and had it issue a new certificate, then checking the OCSP status again showed no errors. Status was 0 (Good).

Make lego more search friendly with godoc.org

Hi. Firstly, thank you for making lego. It's working great for me. This is not a bug report, but merely a suggestion.

When I go looking for Go stuff my first try is normally to type the thing I am looking for into godoc.org (e.g. "lets encrypt" or "acme"). I actually did this twice over the last couple of months and failed to notice lego. I eventually found it a day or two ago via a blog post.

This could be easily remedied by adding single line package comments as discussed at https://golang.org/doc/effective_go.html#commentary for github.com/xenolf/lego and github.com/xenolf/lego/acme. I can't believe I'm the only one looking on godoc.org before looking elsewhere!

Best wishes and thanks again for lego.

NXDOMAIN errors in DNS challenge

Had to hardcode a 5 sec sleep after creating the TXT record because of frequent errors:

acme: Error 0 - urn:acme:error:connection - DNS problem: NXDOMAIN looking up TXT for _acme-challenge.xxxx.xxxx.com

We need to tweak DNS check here a bit: https://github.com/xenolf/lego/blob/master/acme/dns_challenge.go#L70

We should not rely on the SOA record content. This gives us only the master server of the zone - which might not even be part of the NS record that recursive resolvers query to find the nameserers. Boulder uses unbound for that purpose (letsencrypt/boulder#1112 (comment)).
So the record might well be available at the master server when we query it, but this does not mean that the record has (already) been propagated to the actual nameservers that Boulders recursive resolver will query. We should therefore lookup the NS record and use the nameservers listed therein. Maybe query them all.

Listen IP/interface of lego unclear

Hi there!

I upgraded to v0.1 and now I am getting this error:

2015/12/04 10:10:14 Could not create client:decode directory: invalid character '<' looking for beginning of value

I am using the following parameters:

lego --domains=mydomain.de -B 4096 --email="[email protected]" -s "https://acme-v01.api.letsencrypt.org/" --path=/var/container/nginx/newcert/ --port 9999 run

Did something change? I tried using the existing keys and creating new ones, the error is still the same.

Thanks!

Which ports does lego actually need/use?

This is another question/clarification.

From reading the entire README, my understanding is that lego only needs to use port 443 by default, unless you use a custom port, then you need to forward 443 to that.

From https://www.guyrutenberg.com/2015/11/07/getting-started-with-lets-encrypt-tutorial/:

The next step is to issue the certificate and prove to Let’s Encrypt that you have some control over the domain. The client supports two methods to perform the validation. The first one is the standalone server. It works by setting up a webserver on port 443, and responding to a challenge from the Let’s Encrypt servers. However, if you already have your own web-server running on port 443 (the default for TLS/SSL), you would have to temporarily shut it down.

Which seems to confirm that idea.

However, commit c4add3c says:

Assumes the lego binary has permission to bind to ports 80 and 443.

This is the only mention of port 80 that I see in the README.

Is that accurate? Does it actually need both 80 and 443 (meaning I need to temporarily stop whatever's running on both 80 and 443 when running lego)? Or does it only need 443, and mentioning port 80 is unintended? /cc @mholt

Whatever the answer is, I think it would be helpful to cover in a little more detail that given ports need to be available temporarily while lego is running, and that you need to shutdown something else that might be running there. Just to let people know that it's normal procedure (and maybe suggest alternatives, etc.).

Thanks again, this project is great!

DNS challenge error when FQDN is a CNAME

Thanks for lego, it's awesome!

When I use the DNS challenge to request a cert for a FQDN that's a CNAME, I get the following. Assume iamacname.example.com is a CNAME for www.example.com

2016/02/01 13:06:25 [INFO][iamacname.example.com] acme: Obtaining bundled SAN certificate

2016/02/01 13:06:25 [INFO][iamacname.example.com] acme: Trying to solve DNS-01
2016/02/01 13:06:25 [INFO] acme: Please create the following TXT record in your DNS zone:
2016/02/01 13:06:25 [INFO] acme: _acme-challenge.iamacname.example.com. 120 IN TXT "U4BJAr7Mg1x2BSdYWeCDLvWSYPkj14XR3uohxan1_RU"
2016/02/01 13:06:25 [INFO] acme: Press 'Enter' when you are done
2016/02/01 13:06:25 [INFO] acme: You can now remove this TXT record from your DNS zone:
2016/02/01 13:06:25 [INFO] acme: _acme-challenge.iamacname.example.com. 120 IN TXT "..."
panic: interface conversion: dns.RR is *dns.CNAME, not *dns.SOA

goroutine 1 [running]:
github.com/xenolf/lego/acme.checkDNS(0x7ffcb3f28514, 0x13, 0xc820424690, 0x24, 0xc820424690)
        /home/happy/x/src/github.com/xenolf/lego/acme/dns_challenge.go:82 +0x355
github.com/xenolf/lego/acme.(*dnsChallenge).Solve(0xc82011c240, 0x0, 0x0, 0xc820432180, 0x6, 0xc820432190, 0x7, 0xc8203500e0, 0x68, 0xc8204240c0, ...)
        /home/happy/x/src/github.com/xenolf/lego/acme/dns_challenge.go:65 +0x5a6
github.com/xenolf/lego/acme.(*Client).solveChallenges(0xc820126080, 0xc82000a300, 0x1, 0x1, 0xc82000a300)
        /home/happy/x/src/github.com/xenolf/lego/acme/client.go:369 +0x250
github.com/xenolf/lego/acme.(*Client).ObtainCertificate(0xc820126080, 0xc820013990, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /home/happy/x/src/github.com/xenolf/lego/acme/client.go:227 +0x25b
main.run(0xc8200dc240)
        /home/happy/x/src/github.com/xenolf/lego/cli_handlers.go:174 +0x173f
github.com/codegangsta/cli.Command.Run(0x9412b0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9dbd80, 0x3a, 0x0, ...)
        /home/happy/x/src/github.com/codegangsta/cli/command.go:163 +0x131d
github.com/codegangsta/cli.(*App).Run(0xc82008fe60, 0xc82000a0c0, 0xc, 0xc, 0x0, 0x0)
        /home/happy/x/src/github.com/codegangsta/cli/app.go:179 +0x1169
main.main()
        /home/happy/x/src/github.com/xenolf/lego/cli.go:126 +0x106f

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
        /usr/lib/go/src/runtime/asm_amd64.s:1696 +0x1

goroutine 9 [IO wait]:
net.runtime_pollWait(0x7f8f324ee000, 0x72, 0xc820012270)
        /usr/lib/go/src/runtime/netpoll.go:157 +0x60
net.(*pollDesc).Wait(0xc820128060, 0x72, 0x0, 0x0)
        /usr/lib/go/src/net/fd_poll_runtime.go:73 +0x3a
net.(*pollDesc).WaitRead(0xc820128060, 0x0, 0x0)
        /usr/lib/go/src/net/fd_poll_runtime.go:78 +0x36
net.(*netFD).Read(0xc820128000, 0xc82031c000, 0x800, 0x800, 0x0, 0x7f8f34652050, 0xc820012270)
        /usr/lib/go/src/net/fd_unix.go:232 +0x23a
net.(*conn).Read(0xc820030080, 0xc82031c000, 0x800, 0x800, 0x0, 0x0, 0x0)
        /usr/lib/go/src/net/net.go:172 +0xe4
crypto/tls.(*block).readFromUntil(0xc8201123f0, 0x7f8f34656b50, 0xc820030080, 0x5, 0x0, 0x0)
        /usr/lib/go/src/crypto/tls/conn.go:455 +0xcc
crypto/tls.(*Conn).readRecord(0xc8200d4840, 0xa14117, 0x0, 0x0)
        /usr/lib/go/src/crypto/tls/conn.go:540 +0x2d1
crypto/tls.(*Conn).Read(0xc8200d4840, 0xc820188000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
        /usr/lib/go/src/crypto/tls/conn.go:901 +0x167
net/http.noteEOFReader.Read(0x7f8f34663308, 0xc8200d4840, 0xc8200e67e8, 0xc820188000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
        /usr/lib/go/src/net/http/transport.go:1370 +0x67
net/http.(*noteEOFReader).Read(0xc82044a700, 0xc820188000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
        <autogenerated>:126 +0xd0
bufio.(*Reader).fill(0xc8203ecfc0)
        /usr/lib/go/src/bufio/bufio.go:97 +0x1e9
bufio.(*Reader).Peek(0xc8203ecfc0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
        /usr/lib/go/src/bufio/bufio.go:132 +0xcc
net/http.(*persistConn).readLoop(0xc8200e6790)
        /usr/lib/go/src/net/http/transport.go:876 +0xf7
created by net/http.(*Transport).dialConn
        /usr/lib/go/src/net/http/transport.go:685 +0xc78

goroutine 10 [select]:
net/http.(*persistConn).writeLoop(0xc8200e6790)
        /usr/lib/go/src/net/http/transport.go:1009 +0x40c
created by net/http.(*Transport).dialConn
        /usr/lib/go/src/net/http/transport.go:686 +0xc9d

Invalid options produce weird error messages

Example:

   $ ./lego --email="[email protected]" --server="http://192.168.0.200:4000/directory" --http --domains="test1.com" run

Outputs

2016/01/17 18:42:46 Please specify --domains or -d

The real problem is that --http should be --http=":80" but the error is ununsual.

If you want me to fix this I can build a "pull" request.

error 400 from letsencrypt servers

lego --email "[email protected]" -d nella.org -d blog.nella.org run
2015/12/13 00:17:21 [INFO] acme: Registering account for [email protected]
2015/12/13 00:17:21 [DEBUG] {"resource":"new-reg","contact":["mailto:[email protected]"]}
2015/12/13 00:17:21 Could not complete registration
acme: Error 400 - urn:acme:error:malformed - Unable to read/verify body :: Parse error reading JWS

The "DEBUG" line is something I added to dump the jsonBytes to see if they looked right.

My copy of lego is from c4add3c

Installation from source instructions?

I think it'd be very helpful to have a section that covers how to install lego from source. In the README, I could only see that binary releases are available. If I want to build from source, is that supported?

I assume it would be just go get -u github.com/xenolf/lego, but without a section like https://github.com/shurcooL/binstale#installation, I find it hard to be confident.

Leaving this out makes me worry that building from source is not recommended/not supported. Is that the case?

Implement HTTP-01 challenge type

The existing "simpleHttp" and "dvsni" challenges are insecure, and Let's Encrypt will be disabling them in the near future. In order to keep working, lego will need to implement the "http-01" or "tls-sni-01" challenges.

See this issue from the official Let's Encrypt client:
certbot/certbot#914

Exit code is always 0

When certificate generation fails, the client still exits with code 0:

user@host:~$ ./lego --domains=<redacted> -B 4096 -m <redacted> --path=/etc/ssl/letsencrypt --port=9999 run
2015/12/07 15:02:40 [INFO] acme: Obtaining bundled SAN certificate for <redacted>
2015/12/07 15:02:40 [INFO] acme: Trying to solve HTTP-01
2015/12/07 15:02:41 [<redacted>] Could not obtain certificates
    The server could not validate our request.
user@host:~$ echo $?
0

This makes checking for errors in the certificate generation process unnecessarily difficult.

hook for dvsni challenge

I have a situation where the server receiving the certificate has a proxy which serves many servers in front of it (letsencrypt/acme-spec#222).

I need a way for the server behind the proxy to inform the proxy that it would like to respond to SNI requests matching <challenge1>.<challenge2>.acme.invalid.

My initial suggestion was that the format of the challenge should be changed to <challenge1>.<challenge2>.<sub.domain.tld>.acme.invalid (ietf-wg-acme/acme#23), but that was decided to be a non-optimal solution.

The next-best solution I can come up with is that the client should make a hook available to expose the challenge and and perform any necessary work to ensure that the response to the challenge can be received.

Show server error messages

It seems the server can return typed error responses alike:

HTTP/1.1 403 Forbidden
Server: nginx
Content-Type: application/problem+json
Content-Length: 90
Replay-Nonce: BImpOtZwyWj0msQvumDms8FPPheeyA-dpljvm86upH4
Expires: Wed, 28 Oct 2015 14:21:10 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Wed, 28 Oct 2015 14:21:10 GMT
Connection: close

{"type":"urn:acme:error:unauthorized","detail":"Error creating new authz :: Syntax error"}

It would be great if the client could return those error messages to stdout instead of just outputting The server did not provide enough information to proceed.. That particular error was returned because I tried to use --domains localhost.

Revoking certificate with server private key

I'm trying to revoke a certificate using the private key of the host/server. I load the certificate's PEM-encoded bytes from a file (and confirmed that that works), and when I do client.RevokeCertificate(certBytes), I get this error:

2015/10/20 23:33:12 The server returned an error while trying to revoke the certificate.
{"type":"urn:acme:error:malformed","detail":"No such certificate"}

The client is created not necessarily with the same email address as was used to obtain the certificate originally. How can I use the server's private key instead to revoke the cert?

renew --days logic backwards

The logic of the --days parameter seems reversed to me:

 if int(expTime.Sub(time.Now()).Hours() / 24.0) <= c.Int("days") {
        return
 }

This appears to renew the certificate only if it is NOT about to expire.

Is this the behaviour intended, or a typo?

Multiple domains no longer work

Hi there!

I updated to 0.2 today, and my bundled certificate can no longer be aquired.

sudo /home/ansible/lego --exclude "tls-sni-01" --domains="git.example.com" --domains="cd.example.com" --domains="registry.staging.example.com" --domains="chat.staging.example.com" >
2016/01/11 14:30:45 [INFO][git.example.com, cd.example.com, registry.staging.example.com, chat.staging.example.com, accounts.staging.example.com] acme: Obtaining bundled SAN certif>
2016/01/11 14:30:46 [INFO][git.example.com] acme: Trying to solve HTTP-01
2016/01/11 14:30:48 [INFO][git.example.com] Served key authentication
2016/01/11 14:30:49 [INFO][git.example.com] The server validated our request
2016/01/11 14:30:49 [INFO][cd.example.com] acme: Could not find solver for: tls-sni-01
2016/01/11 14:30:49 [INFO][cd.example.com] acme: Trying to solve HTTP-01
2016/01/11 14:30:49 [INFO][registry.staging.example.com] acme: Could not find solver for: tls-sni-01
2016/01/11 14:30:49 [INFO][registry.staging.example.com] acme: Trying to solve HTTP-01
2016/01/11 14:30:49 [INFO][chat.staging.example.com] acme: Could not find solver for: tls-sni-01
2016/01/11 14:30:49 [INFO][chat.staging.example.com] acme: Trying to solve HTTP-01
2016/01/11 14:30:49 [INFO][accounts.staging.example.com] acme: Trying to solve HTTP-01
2016/01/11 14:30:49 [cd.example.com] Could not obtain certificates
  Could not start HTTP server for challenge -> listen tcp 0.0.0.0:9999: bind: address already in use
2016/01/11 14:30:49 [registry.staging.example.com] Could not obtain certificates
  Could not start HTTP server for challenge -> listen tcp 0.0.0.0:9999: bind: address already in use
2016/01/11 14:30:49 [chat.staging.example.com] Could not obtain certificates
  Could not start HTTP server for challenge -> listen tcp 0.0.0.0:9999: bind: address already in use
2016/01/11 14:30:49 [accounts.staging.example.com] Could not obtain certificates
  Could not start HTTP server for challenge -> listen tcp 0.0.0.0:9999: bind: address already in use

it seems to try to start one server for every domain parameter.
Earlier it created one bundled certificate with only one webserver.

Reverse proxying to lego requires modifying reverse proxy transport

Hi. I'm not sure if this is a bug or not, but if not it might be worth documenting somewhere if it isn't.

My setup is that I wanted to run lego on a non-standard port (using the --http flag) and have http-01 acme challenges forwarded to lego from my two web servers.

My first attempt at doing so was to add 302 http redirects but for some reason the Let's Encrypt validation servers just wouldn't play ball (even though everyone on the net says http redirects works fine). This was nothing to do with lego, but I just thought I'd mention it.

Having failed at that I decided to use httputil.ReverseProxy from the Go standard library to send on the challenges. This worked great with my first web server which has a single domain name on the certificate. However my second web server, which has a SAN Multi-Domain certificate, failed. The first domain on the certificate validated fine with Let's Encrypt's servers, but the second did not whith lego returning an acme "404" error.

After a bit of head scratching I turned off re-use of TCP connections between different HTTP requests in the transport of the reverse proxy by setting DisableKeepAlives in the transport to true. Then everything worked perfectly! :)

Anyway, I just thought I'd let you guys know in case it was of interest.

Renew with bundled san certificates drops subject alternate names

hi there, just tried to renew my bundled certificate, but it always drops my SAN.

Tested with one --domains parameter that contained only the main certificate domain and also one test with all --domains parameter.

Tested versions: master and 0.2

Command to check:
openssl x509 -noout -text -in /etc/ssl/letsencrypt/certificate

CLI displays the wrong version

Calling ./lego shows you some information, including the installed version. Currently it displays the wrong version (master still shows 0.1.0 while 0.1.1 is released)

Not a huge deal, I was just a little confused at first :)

Failover by trying other challenges

It would be good - perhaps optionally? - if failure to verify a domain name could try again using a different challenge (whichever challenges are not excluded by the user) to maximize the chances of getting a certificate.

I know we've talked about this before and is on the roadmap already, but just documenting this here so we don't forget.

Suggestion about NewClient

To make NewClient easier to use and more customizable, I propose the following usage:

challengeTypes := acme.ChallengeHTTP | acme.ChallengeTLSSNI | acme.ChallengeDNS
client, err := acme.NewClient(dirURL, user, keyBits, challengeTypes)
// err check

// the client could have exported fields to allow it to be customized, for example:
client.HTTPChallengeServer = myServer // or whatever
client.HTTPChallengePort = optPort // instead of passing it into NewClient, which feels weird for just one challenge type
// any other customizations here, like challenge priorities:
client.ChallengePriority = []acme.ChallengeType{acme.ChallengeHTTP, acme.ChallengeTLSSNI}
// ^ although I'm not sure if the bitmask above should be mutually exclusive with priorities...

Basically, change the last argument of NewClient to be a bitmask (maybe? depends on how challenge priorities is implemented) and allow the *Client to be customized after its construction.

question regarding usage

I am a go developer and am running servers on google compute and AWS.

I saw the python client and how it kind of integrates with Apache. Nice for Apache users but useless for me.

Is there some docs yet regarding using this go based client ?
Can i participate in testing domains and wildcard domains ? I would like to try this out for our development environments now.

Provide builds with go 1.5

Hello,

I'm guessing the current releases are built with go 1.6 which attempts to use http/2 which doesn't currently work with the lets encrypt production servers. Given that go 1.6 has not yet been released, it seems like the released binaries should be built with 1.5 to fix this issue.

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.