Alan Yeung 1 year ago
parent
commit
5ec156865b
2 changed files with 63 additions and 13 deletions
  1. 2 10
      acme.go
  2. 61 3
      mod/acme/acme.go

+ 2 - 10
acme.go

@@ -19,24 +19,18 @@ import (
 
 func acmeRegisterSpecialRoutingRule() {
 	a := acme.NewACME("[email protected]", []string{"r5desktop.alanyeung.co"})
+	a.CheckCertificate()
 
 	err := dynamicProxyRouter.AddRoutingRules(&dynamicproxy.RoutingRule{
 		ID: "acme-autorenew",
 		MatchRule: func(r *http.Request) bool {
 			found, _ := regexp.MatchString("/.well-known/*", r.RequestURI)
-			/*
-				if r.RequestURI == "/.well-known/" {
-					return true
-				}
-
-				return false
-			*/
 			return found
 		},
 		RoutingHandler: func(w http.ResponseWriter, r *http.Request) {
 
 			req, err := http.NewRequest(http.MethodGet, "http://localhost:5002"+r.RequestURI, nil)
-			req.Host = "r5desktop.alanyeung.co"
+			req.Host = r.Host
 			if err != nil {
 				fmt.Printf("client: could not create request: %s\n", err)
 			}
@@ -50,8 +44,6 @@ func acmeRegisterSpecialRoutingRule() {
 				fmt.Printf("error reading: %s\n", err)
 			}
 			w.Write(resBody)
-
-			//w.Write([]byte("HELLO WORLD, THIS IS ACME REQUEST HANDLER"))
 		},
 		Enabled: true,
 	})

+ 61 - 3
mod/acme/acme.go

@@ -5,8 +5,13 @@ import (
 	"crypto/ecdsa"
 	"crypto/elliptic"
 	"crypto/rand"
+	"crypto/x509"
+	"encoding/pem"
 	"io/ioutil"
 	"log"
+	"os"
+	"path/filepath"
+	"time"
 
 	"github.com/go-acme/lego/v4/certcrypto"
 	"github.com/go-acme/lego/v4/certificate"
@@ -47,7 +52,7 @@ func NewACME(email string, domains []string) *ACMEHandler {
 
 func (a *ACMEHandler) ObtainCert() {
 	log.Println("Obtaining certificate...")
-	// Create a user. New accounts need an email and private key to start.
+
 	privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
 	if err != nil {
 		log.Fatal(err)
@@ -66,17 +71,20 @@ func (a *ACMEHandler) ObtainCert() {
 	client, err := lego.NewClient(config)
 	if err != nil {
 		log.Println(err)
+		return
 	}
 
 	err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", "5002"))
 	if err != nil {
 		log.Println(err)
+		return
 	}
 
 	// New users will need to register
 	reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
 	if err != nil {
 		log.Println(err)
+		return
 	}
 	adminUser.Registration = reg
 
@@ -87,16 +95,66 @@ func (a *ACMEHandler) ObtainCert() {
 	certificates, err := client.Certificate.Obtain(request)
 	if err != nil {
 		log.Println(err)
+		return
 	}
 
 	// Each certificate comes back with the cert bytes, the bytes of the client's
 	// private key, and a certificate URL. SAVE THESE TO DISK.
-	err = ioutil.WriteFile("./certs/"+certificates.Domain+".crt", certificates.Certificate, 0777)
-	err = ioutil.WriteFile("./certs/"+certificates.Domain+".key", certificates.PrivateKey, 0777)
+	certificateName := ""
+	if len(a.domains) == 1 {
+		certificateName = certificates.Domain
+	} else {
+		certificateName = "default"
+	}
+	err = ioutil.WriteFile("./certs/"+certificateName+".crt", certificates.Certificate, 0777)
+	if err != nil {
+		log.Println(err)
+		return
+	}
+	err = ioutil.WriteFile("./certs/"+certificateName+".key", certificates.PrivateKey, 0777)
 
 	if err != nil {
 		log.Println(err)
+		return
 	}
 
 	// ... all done.
 }
+
+// Return a list of domains where the certificates covers
+func (a *ACMEHandler) CheckCertificate() {
+
+	filenames, err := os.ReadDir("./certs/")
+
+	if err != nil {
+		log.Println(err)
+		return
+	}
+
+	for _, filename := range filenames {
+		certFilepath := filepath.Join("./certs/", filename.Name())
+
+		certBtyes, err := os.ReadFile(certFilepath)
+		if err != nil {
+			//Unable to load this file
+			continue
+		} else {
+			//Cert loaded. Check its expire time
+			block, _ := pem.Decode(certBtyes)
+			if block != nil {
+				cert, err := x509.ParseCertificate(block.Bytes)
+				if err == nil {
+					elapsed := time.Since(cert.NotAfter)
+					approxMonths := -int(elapsed.Hours() / (24 * 30.44))
+					approxDays := -int(elapsed.Hours()/24) % 30
+					if elapsed > 0 {
+						log.Println("Certificate", certFilepath, " expired")
+					} else {
+						log.Println("Certificate", certFilepath, " will still vaild for the next ", approxMonths, "m", approxDays, "d")
+					}
+				}
+			}
+		}
+
+	}
+}