From 8a065b13686e963bbbedea0398d3f0c8df815d25 Mon Sep 17 00:00:00 2001 From: kovacs Date: Wed, 27 Sep 2023 15:39:03 +0800 Subject: [PATCH 1/2] feat(server): add ZeroSSL EAB add ZeroSSL EAB Signed-off-by: kovacs --- app/cmd/server.go | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/app/cmd/server.go b/app/cmd/server.go index 0beab1e..b42879a 100644 --- a/app/cmd/server.go +++ b/app/cmd/server.go @@ -3,7 +3,10 @@ package cmd import ( "context" "crypto/tls" + "encoding/json" "errors" + "fmt" + "github.com/mholt/acmez/acme" "net" "net/http" "net/http/httputil" @@ -264,6 +267,11 @@ func (c *serverConfig) fillTLSConfig(hyConfig *server.Config) error { cmIssuer.CA = certmagic.LetsEncryptProductionCA case "zerossl", "zero": cmIssuer.CA = certmagic.ZeroSSLProductionCA + eab, err := genZeroSSLEAB(c.ACME.Email) + if err != nil { + return configError{Field: "acme.ca", Err: err} + } + cmIssuer.ExternalAccount = eab default: return configError{Field: "acme.ca", Err: errors.New("unknown CA")} } @@ -288,6 +296,48 @@ func (c *serverConfig) fillTLSConfig(hyConfig *server.Config) error { return nil } +func genZeroSSLEAB(email string) (*acme.EAB, error) { + req, err := http.NewRequest( + http.MethodPost, + "https://api.zerossl.com/acme/eab-credentials-email", + strings.NewReader(url.Values{"email": []string{email}}.Encode()), + ) + if err != nil { + return nil, fmt.Errorf("failed to creare ZeroSSL EAB request: %w", err) + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.Header.Set("User-Agent", certmagic.UserAgent) + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, fmt.Errorf("failed to send ZeroSSL EAB request: %w", err) + } + defer func() { _ = resp.Body.Close() }() + + var result struct { + Success bool `json:"success"` + Error struct { + Code int `json:"code"` + Type string `json:"type"` + } `json:"error"` + EABKID string `json:"eab_kid"` + EABHMACKey string `json:"eab_hmac_key"` + } + if err = json.NewDecoder(resp.Body).Decode(&result); err != nil { + return nil, fmt.Errorf("failed decoding ZeroSSL EAB API response: %w", err) + } + if result.Error.Code != 0 { + return nil, fmt.Errorf("failed getting ZeroSSL EAB credentials: HTTP %d: %s (code %d)", resp.StatusCode, result.Error.Type, result.Error.Code) + } + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("failed getting EAB credentials: HTTP %d", resp.StatusCode) + } + + return &acme.EAB{ + KeyID: result.EABKID, + MACKey: result.EABHMACKey, + }, nil +} + func (c *serverConfig) fillQUICConfig(hyConfig *server.Config) error { hyConfig.QUICConfig = server.QUICConfig{ InitialStreamReceiveWindow: c.QUIC.InitStreamReceiveWindow, From 39518268f083dff2fdd82fe100b8e00b13ae3d72 Mon Sep 17 00:00:00 2001 From: Toby Date: Fri, 29 Sep 2023 22:29:23 -0700 Subject: [PATCH 2/2] chore: format --- app/cmd/server.go | 2 +- app/go.mod | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/cmd/server.go b/app/cmd/server.go index b42879a..6221cc6 100644 --- a/app/cmd/server.go +++ b/app/cmd/server.go @@ -6,7 +6,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/mholt/acmez/acme" "net" "net/http" "net/http/httputil" @@ -16,6 +15,7 @@ import ( "time" "github.com/caddyserver/certmagic" + "github.com/mholt/acmez/acme" "github.com/spf13/cobra" "github.com/spf13/viper" "go.uber.org/zap" diff --git a/app/go.mod b/app/go.mod index 2179881..341c50c 100644 --- a/app/go.mod +++ b/app/go.mod @@ -8,6 +8,7 @@ require ( github.com/apernet/hysteria/extras v0.0.0-00010101000000-000000000000 github.com/caddyserver/certmagic v0.17.2 github.com/mdp/qrterminal/v3 v3.1.1 + github.com/mholt/acmez v1.0.4 github.com/oschwald/geoip2-golang v1.9.0 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.15.0 @@ -29,7 +30,6 @@ require ( github.com/klauspost/cpuid/v2 v2.1.1 // indirect github.com/libdns/libdns v0.2.1 // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/mholt/acmez v1.0.4 // indirect github.com/miekg/dns v1.1.55 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/onsi/ginkgo/v2 v2.9.5 // indirect