Add `tls on_demand validate_command`

This commit is contained in:
Simon Ser 2021-02-17 19:44:57 +01:00
parent 0fb214afc1
commit 36ae57103c
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
2 changed files with 52 additions and 2 deletions

View File

@ -5,6 +5,8 @@ import (
"fmt" "fmt"
"net" "net"
"net/url" "net/url"
"os"
"os/exec"
"strings" "strings"
"git.sr.ht/~emersion/go-scfg" "git.sr.ht/~emersion/go-scfg"
@ -161,10 +163,46 @@ func parseTLS(srv *Server, d *scfg.Directive) error {
} }
srv.ACMEManager.Email = email srv.ACMEManager.Email = email
case "on_demand": case "on_demand":
srv.ACMEConfig.OnDemand = &certmagic.OnDemandConfig{} if err := parseTLSOnDemand(srv, child); err != nil {
return err
}
default: default:
return fmt.Errorf("unknown %q directive", child.Name) return fmt.Errorf("unknown %q directive", child.Name)
} }
} }
return nil return nil
} }
func parseTLSOnDemand(srv *Server, d *scfg.Directive) error {
if srv.ACMEConfig.OnDemand == nil {
srv.ACMEConfig.OnDemand = &certmagic.OnDemandConfig{}
}
for _, child := range d.Children {
switch child.Name {
case "validate_command":
var cmdName string
if err := child.ParseParams(&cmdName); err != nil {
return err
}
decisionFunc := srv.ACMEConfig.OnDemand.DecisionFunc
srv.ACMEConfig.OnDemand.DecisionFunc = func(name string) error {
if decisionFunc != nil {
if err := decisionFunc(name); err != nil {
return err
}
}
cmd := exec.Command(cmdName, child.Params[1:]...)
cmd.Env = append(os.Environ(), "TLSTUNNEL_NAME="+name)
if err := cmd.Run(); err != nil {
return fmt.Errorf("failed to validate domain %q with command %q: %v", name, cmdName, err)
}
return nil
}
default:
return fmt.Errorf("unknown %q directive", child.Name)
}
}
return nil
}

View File

@ -95,7 +95,7 @@ The following directives are supported:
The email address to use when creating or selecting an existing ACME The email address to use when creating or selecting an existing ACME
server account server account
*on_demand* *on_demand* { ... }
Enable on-demand TLS. Enable on-demand TLS.
When enabled, a TLS handshake may trigger maintenance for the relevant When enabled, a TLS handshake may trigger maintenance for the relevant
@ -104,6 +104,18 @@ The following directives are supported:
existing certificate is available, the certificate is renewed in the existing certificate is available, the certificate is renewed in the
background if necessary. background if necessary.
Warning: to prevent abuse, you should specify a _validate_command_
sub-directive.
The on_demand directive supports the following optional sub-directives:
*validate_command* command [arguments...]
Command to run before an on-demand certificate is obtained. If the
command returns a non-zero exit status, the request is denied.
The environment will contain a *TLSTUNNEL_NAME* variable with the
domain name to be validated.
# FILES # FILES
_/etc/tlstunnel/config_ _/etc/tlstunnel/config_