Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DNS challenge for letsencrypt #144

Merged
merged 11 commits into from
May 6, 2024
45 changes: 45 additions & 0 deletions providers-scraper-util.js
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a helper file, that could be usefull in the future to update the supported list of dns providers. I can also remove it if it is not required.

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// This script is used to scrape the DNS providers from the https://go-acme.github.io/lego/dns/ website
// It will fetch the DNS providers and their respective codes and store them in a Map object
// You can copy the code into the browser console and run it to get the Map object
// Dont forget to remove providers that are not supported by the current acme-lego version that is being used

const providerArray = [];
document.querySelectorAll('table a[href^="/lego/dns/"]').forEach((provider) => {
fetch(provider.href)
.then(function(response) { return response.text() })
.then(function(html) {
const parser = new DOMParser();
const doc = parser.parseFromString(html, "text/html")

const providerCodes = Array.from(doc.querySelector('table tbody').querySelectorAll('code')).map(code => code.innerHTML);
const providerId = provider.href.match(/.*?\/dns\/(.*?)\//)[1];
const providerName = provider.innerHTML;
providerArray.push({providerId, providerName, providerCodes});
})
.catch(function(err) {
console.log('Failed to fetch page '+provider.href+': ', err);
});
})

// After fetching all the providers, sort them by providerName. You have to run this line in the console after the fetch is done

providerArray.sort((a,b) => a.providerName.localeCompare(b.providerName))


// Create Dropdown items for the providers

providerDropdownItems = "";
providerArray.forEach(provider => {
providerDropdownItems += '<div class="item" data-value="'+provider.providerId+'">'+provider.providerName+'</div>\n'
})
console.log(providerDropdownItems);


// Create Credential prefill for the providers

switchCasePrefill = "";
providerArray.forEach(provider => {
providerCodes = provider.providerCodes.reduce((accumulator,value) => accumulator + value + "=\\n","").slice(0, -2);
switchCasePrefill += 'case "'+provider.providerId+'":\n\t$("#dnsCredentials").val("'+providerCodes+'");\n\tbreak;\n'
})
console.log(switchCasePrefill);
35 changes: 19 additions & 16 deletions src/acme.go
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All Port changes are not required if the challenge is dns based

Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,26 @@ func acmeRegisterSpecialRoutingRule() {
// This function check if the renew setup is satisfied. If not, toggle them automatically
func AcmeCheckAndHandleRenewCertificate(w http.ResponseWriter, r *http.Request) {
isForceHttpsRedirectEnabledOriginally := false
if dynamicProxyRouter.Option.Port == 443 {
//Enable port 80 to 443 redirect
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
}
dnsPara, _ := utils.PostPara(r, "dns")
if dnsPara == "false" {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better also check for if dnsPara == "" (and error), which might occurs if the dns post parameter is missing

if dynamicProxyRouter.Option.Port == 443 {
//Enable port 80 to 443 redirect
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 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
} 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
Expand All @@ -114,7 +117,7 @@ func AcmeCheckAndHandleRenewCertificate(w http.ResponseWriter, r *http.Request)
tlsCertManager.UpdateLoadedCertList()

//Restore original settings
if dynamicProxyRouter.Option.Port == 443 {
if dynamicProxyRouter.Option.Port == 443 && dnsPara == "false" {
if !isForceHttpsRedirectEnabledOriginally {
//Default is off. Turn the redirection off
SystemWideLogger.PrintAndLog("ACME", "Restoring HTTP to HTTPS redirect settings", nil)
Expand Down
1 change: 1 addition & 0 deletions src/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ func initAPIs() {
authRouter.HandleFunc("/api/acme/autoRenew/email", acmeAutoRenewer.HandleACMEEmail)
authRouter.HandleFunc("/api/acme/autoRenew/setDomains", acmeAutoRenewer.HandleSetAutoRenewDomains)
authRouter.HandleFunc("/api/acme/autoRenew/setEAB", acmeAutoRenewer.HanldeSetEAB)
authRouter.HandleFunc("/api/acme/autoRenew/setDNS", acmeAutoRenewer.HanldeSetDNS)
authRouter.HandleFunc("/api/acme/autoRenew/listDomains", acmeAutoRenewer.HandleLoadAutoRenewDomains)
authRouter.HandleFunc("/api/acme/autoRenew/renewPolicy", acmeAutoRenewer.HandleRenewPolicy)
authRouter.HandleFunc("/api/acme/autoRenew/renewNow", acmeAutoRenewer.HandleRenewNow)
Expand Down
8 changes: 8 additions & 0 deletions src/cert.go
Copy link
Contributor Author

@Teifun2 Teifun2 May 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is porbably the most danegours line here. I am not sure if this will crash for existing certificates (it should not)

But backwards compatability would need to be checked!

In my current testing setup i had no existing certificates.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure about this, but I guess the author for TLS certificate config was by daluntw.

Hi @daluntw , you mind validating if this change here will not cause any problems? Many thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mainly do changes in src/mod/acme, the change on this files lgtm, but I do think handleListCertificate can be rewritten, it seems weird now.

I also agree that DNS bool can be more clarify

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"strings"
"time"

"imuslab.com/zoraxy/mod/acme"
"imuslab.com/zoraxy/mod/utils"
)

Expand Down Expand Up @@ -46,6 +47,7 @@ func handleListCertificate(w http.ResponseWriter, r *http.Request) {
LastModifiedDate string
ExpireDate string
RemainingDays int
DNS bool
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe change this to something like RequireDNSValidation or IsDNSCert so future contributor can better sure what this field is for?

}

results := []*CertInfo{}
Expand Down Expand Up @@ -81,12 +83,18 @@ func handleListCertificate(w http.ResponseWriter, r *http.Request) {
}
}
}
certInfoFilename := filepath.Join(tlsCertManager.CertStore, filename+".json")
certInfo, err := acme.LoadCertInfoJSON(certInfoFilename)
if err != nil {
SystemWideLogger.PrintAndLog("Could not Load CertInfoJson", certInfoFilename, err)
}

thisCertInfo := CertInfo{
Domain: filename,
LastModifiedDate: modifiedTime,
ExpireDate: certExpireTime,
RemainingDays: expiredIn,
DNS: certInfo.DNS,
}

results = append(results, &thisCertInfo)
Expand Down
Loading