forked from TrueCloudLab/lego
New challenges management. (#741)
This commit is contained in:
parent
9979087572
commit
43401f2475
11 changed files with 190 additions and 270 deletions
|
@ -38,7 +38,6 @@
|
||||||
exclude = [
|
exclude = [
|
||||||
"Error return value of (.+) is not checked",
|
"Error return value of (.+) is not checked",
|
||||||
"exported (type|method|function) (.+) should have comment or be unexported",
|
"exported (type|method|function) (.+) should have comment or be unexported",
|
||||||
"possible misuse of unsafe.Pointer",
|
|
||||||
"cyclomatic complexity (.+) of func `NewDNSChallengeProviderByName` is high (.+)", # providers/dns/dns_providers.go
|
"cyclomatic complexity (.+) of func `NewDNSChallengeProviderByName` is high (.+)", # providers/dns/dns_providers.go
|
||||||
"string `(lego\\.wtf|manhattan)` has (\\d+) occurrences, make it a constant", #providers/dns/gcloud/googlecloud_test.go
|
"string `(lego\\.wtf|manhattan)` has (\\d+) occurrences, make it a constant", #providers/dns/gcloud/googlecloud_test.go
|
||||||
|
|
||||||
|
|
85
README.md
85
README.md
|
@ -12,8 +12,8 @@ Let's Encrypt client and ACME library written in Go
|
||||||
|
|
||||||
### Binaries
|
### Binaries
|
||||||
|
|
||||||
To get the binary just download the latest release for your OS/Arch from [the release page](https://github.com/xenolf/lego/releases)
|
To get the binary just download the latest release for your OS/Arch from [the release page](https://github.com/xenolf/lego/releases) and put the binary somewhere convenient.
|
||||||
and put the binary somewhere convenient. lego does not assume anything about the location you run it from.
|
lego does not assume anything about the location you run it from.
|
||||||
|
|
||||||
### From Docker
|
### From Docker
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ go get -u github.com/xenolf/lego/cmd/lego
|
||||||
|
|
||||||
Please keep in mind that CLI switches and APIs are still subject to change.
|
Please keep in mind that CLI switches and APIs are still subject to change.
|
||||||
|
|
||||||
When using the standard `--path` option, all certificates and account configurations are saved to a folder *.lego* in the current working directory.
|
When using the standard `--path` option, all certificates and account configurations are saved to a folder `.lego` in the current working directory.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@ -75,30 +75,31 @@ COMMANDS:
|
||||||
help, h Shows a list of commands or help for one command
|
help, h Shows a list of commands or help for one command
|
||||||
|
|
||||||
GLOBAL OPTIONS:
|
GLOBAL OPTIONS:
|
||||||
--domains value, -d value Add a domain to the process. Can be specified multiple times.
|
--domains value, -d value Add a domain to the process. Can be specified multiple times.
|
||||||
--server value, -s value CA hostname (and optionally :port). The server certificate must be trusted in order to avoid further modifications to the client. (default: "https://acme-v02.api.letsencrypt.org/directory")
|
--server value, -s value CA hostname (and optionally :port). The server certificate must be trusted in order to avoid further modifications to the client. (default: "https://acme-v02.api.letsencrypt.org/directory")
|
||||||
--accept-tos, -a By setting this flag to true you indicate that you accept the current Let's Encrypt terms of service.
|
--accept-tos, -a By setting this flag to true you indicate that you accept the current Let's Encrypt terms of service.
|
||||||
--email value, -m value Email used for registration and recovery contact.
|
--email value, -m value Email used for registration and recovery contact.
|
||||||
--csr value, -c value Certificate signing request filename, if an external CSR is to be used
|
--csr value, -c value Certificate signing request filename, if an external CSR is to be used.
|
||||||
--eab Use External Account Binding for account registration. Requires --kid and --hmac.
|
--eab Use External Account Binding for account registration. Requires --kid and --hmac.
|
||||||
--kid value Key identifier from External CA. Used for External Account Binding.
|
--kid value Key identifier from External CA. Used for External Account Binding.
|
||||||
--hmac value MAC key from External CA. Should be in Base64 URL Encoding without padding format. Used for External Account Binding.
|
--hmac value MAC key from External CA. Should be in Base64 URL Encoding without padding format. Used for External Account Binding.
|
||||||
--key-type value, -k value Key type to use for private keys. Supported: rsa2048, rsa4096, rsa8192, ec256, ec384 (default: "rsa2048")
|
--key-type value, -k value Key type to use for private keys. Supported: rsa2048, rsa4096, rsa8192, ec256, ec384. (default: "rsa2048")
|
||||||
--filename value Filename of the generated certificate
|
--filename value (deprecated) Filename of the generated certificate.
|
||||||
--path value Directory to use for storing the data (default: "./.lego")
|
--path value Directory to use for storing the data. (default: "./.lego")
|
||||||
--exclude value, -x value Explicitly disallow solvers by name from being used. Solvers: "http-01", "dns-01", "tls-alpn-01".
|
--http Use the HTTP challenge to solve challenges. Can be mixed with other types of challenges.
|
||||||
--http-timeout value Set the HTTP timeout value to a specific value in seconds. The default is 10 seconds. (default: 0)
|
--http.port value Set the port and interface to use for HTTP based challenges to listen on.Supported: interface:port or :port. (default: ":80")
|
||||||
--webroot value Set the webroot folder to use for HTTP based challenges to write directly in a file in .well-known/acme-challenge
|
--http.webroot value Set the webroot folder to use for HTTP based challenges to write directly in a file in .well-known/acme-challenge.
|
||||||
--memcached-host value Set the memcached host(s) to use for HTTP based challenges. Challenges will be written to all specified hosts.
|
--http.memcached-host value Set the memcached host(s) to use for HTTP based challenges. Challenges will be written to all specified hosts.
|
||||||
--http value Set the port and interface to use for HTTP based challenges to listen on. Supported: interface:port or :port
|
--tls Use the TLS challenge to solve challenges. Can be mixed with other types of challenges.
|
||||||
--tls value Set the port and interface to use for TLS based challenges to listen on. Supported: interface:port or :port
|
--tls.port value Set the port and interface to use for TLS based challenges to listen on. Supported: interface:port or :port. (default: ":443")
|
||||||
--dns value Solve a DNS challenge using the specified provider. Disables all other challenges. Run 'lego dnshelp' for help on usage.
|
--dns value Solve a DNS challenge using the specified provider. Can be mixed with other types of challenges. Run 'lego dnshelp' for help on usage.
|
||||||
--dns-disable-cp By setting this flag to true, disables the need to wait the propagation of the TXT record to all authoritative name servers.
|
--dns.disable-cp By setting this flag to true, disables the need to wait the propagation of the TXT record to all authoritative name servers.
|
||||||
--dns-resolvers value Set the resolvers to use for performing recursive DNS queries. Supported: host:port. The default is to use the system resolvers, or Google's DNS resolvers if the system's cannot be determined.
|
--dns.resolvers value Set the resolvers to use for performing recursive DNS queries. Supported: host:port. The default is to use the system resolvers, or Google's DNS resolvers if the system's cannot be determined.
|
||||||
--dns-timeout value Set the DNS timeout value to a specific value in seconds. Used only when performing authoritative name servers queries. The default is 10 seconds. (default: 0)
|
--http-timeout value Set the HTTP timeout value to a specific value in seconds. (default: 0)
|
||||||
--pem Generate a .pem file by concatenating the .key and .crt files together.
|
--dns-timeout value Set the DNS timeout value to a specific value in seconds. Used only when performing authoritative name servers queries. (default: 10)
|
||||||
--help, -h show help
|
--pem Generate a .pem file by concatenating the .key and .crt files together.
|
||||||
--version, -v print the version
|
--help, -h show help
|
||||||
|
--version, -v print the version
|
||||||
```
|
```
|
||||||
|
|
||||||
### Sudo
|
### Sudo
|
||||||
|
@ -107,14 +108,14 @@ The CLI does not require root permissions but needs to bind to port 80 and 443 f
|
||||||
To run the CLI without sudo, you have four options:
|
To run the CLI without sudo, you have four options:
|
||||||
|
|
||||||
- Use setcap 'cap_net_bind_service=+ep' /path/to/program
|
- Use setcap 'cap_net_bind_service=+ep' /path/to/program
|
||||||
- Pass the `--http` or/and the `--tls` option and specify a custom port to bind to. In this case you have to forward port 80/443 to these custom ports (see [Port Usage](#port-usage)).
|
- Pass the `--http.port` or/and the `--tls.port` option and specify a custom port to bind to. In this case you have to forward port 80/443 to these custom ports (see [Port Usage](#port-usage)).
|
||||||
- Pass the `--webroot` option and specify the path to your webroot folder. In this case the challenge will be written in a file in `.well-known/acme-challenge/` inside your webroot.
|
- Pass the `--http.webroot` option and specify the path to your webroot folder. In this case the challenge will be written in a file in `.well-known/acme-challenge/` inside your webroot.
|
||||||
- Pass the `--dns` option and specify a DNS provider.
|
- Pass the `--dns` option and specify a DNS provider.
|
||||||
|
|
||||||
### Port Usage
|
### Port Usage
|
||||||
|
|
||||||
By default lego assumes it is able to bind to ports 80 and 443 to solve challenges.
|
By default lego assumes it is able to bind to ports 80 and 443 to solve challenges.
|
||||||
If this is not possible in your environment, you can use the `--http` and `--tls` options to instruct
|
If this is not possible in your environment, you can use the `--http.port` and `--tls.port` options to instruct
|
||||||
lego to listen on that interface:port for any incoming challenges.
|
lego to listen on that interface:port for any incoming challenges.
|
||||||
|
|
||||||
If you are using this option, make sure you proxy all of the following traffic to these ports.
|
If you are using this option, make sure you proxy all of the following traffic to these ports.
|
||||||
|
@ -131,13 +132,14 @@ This traffic redirection is only needed as long as lego solves challenges. As so
|
||||||
|
|
||||||
### CLI Example
|
### CLI Example
|
||||||
|
|
||||||
Assumes the `lego` binary has permission to bind to ports 80 and 443. You can get a pre-built binary from the [releases](https://github.com/xenolf/lego/releases) page.
|
Assumes the `lego` binary has permission to bind to ports 80 and 443.
|
||||||
|
You can get a pre-built binary from the [releases](https://github.com/xenolf/lego/releases) page.
|
||||||
If your environment does not allow you to bind to these ports, please read [Port Usage](#port-usage).
|
If your environment does not allow you to bind to these ports, please read [Port Usage](#port-usage).
|
||||||
|
|
||||||
Obtain a certificate:
|
Obtain a certificate:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
lego --email="foo@bar.com" --domains="example.com" run
|
lego --email="foo@bar.com" --domains="example.com" --http run
|
||||||
```
|
```
|
||||||
|
|
||||||
(Find your certificate in the `.lego` folder of current working directory.)
|
(Find your certificate in the `.lego` folder of current working directory.)
|
||||||
|
@ -145,13 +147,13 @@ lego --email="foo@bar.com" --domains="example.com" run
|
||||||
To renew the certificate:
|
To renew the certificate:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
lego --email="foo@bar.com" --domains="example.com" renew
|
lego --email="foo@bar.com" --domains="example.com" --http renew
|
||||||
```
|
```
|
||||||
|
|
||||||
To renew the certificate only if it expires within 30 days
|
To renew the certificate only if it expires within 30 days
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
lego --email="foo@bar.com" --domains="example.com" renew --days 30
|
lego --email="foo@bar.com" --domains="example.com" --http renew --days 30
|
||||||
```
|
```
|
||||||
|
|
||||||
Obtain a certificate using the DNS challenge and AWS Route 53:
|
Obtain a certificate using the DNS challenge and AWS Route 53:
|
||||||
|
@ -160,17 +162,16 @@ Obtain a certificate using the DNS challenge and AWS Route 53:
|
||||||
AWS_REGION=us-east-1 AWS_ACCESS_KEY_ID=my_id AWS_SECRET_ACCESS_KEY=my_key lego --email="foo@bar.com" --domains="example.com" --dns="route53" run
|
AWS_REGION=us-east-1 AWS_ACCESS_KEY_ID=my_id AWS_SECRET_ACCESS_KEY=my_key lego --email="foo@bar.com" --domains="example.com" --dns="route53" run
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that `--dns=foo` implies `--exclude=http-01`. lego will not attempt other challenges if you've told it to use DNS instead.
|
|
||||||
|
|
||||||
Obtain a certificate given a certificate signing request (CSR) generated by something else:
|
Obtain a certificate given a certificate signing request (CSR) generated by something else:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
lego --email="foo@bar.com" --csr=/path/to/csr.pem run
|
lego --email="foo@bar.com" --http --csr=/path/to/csr.pem run
|
||||||
```
|
```
|
||||||
|
|
||||||
(lego will infer the domains to be validated based on the contents of the CSR, so make sure the CSR's Common Name and optional SubjectAltNames are set correctly.)
|
(lego will infer the domains to be validated based on the contents of the CSR, so make sure the CSR's Common Name and optional SubjectAltNames are set correctly.)
|
||||||
|
|
||||||
lego defaults to communicating with the production Let's Encrypt ACME server. If you'd like to test something without issuing real certificates, consider using the staging endpoint instead:
|
lego defaults to communicating with the production Let's Encrypt ACME server.
|
||||||
|
If you'd like to test something without issuing real certificates, consider using the staging endpoint instead:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
lego --server=https://acme-staging-v02.api.letsencrypt.org/directory …
|
lego --server=https://acme-staging-v02.api.letsencrypt.org/directory …
|
||||||
|
@ -193,6 +194,8 @@ import (
|
||||||
|
|
||||||
"github.com/xenolf/lego/certcrypto"
|
"github.com/xenolf/lego/certcrypto"
|
||||||
"github.com/xenolf/lego/certificate"
|
"github.com/xenolf/lego/certificate"
|
||||||
|
"github.com/xenolf/lego/challenge/http01"
|
||||||
|
"github.com/xenolf/lego/challenge/tlsalpn01"
|
||||||
"github.com/xenolf/lego/lego"
|
"github.com/xenolf/lego/lego"
|
||||||
"github.com/xenolf/lego/registration"
|
"github.com/xenolf/lego/registration"
|
||||||
)
|
)
|
||||||
|
@ -243,10 +246,12 @@ func main() {
|
||||||
// because we aren't running as root and can't bind a listener to port 80 and 443
|
// because we aren't running as root and can't bind a listener to port 80 and 443
|
||||||
// (used later when we attempt to pass challenges). Keep in mind that you still
|
// (used later when we attempt to pass challenges). Keep in mind that you still
|
||||||
// need to proxy challenge traffic to port 5002 and 5001.
|
// need to proxy challenge traffic to port 5002 and 5001.
|
||||||
if err = client.Challenge.SetHTTP01Address(":5002"); err != nil {
|
err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", "5002"))
|
||||||
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
if err = client.Challenge.SetTLSALPN01Address(":5001"); err != nil {
|
err = client.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", "5001"))
|
||||||
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,8 @@ func (c *Challenge) Solve(authz acme.Authorization) error {
|
||||||
|
|
||||||
// CleanUp cleans the challenge.
|
// CleanUp cleans the challenge.
|
||||||
func (c *Challenge) CleanUp(authz acme.Authorization) error {
|
func (c *Challenge) CleanUp(authz acme.Authorization) error {
|
||||||
|
log.Infof("[%s] acme: Cleaning DNS-01 challenge", challenge.GetTargetedDomain(authz))
|
||||||
|
|
||||||
chlng, err := challenge.FindChallenge(challenge.DNS01, authz)
|
chlng, err := challenge.FindChallenge(challenge.DNS01, authz)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -3,7 +3,6 @@ package resolver
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
@ -21,7 +20,7 @@ type byType []acme.Challenge
|
||||||
|
|
||||||
func (a byType) Len() int { return len(a) }
|
func (a byType) Len() int { return len(a) }
|
||||||
func (a byType) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
func (a byType) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||||
func (a byType) Less(i, j int) bool { return a[i].Type < a[j].Type }
|
func (a byType) Less(i, j int) bool { return a[i].Type > a[j].Type }
|
||||||
|
|
||||||
type SolverManager struct {
|
type SolverManager struct {
|
||||||
core *api.Core
|
core *api.Core
|
||||||
|
@ -29,55 +28,12 @@ type SolverManager struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSolversManager(core *api.Core) *SolverManager {
|
func NewSolversManager(core *api.Core) *SolverManager {
|
||||||
solvers := map[challenge.Type]solver{
|
|
||||||
challenge.HTTP01: http01.NewChallenge(core, validate, &http01.ProviderServer{}),
|
|
||||||
challenge.TLSALPN01: tlsalpn01.NewChallenge(core, validate, &tlsalpn01.ProviderServer{}),
|
|
||||||
}
|
|
||||||
|
|
||||||
return &SolverManager{
|
return &SolverManager{
|
||||||
solvers: solvers,
|
solvers: map[challenge.Type]solver{},
|
||||||
core: core,
|
core: core,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHTTP01Address specifies a custom interface:port to be used for HTTP based challenges.
|
|
||||||
// If this option is not used, the default port 80 and all interfaces will be used.
|
|
||||||
// To only specify a port and no interface use the ":port" notation.
|
|
||||||
//
|
|
||||||
// NOTE: This REPLACES any custom HTTP provider previously set by calling
|
|
||||||
// c.SetProvider with the default HTTP challenge provider.
|
|
||||||
func (c *SolverManager) SetHTTP01Address(iface string) error {
|
|
||||||
host, port, err := net.SplitHostPort(iface)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if chlng, ok := c.solvers[challenge.HTTP01]; ok {
|
|
||||||
chlng.(*http01.Challenge).SetProvider(http01.NewProviderServer(host, port))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTLSALPN01Address specifies a custom interface:port to be used for TLS based challenges.
|
|
||||||
// If this option is not used, the default port 443 and all interfaces will be used.
|
|
||||||
// To only specify a port and no interface use the ":port" notation.
|
|
||||||
//
|
|
||||||
// NOTE: This REPLACES any custom TLS-ALPN provider previously set by calling
|
|
||||||
// c.SetProvider with the default TLS-ALPN challenge provider.
|
|
||||||
func (c *SolverManager) SetTLSALPN01Address(iface string) error {
|
|
||||||
host, port, err := net.SplitHostPort(iface)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if chlng, ok := c.solvers[challenge.TLSALPN01]; ok {
|
|
||||||
chlng.(*tlsalpn01.Challenge).SetProvider(tlsalpn01.NewProviderServer(host, port))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetHTTP01Provider specifies a custom provider p that can solve the given HTTP-01 challenge.
|
// SetHTTP01Provider specifies a custom provider p that can solve the given HTTP-01 challenge.
|
||||||
func (c *SolverManager) SetHTTP01Provider(p challenge.Provider) error {
|
func (c *SolverManager) SetHTTP01Provider(p challenge.Provider) error {
|
||||||
c.solvers[challenge.HTTP01] = http01.NewChallenge(c.core, validate, p)
|
c.solvers[challenge.HTTP01] = http01.NewChallenge(c.core, validate, p)
|
||||||
|
@ -96,18 +52,15 @@ func (c *SolverManager) SetDNS01Provider(p challenge.Provider, opts ...dns01.Cha
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exclude explicitly removes challenges from the pool for solving.
|
// Remove Remove a challenge type from the available solvers.
|
||||||
func (c *SolverManager) Exclude(challenges []challenge.Type) {
|
func (c *SolverManager) Remove(chlgType challenge.Type) {
|
||||||
// Loop through all challenges and delete the requested one if found.
|
delete(c.solvers, chlgType)
|
||||||
for _, chlg := range challenges {
|
|
||||||
delete(c.solvers, chlg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks all challenges from the server in order and returns the first matching solver.
|
// Checks all challenges from the server in order and returns the first matching solver.
|
||||||
func (c *SolverManager) chooseSolver(authz acme.Authorization) solver {
|
func (c *SolverManager) chooseSolver(authz acme.Authorization) solver {
|
||||||
// Allow to have a deterministic challenge order
|
// Allow to have a deterministic challenge order
|
||||||
sort.Sort(sort.Reverse(byType(authz.Challenges)))
|
sort.Sort(byType(authz.Challenges))
|
||||||
|
|
||||||
domain := challenge.GetTargetedDomain(authz)
|
domain := challenge.GetTargetedDomain(authz)
|
||||||
for _, chlg := range authz.Challenges {
|
for _, chlg := range authz.Challenges {
|
||||||
|
|
|
@ -5,54 +5,30 @@ import (
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/xenolf/lego/acme"
|
"github.com/xenolf/lego/acme"
|
||||||
"github.com/xenolf/lego/acme/api"
|
"github.com/xenolf/lego/acme/api"
|
||||||
"github.com/xenolf/lego/challenge"
|
|
||||||
"github.com/xenolf/lego/challenge/http01"
|
|
||||||
"github.com/xenolf/lego/platform/tester"
|
"github.com/xenolf/lego/platform/tester"
|
||||||
"gopkg.in/square/go-jose.v2"
|
"gopkg.in/square/go-jose.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSolverManager_SetHTTP01Address(t *testing.T) {
|
func TestByType(t *testing.T) {
|
||||||
_, apiURL, tearDown := tester.SetupFakeAPI()
|
challenges := []acme.Challenge{
|
||||||
defer tearDown()
|
{Type: "dns-01"}, {Type: "tlsalpn-01"}, {Type: "http-01"},
|
||||||
|
}
|
||||||
|
|
||||||
keyBits := 32 // small value keeps test fast
|
sort.Sort(byType(challenges))
|
||||||
key, err := rsa.GenerateKey(rand.Reader, keyBits)
|
|
||||||
require.NoError(t, err, "Could not generate test key")
|
|
||||||
|
|
||||||
core, err := api.New(http.DefaultClient, "lego-test", apiURL+"/dir", "", key)
|
expected := []acme.Challenge{
|
||||||
require.NoError(t, err)
|
{Type: "tlsalpn-01"}, {Type: "http-01"}, {Type: "dns-01"},
|
||||||
|
}
|
||||||
|
|
||||||
solversManager := NewSolversManager(core)
|
assert.Equal(t, expected, challenges)
|
||||||
|
|
||||||
optPort := "1234"
|
|
||||||
optHost := ""
|
|
||||||
|
|
||||||
err = solversManager.SetHTTP01Address(net.JoinHostPort(optHost, optPort))
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.IsType(t, &http01.Challenge{}, solversManager.solvers[challenge.HTTP01])
|
|
||||||
httpSolver := solversManager.solvers[challenge.HTTP01].(*http01.Challenge)
|
|
||||||
|
|
||||||
httpProviderServer := (*http01.ProviderServer)(unsafe.Pointer(reflect.ValueOf(httpSolver).Elem().FieldByName("provider").InterfaceData()[1]))
|
|
||||||
assert.Equal(t, net.JoinHostPort(optHost, optPort), httpProviderServer.GetAddress())
|
|
||||||
|
|
||||||
// test setting different host
|
|
||||||
optHost = "127.0.0.1"
|
|
||||||
err = solversManager.SetHTTP01Address(net.JoinHostPort(optHost, optPort))
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
httpProviderServer = (*http01.ProviderServer)(unsafe.Pointer(reflect.ValueOf(httpSolver).Elem().FieldByName("provider").InterfaceData()[1]))
|
|
||||||
assert.Equal(t, net.JoinHostPort(optHost, optPort), httpProviderServer.GetAddress())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidate(t *testing.T) {
|
func TestValidate(t *testing.T) {
|
||||||
|
|
|
@ -107,7 +107,7 @@ Here is an example bash command using the CloudFlare DNS provider:
|
||||||
fmt.Fprintln(w, "\tglesys:\tGLESYS_POLLING_INTERVAL, GLESYS_PROPAGATION_TIMEOUT, GLESYS_TTL, GLESYS_HTTP_TIMEOUT")
|
fmt.Fprintln(w, "\tglesys:\tGLESYS_POLLING_INTERVAL, GLESYS_PROPAGATION_TIMEOUT, GLESYS_TTL, GLESYS_HTTP_TIMEOUT")
|
||||||
fmt.Fprintln(w, "\tgodaddy:\tGODADDY_POLLING_INTERVAL, GODADDY_PROPAGATION_TIMEOUT, GODADDY_TTL, GODADDY_HTTP_TIMEOUT, GODADDY_SEQUENCE_INTERVAL")
|
fmt.Fprintln(w, "\tgodaddy:\tGODADDY_POLLING_INTERVAL, GODADDY_PROPAGATION_TIMEOUT, GODADDY_TTL, GODADDY_HTTP_TIMEOUT, GODADDY_SEQUENCE_INTERVAL")
|
||||||
fmt.Fprintln(w, "\thostingde:\tHOSTINGDE_POLLING_INTERVAL, HOSTINGDE_PROPAGATION_TIMEOUT, HOSTINGDE_TTL, HOSTINGDE_HTTP_TIMEOUT")
|
fmt.Fprintln(w, "\thostingde:\tHOSTINGDE_POLLING_INTERVAL, HOSTINGDE_PROPAGATION_TIMEOUT, HOSTINGDE_TTL, HOSTINGDE_HTTP_TIMEOUT")
|
||||||
fmt.Fprintln(w, "\thttpreq:\t,HTTPREQ_POLLING_INTERVAL, HTTPREQ_PROPAGATION_TIMEOUT, HTTPREQ_HTTP_TIMEOUT")
|
fmt.Fprintln(w, "\thttpreq:\tHTTPREQ_POLLING_INTERVAL, HTTPREQ_PROPAGATION_TIMEOUT, HTTPREQ_HTTP_TIMEOUT")
|
||||||
fmt.Fprintln(w, "\tiij:\tIIJ_POLLING_INTERVAL, IIJ_PROPAGATION_TIMEOUT, IIJ_TTL")
|
fmt.Fprintln(w, "\tiij:\tIIJ_POLLING_INTERVAL, IIJ_PROPAGATION_TIMEOUT, IIJ_TTL")
|
||||||
fmt.Fprintln(w, "\tinwx:\tINWX_POLLING_INTERVAL, INWX_PROPAGATION_TIMEOUT, INWX_TTL, INWX_SANDBOX")
|
fmt.Fprintln(w, "\tinwx:\tINWX_POLLING_INTERVAL, INWX_PROPAGATION_TIMEOUT, INWX_TTL, INWX_SANDBOX")
|
||||||
fmt.Fprintln(w, "\tlightsail:\tLIGHTSAIL_POLLING_INTERVAL, LIGHTSAIL_PROPAGATION_TIMEOUT")
|
fmt.Fprintln(w, "\tlightsail:\tLIGHTSAIL_POLLING_INTERVAL, LIGHTSAIL_PROPAGATION_TIMEOUT")
|
||||||
|
|
55
cmd/flags.go
55
cmd/flags.go
|
@ -13,8 +13,8 @@ func CreateFlags(defaultPath string) []cli.Flag {
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "server, s",
|
Name: "server, s",
|
||||||
Value: lego.LEDirectoryProduction,
|
|
||||||
Usage: "CA hostname (and optionally :port). The server certificate must be trusted in order to avoid further modifications to the client.",
|
Usage: "CA hostname (and optionally :port). The server certificate must be trusted in order to avoid further modifications to the client.",
|
||||||
|
Value: lego.LEDirectoryProduction,
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "accept-tos, a",
|
Name: "accept-tos, a",
|
||||||
|
@ -26,7 +26,7 @@ func CreateFlags(defaultPath string) []cli.Flag {
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "csr, c",
|
Name: "csr, c",
|
||||||
Usage: "Certificate signing request filename, if an external CSR is to be used",
|
Usage: "Certificate signing request filename, if an external CSR is to be used.",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "eab",
|
Name: "eab",
|
||||||
|
@ -43,56 +43,63 @@ func CreateFlags(defaultPath string) []cli.Flag {
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "key-type, k",
|
Name: "key-type, k",
|
||||||
Value: "rsa2048",
|
Value: "rsa2048",
|
||||||
Usage: "Key type to use for private keys. Supported: rsa2048, rsa4096, rsa8192, ec256, ec384",
|
Usage: "Key type to use for private keys. Supported: rsa2048, rsa4096, rsa8192, ec256, ec384.",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "filename",
|
Name: "filename",
|
||||||
Usage: "Filename of the generated certificate",
|
Usage: "(deprecated) Filename of the generated certificate.",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "path",
|
Name: "path",
|
||||||
Usage: "Directory to use for storing the data",
|
Usage: "Directory to use for storing the data.",
|
||||||
Value: defaultPath,
|
Value: defaultPath,
|
||||||
},
|
},
|
||||||
cli.StringSliceFlag{
|
cli.BoolFlag{
|
||||||
Name: "exclude, x",
|
Name: "http",
|
||||||
Usage: "Explicitly disallow solvers by name from being used. Solvers: \"http-01\", \"dns-01\", \"tls-alpn-01\".",
|
Usage: "Use the HTTP challenge to solve challenges. Can be mixed with other types of challenges.",
|
||||||
},
|
|
||||||
cli.IntFlag{
|
|
||||||
Name: "http-timeout",
|
|
||||||
Usage: "Set the HTTP timeout value to a specific value in seconds. The default is 10 seconds.",
|
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "webroot",
|
Name: "http.port",
|
||||||
Usage: "Set the webroot folder to use for HTTP based challenges to write directly in a file in .well-known/acme-challenge",
|
Usage: "Set the port and interface to use for HTTP based challenges to listen on.Supported: interface:port or :port.",
|
||||||
|
Value: ":80",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "http.webroot",
|
||||||
|
Usage: "Set the webroot folder to use for HTTP based challenges to write directly in a file in .well-known/acme-challenge.",
|
||||||
},
|
},
|
||||||
cli.StringSliceFlag{
|
cli.StringSliceFlag{
|
||||||
Name: "memcached-host",
|
Name: "http.memcached-host",
|
||||||
Usage: "Set the memcached host(s) to use for HTTP based challenges. Challenges will be written to all specified hosts.",
|
Usage: "Set the memcached host(s) to use for HTTP based challenges. Challenges will be written to all specified hosts.",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.BoolFlag{
|
||||||
Name: "http",
|
Name: "tls",
|
||||||
Usage: "Set the port and interface to use for HTTP based challenges to listen on. Supported: interface:port or :port",
|
Usage: "Use the TLS challenge to solve challenges. Can be mixed with other types of challenges.",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "tls",
|
Name: "tls.port",
|
||||||
Usage: "Set the port and interface to use for TLS based challenges to listen on. Supported: interface:port or :port",
|
Usage: "Set the port and interface to use for TLS based challenges to listen on. Supported: interface:port or :port.",
|
||||||
|
Value: ":443",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "dns",
|
Name: "dns",
|
||||||
Usage: "Solve a DNS challenge using the specified provider. Disables all other challenges. Run 'lego dnshelp' for help on usage.",
|
Usage: "Solve a DNS challenge using the specified provider. Can be mixed with other types of challenges. Run 'lego dnshelp' for help on usage.",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "dns-disable-cp",
|
Name: "dns.disable-cp",
|
||||||
Usage: "By setting this flag to true, disables the need to wait the propagation of the TXT record to all authoritative name servers.",
|
Usage: "By setting this flag to true, disables the need to wait the propagation of the TXT record to all authoritative name servers.",
|
||||||
},
|
},
|
||||||
cli.StringSliceFlag{
|
cli.StringSliceFlag{
|
||||||
Name: "dns-resolvers",
|
Name: "dns.resolvers",
|
||||||
Usage: "Set the resolvers to use for performing recursive DNS queries. Supported: host:port. The default is to use the system resolvers, or Google's DNS resolvers if the system's cannot be determined.",
|
Usage: "Set the resolvers to use for performing recursive DNS queries. Supported: host:port. The default is to use the system resolvers, or Google's DNS resolvers if the system's cannot be determined.",
|
||||||
},
|
},
|
||||||
|
cli.IntFlag{
|
||||||
|
Name: "http-timeout",
|
||||||
|
Usage: "Set the HTTP timeout value to a specific value in seconds.",
|
||||||
|
},
|
||||||
cli.IntFlag{
|
cli.IntFlag{
|
||||||
Name: "dns-timeout",
|
Name: "dns-timeout",
|
||||||
Usage: "Set the DNS timeout value to a specific value in seconds. Used only when performing authoritative name servers queries. The default is 10 seconds.",
|
Usage: "Set the DNS timeout value to a specific value in seconds. Used only when performing authoritative name servers queries.",
|
||||||
|
Value: 10,
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "pem",
|
Name: "pem",
|
||||||
|
|
|
@ -3,8 +3,10 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"github.com/xenolf/lego/cmd"
|
"github.com/xenolf/lego/cmd"
|
||||||
|
@ -20,7 +22,12 @@ func main() {
|
||||||
app.Name = "lego"
|
app.Name = "lego"
|
||||||
app.HelpName = "lego"
|
app.HelpName = "lego"
|
||||||
app.Usage = "Let's Encrypt client written in Go"
|
app.Usage = "Let's Encrypt client written in Go"
|
||||||
|
app.EnableBashCompletion = true
|
||||||
|
|
||||||
app.Version = version
|
app.Version = version
|
||||||
|
cli.VersionPrinter = func(c *cli.Context) {
|
||||||
|
fmt.Printf("lego version %s %s/%s\n", c.App.Version, runtime.GOOS, runtime.GOARCH)
|
||||||
|
}
|
||||||
|
|
||||||
defaultPath := ""
|
defaultPath := ""
|
||||||
cwd, err := os.Getwd()
|
cwd, err := os.Getwd()
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"github.com/xenolf/lego/challenge"
|
"github.com/xenolf/lego/challenge"
|
||||||
"github.com/xenolf/lego/challenge/dns01"
|
"github.com/xenolf/lego/challenge/dns01"
|
||||||
|
"github.com/xenolf/lego/challenge/http01"
|
||||||
|
"github.com/xenolf/lego/challenge/tlsalpn01"
|
||||||
"github.com/xenolf/lego/lego"
|
"github.com/xenolf/lego/lego"
|
||||||
"github.com/xenolf/lego/log"
|
"github.com/xenolf/lego/log"
|
||||||
"github.com/xenolf/lego/providers/dns"
|
"github.com/xenolf/lego/providers/dns"
|
||||||
|
@ -15,24 +18,22 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupChallenges(ctx *cli.Context, client *lego.Client) {
|
func setupChallenges(ctx *cli.Context, client *lego.Client) {
|
||||||
if len(ctx.GlobalStringSlice("exclude")) > 0 {
|
if !ctx.GlobalBool("http") && !ctx.GlobalBool("tls") && !ctx.GlobalIsSet("dns") {
|
||||||
excludedSolvers(ctx, client)
|
log.Fatal("No challenge selected. You must specify at least one challenge: `--http`, `--tls`, `--dns`.")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.GlobalIsSet("webroot") {
|
if ctx.GlobalBool("http") {
|
||||||
setupWebroot(client, ctx.GlobalString("webroot"))
|
err := client.Challenge.SetHTTP01Provider(setupHTTPProvider(ctx))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.GlobalIsSet("memcached-host") {
|
if ctx.GlobalBool("tls") {
|
||||||
setupMemcached(client, ctx.GlobalStringSlice("memcached-host"))
|
err := client.Challenge.SetTLSALPN01Provider(setupTLSProvider(ctx))
|
||||||
}
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
if ctx.GlobalIsSet("http") {
|
}
|
||||||
setupHTTP(client, ctx.GlobalString("http"))
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctx.GlobalIsSet("tls") {
|
|
||||||
setupTLS(client, ctx.GlobalString("tls"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.GlobalIsSet("dns") {
|
if ctx.GlobalIsSet("dns") {
|
||||||
|
@ -40,65 +41,59 @@ func setupChallenges(ctx *cli.Context, client *lego.Client) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func excludedSolvers(ctx *cli.Context, client *lego.Client) {
|
func setupHTTPProvider(ctx *cli.Context) challenge.Provider {
|
||||||
var cc []challenge.Type
|
switch {
|
||||||
for _, s := range ctx.GlobalStringSlice("exclude") {
|
case ctx.GlobalIsSet("http.webroot"):
|
||||||
cc = append(cc, challenge.Type(s))
|
ps, err := webroot.NewHTTPProvider(ctx.GlobalString("http.webroot"))
|
||||||
}
|
if err != nil {
|
||||||
client.Challenge.Exclude(cc)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
return ps
|
||||||
|
case ctx.GlobalIsSet("http.memcached-host"):
|
||||||
|
ps, err := memcached.NewMemcachedProvider(ctx.GlobalStringSlice("http.memcached-host"))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return ps
|
||||||
|
case ctx.GlobalIsSet("http.port"):
|
||||||
|
iface := ctx.GlobalString("http.port")
|
||||||
|
if !strings.Contains(iface, ":") {
|
||||||
|
log.Fatalf("The --http switch only accepts interface:port or :port for its argument.")
|
||||||
|
}
|
||||||
|
|
||||||
func setupWebroot(client *lego.Client, path string) {
|
host, port, err := net.SplitHostPort(iface)
|
||||||
provider, err := webroot.NewHTTPProvider(path)
|
if err != nil {
|
||||||
if err != nil {
|
log.Fatal(err)
|
||||||
log.Fatal(err)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
err = client.Challenge.SetHTTP01Provider(provider)
|
return http01.NewProviderServer(host, port)
|
||||||
if err != nil {
|
case ctx.GlobalBool("http"):
|
||||||
log.Fatal(err)
|
return http01.NewProviderServer("", "")
|
||||||
}
|
default:
|
||||||
|
log.Fatal("Invalid HTTP challenge options.")
|
||||||
// --webroot=foo indicates that the user specifically want to do a HTTP challenge
|
return nil
|
||||||
// infer that the user also wants to exclude all other challenges
|
|
||||||
client.Challenge.Exclude([]challenge.Type{challenge.DNS01, challenge.TLSALPN01})
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupMemcached(client *lego.Client, hosts []string) {
|
|
||||||
provider, err := memcached.NewMemcachedProvider(hosts)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = client.Challenge.SetHTTP01Provider(provider)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// --memcached-host=foo:11211 indicates that the user specifically want to do a HTTP challenge
|
|
||||||
// infer that the user also wants to exclude all other challenges
|
|
||||||
client.Challenge.Exclude([]challenge.Type{challenge.DNS01, challenge.TLSALPN01})
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupHTTP(client *lego.Client, iface string) {
|
|
||||||
if !strings.Contains(iface, ":") {
|
|
||||||
log.Fatalf("The --http switch only accepts interface:port or :port for its argument.")
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.Challenge.SetHTTP01Address(iface)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupTLS(client *lego.Client, iface string) {
|
func setupTLSProvider(ctx *cli.Context) challenge.Provider {
|
||||||
if !strings.Contains(iface, ":") {
|
switch {
|
||||||
log.Fatalf("The --tls switch only accepts interface:port or :port for its argument.")
|
case ctx.GlobalIsSet("tls.port"):
|
||||||
}
|
iface := ctx.GlobalString("tls.port")
|
||||||
|
if !strings.Contains(iface, ":") {
|
||||||
|
log.Fatalf("The --tls switch only accepts interface:port or :port for its argument.")
|
||||||
|
}
|
||||||
|
|
||||||
err := client.Challenge.SetTLSALPN01Address(iface)
|
host, port, err := net.SplitHostPort(iface)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tlsalpn01.NewProviderServer(host, port)
|
||||||
|
case ctx.GlobalBool("tls"):
|
||||||
|
return tlsalpn01.NewProviderServer("", "")
|
||||||
|
default:
|
||||||
|
log.Fatal("Invalid HTTP challenge options.")
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,11 +103,11 @@ func setupDNS(ctx *cli.Context, client *lego.Client) {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
servers := ctx.GlobalStringSlice("dns-resolvers")
|
servers := ctx.GlobalStringSlice("dns.resolvers")
|
||||||
err = client.Challenge.SetDNS01Provider(provider,
|
err = client.Challenge.SetDNS01Provider(provider,
|
||||||
dns01.CondOption(len(servers) > 0,
|
dns01.CondOption(len(servers) > 0,
|
||||||
dns01.AddRecursiveNameservers(dns01.ParseNameservers(ctx.GlobalStringSlice("dns-resolvers")))),
|
dns01.AddRecursiveNameservers(dns01.ParseNameservers(ctx.GlobalStringSlice("dns.resolvers")))),
|
||||||
dns01.CondOption(ctx.GlobalIsSet("dns-disable-cp"),
|
dns01.CondOption(ctx.GlobalIsSet("dns.disable-cp"),
|
||||||
dns01.DisableCompletePropagationRequirement()),
|
dns01.DisableCompletePropagationRequirement()),
|
||||||
dns01.CondOption(ctx.GlobalIsSet("dns-timeout"),
|
dns01.CondOption(ctx.GlobalIsSet("dns-timeout"),
|
||||||
dns01.AddDNSTimeout(time.Duration(ctx.GlobalInt("dns-timeout"))*time.Second)),
|
dns01.AddDNSTimeout(time.Duration(ctx.GlobalInt("dns-timeout"))*time.Second)),
|
||||||
|
|
|
@ -13,7 +13,8 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/xenolf/lego/certificate"
|
"github.com/xenolf/lego/certificate"
|
||||||
"github.com/xenolf/lego/challenge"
|
"github.com/xenolf/lego/challenge/http01"
|
||||||
|
"github.com/xenolf/lego/challenge/tlsalpn01"
|
||||||
"github.com/xenolf/lego/e2e/loader"
|
"github.com/xenolf/lego/e2e/loader"
|
||||||
"github.com/xenolf/lego/lego"
|
"github.com/xenolf/lego/lego"
|
||||||
"github.com/xenolf/lego/registration"
|
"github.com/xenolf/lego/registration"
|
||||||
|
@ -50,12 +51,10 @@ func TestChallengeHTTP_Run(t *testing.T) {
|
||||||
output, err := load.RunLego(
|
output, err := load.RunLego(
|
||||||
"-m", "hubert@hubert.com",
|
"-m", "hubert@hubert.com",
|
||||||
"--accept-tos",
|
"--accept-tos",
|
||||||
"-x", "dns-01",
|
|
||||||
"-x", "tls-alpn-01",
|
|
||||||
"-s", "https://localhost:14000/dir",
|
"-s", "https://localhost:14000/dir",
|
||||||
"-d", "acme.wtf",
|
"-d", "acme.wtf",
|
||||||
"--http", ":5002",
|
"--http",
|
||||||
"--tls", ":5001",
|
"--http.port", ":5002",
|
||||||
"run")
|
"run")
|
||||||
|
|
||||||
if len(output) > 0 {
|
if len(output) > 0 {
|
||||||
|
@ -72,12 +71,10 @@ func TestChallengeTLS_Run_Domains(t *testing.T) {
|
||||||
output, err := load.RunLego(
|
output, err := load.RunLego(
|
||||||
"-m", "hubert@hubert.com",
|
"-m", "hubert@hubert.com",
|
||||||
"--accept-tos",
|
"--accept-tos",
|
||||||
"-x", "dns-01",
|
|
||||||
"-x", "http-01",
|
|
||||||
"-s", "https://localhost:14000/dir",
|
"-s", "https://localhost:14000/dir",
|
||||||
"-d", "acme.wtf",
|
"-d", "acme.wtf",
|
||||||
"--http", ":5002",
|
"--tls",
|
||||||
"--tls", ":5001",
|
"--tls.port", ":5001",
|
||||||
"run")
|
"run")
|
||||||
|
|
||||||
if len(output) > 0 {
|
if len(output) > 0 {
|
||||||
|
@ -94,12 +91,10 @@ func TestChallengeTLS_Run_CSR(t *testing.T) {
|
||||||
output, err := load.RunLego(
|
output, err := load.RunLego(
|
||||||
"-m", "hubert@hubert.com",
|
"-m", "hubert@hubert.com",
|
||||||
"--accept-tos",
|
"--accept-tos",
|
||||||
"-x", "dns-01",
|
|
||||||
"-x", "http-01",
|
|
||||||
"-s", "https://localhost:14000/dir",
|
"-s", "https://localhost:14000/dir",
|
||||||
"-csr", "./fixtures/csr.raw",
|
"-csr", "./fixtures/csr.raw",
|
||||||
"--http", ":5002",
|
"--tls",
|
||||||
"--tls", ":5001",
|
"--tls.port", ":5001",
|
||||||
"run")
|
"run")
|
||||||
|
|
||||||
if len(output) > 0 {
|
if len(output) > 0 {
|
||||||
|
@ -116,12 +111,10 @@ func TestChallengeTLS_Run_CSR_PEM(t *testing.T) {
|
||||||
output, err := load.RunLego(
|
output, err := load.RunLego(
|
||||||
"-m", "hubert@hubert.com",
|
"-m", "hubert@hubert.com",
|
||||||
"--accept-tos",
|
"--accept-tos",
|
||||||
"-x", "dns-01",
|
|
||||||
"-x", "http-01",
|
|
||||||
"-s", "https://localhost:14000/dir",
|
"-s", "https://localhost:14000/dir",
|
||||||
"-csr", "./fixtures/csr.cert",
|
"-csr", "./fixtures/csr.cert",
|
||||||
"--http", ":5002",
|
"--tls",
|
||||||
"--tls", ":5001",
|
"--tls.port", ":5001",
|
||||||
"run")
|
"run")
|
||||||
|
|
||||||
if len(output) > 0 {
|
if len(output) > 0 {
|
||||||
|
@ -138,13 +131,11 @@ func TestChallengeTLS_Run_Revoke(t *testing.T) {
|
||||||
output, err := load.RunLego(
|
output, err := load.RunLego(
|
||||||
"-m", "hubert@hubert.com",
|
"-m", "hubert@hubert.com",
|
||||||
"--accept-tos",
|
"--accept-tos",
|
||||||
"-x", "dns-01",
|
|
||||||
"-x", "http-01",
|
|
||||||
"-s", "https://localhost:14000/dir",
|
"-s", "https://localhost:14000/dir",
|
||||||
"-d", "lego.wtf",
|
"-d", "lego.wtf",
|
||||||
"-d", "acme.lego.wtf",
|
"-d", "acme.lego.wtf",
|
||||||
"--http", ":5002",
|
"--tls",
|
||||||
"--tls", ":5001",
|
"--tls.port", ":5001",
|
||||||
"run")
|
"run")
|
||||||
|
|
||||||
if len(output) > 0 {
|
if len(output) > 0 {
|
||||||
|
@ -157,12 +148,10 @@ func TestChallengeTLS_Run_Revoke(t *testing.T) {
|
||||||
output, err = load.RunLego(
|
output, err = load.RunLego(
|
||||||
"-m", "hubert@hubert.com",
|
"-m", "hubert@hubert.com",
|
||||||
"--accept-tos",
|
"--accept-tos",
|
||||||
"-x", "dns-01",
|
|
||||||
"-x", "http-01",
|
|
||||||
"-s", "https://localhost:14000/dir",
|
"-s", "https://localhost:14000/dir",
|
||||||
"-d", "lego.wtf",
|
"-d", "lego.wtf",
|
||||||
"--http", ":5002",
|
"--tls",
|
||||||
"--tls", ":5001",
|
"--tls.port", ":5001",
|
||||||
"revoke")
|
"revoke")
|
||||||
|
|
||||||
if len(output) > 0 {
|
if len(output) > 0 {
|
||||||
|
@ -179,12 +168,10 @@ func TestChallengeTLS_Run_Revoke_Non_ASCII(t *testing.T) {
|
||||||
output, err := load.RunLego(
|
output, err := load.RunLego(
|
||||||
"-m", "hubert@hubert.com",
|
"-m", "hubert@hubert.com",
|
||||||
"--accept-tos",
|
"--accept-tos",
|
||||||
"-x", "dns-01",
|
|
||||||
"-x", "http-01",
|
|
||||||
"-s", "https://localhost:14000/dir",
|
"-s", "https://localhost:14000/dir",
|
||||||
"-d", "légô.wtf",
|
"-d", "légô.wtf",
|
||||||
"--http", ":5002",
|
"--tls",
|
||||||
"--tls", ":5001",
|
"--tls.port", ":5001",
|
||||||
"run")
|
"run")
|
||||||
|
|
||||||
if len(output) > 0 {
|
if len(output) > 0 {
|
||||||
|
@ -197,12 +184,10 @@ func TestChallengeTLS_Run_Revoke_Non_ASCII(t *testing.T) {
|
||||||
output, err = load.RunLego(
|
output, err = load.RunLego(
|
||||||
"-m", "hubert@hubert.com",
|
"-m", "hubert@hubert.com",
|
||||||
"--accept-tos",
|
"--accept-tos",
|
||||||
"-x", "dns-01",
|
|
||||||
"-x", "http-01",
|
|
||||||
"-s", "https://localhost:14000/dir",
|
"-s", "https://localhost:14000/dir",
|
||||||
"-d", "légô.wtf",
|
"-d", "légô.wtf",
|
||||||
"--http", ":5002",
|
"--tls",
|
||||||
"--tls", ":5001",
|
"--tls.port", ":5001",
|
||||||
"revoke")
|
"revoke")
|
||||||
|
|
||||||
if len(output) > 0 {
|
if len(output) > 0 {
|
||||||
|
@ -228,8 +213,7 @@ func TestChallengeHTTP_Client_Obtain(t *testing.T) {
|
||||||
client, err := lego.NewClient(config)
|
client, err := lego.NewClient(config)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
client.Challenge.Exclude([]challenge.Type{challenge.DNS01, challenge.TLSALPN01})
|
err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", "5002"))
|
||||||
err = client.Challenge.SetHTTP01Address(":5002")
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||||
|
@ -267,8 +251,7 @@ func TestChallengeTLS_Client_Obtain(t *testing.T) {
|
||||||
client, err := lego.NewClient(config)
|
client, err := lego.NewClient(config)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
client.Challenge.Exclude([]challenge.Type{challenge.DNS01, challenge.HTTP01})
|
err = client.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", "5001"))
|
||||||
err = client.Challenge.SetTLSALPN01Address(":5001")
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||||
|
@ -307,8 +290,7 @@ func TestChallengeTLS_Client_ObtainForCSR(t *testing.T) {
|
||||||
client, err := lego.NewClient(config)
|
client, err := lego.NewClient(config)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
client.Challenge.Exclude([]challenge.Type{challenge.DNS01, challenge.HTTP01})
|
err = client.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", "5001"))
|
||||||
err = client.Challenge.SetTLSALPN01Address(":5001")
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/xenolf/lego/certificate"
|
"github.com/xenolf/lego/certificate"
|
||||||
"github.com/xenolf/lego/challenge"
|
|
||||||
"github.com/xenolf/lego/challenge/dns01"
|
"github.com/xenolf/lego/challenge/dns01"
|
||||||
"github.com/xenolf/lego/e2e/loader"
|
"github.com/xenolf/lego/e2e/loader"
|
||||||
"github.com/xenolf/lego/lego"
|
"github.com/xenolf/lego/lego"
|
||||||
|
@ -55,16 +54,12 @@ func TestChallengeDNS_Run(t *testing.T) {
|
||||||
output, err := load.RunLego(
|
output, err := load.RunLego(
|
||||||
"-m", "hubert@hubert.com",
|
"-m", "hubert@hubert.com",
|
||||||
"--accept-tos",
|
"--accept-tos",
|
||||||
"-x", "http-01",
|
|
||||||
"-x", "tls-alpn-01",
|
|
||||||
"--dns-disable-cp",
|
|
||||||
"--dns-resolvers", ":8053",
|
|
||||||
"--dns", "exec",
|
"--dns", "exec",
|
||||||
|
"--dns.resolvers", ":8053",
|
||||||
|
"--dns.disable-cp",
|
||||||
"-s", "https://localhost:15000/dir",
|
"-s", "https://localhost:15000/dir",
|
||||||
"-d", "*.légo.acme",
|
"-d", "*.légo.acme",
|
||||||
"-d", "légo.acme",
|
"-d", "légo.acme",
|
||||||
"--http", ":5004",
|
|
||||||
"--tls", ":5003",
|
|
||||||
"run")
|
"run")
|
||||||
|
|
||||||
if len(output) > 0 {
|
if len(output) > 0 {
|
||||||
|
@ -100,7 +95,6 @@ func TestChallengeDNS_Client_Obtain(t *testing.T) {
|
||||||
err = client.Challenge.SetDNS01Provider(provider,
|
err = client.Challenge.SetDNS01Provider(provider,
|
||||||
dns01.AddRecursiveNameservers([]string{":8053"}),
|
dns01.AddRecursiveNameservers([]string{":8053"}),
|
||||||
dns01.DisableCompletePropagationRequirement())
|
dns01.DisableCompletePropagationRequirement())
|
||||||
client.Challenge.Exclude([]challenge.Type{challenge.HTTP01, challenge.TLSALPN01})
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||||
|
|
Loading…
Reference in a new issue