package acme import ( "encoding/json" "errors" "fmt" "log" "net/http" "os" "path/filepath" "time" "imuslab.com/zoraxy/mod/utils" ) /* autorenew.go This script handle auto renew */ type AutoRenewConfig struct { Email string //Email for acme AutomaticRenew bool //Automatic renew is enabled RenewAll bool //Renew all or selective renew with the slice below DomainsToRenew []string } type AutoRenewer struct { ConfigFilePath string CertFolder string RenewerConfig *AutoRenewConfig TickerstopChan chan bool } // Create an auto renew agent, require config filepath and auto scan & renew interval (seconds) // Set renew check interval to 0 for auto (1 day) func NewAutoRenewer(config string, certFolder string, renewCheckInterval int64) (*AutoRenewer, error) { if renewCheckInterval == 0 { renewCheckInterval = 86400 //1 day } ticker := time.NewTicker(time.Duration(renewCheckInterval) * time.Second) done := make(chan bool) //Load the config file. If not found, create one if !utils.FileExists(config) { //Create one os.MkdirAll(filepath.Dir(config), 0775) newConfig := AutoRenewConfig{ RenewAll: true, DomainsToRenew: []string{}, } js, _ := json.MarshalIndent(newConfig, "", " ") err := os.WriteFile(config, js, 0775) if err != nil { return nil, errors.New("Failed to create acme auto renewer config: " + err.Error()) } } renewerConfig := AutoRenewConfig{} content, err := os.ReadFile(config) if err != nil { return nil, errors.New("Failed to open acme auto renewer config: " + err.Error()) } err = json.Unmarshal(content, &renewerConfig) if err != nil { return nil, errors.New("Malformed acme config file: " + err.Error()) } //Create an Auto renew object thisRenewer := AutoRenewer{ ConfigFilePath: config, CertFolder: certFolder, RenewerConfig: &renewerConfig, TickerstopChan: done, } //Check and renew certificate on startup thisRenewer.CheckAndRenewCertificates() //Start the ticker to check and renew every x seconds go func() { for { select { case <-done: return case <-ticker.C: log.Println("Check and renew certificates in progress") thisRenewer.CheckAndRenewCertificates() } } }() return &thisRenewer, nil } func (a *AutoRenewer) HandleSetAutoRenewDomains(w http.ResponseWriter, r *http.Request) { } func (a *AutoRenewer) HandleLoadAutoRenewDomains(w http.ResponseWriter, r *http.Request) { } func (a *AutoRenewer) HandleRenewNow(w http.ResponseWriter, r *http.Request) { } func (a *AutoRenewer) HandleACMEEmail(w http.ResponseWriter, r *http.Request) { /* email, err := utils.PostPara(r, "set") if err != nil { currentEmail := "" } else { } */ } // Check and renew certificates. This check all the certificates in the // certificate folder and return a list of certs that is renewed in this call // Return string array with length 0 when no cert is expired func (a *AutoRenewer) CheckAndRenewCertificates() ([]string, error) { certFolder := a.CertFolder files, err := os.ReadDir(certFolder) if err != nil { log.Println("Unable to renew certificates: " + err.Error()) return []string{}, err } fmt.Println("[ACME DEBUG] Cert found: ", files) return []string{}, nil }