Howdy,
Thank you for Caddy. It’s a way sweet web server and the built-in support for SSL is totally amazing!
I run a small CMS site (https://telegr.am) and am looking to use Caddy to support ssl for every site that’s hosted.
The issue that I’ve run into is that if a user defines a URL that doesn’t currently have DNS pointing at the Caddy-hosted system, Caddy fails to get a cert and fails to start… and that’s a… well. non-starter.
I’ve put together a patch that does two things: (1) if a domain, even a non-wildcard domain, is specified as OnDemand TLS, then the cert is only retrieved when the site is accessed; (2) added an explicit on_demand
property to the tls
configuration so one can specify OnDemand without max_certs
.
This is my first foray into Go coding… although I’ve got a history of open source work… I founded the Lift web framework.
Given my lack of Go skills, I don’t know how to fork a GitHub repo and create a pull request that is also compatible with Go coding which seems to force one into a single branch, master, from the original author’s repo.
So…
I’m attaching the patch.
If someone could help me understand how to fork/create pull request, that’d be awesome.
If there’s any feedback on the patch, please let me know.
Thanks,
David
PS – If there’s anything I can do better to approach this community, I’m open to feedback. I appreciate the work of every open source community member and want to make sure I’m doing things to optimize for the community.
diff --git a/caddyhttp/httpserver/https.go b/caddyhttp/httpserver/https.go
index 1f5465e..eb480e2 100644
--- a/caddyhttp/httpserver/https.go
+++ b/caddyhttp/httpserver/https.go
@@ -23,9 +23,11 @@ func activateHTTPS(cctx caddy.Context) error {
// place certificates and keys on disk
for _, c := range ctx.siteConfigs {
- err := c.TLS.ObtainCert(c.TLS.Hostname, operatorPresent)
- if err != nil {
- return err
+ if !c.TLS.OnDemand {
+ err := c.TLS.ObtainCert(c.TLS.Hostname, operatorPresent)
+ if err != nil {
+ return err
+ }
}
}
@@ -73,7 +75,7 @@ func markQualifiedForAutoHTTPS(configs []*SiteConfig) {
// the returned error value will always be nil.
func enableAutoHTTPS(configs []*SiteConfig, loadCertificates bool) error {
for _, cfg := range configs {
- if cfg == nil || cfg.TLS == nil || !cfg.TLS.Managed {
+ if cfg == nil || cfg.TLS == nil || !cfg.TLS.Managed || cfg.TLS.OnDemand {
continue
}
cfg.TLS.Enabled = true
diff --git a/caddytls/setup.go b/caddytls/setup.go
index d789674..171e9a7 100644
--- a/caddytls/setup.go
+++ b/caddytls/setup.go
@@ -35,7 +35,7 @@ func setupTLS(c *caddy.Controller) error {
config.Enabled = true
for c.Next() {
- var certificateFile, keyFile, loadDir, maxCerts string
+ var certificateFile, keyFile, loadDir, onDemand, maxCerts string
args := c.RemainingArgs()
switch len(args) {
@@ -144,6 +144,8 @@ func setupTLS(c *caddy.Controller) error {
case "max_certs":
c.Args(&maxCerts)
config.OnDemand = true
+ case "on_demand":
+ c.Args(&onDemand)
case "dns":
args := c.RemainingArgs()
if len(args) != 1 {
@@ -176,6 +178,15 @@ func setupTLS(c *caddy.Controller) error {
return c.ArgErr()
}
+ if onDemand != "" {
+ od, err := strconv.ParseBool(onDemand)
+ config.OnDemand = od
+ if err != nil {
+ return c.Err("on_demand must be a bool")
+ }
+ config.OnDemand = od
+ }
+
// set certificate limit if on-demand TLS is enabled
if maxCerts != "" {
maxCertsNum, err := strconv.Atoi(maxCerts)