mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-06-01 13:17:21 +02:00
commit
4d163fe80f
@ -21,6 +21,7 @@ import (
|
||||
|
||||
"github.com/go-acme/lego/v4/certcrypto"
|
||||
"github.com/go-acme/lego/v4/certificate"
|
||||
"github.com/go-acme/lego/v4/challenge/dns01"
|
||||
"github.com/go-acme/lego/v4/challenge/http01"
|
||||
"github.com/go-acme/lego/v4/lego"
|
||||
"github.com/go-acme/lego/v4/registration"
|
||||
@ -29,12 +30,20 @@ import (
|
||||
"imuslab.com/zoraxy/mod/utils"
|
||||
)
|
||||
|
||||
var defaultNameservers = []string{
|
||||
"8.8.8.8:53", // Google DNS
|
||||
"8.8.4.4:53", // Google DNS
|
||||
"1.1.1.1:53", // Cloudflare DNS
|
||||
"1.0.0.1:53", // Cloudflare DNS
|
||||
}
|
||||
|
||||
type CertificateInfoJSON struct {
|
||||
AcmeName string `json:"acme_name"` //ACME provider name
|
||||
AcmeUrl string `json:"acme_url"` //Custom ACME URL (if any)
|
||||
SkipTLS bool `json:"skip_tls"` //Skip TLS verification of upstream
|
||||
UseDNS bool `json:"dns"` //Use DNS challenge
|
||||
PropTimeout int `json:"prop_time"` //Propagation timeout
|
||||
AcmeName string `json:"acme_name"` //ACME provider name
|
||||
AcmeUrl string `json:"acme_url"` //Custom ACME URL (if any)
|
||||
SkipTLS bool `json:"skip_tls"` //Skip TLS verification of upstream
|
||||
UseDNS bool `json:"dns"` //Use DNS challenge
|
||||
PropTimeout int `json:"prop_time"` //Propagation timeout
|
||||
DNSServers []string `json:"dnsServers"` // DNS servers
|
||||
}
|
||||
|
||||
// ACMEUser represents a user in the ACME system.
|
||||
@ -94,7 +103,7 @@ func (a *ACMEHandler) Close() error {
|
||||
}
|
||||
|
||||
// ObtainCert obtains a certificate for the specified domains.
|
||||
func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email string, caName string, caUrl string, skipTLS bool, useDNS bool, propagationTimeout int) (bool, error) {
|
||||
func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email string, caName string, caUrl string, skipTLS bool, useDNS bool, propagationTimeout int, dnsServers string) (bool, error) {
|
||||
a.Logf("Obtaining certificate for: "+strings.Join(domains, ", "), nil)
|
||||
|
||||
// generate private key
|
||||
@ -164,15 +173,31 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Load certificate info from JSON file
|
||||
certInfo, err := LoadCertInfoJSON(fmt.Sprintf("./conf/certs/%s.json", certificateName))
|
||||
if err == nil {
|
||||
useDNS = certInfo.UseDNS
|
||||
if dnsServers == "" && certInfo.DNSServers != nil && len(certInfo.DNSServers) > 0 {
|
||||
dnsServers = strings.Join(certInfo.DNSServers, ",")
|
||||
}
|
||||
propagationTimeout = certInfo.PropTimeout
|
||||
}
|
||||
|
||||
// Clean DNS servers
|
||||
dnsNameservers := strings.Split(dnsServers, ",")
|
||||
for i := range dnsNameservers {
|
||||
dnsNameservers[i] = strings.TrimSpace(dnsNameservers[i])
|
||||
}
|
||||
|
||||
// setup how to receive challenge
|
||||
if useDNS {
|
||||
if !a.Database.TableExists("acme") {
|
||||
a.Database.NewTable("acme")
|
||||
return false, errors.New("DNS Provider and DNS Credenital configuration required for ACME Provider (Error -1)")
|
||||
return false, errors.New("DNS Provider and DNS Credential configuration required for ACME Provider (Error -1)")
|
||||
}
|
||||
|
||||
if !a.Database.KeyExists("acme", certificateName+"_dns_provider") || !a.Database.KeyExists("acme", certificateName+"_dns_credentials") {
|
||||
return false, errors.New("DNS Provider and DNS Credenital configuration required for ACME Provider (Error -2)")
|
||||
return false, errors.New("DNS Provider and DNS Credential configuration required for ACME Provider (Error -2)")
|
||||
}
|
||||
|
||||
var dnsCredentials string
|
||||
@ -195,7 +220,13 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = client.Challenge.SetDNS01Provider(provider)
|
||||
if len(dnsNameservers) > 0 && dnsNameservers[0] != "" {
|
||||
a.Logf("Using DNS servers: "+strings.Join(dnsNameservers, ", "), nil)
|
||||
err = client.Challenge.SetDNS01Provider(provider, dns01.AddRecursiveNameservers(dnsNameservers))
|
||||
} else {
|
||||
// Use default DNS-01 nameservers if dnsServers is empty
|
||||
err = client.Challenge.SetDNS01Provider(provider, dns01.AddRecursiveNameservers(defaultNameservers))
|
||||
}
|
||||
if err != nil {
|
||||
a.Logf("Failed to resolve DNS01 Provider", err)
|
||||
return false, err
|
||||
@ -292,12 +323,13 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email
|
||||
}
|
||||
|
||||
// Save certificate's ACME info for renew usage
|
||||
certInfo := &CertificateInfoJSON{
|
||||
certInfo = &CertificateInfoJSON{
|
||||
AcmeName: caName,
|
||||
AcmeUrl: caUrl,
|
||||
SkipTLS: skipTLS,
|
||||
UseDNS: useDNS,
|
||||
PropTimeout: propagationTimeout,
|
||||
DNSServers: dnsNameservers,
|
||||
}
|
||||
|
||||
certInfoBytes, err := json.Marshal(certInfo)
|
||||
@ -484,7 +516,21 @@ func (a *ACMEHandler) HandleRenewCertificate(w http.ResponseWriter, r *http.Requ
|
||||
for _, domain := range domains {
|
||||
cleanedDomains = append(cleanedDomains, strings.TrimSpace(domain))
|
||||
}
|
||||
result, err := a.ObtainCert(cleanedDomains, filename, email, ca, caUrl, skipTLS, dns, propagationTimeout)
|
||||
|
||||
// Extract DNS servers from the request
|
||||
var dnsServers []string
|
||||
dnsServersPara, err := utils.PostPara(r, "dnsServers")
|
||||
if err == nil && dnsServersPara != "" {
|
||||
dnsServers = strings.Split(dnsServersPara, ",")
|
||||
for i := range dnsServers {
|
||||
dnsServers[i] = strings.TrimSpace(dnsServers[i])
|
||||
}
|
||||
}
|
||||
|
||||
// Convert DNS servers slice to a single string
|
||||
dnsServersString := strings.Join(dnsServers, ",")
|
||||
|
||||
result, err := a.ObtainCert(cleanedDomains, filename, email, ca, caUrl, skipTLS, dns, propagationTimeout, dnsServersString)
|
||||
if err != nil {
|
||||
utils.SendErrorResponse(w, jsonEscape(err.Error()))
|
||||
return
|
||||
@ -527,5 +573,10 @@ func LoadCertInfoJSON(filename string) (*CertificateInfoJSON, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Clean DNS servers
|
||||
for i := range certInfo.DNSServers {
|
||||
certInfo.DNSServers[i] = strings.TrimSpace(certInfo.DNSServers[i])
|
||||
}
|
||||
|
||||
return certInfo, nil
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ type AutoRenewConfig struct {
|
||||
Email string //Email for acme
|
||||
RenewAll bool //Renew all or selective renew with the slice below
|
||||
FilesToRenew []string //If RenewAll is false, renew these certificate files
|
||||
DNSServers string // DNS servers
|
||||
}
|
||||
|
||||
type AutoRenewer struct {
|
||||
@ -390,7 +391,13 @@ func (a *AutoRenewer) renewExpiredDomains(certs []*ExpiredCerts) ([]string, erro
|
||||
certInfo.PropTimeout = 300
|
||||
}
|
||||
|
||||
_, err = a.AcmeHandler.ObtainCert(expiredCert.Domains, certName, a.RenewerConfig.Email, certInfo.AcmeName, certInfo.AcmeUrl, certInfo.SkipTLS, certInfo.UseDNS, certInfo.PropTimeout)
|
||||
// Extract DNS servers from the certificate info if available
|
||||
var dnsServers string
|
||||
if len(certInfo.DNSServers) > 0 {
|
||||
dnsServers = strings.Join(certInfo.DNSServers, ",")
|
||||
}
|
||||
|
||||
_, err = a.AcmeHandler.ObtainCert(expiredCert.Domains, certName, a.RenewerConfig.Email, certInfo.AcmeName, certInfo.AcmeUrl, certInfo.SkipTLS, certInfo.UseDNS, certInfo.PropTimeout, dnsServers)
|
||||
if err != nil {
|
||||
a.Logf("Renew "+fileName+"("+strings.Join(expiredCert.Domains, ",")+") failed", err)
|
||||
} else {
|
||||
@ -459,12 +466,18 @@ func (a *AutoRenewer) HandleSetDNS(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
dnsServers, err := utils.PostPara(r, "dnsServers")
|
||||
if err != nil {
|
||||
dnsServers = ""
|
||||
}
|
||||
|
||||
if !a.AcmeHandler.Database.TableExists("acme") {
|
||||
a.AcmeHandler.Database.NewTable("acme")
|
||||
}
|
||||
|
||||
a.AcmeHandler.Database.Write("acme", filename+"_dns_provider", dnsProvider)
|
||||
a.AcmeHandler.Database.Write("acme", filename+"_dns_credentials", dnsCredentials)
|
||||
a.AcmeHandler.Database.Write("acme", filename+"_dns_servers", dnsServers)
|
||||
|
||||
utils.SendOK(w)
|
||||
|
||||
|
@ -161,6 +161,11 @@
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
<div class="field dnsChallengeOnly" style="display:none;">
|
||||
<label>Domain Name Server (optional)</label>
|
||||
<input id="dnsInput" type="text" placeholder="ns.example.com">
|
||||
<small>If you have more than one DNS server, enter them separated by commas (e.g. ns1.example.com,ns2.example.com)</small>
|
||||
</div>
|
||||
<div class="field" id="caInput" style="display:none;">
|
||||
<label>ACME Server URL</label>
|
||||
<input id="caURL" type="text" placeholder="https://example.com/acme/dictionary">
|
||||
@ -725,8 +730,7 @@
|
||||
if (callback != undefined){callback(false);}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
var ca = $("#ca").dropdown("get value");
|
||||
var caURL = "";
|
||||
if (ca == "Custom ACME Server") {
|
||||
@ -734,9 +738,9 @@
|
||||
caURL = $("#caURL").val();
|
||||
}
|
||||
|
||||
|
||||
var dns = $("#useDnsChallenge")[0].checked;
|
||||
var skipTLSValue = $("#skipTLSCheckbox")[0].checked;
|
||||
var dnsServers = $("#dnsInput").val(); // Erfassen der DNS-Server
|
||||
|
||||
$.ajax({
|
||||
url: "/api/acme/obtainCert",
|
||||
@ -749,6 +753,7 @@
|
||||
caURL: caURL,
|
||||
skipTLS: skipTLSValue,
|
||||
dns: dns,
|
||||
dnsServers: dnsServers // DNS-Server in die Anfrage einfügen
|
||||
},
|
||||
success: function(response) {
|
||||
$("#obtainButton").removeClass("loading").removeClass("disabled");
|
||||
@ -761,7 +766,6 @@
|
||||
console.log("Certificate renewed successfully");
|
||||
// Show success message
|
||||
parent.msgbox("Certificate renewed successfully");
|
||||
|
||||
// Renew the parent certificate list
|
||||
parent.initManagedDomainCertificateList();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user