mirror of
https://github.com/NginxProxyManager/nginx-proxy-manager.git
synced 2025-10-27 22:03:34 +00:00
Work on acme.sh hander
and dns providers
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
package acme
|
||||
|
||||
// Some light reading:
|
||||
// https://github.com/acmesh-official/acme.sh/wiki/How-to-issue-a-cert
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@@ -10,6 +13,7 @@ import (
|
||||
|
||||
"npm/embed"
|
||||
"npm/internal/config"
|
||||
"npm/internal/entity/dnsprovider"
|
||||
"npm/internal/logger"
|
||||
)
|
||||
|
||||
@@ -17,7 +21,7 @@ var acmeShFile string
|
||||
|
||||
// GetAcmeShVersion will return the acme.sh script version
|
||||
func GetAcmeShVersion() string {
|
||||
if r, err := shExec("--version"); err == nil {
|
||||
if r, err := shExec([]string{"--version"}, nil); err == nil {
|
||||
// modify the output
|
||||
r = strings.Trim(r, "\n")
|
||||
v := strings.Split(r, "\n")
|
||||
@@ -27,7 +31,7 @@ func GetAcmeShVersion() string {
|
||||
}
|
||||
|
||||
// shExec executes the acme.sh with arguments
|
||||
func shExec(args ...string) (string, error) {
|
||||
func shExec(args []string, envs []string) (string, error) {
|
||||
if _, err := os.Stat(acmeShFile); os.IsNotExist(err) {
|
||||
e := fmt.Errorf("%s does not exist", acmeShFile)
|
||||
logger.Error("AcmeShError", e)
|
||||
@@ -37,6 +41,8 @@ func shExec(args ...string) (string, error) {
|
||||
logger.Debug("CMD: %s %v", acmeShFile, args)
|
||||
// nolint: gosec
|
||||
c := exec.Command(acmeShFile, args...)
|
||||
c.Env = envs
|
||||
|
||||
b, e := c.Output()
|
||||
|
||||
if e != nil {
|
||||
@@ -65,26 +71,22 @@ func WriteAcmeSh() {
|
||||
}
|
||||
|
||||
// RequestCert does all the heavy lifting
|
||||
func RequestCert(domains []string, method string) error {
|
||||
args := []string{"--issue"}
|
||||
|
||||
webroot := "/home/wwwroot/example.com"
|
||||
|
||||
// Add domains to args
|
||||
for _, domain := range domains {
|
||||
args = append(args, "-d", domain)
|
||||
func RequestCert(domains []string, method, caBundle, outputFullchainFile, outputKeyFile string, dnsProvider *dnsprovider.Model) error {
|
||||
// TODO log file location configurable
|
||||
args, err := buildCertRequestArgs(domains, method, caBundle, outputFullchainFile, outputKeyFile, dnsProvider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch method {
|
||||
// case "dns":
|
||||
case "http":
|
||||
args = append(args, "-w", webroot)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("RequestCert method not supported: %s", method)
|
||||
envs := make([]string, 0)
|
||||
if dnsProvider != nil {
|
||||
envs, err = dnsProvider.GetAcmeShEnvVars()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
ret, err := shExec(args...)
|
||||
ret, err := shExec(args, envs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -93,3 +95,56 @@ func RequestCert(domains []string, method string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// This is split out into it's own function so it's testable
|
||||
func buildCertRequestArgs(domains []string, method, caBundle, outputFullchainFile, outputKeyFile string, dnsProvider *dnsprovider.Model) ([]string, error) {
|
||||
// TODO log file location configurable
|
||||
args := []string{"--issue", "--log", "/data/logs/acme.sh.log"}
|
||||
|
||||
if caBundle != "" {
|
||||
args = append(args, "--ca-bundle", caBundle)
|
||||
}
|
||||
|
||||
if outputFullchainFile != "" {
|
||||
args = append(args, "--fullchain-file", outputFullchainFile)
|
||||
}
|
||||
|
||||
if outputKeyFile != "" {
|
||||
args = append(args, "--key-file", outputKeyFile)
|
||||
}
|
||||
|
||||
// TODO webroot location configurable
|
||||
webroot := "/data/acme/wellknown"
|
||||
|
||||
methodArgs := make([]string, 0)
|
||||
switch method {
|
||||
case "dns":
|
||||
if dnsProvider == nil {
|
||||
return nil, ErrDNSNeedsDNSProvider
|
||||
}
|
||||
methodArgs = append(methodArgs, "--dns", dnsProvider.AcmeShName)
|
||||
|
||||
case "http":
|
||||
if dnsProvider != nil {
|
||||
return nil, ErrHTTPHasDNSProvider
|
||||
}
|
||||
methodArgs = append(methodArgs, "-w", webroot)
|
||||
default:
|
||||
return nil, ErrMethodNotSupported
|
||||
}
|
||||
|
||||
hasMethod := false
|
||||
|
||||
// Add domains to args
|
||||
for _, domain := range domains {
|
||||
args = append(args, "-d", domain)
|
||||
// Method has to appear after first domain, but does not need to be repeated
|
||||
// for other domains.
|
||||
if !hasMethod {
|
||||
args = append(args, methodArgs...)
|
||||
hasMethod = true
|
||||
}
|
||||
}
|
||||
|
||||
return args, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user