From 6615cf3bf2b2351c769404c028eb758f31293f05 Mon Sep 17 00:00:00 2001 From: Kapil Agrawal <7047165+netops2devops@users.noreply.github.com> Date: Fri, 3 Apr 2026 18:29:39 -0500 Subject: [PATCH 1/3] simplify project build system by taking out patches from Makefile into a separate forked repo --- Makefile | 6 -- go.mod | 10 +-- go.sum | 2 + hack/server/server.go | 171 ------------------------------------------ 4 files changed, 4 insertions(+), 185 deletions(-) delete mode 100644 hack/server/server.go diff --git a/Makefile b/Makefile index 105cea9..6383e4e 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,6 @@ clean: go clean -cache rm -f step-ca rm -rf db - rm -rf .build check-deps: @echo "🔍 Checking for libpcsclite-dev dependency..." @@ -43,17 +42,12 @@ check-deps: dev: clean check-deps @echo "⬇️ Downloading dependencies to create dev environment..." - git clone --branch $(VERSION) --depth 1 $(UPSTREAM) .build/certificates/ - rm -rf .build/certificates/server && cp -r ./hack/server .build/certificates/server mkdir db go mod tidy @echo "✅ Ready" build: clean check-deps @echo "⚙️ Building ACME proxy with Step CA..." - mkdir .build - git clone --branch $(VERSION) --depth 1 $(UPSTREAM) .build/certificates/ - rm -rf .build/certificates/server && cp -r ./hack/server .build/certificates/server mkdir db go build -v -o $(APP_NAME) . @echo "✅ Done" diff --git a/go.mod b/go.mod index c705796..787b3f4 100644 --- a/go.mod +++ b/go.mod @@ -2,17 +2,10 @@ module github.com/esnet/acme-proxy go 1.25.0 -// The root cause of the bug appears to be caused by short `WriteTimeout` value -// which is currently hardcoded to 15 seconds in the upstream repository -// https://github.com/smallstep/certificates/blob/master/server/server.go#L45 -// Our workaround simply bumps up the timeout from 15s to 90s. -// There is already a pull request for a permanent fix but it remains to be merged -// See https://github.com/smallstep/certificates/pull/1643/files -replace github.com/smallstep/certificates => ./.build/certificates +replace github.com/smallstep/certificates => github.com/esnet/certificates v0.30.2-patch.2 require ( github.com/go-acme/lego/v4 v4.33.0 - github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.23.2 github.com/smallstep/certificates v0.30.2 github.com/smallstep/cli-utils v0.12.2 @@ -136,6 +129,7 @@ require ( github.com/newrelic/go-agent/v3 v3.42.0 // indirect github.com/peterbourgon/diskv/v3 v3.0.1 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/procfs v0.19.2 // indirect diff --git a/go.sum b/go.sum index 6d751f8..079a838 100644 --- a/go.sum +++ b/go.sum @@ -143,6 +143,8 @@ github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3re github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98= github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4= github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= +github.com/esnet/certificates v0.30.2-patch.2 h1:k4+zeuvqetGdYQHgEfeF6HdUDfNEAkT+BsGKdkx7DZk= +github.com/esnet/certificates v0.30.2-patch.2/go.mod h1:oyaE/aEYUGDr+YiCZLAxxP22bOQqcSHTeDgp8Vv2rlY= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= diff --git a/hack/server/server.go b/hack/server/server.go deleted file mode 100644 index 4372126..0000000 --- a/hack/server/server.go +++ /dev/null @@ -1,171 +0,0 @@ -// This package contains a workaround for a transport layer timeout related bug -// between the ACME client & this ACME server whenever -// a certificate authority takes longer than 15 seconds to return a signed certificate. -// This bug is specially triggered when using InCommon as the CA - -// The root cause of the bug appears to be caused by short `WriteTimeout` value -// which is currently hardcoded to 15 seconds in the upstream repository -// https://github.com/smallstep/certificates/blob/master/server/server.go#L45 - -// This workaround simply bumps up those timeout values from 15 seconds to 90 seconds. -// There is a pull request already out there to fix this but is yet to be merged -// https://github.com/smallstep/certificates/pull/1643/files - -package server - -import ( - "context" - "crypto/tls" - "log" - "net" - "net/http" - "os" - "time" - - "github.com/pkg/errors" -) - -// ServerShutdownTimeout is the default time to wait before closing -// connections on shutdown. -const ServerShutdownTimeout = 90 * time.Second - -// Server is a incomplete component that implements a basic HTTP/HTTPS -// server. -type Server struct { - *http.Server - listener *net.TCPListener - reloadCh chan net.Listener - shutdownCh chan struct{} -} - -// New creates a new HTTP/HTTPS server configured with the passed -// address, http.Handler and tls.Config. -func New(addr string, handler http.Handler, tlsConfig *tls.Config) *Server { - return &Server{ - reloadCh: make(chan net.Listener), - shutdownCh: make(chan struct{}), - Server: newHTTPServer(addr, handler, tlsConfig), - } -} - -// newHTTPServer creates a new http.Server with the TCP address, handler and -// tls.Config. -func newHTTPServer(addr string, handler http.Handler, tlsConfig *tls.Config) *http.Server { - return &http.Server{ - Addr: addr, - Handler: handler, - TLSConfig: tlsConfig, - WriteTimeout: 90 * time.Second, - ReadTimeout: 90 * time.Second, - ReadHeaderTimeout: 90 * time.Second, - IdleTimeout: 90 * time.Second, - ErrorLog: log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Llongfile), - } -} - -// ListenAndServe listens on the TCP network address srv.Addr and then calls -// Serve to handle requests on incoming connections. -func (srv *Server) ListenAndServe() error { - ln, err := net.Listen("tcp", srv.Addr) - if err != nil { - return err - } - - return srv.Serve(ln) -} - -// Serve runs Serve or ServeTLS on the underlying http.Server and listen to -// channels to reload or shutdown the server. -func (srv *Server) Serve(ln net.Listener) error { - var err error - // Store the current listener. - // In reloads we'll create a copy of the underlying os.File so the close of the server one does not affect the copy. - srv.listener = ln.(*net.TCPListener) - - for { - // Start server - if srv.TLSConfig == nil || (len(srv.TLSConfig.Certificates) == 0 && srv.TLSConfig.GetCertificate == nil) { - log.Printf("Serving HTTP on %s ...", srv.Addr) - err = srv.Server.Serve(ln) - } else { - log.Printf("Serving HTTPS on %s ...", srv.Addr) - err = srv.Server.ServeTLS(ln, "", "") - } - - // log unexpected errors - if err != http.ErrServerClosed { - log.Println(errors.Wrap(err, "unexpected error")) - } - - select { - case ln = <-srv.reloadCh: - srv.listener = ln.(*net.TCPListener) - case <-srv.shutdownCh: - return http.ErrServerClosed - } - } -} - -// Shutdown gracefully shuts down the server without interrupting any active -// connections. -func (srv *Server) Shutdown() error { - ctx, cancel := context.WithTimeout(context.Background(), ServerShutdownTimeout) - defer cancel() // release resources if Shutdown ends before the timeout - defer close(srv.shutdownCh) // close shutdown channel - return srv.Server.Shutdown(ctx) -} - -func (srv *Server) reloadShutdown() error { - ctx, cancel := context.WithTimeout(context.Background(), ServerShutdownTimeout) - defer cancel() // release resources if Shutdown ends before the timeout - return srv.Server.Shutdown(ctx) -} - -// Reload reloads the current server with the configuration of the passed -// server. -func (srv *Server) Reload(ns *Server) error { - var err error - var ln net.Listener - - if srv.Addr != ns.Addr { - // Open new address - ln, err = net.Listen("tcp", ns.Addr) - if err != nil { - return errors.WithStack(err) - } - } else { - // Get a copy of the underlying os.File - fd, err := srv.listener.File() - if err != nil { - return errors.WithStack(err) - } - // Make sure to close the copy - defer fd.Close() - - // Creates a new listener copying fd - ln, err = net.FileListener(fd) - if err != nil { - return errors.WithStack(err) - } - } - - // Close old server without sending a signal - if err := srv.reloadShutdown(); err != nil { - return err - } - - // Update old server - srv.Server = ns.Server - srv.reloadCh <- ln - return nil -} - -// Forbidden writes on the http.ResponseWriter a text/plain forbidden -// response. -func (srv *Server) Forbidden(w http.ResponseWriter) { - header := w.Header() - header.Set("Content-Type", "text/plain; charset=utf-8") - header.Set("Content-Length", "11") - w.WriteHeader(http.StatusForbidden) - w.Write([]byte("Forbidden.\n")) -} From e58b8c5cb4d96efcbac0aa7cf5a91a48eceab5e2 Mon Sep 17 00:00:00 2001 From: Kapil Agrawal <7047165+netops2devops@users.noreply.github.com> Date: Wed, 8 Apr 2026 21:21:23 -0500 Subject: [PATCH 2/3] update Github build container to go1.26 --- .github/workflows/ci.yml | 2 +- Makefile | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58cc8ae..aee0a6b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ on: branches: [main] env: - GO_VERSION: '1.25' + GO_VERSION: '1.26' REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} diff --git a/Makefile b/Makefile index 6383e4e..3436d90 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,4 @@ APP_NAME = step-ca -VERSION = v0.30.2 -UPSTREAM = https://github.com/smallstep/certificates.git SUDO := $(shell if [ $$(id -u) -ne 0 ]; then echo "$(SUDO)"; else echo ""; fi) From 112e63137ede9c06c4c45e5f0e1253af821e0a87 Mon Sep 17 00:00:00 2001 From: Kapil Agrawal <7047165+netops2devops@users.noreply.github.com> Date: Wed, 8 Apr 2026 21:36:39 -0500 Subject: [PATCH 3/3] Bump up Go version in Dockerfile & drop debug specific symbols from binary to reduce binary size --- Dockerfile | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8471a01..48e78e9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # Stage 1: Build step-ca with acme-proxy plugin -FROM golang:1.25.5-trixie AS build +FROM golang:1.26.2-trixie AS build WORKDIR /build diff --git a/Makefile b/Makefile index 3436d90..b378c7f 100644 --- a/Makefile +++ b/Makefile @@ -47,5 +47,5 @@ dev: clean check-deps build: clean check-deps @echo "⚙️ Building ACME proxy with Step CA..." mkdir db - go build -v -o $(APP_NAME) . + go build -ldflags="-s -w" -v -o $(APP_NAME) . @echo "✅ Done"