mirror of
				https://github.com/tobychui/zoraxy.git
				synced 2025-10-30 21:44:04 +01:00 
			
		
		
		
	add custom acme feature in backend
This commit is contained in:
		| @@ -8,7 +8,6 @@ import ( | ||||
| 	"crypto/x509" | ||||
| 	"encoding/json" | ||||
| 	"encoding/pem" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"log" | ||||
| @@ -28,6 +27,11 @@ import ( | ||||
| 	"imuslab.com/zoraxy/mod/utils" | ||||
| ) | ||||
|  | ||||
| type CertificateInfoJSON struct { | ||||
| 	AcmeName string `json:"acme_name"` | ||||
| 	AcmeUrl  string `json:"acme_url"` | ||||
| } | ||||
|  | ||||
| // ACMEUser represents a user in the ACME system. | ||||
| type ACMEUser struct { | ||||
| 	Email        string | ||||
| @@ -65,7 +69,7 @@ func NewACME(acmeServer string, port string) *ACMEHandler { | ||||
| } | ||||
|  | ||||
| // ObtainCert obtains a certificate for the specified domains. | ||||
| func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email string, ca string) (bool, error) { | ||||
| func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email string, caName string, caUrl string) (bool, error) { | ||||
| 	log.Println("[ACME] Obtaining certificate...") | ||||
|  | ||||
| 	// generate private key | ||||
| @@ -84,17 +88,23 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email | ||||
| 	// create config | ||||
| 	config := lego.NewConfig(&adminUser) | ||||
|  | ||||
| 	// setup who is the issuer and the key type | ||||
| 	config.CADirURL = a.DefaultAcmeServer | ||||
| 	// setup the custom ACME url endpoint. | ||||
| 	if caUrl != "" { | ||||
| 		config.CADirURL = caUrl | ||||
| 	} | ||||
|  | ||||
| 	//Overwrite the CADir URL if set | ||||
| 	if ca != "" { | ||||
| 		caLinkOverwrite, err := loadCAApiServerFromName(ca) | ||||
| 	// if not custom ACME url, load it from ca.json | ||||
| 	if caName == "custom" { | ||||
| 		log.Println("[INFO] Using Custom ACME" + caUrl + " for CA Directory URL") | ||||
| 	} else { | ||||
| 		caLinkOverwrite, err := loadCAApiServerFromName(caName) | ||||
| 		if err == nil { | ||||
| 			config.CADirURL = caLinkOverwrite | ||||
| 			log.Println("[INFO] Using " + caLinkOverwrite + " for CA Directory URL") | ||||
| 		} else { | ||||
| 			return false, errors.New("CA " + ca + " is not supported. Please contribute to the source code and add this CA's directory link.") | ||||
| 			// (caName == "" || caUrl == "") will use default acme | ||||
| 			config.CADirURL = a.DefaultAcmeServer | ||||
| 			log.Println("[INFO] Using Default ACME" + a.DefaultAcmeServer + " for CA Directory URL") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -145,6 +155,24 @@ func (a *ACMEHandler) ObtainCert(domains []string, certificateName string, email | ||||
| 		return false, err | ||||
| 	} | ||||
|  | ||||
| 	// Save certificate's ACME info for renew usage | ||||
| 	certInfo := &CertificateInfoJSON{ | ||||
| 		AcmeName: caName, | ||||
| 		AcmeUrl:  caUrl, | ||||
| 	} | ||||
|  | ||||
| 	certInfoBytes, err := json.Marshal(certInfo) | ||||
| 	if err != nil { | ||||
| 		log.Println(err) | ||||
| 		return false, err | ||||
| 	} | ||||
|  | ||||
| 	err = os.WriteFile("./conf/certs/"+certificateName+".json", certInfoBytes, 0777) | ||||
| 	if err != nil { | ||||
| 		log.Println(err) | ||||
| 		return false, err | ||||
| 	} | ||||
|  | ||||
| 	return true, nil | ||||
| } | ||||
|  | ||||
| @@ -250,14 +278,24 @@ func (a *ACMEHandler) HandleRenewCertificate(w http.ResponseWriter, r *http.Requ | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	var caUrl string | ||||
|  | ||||
| 	ca, err := utils.PostPara(r, "ca") | ||||
| 	if err != nil { | ||||
| 		log.Println("CA not set. Using default (Let's Encrypt)") | ||||
| 		ca = "Let's Encrypt" | ||||
| 		log.Println("CA not set. Using default") | ||||
| 		ca, caUrl = "", "" | ||||
| 	} | ||||
|  | ||||
| 	if ca == "custom" { | ||||
| 		caUrl, err = utils.PostPara(r, "ca_url") | ||||
| 		if err != nil { | ||||
| 			log.Println("Custom CA set but no URL provide, Using default") | ||||
| 			ca, caUrl = "", "" | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	domains := strings.Split(domainPara, ",") | ||||
| 	result, err := a.ObtainCert(domains, filename, email, ca) | ||||
| 	result, err := a.ObtainCert(domains, filename, email, ca, caUrl) | ||||
| 	if err != nil { | ||||
| 		utils.SendErrorResponse(w, jsonEscape(err.Error())) | ||||
| 		return | ||||
| @@ -285,4 +323,20 @@ func IsPortInUse(port int) bool { | ||||
| 	} | ||||
| 	defer listener.Close() | ||||
| 	return false // Port is not in use | ||||
|  | ||||
| } | ||||
|  | ||||
| func loadCertInfoJSON(filename string) (*CertificateInfoJSON, error) { | ||||
|  | ||||
| 	certInfoBytes, err := os.ReadFile(filename) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	certInfo := &CertificateInfoJSON{} | ||||
| 	if err = json.Unmarshal(certInfoBytes, certInfo); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return certInfo, nil | ||||
| } | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package acme | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"net/http" | ||||
| 	"net/mail" | ||||
| @@ -355,7 +356,16 @@ func (a *AutoRenewer) renewExpiredDomains(certs []*ExpiredCerts) ([]string, erro | ||||
| 		log.Println("Renewing " + expiredCert.Filepath + " (Might take a few minutes)") | ||||
| 		fileName := filepath.Base(expiredCert.Filepath) | ||||
| 		certName := fileName[:len(fileName)-len(filepath.Ext(fileName))] | ||||
| 		_, err := a.AcmeHandler.ObtainCert(expiredCert.Domains, certName, a.RenewerConfig.Email, expiredCert.CA) | ||||
|  | ||||
| 		// Load certificate info for ACME detail | ||||
| 		certInfoFilename := fmt.Sprintf("%s/%s.json", filepath.Dir(expiredCert.Filepath), certName) | ||||
| 		certInfo, err := loadCertInfoJSON(certInfoFilename) | ||||
| 		if err != nil { | ||||
| 			log.Printf("Renew %s certificate error, can't get the ACME detail for cert: %v, using default ACME", certName, err) | ||||
| 			certInfo = &CertificateInfoJSON{} | ||||
| 		} | ||||
|  | ||||
| 		_, err = a.AcmeHandler.ObtainCert(expiredCert.Domains, certName, a.RenewerConfig.Email, certInfo.AcmeName, certInfo.AcmeUrl) | ||||
| 		if err != nil { | ||||
| 			log.Println("Renew " + fileName + "(" + strings.Join(expiredCert.Domains, ",") + ") failed: " + err.Error()) | ||||
| 		} else { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 dalun
					dalun