SSL Cert Renew failed for all Wildcard Domains

Bug Report Template

Description

SSL Renewal failed for each wildcard domain.

Steps to Reproduce

Please provide detailed steps to reproduce the bug. Include any necessary code snippets, commands, or configuration files.

  • env DEBUG=1 cpcmd -d sitexxx letsencrypt:renew

Expected Behavior

SSL Renewal works flawless

Actual Behavior

Error Message

DEBUG  : SSL challenge attempt: dns (*.one-ofmay-domains.de)
(TypeError) EXCEPTION: str_replace(): Argument #3 ($subject) must be of type array|string, null given
[/usr/local/apnscp/lib/Opcenter/Dns/Providers/Hetzner/Record.php:28]

         0. str_replace([" "" ", "" ""], ["", ""], null)
            [/usr/local/apnscp/lib/Opcenter/Dns/Providers/Hetzner/Record.php:28]
         1. Opcenter\Dns\Providers\Hetzner\Record->formatTxt()
            [/usr/local/apnscp/lib/Opcenter/Dns/Record.php:67]
         2. Opcenter\Dns\Record->__construct("one-ofmay-domains.de", [name:"_acme-challenge", rr:"TXT", parameter:null])
            [/usr/local/apnscp/lib/Opcenter/Dns/Providers/Hetzner/Record.php:23]
         3. Opcenter\Dns\Providers\Hetzner\Record->__construct("one-ofmay-domains.de", [name:"_acme-challenge", rr:"TXT", parameter:null])
            [/usr/local/apnscp/lib/Module/Support/Dns.php:155]
         4. Module\Support\Dns::createRecord("one-ofmay-domains.de", [name:"_acme-challenge", rr:"TXT", parameter:null])
            [/usr/local/apnscp/lib/modules/dns.php:1318]
         5. Dns_Module->record_exists("one-ofmay-domains.de", "_acme-challenge", "TXT")
            [/usr/local/apnscp/lib/Module/Skeleton/Standard.php:145]
         6. Module\Skeleton\Standard->_invoke("record_exists", ["one-ofmay-domains.de", "_acme-challenge", "TXT"])
            [/usr/local/apnscp/lib/apnscpfunction.php:992]
         7. apnscpFunctionInterceptor->call("dns_record_exists", ["one-ofmay-domains.de", "_acme-challenge", "TXT"])
            [/usr/local/apnscp/lib/apnscpfunction.php:932]
         8. apnscpFunctionInterceptor->__call("dns_record_exists", ["one-ofmay-domains.de", "_acme-challenge", "TXT"])
            [/usr/local/apnscp/lib/Opcenter/Crypto/Letsencrypt/Solvers/Dns.php:44]
         9. Opcenter\Crypto\Letsencrypt\Solvers\Dns->resolve()
            [/usr/local/apnscp/lib/Opcenter/Crypto/Letsencrypt/AcmeDispatcher.php:296]
        10. Opcenter\Crypto\Letsencrypt\AcmeDispatcher->solve(AcmePhp\Core\Protocol\CertificateOrder)
            [/usr/local/apnscp/lib/Opcenter/Crypto/Letsencrypt/AcmeDispatcher.php:175]
        11. Opcenter\Crypto\Letsencrypt\AcmeDispatcher->issue(["one-ofmay-domains.de", "*.one-ofmay-domains.de"])
            [/usr/local/apnscp/lib/Module/Support/Letsencrypt.php:256]
        12. Module\Support\Letsencrypt->requestReal(["one-ofmay-domains.de", "*.one-ofmay-domains.de"], "site9", true)
            [/usr/local/apnscp/lib/modules/letsencrypt.php:390]
        13. Letsencrypt_Module->request(["*.one-ofmay-domains.de", "one-ofmay-domains.de"], true)
            [/usr/local/apnscp/lib/modules/letsencrypt.php:126]
        14. Letsencrypt_Module->renew()
            [/usr/local/apnscp/lib/Module/Skeleton/Standard.php:145]
        15. Module\Skeleton\Standard->_invoke("renew", )
            [/usr/local/apnscp/lib/apnscpfunction.php:992]
        16. apnscpFunctionInterceptor->call("letsencrypt_renew", )
            [/usr/local/apnscp/lib/CLI/cmd.php:55]
        17. CLI\__call("letsencrypt_renew", )
            [/usr/local/apnscp/lib/CLI/cmd.php:574]
        18. CLI\main()
            [/usr/local/apnscp/bin/cmd:7]
