Skip to content

Commit

Permalink
Merge pull request #144 from Teifun2/dns-challenge-for-letsencrypt
Browse files Browse the repository at this point in the history
DNS challenge for letsencrypt
  • Loading branch information
tobychui authored May 6, 2024
2 parents b4c771c + 90c2199 commit 0b60140
Show file tree
Hide file tree
Showing 10 changed files with 1,793 additions and 46 deletions.
45 changes: 45 additions & 0 deletions providers-scraper-util.js
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
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" {
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
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
}

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

0 comments on commit 0b60140

Please sign in to comment.