@marcel91200 / caddy Mirror · read-only / commits / 7a4548c5
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 14, 05:15 UTC

Some hotfixes for beta 16

Matthew Holt committed Mar 13, 2020 at 19:14 UTC 7a4548c5823e85bab0a2e2f40a3ea00f64ce8552
8 files changed +68 -65
caddyconfig/httpcaddyfile/httptype.go
+6 -14
@@ -84,12 +84,11 @@ func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,
84 "{method}", "{http.request.method}",
85 "{path}", "{http.request.uri.path}",
86 "{query}", "{http.request.uri.query}",
87 + "{remote}", "{http.request.remote}",
88 "{remote_host}", "{http.request.remote.host}",
89 "{remote_port}", "{http.request.remote.port}",
89 - "{remote}", "{http.request.remote}",
90 "{scheme}", "{http.request.scheme}",
91 "{uri}", "{http.request.uri}",
92 -
92 "{tls_cipher}", "{http.request.tls.cipher_suite}",
93 "{tls_version}", "{http.request.tls.version}",
94 "{tls_client_fingerprint}", "{http.request.tls.client.fingerprint}",
@@ -173,10 +172,9 @@ func (st ServerType) Setup(originalServerBlocks []caddyfile.ServerBlock,
172
173 // now that each server is configured, make the HTTP app
174 httpApp := caddyhttp.App{
176 - HTTPPort: tryInt(options["http_port"], &warnings),
177 - HTTPSPort: tryInt(options["https_port"], &warnings),
178 - DefaultSNI: tryString(options["default_sni"], &warnings),
179 - Servers: servers,
175 + HTTPPort: tryInt(options["http_port"], &warnings),
176 + HTTPSPort: tryInt(options["https_port"], &warnings),
177 + Servers: servers,
178 }
179
180 // now for the TLS app! (TODO: refactor into own func)
@@ -449,7 +447,6 @@ func (st *ServerType) serversFromPairings(
447 groupCounter counter,
448 ) (map[string]*caddyhttp.Server, error) {
449 servers := make(map[string]*caddyhttp.Server)
452 -
450 defaultSNI := tryString(options["default_sni"], warnings)
451
452 for i, p := range pairings {
@@ -538,12 +535,7 @@ func (st *ServerType) serversFromPairings(
535
536 srv.TLSConnPolicies = append(srv.TLSConnPolicies, cp)
537 }
541 - // TODO: consolidate equal conn policies
542 - } else if defaultSNI != "" {
543 - hasCatchAllTLSConnPolicy = true
544 - srv.TLSConnPolicies = append(srv.TLSConnPolicies, &caddytls.ConnectionPolicy{
545 - DefaultSNI: defaultSNI,
546 - })
538 + // TODO: consolidate equal conn policies?
539 }
540
541 // exclude any hosts that were defined explicitly with
@@ -614,7 +606,7 @@ func (st *ServerType) serversFromPairings(
606 // catch-all/default policy if there isn't one already (it's
607 // important that it goes at the end) - see issue #3004:
608 // https://github.com/caddyserver/caddy/issues/3004
617 - if len(srv.TLSConnPolicies) > 0 && !hasCatchAllTLSConnPolicy {
609 + if !hasCatchAllTLSConnPolicy && (len(srv.TLSConnPolicies) > 0 || defaultSNI != "") {
610 srv.TLSConnPolicies = append(srv.TLSConnPolicies, &caddytls.ConnectionPolicy{DefaultSNI: defaultSNI})
611 }
612
go.mod
+1 -1
@@ -6,7 +6,7 @@ require (
6 github.com/Masterminds/sprig/v3 v3.0.2
7 github.com/alecthomas/chroma v0.7.2-0.20200305040604-4f3623dce67a
8 github.com/andybalholm/brotli v1.0.0
9 - github.com/caddyserver/certmagic v0.10.1
9 + github.com/caddyserver/certmagic v0.10.2
10 github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac
11 github.com/go-acme/lego/v3 v3.4.0
12 github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e
go.sum
+2 -2
@@ -108,8 +108,8 @@ github.com/bombsimon/wsl/v2 v2.0.0/go.mod h1:mf25kr/SqFEPhhcxW1+7pxzGlW+hIl/hYTK
108 github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
109 github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
110 github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
111 -github.com/caddyserver/certmagic v0.10.1 h1:k9E+C4b8WM3sTs3PSfmWIAwxtO9cXtr0bDHX2Bc0RIM=
112 -github.com/caddyserver/certmagic v0.10.1/go.mod h1:Y8jcUBctgk/IhpAzlHKfimZNyXCkfGgRTC0orl8gROQ=
111 +github.com/caddyserver/certmagic v0.10.2 h1:uz+QTSZULEN9iW2woZYf01ipR2O88iLx/bkIAoEXYbo=
112 +github.com/caddyserver/certmagic v0.10.2/go.mod h1:Y8jcUBctgk/IhpAzlHKfimZNyXCkfGgRTC0orl8gROQ=
113 github.com/cenkalti/backoff/v4 v4.0.0 h1:6VeaLF9aI+MAUQ95106HwWzYZgJJpZ4stumjj6RFYAU=
114 github.com/cenkalti/backoff/v4 v4.0.0/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg=
115 github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
modules/caddyhttp/autohttps.go
+38 -21
@@ -101,10 +101,6 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er
101 continue
102 }
103
104 - defaultConnPolicies := caddytls.ConnectionPolicies{
105 - &caddytls.ConnectionPolicy{ALPN: defaultALPN},
106 - }
107 -
104 // if all listeners are on the HTTPS port, make sure
105 // there is at least one TLS connection policy; it
106 // should be obvious that they want to use TLS without
@@ -115,7 +111,7 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er
111 zap.String("server_name", srvName),
112 zap.Int("https_port", app.httpsPort()),
113 )
118 - srv.TLSConnPolicies = defaultConnPolicies
114 + srv.TLSConnPolicies = caddytls.ConnectionPolicies{new(caddytls.ConnectionPolicy)}
115 }
116
117 // find all qualifying domain names (deduplicated) in this server
@@ -149,7 +145,8 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er
145 // for all the hostnames we found, filter them so we have
146 // a deduplicated list of names for which to obtain certs
147 for d := range serverDomainSet {
152 - if !srv.AutoHTTPS.Skipped(d, srv.AutoHTTPS.SkipCerts) {
148 + if certmagic.SubjectQualifiesForCert(d) &&
149 + !srv.AutoHTTPS.Skipped(d, srv.AutoHTTPS.SkipCerts) {
150 // if a certificate for this name is already loaded,
151 // don't obtain another one for it, unless we are
152 // supposed to ignore loaded certificates
@@ -176,7 +173,7 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er
173
174 // tell the server to use TLS if it is not already doing so
175 if srv.TLSConnPolicies == nil {
179 - srv.TLSConnPolicies = defaultConnPolicies
176 + srv.TLSConnPolicies = caddytls.ConnectionPolicies{new(caddytls.ConnectionPolicy)}
177 }
178
179 // nothing left to do if auto redirects are disabled
@@ -212,13 +209,33 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er
209 // turn the set into a slice so that phase 2 can use it
210 app.allCertDomains = make([]string, 0, len(uniqueDomainsForCerts))
211 var internal, external []string
212 +uniqueDomainsLoop:
213 for d := range uniqueDomainsForCerts {
214 + // whether or not there is already an automation policy for this
215 + // name, we should add it to the list to manage a cert for it
216 + app.allCertDomains = append(app.allCertDomains, d)
217 +
218 + // some names we've found might already have automation policies
219 + // explicitly specified for them; we should exclude those from
220 + // our hidden/implicit policy, since applying a name to more than
221 + // one automation policy would be confusing and an error
222 + if app.tlsApp.Automation != nil {
223 + for _, ap := range app.tlsApp.Automation.Policies {
224 + for _, apHost := range ap.Hosts {
225 + if apHost == d {
226 + continue uniqueDomainsLoop
227 + }
228 + }
229 + }
230 + }
231 +
232 + // if no automation policy exists for the name yet, we
233 + // will associate it with an implicit one
234 if certmagic.SubjectQualifiesForPublicCert(d) {
235 external = append(external, d)
236 } else {
237 internal = append(internal, d)
238 }
221 - app.allCertDomains = append(app.allCertDomains, d)
239 }
240
241 // ensure there is an automation policy to handle these certs
@@ -263,7 +280,7 @@ func (app *App) automaticHTTPSPhase1(ctx caddy.Context, repl *caddy.Replacer) er
280 return err
281 }
282 redirTo := "https://{http.request.host}"
266 - if addr.StartPort != DefaultHTTPSPort {
283 + if addr.StartPort != uint(app.httpsPort()) {
284 redirTo += ":" + strconv.Itoa(int(addr.StartPort))
285 }
286 redirTo += "{http.request.uri}"
@@ -384,23 +401,23 @@ func (app *App) createAutomationPolicies(ctx caddy.Context, publicNames, interna
401 // start by finding a base policy that the user may have defined
402 // which should, in theory, apply to any policies derived from it;
403 // typically this would be a "catch-all" policy with no host filter
387 - var matchingPolicy *caddytls.AutomationPolicy
404 + var basePolicy *caddytls.AutomationPolicy
405 if app.tlsApp.Automation != nil {
389 - // if an existing policy matches (specifically, a catch-all policy),
390 - // we should inherit from it, because that is what the user expects;
391 - // this is very common for user setting a default issuer, with a
392 - // custom CA endpoint, for example - whichever one we choose must
393 - // have a host list that is a superset of the policy we make...
394 - // the policy with no host filter is guaranteed to qualify
406 for _, ap := range app.tlsApp.Automation.Policies {
407 + // if an existing policy matches (specifically, a catch-all policy),
408 + // we should inherit from it, because that is what the user expects;
409 + // this is very common for user setting a default issuer, with a
410 + // custom CA endpoint, for example - whichever one we choose must
411 + // have a host list that is a superset of the policy we make...
412 + // the policy with no host filter is guaranteed to qualify
413 if len(ap.Hosts) == 0 {
397 - matchingPolicy = ap
414 + basePolicy = ap
415 break
416 }
417 }
418 }
402 - if matchingPolicy == nil {
403 - matchingPolicy = new(caddytls.AutomationPolicy)
419 + if basePolicy == nil {
420 + basePolicy = new(caddytls.AutomationPolicy)
421 }
422
423 // addPolicy adds an automation policy that uses issuer for hosts.
@@ -408,7 +425,7 @@ func (app *App) createAutomationPolicies(ctx caddy.Context, publicNames, interna
425 // shallow-copy the matching policy; we want to inherit
426 // from it, not replace it... this takes two lines to
427 // overrule compiler optimizations
411 - policyCopy := *matchingPolicy
428 + policyCopy := *basePolicy
429 newPolicy := &policyCopy
430
431 // very important to provision it, since we are
@@ -429,7 +446,7 @@ func (app *App) createAutomationPolicies(ctx caddy.Context, publicNames, interna
446 var acmeIssuer *caddytls.ACMEIssuer
447 // if it has an ACME issuer, maybe we can just use that
448 // TODO: we might need a deep copy here, like a Clone() method on ACMEIssuer...
432 - acmeIssuer, _ = matchingPolicy.Issuer.(*caddytls.ACMEIssuer)
449 + acmeIssuer, _ = basePolicy.Issuer.(*caddytls.ACMEIssuer)
450 if acmeIssuer == nil {
451 acmeIssuer = new(caddytls.ACMEIssuer)
452 }
modules/caddyhttp/caddyhttp.go
-16
@@ -29,7 +29,6 @@ import (
29
30 "github.com/caddyserver/caddy/v2"
31 "github.com/caddyserver/caddy/v2/modules/caddytls"
32 - "github.com/caddyserver/certmagic"
32 "github.com/lucas-clemente/quic-go/http3"
33 "go.uber.org/zap"
34 )
@@ -113,10 +112,6 @@ type App struct {
112 // affect functionality.
113 Servers map[string]*Server `json:"servers,omitempty"`
114
116 - // DefaultSNI if set configures all certificate lookups to fallback to use
117 - // this SNI name if a more specific certificate could not be found
118 - DefaultSNI string `json:"default_sni,omitempty"`
119 -
115 servers []*http.Server
116 h3servers []*http3.Server
117 h3listeners []net.PacketConn
@@ -150,8 +145,6 @@ func (app *App) Provision(ctx caddy.Context) error {
145
146 repl := caddy.NewReplacer()
147
153 - certmagic.Default.DefaultServerName = app.DefaultSNI
154 -
148 // this provisions the matchers for each route,
149 // and prepares auto HTTP->HTTPS redirects, and
150 // is required before we provision each server
@@ -278,13 +271,6 @@ func (app *App) Start() error {
271 return fmt.Errorf("%s: listening on %s: %v", listenAddr.Network, hostport, err)
272 }
273
281 - // enable HTTP/2 by default
282 - for _, pol := range srv.TLSConnPolicies {
283 - if len(pol.ALPN) == 0 {
284 - pol.ALPN = append(pol.ALPN, defaultALPN...)
285 - }
286 - }
287 -
274 // enable TLS if there is a policy and if this is not the HTTP port
275 useTLS := len(srv.TLSConnPolicies) > 0 && int(listenAddr.StartPort+portOffset) != app.httpPort()
276 if useTLS {
@@ -397,8 +383,6 @@ func (app *App) httpsPort() int {
383 return app.HTTPSPort
384 }
385
400 -var defaultALPN = []string{"h2", "http/1.1"}
401 -
386 // RequestMatcher is a type that can match to a request.
387 // A route matcher MUST NOT modify the request, with the
388 // only exception being its context.
modules/caddytls/acmeissuer.go
+5 -1
@@ -144,6 +144,10 @@ func (m *ACMEIssuer) SetConfig(cfg *certmagic.Config) {
144 m.magic = cfg
145 }
146
147 +// TODO: I kind of hate how each call to these methods needs to
148 +// make a new ACME manager to fill in defaults before using; can
149 +// we find the right place to do that just once and then re-use?
150 +
151 // PreCheck implements the certmagic.PreChecker interface.
152 func (m *ACMEIssuer) PreCheck(names []string, interactive bool) error {
153 return certmagic.NewACMEManager(m.magic, m.template).PreCheck(names, interactive)
@@ -156,7 +160,7 @@ func (m *ACMEIssuer) Issue(ctx context.Context, csr *x509.CertificateRequest) (*
160
161 // IssuerKey returns the unique issuer key for the configured CA endpoint.
162 func (m *ACMEIssuer) IssuerKey() string {
159 - return m.template.IssuerKey() // does not need storage and cache
163 + return certmagic.NewACMEManager(m.magic, m.template).IssuerKey()
164 }
165
166 // Revoke revokes the given certificate.
modules/caddytls/connpolicy.go
+7
@@ -55,6 +55,11 @@ func (cp ConnectionPolicies) Provision(ctx caddy.Context) error {
55 cp[i].certSelector = val.(certmagic.CertificateSelector)
56 }
57
58 + // enable HTTP/2 by default
59 + if len(pol.ALPN) == 0 {
60 + pol.ALPN = append(pol.ALPN, defaultALPN...)
61 + }
62 +
63 // pre-build standard TLS config so we don't have to at handshake-time
64 err = pol.buildStandardTLSConfig(ctx)
65 if err != nil {
@@ -452,3 +457,5 @@ func (a *PublicKeyAlgorithm) UnmarshalJSON(b []byte) error {
457 type ConnectionMatcher interface {
458 Match(*tls.ClientHelloInfo) bool
459 }
460 +
461 +var defaultALPN = []string{"h2", "http/1.1"}
modules/caddytls/tls.go
+9 -10
@@ -181,7 +181,6 @@ func (t *TLS) Validate() error {
181 // ensure that host aren't repeated; since only the first
182 // automation policy is used, repeating a host in the lists
183 // isn't useful and is probably a mistake
184 - // TODO: test this
184 hostSet := make(map[string]int)
185 for i, ap := range t.Automation.Policies {
186 for _, h := range ap.Hosts {
@@ -279,8 +278,8 @@ func (t *TLS) HandleHTTPChallenge(w http.ResponseWriter, r *http.Request) bool {
278 if ap.magic.Issuer == nil {
279 return false
280 }
282 - if am, ok := ap.magic.Issuer.(*certmagic.ACMEManager); ok {
283 - return am.HandleHTTPChallenge(w, r)
281 + if am, ok := ap.magic.Issuer.(*ACMEIssuer); ok {
282 + return certmagic.NewACMEManager(am.magic, am.template).HandleHTTPChallenge(w, r)
283 }
284 return false
285 }
@@ -709,7 +708,7 @@ const automateKey = "automate"
708 // (beta 16 changed the storage path for certificates),
709 // after which this function can be deleted
710 func (t *TLS) moveCertificates() error {
712 - log := t.logger.Named("automigrate")
711 + logger := t.logger.Named("automigrate")
712
713 baseDir := caddy.AppDataDir()
714
@@ -760,7 +759,7 @@ func (t *TLS) moveCertificates() error {
759 }
760
761 if len(oldAcmeSites) > 0 {
763 - log.Warn("certificate storage path has changed; attempting one-time auto-migration",
762 + logger.Warn("certificate storage path has changed; attempting one-time auto-migration",
763 zap.String("old_folder", oldAcmeSitesDir),
764 zap.String("new_folder", newBaseDir),
765 zap.String("details", "https://github.com/caddyserver/caddy/issues/2955"))
@@ -775,13 +774,13 @@ func (t *TLS) moveCertificates() error {
774 // move the folder
775 oldPath := filepath.Join(oldAcmeSitesDir, siteInfo.Name())
776 newPath := filepath.Join(newBaseDir, siteInfo.Name())
778 - log.Info("moving certificate assets",
777 + logger.Info("moving certificate assets",
778 zap.String("ca", oldCA),
779 zap.String("site", siteInfo.Name()),
780 zap.String("destination", newPath))
781 err = os.Rename(oldPath, newPath)
782 if err != nil {
784 - log.Error("failed moving site to new path; skipping",
783 + logger.Error("failed moving site to new path; skipping",
784 zap.String("old_path", oldPath),
785 zap.String("new_path", newPath),
786 zap.Error(err))
@@ -792,7 +791,7 @@ func (t *TLS) moveCertificates() error {
791 metaFilePath := filepath.Join(newPath, siteInfo.Name()+".json")
792 metaContents, err := ioutil.ReadFile(metaFilePath)
793 if err != nil {
795 - log.Error("could not read metadata file",
794 + logger.Error("could not read metadata file",
795 zap.String("filename", metaFilePath),
796 zap.Error(err))
797 continue
@@ -806,12 +805,12 @@ func (t *TLS) moveCertificates() error {
805 }
806 newMeta, err := json.MarshalIndent(cr, "", "\t")
807 if err != nil {
809 - log.Error("encoding new metadata file", zap.Error(err))
808 + logger.Error("encoding new metadata file", zap.Error(err))
809 continue
810 }
811 err = ioutil.WriteFile(metaFilePath, newMeta, 0600)
812 if err != nil {
814 - log.Error("writing new metadata file", zap.Error(err))
813 + logger.Error("writing new metadata file", zap.Error(err))
814 continue
815 }
816 }