caddy/caddytls/setup_test.go

452 lines
14 KiB
Go
Raw Normal View History

// Copyright 2015 Light Code Labs, LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
package caddytls
import (
"crypto/tls"
"io/ioutil"
"log"
"os"
"testing"
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
"github.com/mholt/caddy"
2016-04-01 17:30:38 +08:00
"github.com/xenolf/lego/acme"
)
func TestMain(m *testing.M) {
// Write test certificates to disk before tests, and clean up
// when we're done.
err := ioutil.WriteFile(certFile, testCert, 0644)
if err != nil {
log.Fatal(err)
}
err = ioutil.WriteFile(keyFile, testKey, 0644)
if err != nil {
os.Remove(certFile)
log.Fatal(err)
}
result := m.Run()
os.Remove(certFile)
os.Remove(keyFile)
os.Exit(result)
}
func TestSetupParseBasic(t *testing.T) {
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
certCache := &certificateCache{cache: make(map[string]Certificate)}
cfg := &Config{Certificates: make(map[string]string), certCache: certCache}
RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController("", `tls `+certFile+` `+keyFile+``)
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
c.Set(CertCacheInstStorageKey, certCache)
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
err := setupTLS(c)
if err != nil {
t.Errorf("Expected no errors, got: %v", err)
}
// Basic checks
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
if !cfg.Manual {
t.Error("Expected TLS Manual=true, but was false")
}
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
if !cfg.Enabled {
t.Error("Expected TLS Enabled=true, but was false")
}
// Security defaults
if cfg.ProtocolMinVersion != tls.VersionTLS12 {
t.Errorf("Expected 'tls1.2 (0x0303)' as ProtocolMinVersion, got %#v", cfg.ProtocolMinVersion)
}
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
if cfg.ProtocolMaxVersion != tls.VersionTLS12 {
t.Errorf("Expected 'tls1.2 (0x0303)' as ProtocolMaxVersion, got %v", cfg.ProtocolMaxVersion)
2016-04-05 07:59:40 +08:00
}
// Cipher checks
expectedCiphers := append([]uint16{tls.TLS_FALLBACK_SCSV}, getPreferredDefaultCiphers()...)
// Ensure count is correct (plus one for TLS_FALLBACK_SCSV)
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
if len(cfg.Ciphers) != len(expectedCiphers) {
t.Errorf("Expected %v Ciphers (including TLS_FALLBACK_SCSV), got %v",
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
len(expectedCiphers), len(cfg.Ciphers))
}
// Ensure ordering is correct
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
for i, actual := range cfg.Ciphers {
if actual != expectedCiphers[i] {
t.Errorf("Expected cipher in position %d to be %0x, got %0x", i, expectedCiphers[i], actual)
}
}
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
if !cfg.PreferServerCipherSuites {
t.Error("Expected PreferServerCipherSuites = true, but was false")
}
if len(cfg.ALPN) != 0 {
t.Error("Expected ALPN empty by default")
}
// Ensure curve count is correct
if len(cfg.CurvePreferences) != len(defaultCurves) {
t.Errorf("Expected %v Curves, got %v", len(defaultCurves), len(cfg.CurvePreferences))
}
// Ensure curve ordering is correct
for i, actual := range cfg.CurvePreferences {
if actual != defaultCurves[i] {
t.Errorf("Expected curve in position %d to be %0x, got %0x", i, defaultCurves[i], actual)
}
}
}
func TestSetupParseIncompleteParams(t *testing.T) {
2016-01-12 23:55:01 +08:00
// Using tls without args is an error because it's unnecessary.
c := caddy.NewTestController("", `tls`)
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
err := setupTLS(c)
2016-01-12 23:55:01 +08:00
if err == nil {
t.Error("Expected an error, but didn't get one")
}
}
func TestSetupParseWithOptionalParams(t *testing.T) {
params := `tls ` + certFile + ` ` + keyFile + ` {
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
protocols tls1.0 tls1.2
2016-02-23 08:43:40 +08:00
ciphers RSA-AES256-CBC-SHA ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384
must_staple
alpn http/1.1
}`
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
certCache := &certificateCache{cache: make(map[string]Certificate)}
cfg := &Config{Certificates: make(map[string]string), certCache: certCache}
RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController("", params)
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
c.Set(CertCacheInstStorageKey, certCache)
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
err := setupTLS(c)
if err != nil {
t.Errorf("Expected no errors, got: %v", err)
}
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
if cfg.ProtocolMinVersion != tls.VersionTLS10 {
t.Errorf("Expected 'tls1.0 (0x0301)' as ProtocolMinVersion, got %#v", cfg.ProtocolMinVersion)
}
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
if cfg.ProtocolMaxVersion != tls.VersionTLS12 {
t.Errorf("Expected 'tls1.2 (0x0303)' as ProtocolMaxVersion, got %#v", cfg.ProtocolMaxVersion)
}
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
if len(cfg.Ciphers)-1 != 3 {
t.Errorf("Expected 3 Ciphers (not including TLS_FALLBACK_SCSV), got %v", len(cfg.Ciphers)-1)
}
if !cfg.MustStaple {
t.Error("Expected must staple to be true")
}
if len(cfg.ALPN) != 1 || cfg.ALPN[0] != "http/1.1" {
t.Errorf("Expected ALPN to contain only 'http/1.1' but got: %v", cfg.ALPN)
}
}
func TestSetupDefaultWithOptionalParams(t *testing.T) {
params := `tls {
ciphers RSA-3DES-EDE-CBC-SHA
}`
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
certCache := &certificateCache{cache: make(map[string]Certificate)}
cfg := &Config{Certificates: make(map[string]string), certCache: certCache}
RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController("", params)
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
c.Set(CertCacheInstStorageKey, certCache)
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
err := setupTLS(c)
if err != nil {
t.Errorf("Expected no errors, got: %v", err)
}
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
if len(cfg.Ciphers)-1 != 1 {
t.Errorf("Expected 1 ciphers (not including TLS_FALLBACK_SCSV), got %v", len(cfg.Ciphers)-1)
}
}
func TestSetupParseWithWrongOptionalParams(t *testing.T) {
// Test protocols wrong params
params := `tls ` + certFile + ` ` + keyFile + ` {
protocols ssl tls
}`
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
certCache := &certificateCache{cache: make(map[string]Certificate)}
cfg := &Config{Certificates: make(map[string]string), certCache: certCache}
RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController("", params)
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
c.Set(CertCacheInstStorageKey, certCache)
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
err := setupTLS(c)
if err == nil {
t.Errorf("Expected errors, but no error returned")
}
// Test ciphers wrong params
params = `tls ` + certFile + ` ` + keyFile + ` {
ciphers not-valid-cipher
}`
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
cfg = new(Config)
RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c = caddy.NewTestController("", params)
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
c.Set(CertCacheInstStorageKey, certCache)
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
err = setupTLS(c)
if err == nil {
t.Error("Expected errors, but no error returned")
}
2016-04-01 17:30:38 +08:00
// Test key_type wrong params
params = `tls {
key_type ab123
}`
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
cfg = new(Config)
RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c = caddy.NewTestController("", params)
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
err = setupTLS(c)
2016-04-01 17:30:38 +08:00
if err == nil {
t.Error("Expected errors, but no error returned")
2016-04-01 17:30:38 +08:00
}
// Test curves wrong params
params = `tls {
curves ab123, cd456, ef789
}`
cfg = new(Config)
RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c = caddy.NewTestController("", params)
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
c.Set(CertCacheInstStorageKey, certCache)
err = setupTLS(c)
if err == nil {
t.Error("Expected errors, but no error returned")
}
}
2015-06-02 13:22:11 +08:00
func TestSetupParseWithClientAuth(t *testing.T) {
// Test missing client cert file
params := `tls ` + certFile + ` ` + keyFile + ` {
clients
2015-06-02 13:22:11 +08:00
}`
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
certCache := &certificateCache{cache: make(map[string]Certificate)}
cfg := &Config{Certificates: make(map[string]string), certCache: certCache}
RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController("", params)
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
err := setupTLS(c)
if err == nil {
t.Error("Expected an error, but no error returned")
2015-06-02 13:22:11 +08:00
}
noCAs, twoCAs := []string{}, []string{"client_ca.crt", "client2_ca.crt"}
for caseNumber, caseData := range []struct {
params string
clientAuthType tls.ClientAuthType
expectedErr bool
expectedCAs []string
}{
{"", tls.NoClientCert, false, noCAs},
{`tls ` + certFile + ` ` + keyFile + ` {
clients client_ca.crt client2_ca.crt
}`, tls.RequireAndVerifyClientCert, false, twoCAs},
// now come modifier
{`tls ` + certFile + ` ` + keyFile + ` {
clients request
}`, tls.RequestClientCert, false, noCAs},
{`tls ` + certFile + ` ` + keyFile + ` {
clients require
}`, tls.RequireAnyClientCert, false, noCAs},
{`tls ` + certFile + ` ` + keyFile + ` {
clients verify_if_given client_ca.crt client2_ca.crt
}`, tls.VerifyClientCertIfGiven, false, twoCAs},
{`tls ` + certFile + ` ` + keyFile + ` {
clients verify_if_given
}`, tls.VerifyClientCertIfGiven, true, noCAs},
} {
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
certCache := &certificateCache{cache: make(map[string]Certificate)}
cfg := &Config{Certificates: make(map[string]string), certCache: certCache}
RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController("", caseData.params)
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
c.Set(CertCacheInstStorageKey, certCache)
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
err := setupTLS(c)
if caseData.expectedErr {
if err == nil {
t.Errorf("In case %d: Expected an error, got: %v", caseNumber, err)
}
continue
}
if err != nil {
t.Errorf("In case %d: Expected no errors, got: %v", caseNumber, err)
}
2015-06-02 13:22:11 +08:00
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
if caseData.clientAuthType != cfg.ClientAuth {
t.Errorf("In case %d: Expected TLS client auth type %v, got: %v",
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
caseNumber, caseData.clientAuthType, cfg.ClientAuth)
}
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
if count := len(cfg.ClientCerts); count < len(caseData.expectedCAs) {
t.Fatalf("In case %d: Expected %d client certs, had %d", caseNumber, len(caseData.expectedCAs), count)
}
for idx, expected := range caseData.expectedCAs {
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
if actual := cfg.ClientCerts[idx]; actual != expected {
t.Errorf("In case %d: Expected %dth client cert file to be '%s', but was '%s'",
caseNumber, idx, expected, actual)
}
}
2015-06-02 13:22:11 +08:00
}
}
func TestSetupParseWithCAUrl(t *testing.T) {
testURL := "https://acme-staging.api.letsencrypt.org/directory"
for caseNumber, caseData := range []struct {
params string
expectedErr bool
expectedCAUrl string
}{
// Test working case
{`tls {
ca ` + testURL + `
}`, false, testURL},
// Test too few args
{`tls {
ca
}`, true, ""},
// Test too many args
{`tls {
ca 1 2
}`, true, ""},
} {
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
certCache := &certificateCache{cache: make(map[string]Certificate)}
cfg := &Config{Certificates: make(map[string]string), certCache: certCache}
RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController("", caseData.params)
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
c.Set(CertCacheInstStorageKey, certCache)
err := setupTLS(c)
if caseData.expectedErr {
if err == nil {
t.Errorf("In case %d: Expected an error, got: %v", caseNumber, err)
}
continue
}
if err != nil {
t.Errorf("In case %d: Expected no errors, got: %v", caseNumber, err)
}
if cfg.CAUrl != caseData.expectedCAUrl {
t.Errorf("Expected '%v' as CAUrl, got %#v", caseData.expectedCAUrl, cfg.CAUrl)
}
}
}
2016-04-01 17:30:38 +08:00
func TestSetupParseWithKeyType(t *testing.T) {
params := `tls {
2016-04-05 21:37:39 +08:00
key_type p384
2016-04-01 17:30:38 +08:00
}`
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
certCache := &certificateCache{cache: make(map[string]Certificate)}
cfg := &Config{Certificates: make(map[string]string), certCache: certCache}
RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController("", params)
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
c.Set(CertCacheInstStorageKey, certCache)
2016-04-01 17:30:38 +08:00
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
err := setupTLS(c)
2016-04-01 17:30:38 +08:00
if err != nil {
t.Errorf("Expected no errors, got: %v", err)
}
Rewrote Caddy from the ground up; initial commit of 0.9 branch These changes span work from the last ~4 months in an effort to make Caddy more extensible, reduce the coupling between its components, and lay a more robust foundation of code going forward into 1.0. A bunch of new features have been added, too, with even higher future potential. The most significant design change is an overall inversion of dependencies. Instead of the caddy package knowing about the server and the notion of middleware and config, the caddy package exposes an interface that other components plug into. This does introduce more indirection when reading the code, but every piece is very modular and pluggable. Even the HTTP server is pluggable. The caddy package has been moved to the top level, and main has been pushed into a subfolder called caddy. The actual logic of the main file has been pushed even further into caddy/caddymain/run.go so that custom builds of Caddy can be 'go get'able. The HTTPS logic was surgically separated into two parts to divide the TLS-specific code and the HTTPS-specific code. The caddytls package can now be used by any type of server that needs TLS, not just HTTP. I also added the ability to customize nearly every aspect of TLS at the site level rather than all sites sharing the same TLS configuration. Not all of this flexibility is exposed in the Caddyfile yet, but it may be in the future. Caddy can also generate self-signed certificates in memory for the convenience of a developer working on localhost who wants HTTPS. And Caddy now supports the DNS challenge, assuming at least one DNS provider is plugged in. Dozens, if not hundreds, of other minor changes swept through the code base as I literally started from an empty main function, copying over functions or files as needed, then adjusting them to fit in the new design. Most tests have been restored and adapted to the new API, but more work is needed there. A lot of what was "impossible" before is now possible, or can be made possible with minimal disruption of the code. For example, it's fairly easy to make plugins hook into another part of the code via callbacks. Plugins can do more than just be directives; we now have plugins that customize how the Caddyfile is loaded (useful when you need to get your configuration from a remote store). Site addresses no longer need be just a host and port. They can have a path, allowing you to scope a configuration to a specific path. There is no inheretance, however; each site configuration is distinct. Thanks to amazing work by Lucas Clemente, this commit adds experimental QUIC support. Turn it on using the -quic flag; your browser may have to be configured to enable it. Almost everything is here, but you will notice that most of the middle- ware are missing. After those are transferred over, we'll be ready for beta tests. I'm very excited to get this out. Thanks for everyone's help and patience these last few months. I hope you like it!!
2016-06-05 07:00:29 +08:00
if cfg.KeyType != acme.EC384 {
t.Errorf("Expected 'P384' as KeyType, got %#v", cfg.KeyType)
2016-04-01 17:30:38 +08:00
}
}
func TestSetupParseWithCurves(t *testing.T) {
params := `tls {
curves x25519 p256 p384 p521
}`
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
certCache := &certificateCache{cache: make(map[string]Certificate)}
cfg := &Config{Certificates: make(map[string]string), certCache: certCache}
RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController("", params)
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
c.Set(CertCacheInstStorageKey, certCache)
err := setupTLS(c)
if err != nil {
t.Errorf("Expected no errors, got: %v", err)
}
if len(cfg.CurvePreferences) != 4 {
t.Errorf("Expected 4 curves, got %v", len(cfg.CurvePreferences))
}
expectedCurves := []tls.CurveID{tls.X25519, tls.CurveP256, tls.CurveP384, tls.CurveP521}
// Ensure ordering is correct
for i, actual := range cfg.CurvePreferences {
if actual != expectedCurves[i] {
t.Errorf("Expected curve in position %d to be %v, got %v", i, expectedCurves[i], actual)
}
}
}
func TestSetupParseWithOneTLSProtocol(t *testing.T) {
params := `tls {
protocols tls1.2
}`
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
certCache := &certificateCache{cache: make(map[string]Certificate)}
cfg := &Config{Certificates: make(map[string]string), certCache: certCache}
RegisterConfigGetter("", func(c *caddy.Controller) *Config { return cfg })
c := caddy.NewTestController("", params)
tls: Restructure and improve certificate management - Expose the list of Caddy instances through caddy.Instances() - Added arbitrary storage to caddy.Instance - The cache of loaded certificates is no longer global; now scoped per-instance, meaning upon reload (like SIGUSR1) the old cert cache will be discarded entirely, whereas before, aggressively reloading config that added and removed lots of sites would cause unnecessary build-up in the cache over time. - Key certificates in the cache by their SHA-256 hash instead of by their names. This means certificates will not be duplicated in memory (within each instance), making Caddy much more memory-efficient for large-scale deployments with thousands of sites sharing certs. - Perform name-to-certificate lookups scoped per caddytls.Config instead of a single global lookup. This prevents certificates from stepping on each other when they overlap in their names. - Do not allow TLS configurations keyed by the same hostname to be different; this now throws an error. - Updated relevant tests, with a stark awareness that more tests are needed. - Change the NewContext function signature to include an *Instance. - Strongly recommend (basically require) use of caddytls.NewConfig() to create a new *caddytls.Config, to ensure pointers to the instance certificate cache are initialized properly. - Update the TLS-SNI challenge solver (even though TLS-SNI is disabled currently on the CA side). Store temporary challenge cert in instance cache, but do so directly by the ACME challenge name, not the hash. Modified the getCertificate function to check the cache directly for a name match if one isn't found otherwise. This will allow any caddytls.Config to be able to help solve a TLS-SNI challenge, with one extra side-effect that might actually be kind of interesting (and useless): clients could send a certificate's hash as the SNI and Caddy would be able to serve that certificate for the handshake. - Do not attempt to match a "default" (random) certificate when SNI is present but unrecognized; return no certificate so a TLS alert happens instead. - Store an Instance in the list of instances even while the instance is still starting up (this allows access to the cert cache for performing renewals at startup, etc). Will be removed from list again if instance startup fails. - Laid groundwork for ACMEv2 and Let's Encrypt wildcard support. Server type plugins will need to be updated slightly to accommodate minor adjustments to their API (like passing in an Instance). This commit includes the changes for the HTTP server. Certain Caddyfile configurations might error out with this change, if they configured different TLS settings for the same hostname. This change trades some complexity for other complexity, but ultimately this new complexity is more correct and robust than earlier logic. Fixes #1991 Fixes #1994 Fixes #1303
2018-02-04 15:58:27 +08:00
c.Set(CertCacheInstStorageKey, certCache)
err := setupTLS(c)
if err != nil {
t.Errorf("Expected no errors, got: %v", err)
}
if cfg.ProtocolMinVersion != cfg.ProtocolMaxVersion {
t.Errorf("Expected ProtocolMinVersion to be the same as ProtocolMaxVersion")
}
if cfg.ProtocolMinVersion != tls.VersionTLS12 && cfg.ProtocolMaxVersion != tls.VersionTLS12 {
t.Errorf("Expected 'tls1.2 (0x0303)' as ProtocolMinVersion/ProtocolMaxVersion, got %v/%v", cfg.ProtocolMinVersion, cfg.ProtocolMaxVersion)
}
}
const (
certFile = "test_cert.pem"
keyFile = "test_key.pem"
)
var testCert = []byte(`-----BEGIN CERTIFICATE-----
MIIBkjCCATmgAwIBAgIJANfFCBcABL6LMAkGByqGSM49BAEwFDESMBAGA1UEAxMJ
bG9jYWxob3N0MB4XDTE2MDIxMDIyMjAyNFoXDTE4MDIwOTIyMjAyNFowFDESMBAG
A1UEAxMJbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEs22MtnG7
9K1mvIyjEO9GLx7BFD0tBbGnwQ0VPsuCxC6IeVuXbQDLSiVQvFZ6lUszTlczNxVk
pEfqrM6xAupB7qN1MHMwHQYDVR0OBBYEFHxYDvAxUwL4XrjPev6qZ/BiLDs5MEQG
A1UdIwQ9MDuAFHxYDvAxUwL4XrjPev6qZ/BiLDs5oRikFjAUMRIwEAYDVQQDEwls
b2NhbGhvc3SCCQDXxQgXAAS+izAMBgNVHRMEBTADAQH/MAkGByqGSM49BAEDSAAw
RQIgRvBqbyJM2JCJqhA1FmcoZjeMocmhxQHTt1c+1N2wFUgCIQDtvrivbBPA688N
Qh3sMeAKNKPsx5NxYdoWuu9KWcKz9A==
-----END CERTIFICATE-----
`)
var testKey = []byte(`-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIGLtRmwzYVcrH3J0BnzYbGPdWVF10i9p6mxkA4+b2fURoAoGCCqGSM49
AwEHoUQDQgAEs22MtnG79K1mvIyjEO9GLx7BFD0tBbGnwQ0VPsuCxC6IeVuXbQDL
SiVQvFZ6lUszTlczNxVkpEfqrM6xAupB7g==
-----END EC PRIVATE KEY-----
`)