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

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

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

Synced Nov 12, 12:00 UTC

caddytls: fix permission requirement with AutomationPolicy (#6328)

Certificate automation has permission modules that are designed to prevent inappropriate issuance of unbounded or wildcard certificates. When an explicit cert manager is used, no additional permission should be necessary. For example, this should be a valid caddyfile: https:// { tls { get_certificate tailscale } respond OK } This is accomplished when provisioning an AutomationPolicy by tracking whether there were explicit managers configured directly on the policy (in the ManagersRaw field). Only when a number of potentially unsafe conditions are present AND no explicit cert managers are configured is an error returned. The problem arises from the fact that ctx.LoadModule deletes the raw bytes after loading in order to save memory. The first time an AutomationPolicy is provisioned, the ManagersRaw field is populated, and everything is fine. An AutomationPolicy with no subjects is treated as a special "catch-all" policy. App.createAutomationPolicies ensures that this catch-all policy has an ACME issuer, and then calls its Provision method again because it may have changed. This second time Provision is called, ManagesRaw is no longer populated, and the permission check fails because it appears as though the policy has no explicit managers. Address this by storing a new boolean on AutomationPolicy recording whether it had explicit cert managers configured on it. Also fix an inverted boolean check on this value when setting failClosed. Updates #6060 Updates #6229 Updates #6327 Signed-off-by: Will Norris <will@tailscale.com>

Will Norris committed May 20, 2024 at 08:48 UTC db3e19b7b5322fba59068ce9f5c3532aa0c90740
1 file changed +6 -3
modules/caddytls/automation.go
+6 -3
@@ -170,6 +170,9 @@ type AutomationPolicy struct {
170 subjects []string
171 magic *certmagic.Config
172 storage certmagic.Storage
173 +
174 + // Whether this policy had explicit managers configured directly on it.
175 + hadExplicitManagers bool
176 }
177
178 // Provision sets up ap and builds its underlying CertMagic config.
@@ -201,8 +204,8 @@ func (ap *AutomationPolicy) Provision(tlsApp *TLS) error {
204 // store them on the policy before putting it on the config
205
206 // load and provision any cert manager modules
204 - hadExplicitManagers := len(ap.ManagersRaw) > 0
207 if ap.ManagersRaw != nil {
208 + ap.hadExplicitManagers = true
209 vals, err := tlsApp.ctx.LoadModule(ap, "ManagersRaw")
210 if err != nil {
211 return fmt.Errorf("loading external certificate manager modules: %v", err)
@@ -262,9 +265,9 @@ func (ap *AutomationPolicy) Provision(tlsApp *TLS) error {
265 // prevent issuance from Issuers (when Managers don't provide a certificate) if there's no
266 // permission module configured
267 noProtections := ap.isWildcardOrDefault() && !ap.onlyInternalIssuer() && (tlsApp.Automation == nil || tlsApp.Automation.OnDemand == nil || tlsApp.Automation.OnDemand.permission == nil)
265 - failClosed := noProtections && hadExplicitManagers // don't allow on-demand issuance (other than implicit managers) if no managers have been explicitly configured
268 + failClosed := noProtections && !ap.hadExplicitManagers // don't allow on-demand issuance (other than implicit managers) if no managers have been explicitly configured
269 if noProtections {
267 - if !hadExplicitManagers {
270 + if !ap.hadExplicitManagers {
271 // no managers, no explicitly-configured permission module, this is a config error
272 return fmt.Errorf("on-demand TLS cannot be enabled without a permission module to prevent abuse; please refer to documentation for details")
273 }