acme.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "log"
  6. "math/rand"
  7. "net"
  8. "net/http"
  9. "regexp"
  10. "strconv"
  11. "time"
  12. "imuslab.com/zoraxy/mod/acme"
  13. "imuslab.com/zoraxy/mod/dynamicproxy"
  14. )
  15. /*
  16. acme.go
  17. This script handle special routing required for acme auto cert renew functions
  18. */
  19. var acmeHandler *acme.ACMEHandler
  20. // Helper function to generate a random port above a specified value
  21. func getRandomPort(minPort int) int {
  22. return rand.Intn(65535-minPort) + minPort
  23. }
  24. // Helper function to check if a port is in use
  25. func isPortInUse(port int) bool {
  26. address := fmt.Sprintf(":%d", port)
  27. listener, err := net.Listen("tcp", address)
  28. if err != nil {
  29. return true // Port is in use
  30. }
  31. defer listener.Close()
  32. return false // Port is not in use
  33. }
  34. func initACME() *acme.ACMEHandler {
  35. log.Println("Start initializing ACME")
  36. rand.Seed(time.Now().UnixNano())
  37. // Generate a random port above 30000
  38. port := getRandomPort(30000)
  39. // Check if the port is already in use
  40. for isPortInUse(port) {
  41. port = getRandomPort(30000)
  42. }
  43. return acme.NewACME("[email protected]", "https://acme-staging-v02.api.letsencrypt.org/directory", strconv.Itoa(port))
  44. }
  45. func acmeRegisterSpecialRoutingRule() {
  46. log.Println("Assigned temporary port:" + acmeHandler.Getport())
  47. err := dynamicProxyRouter.AddRoutingRules(&dynamicproxy.RoutingRule{
  48. ID: "acme-autorenew",
  49. MatchRule: func(r *http.Request) bool {
  50. found, _ := regexp.MatchString("/.well-known/*", r.RequestURI)
  51. return found
  52. },
  53. RoutingHandler: func(w http.ResponseWriter, r *http.Request) {
  54. req, err := http.NewRequest(http.MethodGet, "http://localhost:"+acmeHandler.Getport()+r.RequestURI, nil)
  55. req.Host = r.Host
  56. if err != nil {
  57. fmt.Printf("client: could not create request: %s\n", err)
  58. }
  59. res, err := http.DefaultClient.Do(req)
  60. if err != nil {
  61. fmt.Printf("client: error making http request: %s\n", err)
  62. }
  63. resBody, err := ioutil.ReadAll(res.Body)
  64. if err != nil {
  65. fmt.Printf("error reading: %s\n", err)
  66. }
  67. w.Write(resBody)
  68. },
  69. Enabled: true,
  70. })
  71. if err != nil {
  72. log.Println("[Err] " + err.Error())
  73. }
  74. }