autorenew.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package acme
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "log"
  7. "net/http"
  8. "os"
  9. "path/filepath"
  10. "time"
  11. "imuslab.com/zoraxy/mod/utils"
  12. )
  13. /*
  14. autorenew.go
  15. This script handle auto renew
  16. */
  17. type AutoRenewConfig struct {
  18. Email string //Email for acme
  19. AutomaticRenew bool //Automatic renew is enabled
  20. RenewAll bool //Renew all or selective renew with the slice below
  21. DomainsToRenew []string
  22. }
  23. type AutoRenewer struct {
  24. ConfigFilePath string
  25. CertFolder string
  26. RenewerConfig *AutoRenewConfig
  27. TickerstopChan chan bool
  28. }
  29. // Create an auto renew agent, require config filepath and auto scan & renew interval (seconds)
  30. // Set renew check interval to 0 for auto (1 day)
  31. func NewAutoRenewer(config string, certFolder string, renewCheckInterval int64) (*AutoRenewer, error) {
  32. if renewCheckInterval == 0 {
  33. renewCheckInterval = 86400 //1 day
  34. }
  35. ticker := time.NewTicker(time.Duration(renewCheckInterval) * time.Second)
  36. done := make(chan bool)
  37. //Load the config file. If not found, create one
  38. if !utils.FileExists(config) {
  39. //Create one
  40. os.MkdirAll(filepath.Dir(config), 0775)
  41. newConfig := AutoRenewConfig{
  42. RenewAll: true,
  43. DomainsToRenew: []string{},
  44. }
  45. js, _ := json.MarshalIndent(newConfig, "", " ")
  46. err := os.WriteFile(config, js, 0775)
  47. if err != nil {
  48. return nil, errors.New("Failed to create acme auto renewer config: " + err.Error())
  49. }
  50. }
  51. renewerConfig := AutoRenewConfig{}
  52. content, err := os.ReadFile(config)
  53. if err != nil {
  54. return nil, errors.New("Failed to open acme auto renewer config: " + err.Error())
  55. }
  56. err = json.Unmarshal(content, &renewerConfig)
  57. if err != nil {
  58. return nil, errors.New("Malformed acme config file: " + err.Error())
  59. }
  60. //Create an Auto renew object
  61. thisRenewer := AutoRenewer{
  62. ConfigFilePath: config,
  63. CertFolder: certFolder,
  64. RenewerConfig: &renewerConfig,
  65. TickerstopChan: done,
  66. }
  67. //Check and renew certificate on startup
  68. thisRenewer.CheckAndRenewCertificates()
  69. //Start the ticker to check and renew every x seconds
  70. go func() {
  71. for {
  72. select {
  73. case <-done:
  74. return
  75. case <-ticker.C:
  76. log.Println("Check and renew certificates in progress")
  77. thisRenewer.CheckAndRenewCertificates()
  78. }
  79. }
  80. }()
  81. return &thisRenewer, nil
  82. }
  83. func (a *AutoRenewer) HandleSetAutoRenewDomains(w http.ResponseWriter, r *http.Request) {
  84. }
  85. func (a *AutoRenewer) HandleLoadAutoRenewDomains(w http.ResponseWriter, r *http.Request) {
  86. }
  87. func (a *AutoRenewer) HandleRenewNow(w http.ResponseWriter, r *http.Request) {
  88. }
  89. func (a *AutoRenewer) HandleACMEEmail(w http.ResponseWriter, r *http.Request) {
  90. /*
  91. email, err := utils.PostPara(r, "set")
  92. if err != nil {
  93. currentEmail := ""
  94. } else {
  95. }
  96. */
  97. }
  98. // Check and renew certificates. This check all the certificates in the
  99. // certificate folder and return a list of certs that is renewed in this call
  100. // Return string array with length 0 when no cert is expired
  101. func (a *AutoRenewer) CheckAndRenewCertificates() ([]string, error) {
  102. certFolder := a.CertFolder
  103. files, err := os.ReadDir(certFolder)
  104. if err != nil {
  105. log.Println("Unable to renew certificates: " + err.Error())
  106. return []string{}, err
  107. }
  108. fmt.Println("[ACME DEBUG] Cert found: ", files)
  109. return []string{}, nil
  110. }