diff --git a/docs/full-configuration.md b/docs/full-configuration.md index 4fffa5a7..6a1e4356 100644 --- a/docs/full-configuration.md +++ b/docs/full-configuration.md @@ -114,7 +114,7 @@ The configuration file contains the following sections:
ACME - **"acme"**, Automatic Certificate Management Environment (ACME) protocol configuration. To obtain the certificates the first time you have to configure the ACME protocol and execute the `sftpgo acme run` command. The SFTPGo service will take care of the automatic renewal of certificates for the configured domains. - - `domains`, list of domains for which to obtain certificates. If a single certificate is to be valid for multiple domains specify the names separated by commas, for example: `example.com,www.example.com`. An empty list means that ACME protocol is disabled. Default: empty. + - `domains`, list of domains for which to obtain certificates. If a single certificate is to be valid for multiple domains specify the names separated by commas or spaces, for example: `example.com,www.example.com` or `example.com www.example.com`. An empty list means that ACME protocol is disabled. Default: empty. - `email`, string. Email used for registration and recovery contact. Default: empty. - `key_type`, string. Key type to use for private keys. Supported values: `2048` (RSA 2048), `4096` (RSA 4096), `8192` (RSA 8192), `P256` (EC 256), `P384` (EC 384). Default: `4096` - `certs_path`, string. Directory, absolute or relative to the configuration directory, to use for storing certificates and related data. diff --git a/internal/acme/acme.go b/internal/acme/acme.go index 57667020..dd4caddb 100644 --- a/internal/acme/acme.go +++ b/internal/acme/acme.go @@ -489,14 +489,7 @@ func (c *Configuration) tryRecoverRegistration(privateKey crypto.PrivateKey) (*r } func (c *Configuration) obtainAndSaveCertificate(client *lego.Client, domain string) error { - var domains []string - - for _, d := range strings.Split(domain, ",") { - d = strings.TrimSpace(d) - if d != "" { - domains = append(domains, d) - } - } + domains := getDomains(domain) acmeLog(logger.LevelInfo, "requesting certificates for domains %+v", domains) request := certificate.ObtainRequest{ Domains: domains, @@ -655,8 +648,25 @@ func isDomainValid(domain string) (string, bool) { return domain, isValid } +func getDomains(domain string) []string { + var domains []string + + delimiter := "," + if !strings.Contains(domain, ",") && strings.Contains(domain, " ") { + delimiter = " " + } + + for _, d := range strings.Split(domain, delimiter) { + d = strings.TrimSpace(d) + if d != "" { + domains = append(domains, d) + } + } + return domains +} + func sanitizedDomain(domain string) string { - return strings.NewReplacer(":", "_", "*", "_", ",", "_").Replace(domain) + return strings.NewReplacer(":", "_", "*", "_", ",", "_", " ", "_").Replace(domain) } func stopScheduler() {