From 6bc3e7536e915c0f7dd0c22be36201760e9d816d Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Wed, 8 Mar 2017 00:06:49 -0700 Subject: [PATCH] tls: Command line flags to disable HTTP and TLS-SNI challenges This could have just as easily been a tls directive property in the Caddyfile, but I figure if these challenges are being disabled, it's because of port availability or process privileges, both of which would affect all sites served by this process. The names of the flag are long but descriptive. I've never needed this but I hear of quite a few people who say they need this ability, so here it is. --- caddy/caddymain/run.go | 2 ++ caddytls/client.go | 12 ++++++++++++ caddytls/httphandler.go | 3 +++ caddytls/tls.go | 6 ++++++ 4 files changed, 23 insertions(+) diff --git a/caddy/caddymain/run.go b/caddy/caddymain/run.go index 23d938703..fd193d5f7 100644 --- a/caddy/caddymain/run.go +++ b/caddy/caddymain/run.go @@ -29,6 +29,8 @@ func init() { flag.BoolVar(&caddytls.Agreed, "agree", false, "Agree to the CA's Subscriber Agreement") flag.StringVar(&caddytls.DefaultCAUrl, "ca", "https://acme-v01.api.letsencrypt.org/directory", "URL to certificate authority's ACME server directory") + flag.BoolVar(&caddytls.DisableHTTPChallenge, "disable-http-challenge", caddytls.DisableHTTPChallenge, "Disable the ACME HTTP challenge") + flag.BoolVar(&caddytls.DisableTLSSNIChallenge, "disable-tls-sni-challenge", caddytls.DisableTLSSNIChallenge, "Disable the ACME TLS-SNI challenge") flag.StringVar(&conf, "conf", "", "Caddyfile to load (default \""+caddy.DefaultConfigFile+"\")") flag.StringVar(&cpu, "cpu", "100%", "CPU cap") flag.BoolVar(&plugins, "plugins", false, "List installed plugins") diff --git a/caddytls/client.go b/caddytls/client.go index d1c3295e5..394c36882 100644 --- a/caddytls/client.go +++ b/caddytls/client.go @@ -143,6 +143,18 @@ var newACMEClient = func(config *Config, allowPrompts bool) (*ACMEClient, error) if caddy.HasListenerWithAddress(net.JoinHostPort(config.ListenHost, useTLSSNIPort)) { c.acmeClient.SetChallengeProvider(acme.TLSSNI01, tlsSniSolver{}) } + + // Disable any challenges that should not be used + var disabledChallenges []acme.Challenge + if DisableHTTPChallenge { + disabledChallenges = append(disabledChallenges, acme.HTTP01) + } + if DisableTLSSNIChallenge { + disabledChallenges = append(disabledChallenges, acme.TLSSNI01) + } + if len(disabledChallenges) > 0 { + c.acmeClient.ExcludeChallenges(disabledChallenges) + } } else { // Otherwise, use DNS challenge exclusively diff --git a/caddytls/httphandler.go b/caddytls/httphandler.go index 0ea40c67d..db3c93a01 100644 --- a/caddytls/httphandler.go +++ b/caddytls/httphandler.go @@ -20,6 +20,9 @@ func HTTPChallengeHandler(w http.ResponseWriter, r *http.Request, listenHost, al if !strings.HasPrefix(r.URL.Path, challengeBasePath) { return false } + if DisableHTTPChallenge { + return false + } if !namesObtaining.Has(r.Host) { return false } diff --git a/caddytls/tls.go b/caddytls/tls.go index 50c9814a7..f7a084357 100644 --- a/caddytls/tls.go +++ b/caddytls/tls.go @@ -167,6 +167,12 @@ var ( // DefaultKeyType is used as the type of key for new certificates // when no other key type is specified. DefaultKeyType = acme.RSA2048 + + // DisableHTTPChallenge will disable all HTTP challenges. + DisableHTTPChallenge bool + + // DisableTLSSNIChallenge will disable all TLS-SNI challenges. + DisableTLSSNIChallenge bool ) var storageProviders = make(map[string]StorageConstructor)