(TypeError) EXCEPTION: str_replace(): Argument #3 ($subject) must be of type array|string, null given
[/usr/local/apnscp/lib/Opcenter/Dns/Providers/Hetzner/Record.php:28]

         0. str_replace([" "" ", "" ""], ["", ""], null)
            [/usr/local/apnscp/lib/Opcenter/Dns/Providers/Hetzner/Record.php:28]
         1. Opcenter\Dns\Providers\Hetzner\Record->formatTxt()
            [/usr/local/apnscp/lib/Opcenter/Dns/Record.php:67]
         2. Opcenter\Dns\Record->__construct("one-ofmay-domains.de", [name:"_acme-challenge", rr:"TXT", parameter:null])
            [/usr/local/apnscp/lib/Opcenter/Dns/Providers/Hetzner/Record.php:23]
         3. Opcenter\Dns\Providers\Hetzner\Record->__construct("one-ofmay-domains.de", [name:"_acme-challenge", rr:"TXT", parameter:null])
            [/usr/local/apnscp/lib/Module/Support/Dns.php:155]
         4. Module\Support\Dns::createRecord("one-ofmay-domains.de", [name:"_acme-challenge", rr:"TXT", parameter:null])
            [/usr/local/apnscp/lib/modules/dns.php:1318]
         5. Dns_Module->record_exists("one-ofmay-domains.de", "_acme-challenge", "TXT")
            [/usr/local/apnscp/lib/Module/Skeleton/Standard.php:145]
         6. Module\Skeleton\Standard->_invoke("record_exists", ["one-ofmay-domains.de", "_acme-challenge", "TXT"])
            [/usr/local/apnscp/lib/apnscpfunction.php:992]
         7. apnscpFunctionInterceptor->call("dns_record_exists", ["one-ofmay-domains.de", "_acme-challenge", "TXT"])
            [/usr/local/apnscp/lib/apnscpfunction.php:932]
         8. apnscpFunctionInterceptor->__call("dns_record_exists", ["one-ofmay-domains.de", "_acme-challenge", "TXT"])
            [/usr/local/apnscp/lib/Opcenter/Crypto/Letsencrypt/Solvers/Dns.php:44]
         9. Opcenter\Crypto\Letsencrypt\Solvers\Dns->resolve()
            [/usr/local/apnscp/lib/Opcenter/Crypto/Letsencrypt/AcmeDispatcher.php:296]
        10. Opcenter\Crypto\Letsencrypt\AcmeDispatcher->solve(AcmePhp\Core\Protocol\CertificateOrder)
            [/usr/local/apnscp/lib/Opcenter/Crypto/Letsencrypt/AcmeDispatcher.php:175]
        11. Opcenter\Crypto\Letsencrypt\AcmeDispatcher->issue(["one-ofmay-domains.de", "*.one-ofmay-domains.de"])
            [/usr/local/apnscp/lib/Module/Support/Letsencrypt.php:256]
        12. Module\Support\Letsencrypt->requestReal(["one-ofmay-domains.de", "*.one-ofmay-domains.de"], "site9", true)
            [/usr/local/apnscp/lib/modules/letsencrypt.php:390]
        13. Letsencrypt_Module->request(["*.one-ofmay-domains.de", "one-ofmay-domains.de"], true)
            [/usr/local/apnscp/lib/modules/letsencrypt.php:126]
        14. Letsencrypt_Module->renew()
            [/usr/local/apnscp/lib/Module/Skeleton/Standard.php:145]
        15. Module\Skeleton\Standard->_invoke("renew", )
            [/usr/local/apnscp/lib/apnscpfunction.php:992]
        16. apnscpFunctionInterceptor->call("letsencrypt_renew", )
            [/usr/local/apnscp/lib/CLI/cmd.php:55]
        17. CLI\__call("letsencrypt_renew", )
            [/usr/local/apnscp/lib/CLI/cmd.php:574]
        18. CLI\main()
            [/usr/local/apnscp/bin/cmd:7]

Environment

ApisCP version: cpcmd misc:cp-version

revision: dd6024bcb1aa8eafed84173f3f25c00cce226c86
timestamp: 1722360217
ver_maj: 3
ver_min: 2
ver_patch: 44
ver_pre: ''
dirty: false
debug: false

Operating System: 4.18.0-552.el8.x86_64

Additional relevant information (e.g., PHP version, database, etc.):
Hetzner DNS

Additional Information

Enabling or disabling the IP Check / Verification didn´t change the behaviour.

current Workaround: Creating non-wildcard Domains SSL Certs work (via http Challenge)

Further Information:

Doing the same via WebGui:
results in blank screen, no Error from the WebGui, with unformatted same errors , as above, in start.log
Only Browser Back Button works

ALSO: the SSL Cert for the WebServer / APSCP Panel, Mail and so on are expired, and can´t be renewed

One further Question to this topic:

why is there no MAIL generated, when the SSL Renewal failed?

If Hostnames are dropped during renewal, i got an e-mail, but no mail that the WILD Card SSL Certs can´t be renewed?

Kind regards

Thanks for the bug report. Fixed in edge. To hop on edge until the next release:

cpcmd scope:set cp.update-policy edge-major
upcp

Set [crm] => copy_admin in config.ini, cpcmd scope:set cp.config crm copy_admin my@alternative-domain.com. By default it sends to system user “apnscp”, which is aliased to root. mutt will show local email.

It’ll attempt renewal automatically on start. An unhandled exception on a weak DNS match has prevented this.