POC DNS Challenge with Dynu

This commit is contained in:
Linard Schwendener 2024-05-02 21:39:34 +02:00
parent 7dad7c7305
commit 73c0ea0896
4 changed files with 57 additions and 25 deletions

View File

@ -85,23 +85,26 @@ func acmeRegisterSpecialRoutingRule() {
// This function check if the renew setup is satisfied. If not, toggle them automatically // This function check if the renew setup is satisfied. If not, toggle them automatically
func AcmeCheckAndHandleRenewCertificate(w http.ResponseWriter, r *http.Request) { func AcmeCheckAndHandleRenewCertificate(w http.ResponseWriter, r *http.Request) {
isForceHttpsRedirectEnabledOriginally := false isForceHttpsRedirectEnabledOriginally := false
if dynamicProxyRouter.Option.Port == 443 { dnsPara, _ := utils.PostPara(r, "dns")
//Enable port 80 to 443 redirect if dnsPara == "false" {
if !dynamicProxyRouter.Option.ForceHttpsRedirect { if dynamicProxyRouter.Option.Port == 443 {
SystemWideLogger.Println("Temporary enabling HTTP to HTTPS redirect for ACME certificate renew requests") //Enable port 80 to 443 redirect
dynamicProxyRouter.UpdateHttpToHttpsRedirectSetting(true) if !dynamicProxyRouter.Option.ForceHttpsRedirect {
SystemWideLogger.Println("Temporary enabling HTTP to HTTPS redirect for ACME certificate renew requests")
dynamicProxyRouter.UpdateHttpToHttpsRedirectSetting(true)
} else {
//Set this to true, so after renew, do not turn it off
isForceHttpsRedirectEnabledOriginally = true
}
} else if dynamicProxyRouter.Option.Port == 80 {
//Go ahead
} else { } else {
//Set this to true, so after renew, do not turn it off //This port do not support ACME
isForceHttpsRedirectEnabledOriginally = true utils.SendErrorResponse(w, "ACME renew only support web server listening on port 80 (http) or 443 (https)")
return
} }
} else if dynamicProxyRouter.Option.Port == 80 {
//Go ahead
} else {
//This port do not support ACME
utils.SendErrorResponse(w, "ACME renew only support web server listening on port 80 (http) or 443 (https)")
return
} }
//Add a 3 second delay to make sure everything is settle down //Add a 3 second delay to make sure everything is settle down
@ -114,7 +117,7 @@ func AcmeCheckAndHandleRenewCertificate(w http.ResponseWriter, r *http.Request)
tlsCertManager.UpdateLoadedCertList() tlsCertManager.UpdateLoadedCertList()
//Restore original settings //Restore original settings
if dynamicProxyRouter.Option.Port == 443 { if dynamicProxyRouter.Option.Port == 443 && dnsPara == "false" {
if !isForceHttpsRedirectEnabledOriginally { if !isForceHttpsRedirectEnabledOriginally {
//Default is off. Turn the redirection off //Default is off. Turn the redirection off
SystemWideLogger.PrintAndLog("ACME", "Restoring HTTP to HTTPS redirect settings", nil) SystemWideLogger.PrintAndLog("ACME", "Restoring HTTP to HTTPS redirect settings", nil)

View File

@ -24,6 +24,7 @@ import (
"github.com/go-acme/lego/v4/certificate" "github.com/go-acme/lego/v4/certificate"
"github.com/go-acme/lego/v4/challenge/http01" "github.com/go-acme/lego/v4/challenge/http01"
"github.com/go-acme/lego/v4/lego" "github.com/go-acme/lego/v4/lego"
"github.com/go-acme/lego/v4/providers/dns/dynu"
"github.com/go-acme/lego/v4/registration" "github.com/go-acme/lego/v4/registration"
"imuslab.com/zoraxy/mod/database" "imuslab.com/zoraxy/mod/database"
"imuslab.com/zoraxy/mod/utils" "imuslab.com/zoraxy/mod/utils"
@ -33,6 +34,7 @@ type CertificateInfoJSON struct {
AcmeName string `json:"acme_name"` AcmeName string `json:"acme_name"`
AcmeUrl string `json:"acme_url"` AcmeUrl string `json:"acme_url"`
SkipTLS bool `json:"skip_tls"` SkipTLS bool `json:"skip_tls"`
DNS bool `json:"dns"`
} }
// ACMEUser represents a user in the ACME system. // ACMEUser represents a user in the ACME system.
@ -79,7 +81,7 @@ func NewACME(acmeServer string, port string, database *database.Database) *ACMEH
} }
// ObtainCert obtains a certificate for the specified domains. // ObtainCert obtains a certificate for the specified domains.
func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email string, caName string, caUrl string, skipTLS bool) (bool, error) { func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email string, caName string, caUrl string, skipTLS bool, dns bool) (bool, error) {
log.Println("[ACME] Obtaining certificate...") log.Println("[ACME] Obtaining certificate...")
// generate private key // generate private key
@ -145,10 +147,26 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
} }
// setup how to receive challenge // setup how to receive challenge
err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", a.Port)) if dns {
if err != nil { dynuConfig := dynu.NewDefaultConfig()
log.Println(err) dynuConfig.APIKey = "yourApiKey"
return false, err
provider, err := dynu.NewDNSProviderConfig(dynuConfig)
if err != nil {
log.Fatal(err)
}
err = client.Challenge.SetDNS01Provider(provider)
if err != nil {
log.Println(err)
return false, err
}
} else {
err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", a.Port))
if err != nil {
log.Println(err)
return false, err
}
} }
// New users will need to register // New users will need to register
@ -241,6 +259,7 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
AcmeName: caName, AcmeName: caName,
AcmeUrl: caUrl, AcmeUrl: caUrl,
SkipTLS: skipTLS, SkipTLS: skipTLS,
DNS: dns,
} }
certInfoBytes, err := json.Marshal(certInfo) certInfoBytes, err := json.Marshal(certInfo)
@ -391,8 +410,18 @@ func (a *ACMEHandler) HandleRenewCertificate(w http.ResponseWriter, r *http.Requ
skipTLS = true skipTLS = true
} }
var dns bool
if dnsString, err := utils.PostPara(r, "dns"); err != nil {
dns = false
} else if dnsString != "true" {
dns = false
} else {
dns = true
}
domains := strings.Split(domainPara, ",") domains := strings.Split(domainPara, ",")
result, err := a.ObtainCert(domains, filename, email, ca, caUrl, skipTLS) result, err := a.ObtainCert(domains, filename, email, ca, caUrl, skipTLS, dns)
if err != nil { if err != nil {
utils.SendErrorResponse(w, jsonEscape(err.Error())) utils.SendErrorResponse(w, jsonEscape(err.Error()))
return return

View File

@ -356,7 +356,7 @@ func (a *AutoRenewer) renewExpiredDomains(certs []*ExpiredCerts) ([]string, erro
} }
} }
_, err = a.AcmeHandler.ObtainCert(expiredCert.Domains, certName, a.RenewerConfig.Email, certInfo.AcmeName, certInfo.AcmeUrl, certInfo.SkipTLS) _, err = a.AcmeHandler.ObtainCert(expiredCert.Domains, certName, a.RenewerConfig.Email, certInfo.AcmeName, certInfo.AcmeUrl, certInfo.SkipTLS, certInfo.DNS)
if err != nil { if err != nil {
log.Println("Renew " + fileName + "(" + strings.Join(expiredCert.Domains, ",") + ") failed: " + err.Error()) log.Println("Renew " + fileName + "(" + strings.Join(expiredCert.Domains, ",") + ") failed: " + err.Error())
} else { } else {

View File

@ -463,6 +463,8 @@
var dnsProvider = ""; var dnsProvider = "";
var dnsCredentials = ""; var dnsCredentials = "";
if (dns) { if (dns) {
//Filename cannot contain wildcards, and wildcards are possible with DNS challenges
filename = filename.replace("*", "_");
dnsProvider = $("#dnsProvider").dropdown("get value"); dnsProvider = $("#dnsProvider").dropdown("get value");
dnsCredentials = $("#dnsCredentials").val(); dnsCredentials = $("#dnsCredentials").val();
} }
@ -480,8 +482,6 @@
caURL: caURL, caURL: caURL,
skipTLS: skipTLSValue, skipTLS: skipTLSValue,
dns: dns, dns: dns,
dnsProvider: dnsProvider,
dnsCredentials: dnsCredentials,
}, },
success: function(response) { success: function(response) {
$("#obtainButton").removeClass("loading").removeClass("disabled"); $("#obtainButton").removeClass("loading").removeClass("disabled");