package main import ( "crypto" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "fmt" "log" "net/url" "os" "time" "github.com/go-acme/lego/v4/certcrypto" "github.com/go-acme/lego/v4/certificate" "github.com/go-acme/lego/v4/lego" "github.com/go-acme/lego/v4/providers/dns/pdns" "github.com/go-acme/lego/v4/registration" ) // You'll need a user or account type that implements acme.User type MyUser struct { Email string Registration *registration.Resource key crypto.PrivateKey } func (u *MyUser) GetEmail() string { return u.Email } func (u MyUser) GetRegistration() *registration.Resource { return u.Registration } func (u *MyUser) GetPrivateKey() crypto.PrivateKey { return u.key } func GenCerts() { testMode := false testModeStr, exists := os.LookupEnv("TEST_MODE") if !exists { if testModeStr == "true" { testMode = true } } rootDomain, exists := os.LookupEnv("ROOT_DOMAIN") if !exists { rootDomain = "localhost" } pdnsKey, has := os.LookupEnv("PDNS_KEY") if !has { fmt.Println("must have PDNS_KEY") os.Exit(1) } pdnsHost, has := os.LookupEnv("PDNS_HOST") if !has { fmt.Println("must have PDNS_HOST ENV") os.Exit(1) } acmeEmail, has := os.LookupEnv("ACME_EMAIL") if !has { fmt.Println("must have ACME_EMAIL ENV") os.Exit(1) } fmt.Println("root domain is", rootDomain) // 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) } myUser := MyUser{ Email: acmeEmail, key: privateKey, } pdnsUrl, _ := url.Parse(pdnsHost) provider, err := pdns.NewDNSProviderConfig(&pdns.Config{ Host: pdnsUrl, APIKey: pdnsKey, ServerName: "localhost", TTL: 5, PropagationTimeout: time.Duration(time.Second * 30), PollingInterval: time.Duration(time.Millisecond * 500), }) if err != nil { log.Fatal(err) } config := lego.NewConfig(&myUser) // uncoment for tesing ->> if testMode { config.CADirURL = lego.LEDirectoryStaging } config.Certificate.KeyType = certcrypto.RSA2048 // A client facilitates communication with the CA server. client, err := lego.NewClient(config) if err != nil { log.Fatal(err) } client.Challenge.SetDNS01Provider(provider) // New users will need to register reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true}) if err != nil { log.Fatal(err) } myUser.Registration = reg request := certificate.ObtainRequest{ Domains: []string{rootDomain, "*." + rootDomain}, Bundle: true, } certificates, err := client.Certificate.Obtain(request) if err != nil { log.Fatal(err) } // Each certificate comes back with the cert bytes, the bytes of the client's // private key, and a certificate URL. SAVE THESE TO DISK. os.Mkdir("./certs", 0777) os.WriteFile("./certs/cert.crt", certificates.Certificate, 0777) os.WriteFile("./certs/priv.key", certificates.PrivateKey, 0777) // ... all done. }