// SetDefaultTLSParams sets the default TLS cipher suites, protocol versions, // and server preferences of a server.Config if they were not previously set // (it does not overwrite; only fills in missing values). func SetDefaultTLSParams(c *server.Config) { // If no ciphers provided, use all that Caddy supports for the protocol if len(c.TLS.Ciphers) == 0 { c.TLS.Ciphers = defaultCiphers } // Not a cipher suite, but still important for mitigating protocol downgrade attacks c.TLS.Ciphers = append(c.TLS.Ciphers, tls.TLS_FALLBACK_SCSV) // Set default protocol min and max versions - must balance compatibility and security if c.TLS.ProtocolMinVersion == 0 { c.TLS.ProtocolMinVersion = tls.VersionTLS10 } if c.TLS.ProtocolMaxVersion == 0 { c.TLS.ProtocolMaxVersion = tls.VersionTLS12 } // Prefer server cipher suites c.TLS.PreferServerCipherSuites = true // Default TLS port is 443; only use if port is not manually specified, // TLS is enabled, and the host is not localhost if c.Port == "" && c.TLS.Enabled && c.Host != "localhost" { c.Port = "443" } }
// setDefaultTLSParams sets the default TLS cipher suites, protocol versions, // and server preferences of a server.Config if they were not previously set // (it does not overwrite; only fills in missing values). It will also set the // port to 443 if not already set, TLS is enabled, TLS is manual, and the host // does not equal localhost. func setDefaultTLSParams(c *server.Config) { // If no ciphers provided, use default list if len(c.TLS.Ciphers) == 0 { c.TLS.Ciphers = defaultCiphers } // Not a cipher suite, but still important for mitigating protocol downgrade attacks // (prepend since having it at end breaks http2 due to non-h2-approved suites before it) c.TLS.Ciphers = append([]uint16{tls.TLS_FALLBACK_SCSV}, c.TLS.Ciphers...) // Set default protocol min and max versions - must balance compatibility and security if c.TLS.ProtocolMinVersion == 0 { c.TLS.ProtocolMinVersion = tls.VersionTLS10 } if c.TLS.ProtocolMaxVersion == 0 { c.TLS.ProtocolMaxVersion = tls.VersionTLS12 } // Prefer server cipher suites c.TLS.PreferServerCipherSuites = true // Default TLS port is 443; only use if port is not manually specified, // TLS is enabled, and the host is not localhost if c.Port == "" && c.TLS.Enabled && (!c.TLS.Manual || c.TLS.OnDemand) && c.Host != "localhost" { c.Port = "443" } }
// Load reads input (named filename) and parses it, returning server // configurations grouped by listening address. func Load(filename string, input io.Reader) (Group, error) { var configs []server.Config // turn off timestamp for parsing flags := log.Flags() log.SetFlags(0) serverBlocks, err := parse.ServerBlocks(filename, input) if err != nil { return nil, err } if len(serverBlocks) == 0 { return Default() } // Each server block represents similar hosts/addresses. // Iterate each server block and make a config for each one, // executing the directives that were parsed. for i, sb := range serverBlocks { onces := makeOnces() storages := makeStorages() for j, addr := range sb.Addresses { config := server.Config{ Host: addr.Host, Port: addr.Port, Root: Root, Middleware: make(map[string][]middleware.Middleware), ConfigFile: filename, AppName: app.Name, AppVersion: app.Version, } // It is crucial that directives are executed in the proper order. for _, dir := range directiveOrder { // Execute directive if it is in the server block if tokens, ok := sb.Tokens[dir.name]; ok { // Each setup function gets a controller, which is the // server config and the dispenser containing only // this directive's tokens. controller := &setup.Controller{ Config: &config, Dispenser: parse.NewDispenserTokens(filename, tokens), OncePerServerBlock: func(f func() error) error { var err error onces[dir.name].Do(func() { err = f() }) return err }, ServerBlockIndex: i, ServerBlockHostIndex: j, ServerBlockHosts: sb.HostList(), ServerBlockStorage: storages[dir.name], } midware, err := dir.setup(controller) if err != nil { return nil, err } if midware != nil { // TODO: For now, we only support the default path scope / config.Middleware["/"] = append(config.Middleware["/"], midware) } storages[dir.name] = controller.ServerBlockStorage // persist for this server block } } if config.Port == "" { config.Port = Port } configs = append(configs, config) } } // restore logging settings log.SetFlags(flags) return arrangeBindings(configs) }
func Load(filename string, input io.Reader) ([]server.Config, error) { var configs []server.Config // turn off timestamp for parsing flags := log.Flags() log.SetFlags(0) serverBlocks, err := parse.ServerBlocks(filename, input) if err != nil { return configs, err } // Each server block represents a single server/address. // Iterate each server block and make a config for each one, // executing the directives that were parsed. for _, sb := range serverBlocks { config := server.Config{ Host: sb.Host, Port: sb.Port, Root: Root, Middleware: make(map[string][]middleware.Middleware), ConfigFile: filename, AppName: app.Name, AppVersion: app.Version, } // It is crucial that directives are executed in the proper order. for _, dir := range directiveOrder { // Execute directive if it is in the server block if tokens, ok := sb.Tokens[dir.name]; ok { // Each setup function gets a controller, which is the // server config and the dispenser containing only // this directive's tokens. controller := &setup.Controller{ Config: &config, Dispenser: parse.NewDispenserTokens(filename, tokens), } midware, err := dir.setup(controller) if err != nil { return configs, err } if midware != nil { // TODO: For now, we only support the default path scope / config.Middleware["/"] = append(config.Middleware["/"], midware) } } } if config.Port == "" { config.Port = Port } configs = append(configs, config) } // restore logging settings log.SetFlags(flags) return configs, nil }