Add renew to acme
This commit is contained in:
96
acme/acme.go
96
acme/acme.go
@@ -8,9 +8,9 @@ import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/go-acme/lego/v4/certcrypto"
|
||||
"github.com/go-acme/lego/v4/certificate"
|
||||
@@ -21,25 +21,33 @@ import (
|
||||
domainrouter "github.com/pablu23/domain-router"
|
||||
)
|
||||
|
||||
func SetupAcme(config *domainrouter.Config) error {
|
||||
acme := config.Server.Ssl.Acme
|
||||
type Acme struct {
|
||||
user *User
|
||||
client *lego.Client
|
||||
domains []string
|
||||
certFilePath string
|
||||
keyFilePath string
|
||||
renewTicker *time.Ticker
|
||||
}
|
||||
|
||||
func SetupAcme(config *domainrouter.Config) (*Acme, error) {
|
||||
acme := config.Server.Ssl.Acme
|
||||
var privateKey *ecdsa.PrivateKey
|
||||
if _, err := os.Stat(acme.KeyFile); errors.Is(err, os.ErrNotExist) {
|
||||
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
err = os.WriteFile(acme.KeyFile, []byte(encode(privateKey)), 0666)
|
||||
err = os.WriteFile(acme.KeyFile, []byte(encodePrivKey(privateKey)), 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
keyBytes, err := os.ReadFile(acme.KeyFile)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
privateKey = decode(string(keyBytes))
|
||||
privateKey = decodePrivKey(string(keyBytes))
|
||||
}
|
||||
|
||||
user := User{
|
||||
@@ -56,23 +64,23 @@ func SetupAcme(config *domainrouter.Config) error {
|
||||
|
||||
client, err := lego.NewClient(leConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// strconv.Itoa(config.Server.Port)
|
||||
err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", "5002"))
|
||||
err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", acme.Http01Port))
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = client.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", "5001"))
|
||||
err = client.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", acme.TlsAlpn01Port))
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
user.Registration = reg
|
||||
|
||||
@@ -87,22 +95,76 @@ func SetupAcme(config *domainrouter.Config) error {
|
||||
}
|
||||
|
||||
certificates, err := client.Certificate.Obtain(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = os.WriteFile(config.Server.Ssl.CertFile, certificates.Certificate, 0666)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = os.WriteFile(config.Server.Ssl.KeyFile, certificates.PrivateKey, 0666)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d, err := time.ParseDuration(acme.RenewTime)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Acme{
|
||||
user: &user,
|
||||
client: client,
|
||||
domains: domains,
|
||||
certFilePath: config.Server.Ssl.CertFile,
|
||||
keyFilePath: config.Server.Ssl.KeyFile,
|
||||
renewTicker: time.NewTicker(d),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *Acme) RenewAcme() error {
|
||||
request := certificate.ObtainRequest{
|
||||
Domains: a.domains,
|
||||
Bundle: true,
|
||||
}
|
||||
|
||||
certificates, err := a.client.Certificate.Obtain(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.WriteFile(a.certFilePath, certificates.Certificate, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.WriteFile(a.keyFilePath, certificates.PrivateKey, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("%#v\n", certificates)
|
||||
return nil
|
||||
}
|
||||
|
||||
func encode(privateKey *ecdsa.PrivateKey) string {
|
||||
func (a *Acme) RegisterTicker() {
|
||||
for {
|
||||
select {
|
||||
case <-a.renewTicker.C:
|
||||
a.RenewAcme()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func encodePrivKey(privateKey *ecdsa.PrivateKey) string {
|
||||
x509Encoded, _ := x509.MarshalECPrivateKey(privateKey)
|
||||
pemEncoded := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: x509Encoded})
|
||||
|
||||
return string(pemEncoded)
|
||||
}
|
||||
|
||||
func decode(pemEncoded string) *ecdsa.PrivateKey {
|
||||
func decodePrivKey(pemEncoded string) *ecdsa.PrivateKey {
|
||||
block, _ := pem.Decode([]byte(pemEncoded))
|
||||
x509Encoded := block.Bytes
|
||||
privateKey, _ := x509.ParseECPrivateKey(x509Encoded)
|
||||
|
||||
@@ -70,12 +70,15 @@ func main() {
|
||||
}
|
||||
|
||||
if config.Server.Ssl.Acme.Enabled {
|
||||
err := acme.SetupAcme(config)
|
||||
acmeRenewer, err := acme.SetupAcme(config)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("unable to setup acme")
|
||||
}
|
||||
}
|
||||
|
||||
go func() {
|
||||
acmeRenewer.RegisterTicker()
|
||||
}()
|
||||
}
|
||||
log.Info().Int("port", config.Server.Port).Str("cert", config.Server.Ssl.CertFile).Str("key", config.Server.Ssl.KeyFile).Msg("Starting server")
|
||||
err := server.ListenAndServeTLS("", "")
|
||||
log.Fatal().Err(err).Str("cert", config.Server.Ssl.CertFile).Str("key", config.Server.Ssl.KeyFile).Int("port", config.Server.Port).Msg("Could not start server")
|
||||
|
||||
11
config.go
11
config.go
@@ -12,10 +12,13 @@ type Config struct {
|
||||
CertFile string `yaml:"certFile"`
|
||||
KeyFile string `yaml:"keyFile"`
|
||||
Acme struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Email string `yaml:"email"`
|
||||
KeyFile string `yaml:"keyFile"`
|
||||
CADirURL string `yaml:"caDirUrl"`
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Email string `yaml:"email"`
|
||||
KeyFile string `yaml:"keyFile"`
|
||||
CADirURL string `yaml:"caDirUrl"`
|
||||
Http01Port string `yaml:"http01Port"`
|
||||
TlsAlpn01Port string `yaml:"tlsAlpn01Port"`
|
||||
RenewTime string `yaml:"renewTime"`
|
||||
} `yaml:"acme"`
|
||||
} `yaml:"ssl"`
|
||||
} `yaml:"server"`
|
||||
|
||||
@@ -9,6 +9,9 @@ server:
|
||||
email: me@pablu.de
|
||||
keyFile: userKey.key
|
||||
caDirUrl: https://192.168.2.154:14000/dir
|
||||
tlsAlpn01Port: 5001
|
||||
http01Port: 5002
|
||||
renewTime: 30s
|
||||
|
||||
|
||||
logging:
|
||||
|
||||
Reference in New Issue
Block a user