diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cea88b8..ac5ca92 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,7 @@ jobs: fail-fast: false matrix: GO_VERSION: - - 1.20.7 + - 1.21.1 steps: - name: Checkout diff --git a/README.md b/README.md index 5f97f51..f52ab5c 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,9 @@ Getting Boulder up and running has quite a learning curve though and that is whe ## Install -LabCA is best run on its own server / virtual machine to prevent any issues caused by conflicting applications. On a freshly installed Linux machine (currently tested with Debian 11/bullseye, Debian 10/buster, Ubuntu 22.04 and Ubuntu 20.04) run this command as root user (or as a regular user that already is in the sudo group): +NOTE: LabCA cannot run on a Raspberry Pi. + +LabCA is best run on its own server / virtual machine to prevent any issues caused by conflicting applications. On a freshly installed Linux machine (currently tested with Debian 12/bookworm, Debian 11/bullseye, and Ubuntu 22.04) run this command as root user (or as a regular user that already is in the sudo group): ```sh curl -sSL https://raw.githubusercontent.com/hakwerk/labca/master/install | bash diff --git a/build/Dockerfile-boulder b/build/Dockerfile-boulder index 916b537..fa35740 100644 --- a/build/Dockerfile-boulder +++ b/build/Dockerfile-boulder @@ -1,4 +1,4 @@ -FROM letsencrypt/boulder-tools:go1.20.7_2023-08-02 AS boulder-tools +FROM letsencrypt/boulder-tools:go1.21.1_2023-09-07 AS boulder-tools FROM ubuntu:focal diff --git a/build/build.sh b/build/build.sh index 60638ec..1a510ec 100755 --- a/build/build.sh +++ b/build/build.sh @@ -8,7 +8,7 @@ TMP_DIR=$(pwd)/tmp rm -rf $TMP_DIR && mkdir -p $TMP_DIR/{admin,bin,logs,src} boulderDir=$TMP_DIR/src -boulderTag="release-2023-08-14" +boulderTag="release-2023-09-11" boulderUrl="https://github.com/letsencrypt/boulder/" cloneDir=$(pwd)/.. diff --git a/build/tmp.patch b/build/tmp.patch index b26ebf5..7262330 100644 --- a/build/tmp.patch +++ b/build/tmp.patch @@ -1,12 +1,12 @@ diff --git a/docker-compose.yml b/docker-compose.yml -index df62bf8b..748d81cc 100644 +index d52dfc3e..7d9fb59c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ name: labca services: boulder: # Should match one of the GO_DEV_VERSIONS in test/boulder-tools/tag_and_upload.sh. -- image: &boulder_image letsencrypt/boulder-tools:${BOULDER_TOOLS_TAG:-go1.20.7_2023-08-02} +- image: &boulder_image letsencrypt/boulder-tools:${BOULDER_TOOLS_TAG:-go1.21.1_2023-09-07} + image: ghcr.io/hakwerk/labca-boulder:${LABCA_IMAGE_VERSION:-latest} environment: # To solve HTTP-01 and TLS-ALPN-01 challenges, change the IP in FAKE_DNS diff --git a/install b/install index 764fb16..4977132 100755 --- a/install +++ b/install @@ -30,7 +30,7 @@ dockerComposeVersion="v2.5.0" labcaUrl="https://github.com/hakwerk/labca/" boulderUrl="https://github.com/letsencrypt/boulder/" -boulderTag="release-2023-08-14" +boulderTag="release-2023-09-11" # Feature flags flag_skip_redis=true diff --git a/patch-cfg.sh b/patch-cfg.sh index c6bf32e..e23552f 100755 --- a/patch-cfg.sh +++ b/patch-cfg.sh @@ -30,9 +30,9 @@ $SUDO patch -p1 -o "$boulderLabCADir/config/ra.json" < $cloneDir/patches/config_ $SUDO patch -p1 -o "$boulderLabCADir/config/akamai-purger.json" < $cloneDir/patches/config_akamai-purger.patch cp test/config/va*.json "$boulderLabCADir/config/" -perl -i -p0e "s/\"dnsProvider\": {.*?\t\t},/\"dnsResolvers\": [\n\t\t\t\"127.0.0.1:8053\",\n\t\t\t\"127.0.0.1:8054\"\n\t\t],/igs" $boulderLabCADir/config/va.json -perl -i -p0e "s/\"dnsProvider\": {.*?\t\t},/\"dnsResolvers\": [\n\t\t\t\"127.0.0.1:8053\",\n\t\t\t\"127.0.0.1:8054\"\n\t\t],/igs" $boulderLabCADir/config/va-remote-a.json -perl -i -p0e "s/\"dnsProvider\": {.*?\t\t},/\"dnsResolvers\": [\n\t\t\t\"127.0.0.1:8053\",\n\t\t\t\"127.0.0.1:8054\"\n\t\t],/igs" $boulderLabCADir/config/va-remote-b.json +perl -i -p0e "s/\"dnsProvider\": \{.*?\t\t},/\"dnsResolvers\": [\n\t\t\t\"127.0.0.1:8053\",\n\t\t\t\"127.0.0.1:8054\"\n\t\t],/igs" $boulderLabCADir/config/va.json +perl -i -p0e "s/\"dnsProvider\": \{.*?\t\t},/\"dnsResolvers\": [\n\t\t\t\"127.0.0.1:8053\",\n\t\t\t\"127.0.0.1:8054\"\n\t\t],/igs" $boulderLabCADir/config/va-remote-a.json +perl -i -p0e "s/\"dnsProvider\": \{.*?\t\t},/\"dnsResolvers\": [\n\t\t\t\"127.0.0.1:8053\",\n\t\t\t\"127.0.0.1:8054\"\n\t\t],/igs" $boulderLabCADir/config/va-remote-b.json if [ "$flag_skip_redis" == true ]; then perl -i -p0e "s/\n \"redis\": \{\n.*? \},//igs" $boulderLabCADir/config/ocsp-responder.json diff --git a/patch.sh b/patch.sh index e101c83..b3d527d 100755 --- a/patch.sh +++ b/patch.sh @@ -52,6 +52,7 @@ if [ "$SUDO" == "" ]; then fi $SUDO patch -p1 < $cloneDir/patches/storer_storer.patch $SUDO patch -p1 < $cloneDir/patches/updater_updater.patch +$SUDO patch -p1 < $cloneDir/patches/updater_continuous.patch $SUDO patch -p1 < $cloneDir/patches/wfe2_main.patch sed -i -e "s|./test|./labca|" start.py diff --git a/patches/cmd_config.patch b/patches/cmd_config.patch index a3fe767..bf785b6 100644 --- a/patches/cmd_config.patch +++ b/patches/cmd_config.patch @@ -1,8 +1,8 @@ diff --git a/cmd/config.go b/cmd/config.go -index 62c99005a..6794a9712 100644 +index d38291d5..13fe4a52 100644 --- a/cmd/config.go +++ b/cmd/config.go -@@ -449,7 +449,7 @@ type GRPCServerConfig struct { +@@ -454,7 +454,7 @@ type GRPCServerConfig struct { // this controls how long it takes before a client learns about changes to its // backends. // https://pkg.go.dev/google.golang.org/grpc/keepalive#ServerParameters diff --git a/patches/config_wfe2.patch b/patches/config_wfe2.patch index 13e4951..f5db3d1 100644 --- a/patches/config_wfe2.patch +++ b/patches/config_wfe2.patch @@ -2,7 +2,7 @@ diff --git a/test/config/wfe2.json b/test/config/wfe2.json index c0093044..e8ba4263 100644 --- a/test/config/wfe2.json +++ b/test/config/wfe2.json -@@ -56,18 +56,6 @@ +@@ -56,26 +56,6 @@ [ "/hierarchy/intermediate-cert-rsa-a.pem", "/hierarchy/root-cert-rsa.pem" @@ -18,6 +18,14 @@ index c0093044..e8ba4263 100644 - [ - "/hierarchy/intermediate-cert-ecdsa-b.pem", - "/hierarchy/root-cert-ecdsa.pem" +- ], +- [ +- "/hierarchy/intermediate-cross-cert-ecdsa-a.pem", +- "/hierarchy/root-cert-rsa.pem" +- ], +- [ +- "/hierarchy/intermediate-cross-cert-ecdsa-b.pem", +- "/hierarchy/root-cert-rsa.pem" ] ], "staleTimeout": "5m", diff --git a/patches/linter_linter.patch b/patches/linter_linter.patch index de5c944..3aa8ddb 100644 --- a/patches/linter_linter.patch +++ b/patches/linter_linter.patch @@ -1,8 +1,8 @@ diff --git a/linter/linter.go b/linter/linter.go -index cf8c93cad..76d3c7dab 100644 +index 82c3e238..bda07bd9 100644 --- a/linter/linter.go +++ b/linter/linter.go -@@ -184,10 +184,21 @@ func makeIssuer(realIssuer *x509.Certificate, lintSigner crypto.Signer) (*x509.C +@@ -194,10 +194,21 @@ func makeIssuer(realIssuer *x509.Certificate, lintSigner crypto.Signer) (*x509.C SubjectKeyId: realIssuer.SubjectKeyId, URIs: realIssuer.URIs, UnknownExtKeyUsage: realIssuer.UnknownExtKeyUsage, diff --git a/patches/ra_ra.patch b/patches/ra_ra.patch index dd39016..ca45ae8 100644 --- a/patches/ra_ra.patch +++ b/patches/ra_ra.patch @@ -1,8 +1,8 @@ diff --git a/ra/ra.go b/ra/ra.go -index fb881c4ed..0bb0a317a 100644 +index 21c7c2fc..348146f4 100644 --- a/ra/ra.go +++ b/ra/ra.go -@@ -43,7 +43,6 @@ import ( +@@ -41,7 +41,6 @@ import ( "github.com/letsencrypt/boulder/issuance" blog "github.com/letsencrypt/boulder/log" "github.com/letsencrypt/boulder/metrics" @@ -10,7 +10,7 @@ index fb881c4ed..0bb0a317a 100644 "github.com/letsencrypt/boulder/probs" pubpb "github.com/letsencrypt/boulder/publisher/proto" rapb "github.com/letsencrypt/boulder/ra/proto" -@@ -531,7 +530,7 @@ func (ra *RegistrationAuthorityImpl) validateContacts(contacts []string) error { +@@ -540,7 +539,7 @@ func (ra *RegistrationAuthorityImpl) validateContacts(contacts []string) error { contact, ) } diff --git a/patches/ratelimit_rate-limits.patch b/patches/ratelimit_rate-limits.patch index a8e2735..49ae949 100644 --- a/patches/ratelimit_rate-limits.patch +++ b/patches/ratelimit_rate-limits.patch @@ -1,16 +1,16 @@ diff --git a/ratelimit/rate-limits.go b/ratelimit/rate-limits.go -index 35c981bc..5fc6f2ff 100644 +index bbca3dc4..37d08b66 100644 --- a/ratelimit/rate-limits.go +++ b/ratelimit/rate-limits.go -@@ -21,6 +21,7 @@ type Limits interface { - PendingOrdersPerAccount() RateLimitPolicy +@@ -56,6 +56,7 @@ type Limits interface { + CertificatesPerFQDNSetFast() RateLimitPolicy NewOrdersPerAccount() RateLimitPolicy LoadPolicies(contents []byte) error + RateLimitsURL() string } // limitsImpl is an unexported implementation of the Limits interface. It acts -@@ -113,6 +114,15 @@ func (r *limitsImpl) NewOrdersPerAccount() RateLimitPolicy { +@@ -139,6 +140,15 @@ func (r *limitsImpl) NewOrdersPerAccount() RateLimitPolicy { return r.rlPolicy.NewOrdersPerAccount } @@ -26,7 +26,7 @@ index 35c981bc..5fc6f2ff 100644 // LoadPolicies loads various rate limiting policies from a byte array of // YAML configuration (typically read from disk by a reloader) func (r *limitsImpl) LoadPolicies(contents []byte) error { -@@ -170,6 +180,8 @@ type rateLimitConfig struct { +@@ -193,6 +203,8 @@ type rateLimitConfig struct { // lower threshold and smaller window), so that clients don't have to wait // a long time after a small burst of accidental duplicate issuance. CertificatesPerFQDNSetFast RateLimitPolicy `yaml:"certificatesPerFQDNSetFast"` diff --git a/patches/test_config_ca_a.patch b/patches/test_config_ca_a.patch index 50c7f10..4a92147 100644 --- a/patches/test_config_ca_a.patch +++ b/patches/test_config_ca_a.patch @@ -2,15 +2,10 @@ diff --git a/test/config/ca-a.json b/test/config/ca-a.json index 1233a9c95..3c4a0a3ca 100644 --- a/test/config/ca-a.json +++ b/test/config/ca-a.json -@@ -61,30 +61,7 @@ - "crlURL": "http://example.com/crl", - "location": { - "configFile": "test/test-ca.key-pkcs11.json", -- "certFile": "/hierarchy/intermediate-cert-rsa-a.pem", -- "numSessions": 2 -- } -- }, -- { +@@ -54,17 +54,6 @@ + }, + "issuers": [ + { - "useForRSALeaves": false, - "useForECDSALeaves": true, - "issuerURL": "http://127.0.0.1:4001/aia/issuer/5214744660557630", @@ -21,6 +16,18 @@ index 1233a9c95..3c4a0a3ca 100644 - "numSessions": 2 - } - }, +- { + "useForRSALeaves": true, + "useForECDSALeaves": true, + "issuerURL": "http://127.0.0.1:4001/aia/issuer/6605440498369741", +@@ -72,19 +61,7 @@ + "crlURL": "http://example.com/crl", + "location": { + "configFile": "test/test-ca.key-pkcs11.json", +- "certFile": "/hierarchy/intermediate-cert-rsa-a.pem", +- "numSessions": 2 +- } +- }, - { - "useForRSALeaves": false, - "useForECDSALeaves": false, diff --git a/patches/test_config_ca_b.patch b/patches/test_config_ca_b.patch index ff16c86..b44f5b5 100644 --- a/patches/test_config_ca_b.patch +++ b/patches/test_config_ca_b.patch @@ -2,15 +2,10 @@ diff --git a/test/config/ca-b.json b/test/config/ca-b.json index 960d62f95..54b25dd81 100644 --- a/test/config/ca-b.json +++ b/test/config/ca-b.json -@@ -61,30 +61,7 @@ - "crlURL": "http://example.com/crl", - "location": { - "configFile": "test/test-ca.key-pkcs11.json", -- "certFile": "/hierarchy/intermediate-cert-rsa-a.pem", -- "numSessions": 2 -- } -- }, -- { +@@ -54,17 +54,6 @@ + }, + "issuers": [ + { - "useForRSALeaves": false, - "useForECDSALeaves": true, - "issuerURL": "http://127.0.0.1:4001/aia/issuer/5214744660557630", @@ -21,6 +16,18 @@ index 960d62f95..54b25dd81 100644 - "numSessions": 2 - } - }, +- { + "useForRSALeaves": true, + "useForECDSALeaves": true, + "issuerURL": "http://127.0.0.1:4001/aia/issuer/6605440498369741", +@@ -72,19 +61,7 @@ + "crlURL": "http://example.com/crl", + "location": { + "configFile": "test/test-ca.key-pkcs11.json", +- "certFile": "/hierarchy/intermediate-cert-rsa-a.pem", +- "numSessions": 2 +- } +- }, - { - "useForRSALeaves": false, - "useForECDSALeaves": false, diff --git a/patches/updater_continuous.patch b/patches/updater_continuous.patch new file mode 100644 index 0000000..830647e --- /dev/null +++ b/patches/updater_continuous.patch @@ -0,0 +1,42 @@ +diff --git a/crl/updater/continuous.go b/crl/updater/continuous.go +index c4b8f1a4..d78ebf18 100644 +--- a/crl/updater/continuous.go ++++ b/crl/updater/continuous.go +@@ -4,6 +4,7 @@ import ( + "context" + "math/big" + "math/rand" ++ "os" + "sync" + "time" + +@@ -17,6 +18,29 @@ import ( + func (cu *crlUpdater) Run(ctx context.Context) error { + var wg sync.WaitGroup + ++ // If there is no .crl file yet, generate one (after a delay to let all other ++ // components start up fully). ++ // Dirty hack to check filesystem directly instead of using the crl-storer... ++ files, err := os.ReadDir("/opt/wwwstatic/crl/") ++ if err != nil { ++ return err ++ } ++ present := false ++ for _, file := range files { ++ if file.Name() != "root-ca.crl" { ++ present = true ++ } ++ } ++ if !present { ++ select { ++ case <-ctx.Done(): ++ return ctx.Err() ++ case <-time.After(2 * time.Minute): ++ } ++ ++ cu.RunOnce(ctx, cu.clk.Now()) ++ } ++ + shardWorker := func(issuerNameID issuance.IssuerNameID, shardIdx int) { + defer wg.Done() + diff --git a/patches/updater_updater.patch b/patches/updater_updater.patch index 660e697..de00020 100644 --- a/patches/updater_updater.patch +++ b/patches/updater_updater.patch @@ -1,55 +1,8 @@ diff --git a/crl/updater/updater.go b/crl/updater/updater.go -index 678f15ce9..df3cdc2f5 100644 +index 7df31371..da92a3d3 100644 --- a/crl/updater/updater.go +++ b/crl/updater/updater.go -@@ -8,6 +8,7 @@ import ( - "io" - "math" - "math/big" -+ "os" - "sort" - "strings" - "time" -@@ -136,6 +137,29 @@ func NewUpdater( - // next scheduled run time based on the current time and the updateOffset, then - // begins running once every updatePeriod. - func (cu *crlUpdater) Run(ctx context.Context) error { -+ // If there is no .crl file yet, generate one (after a delay to let all other -+ // components start up fully). -+ // Dirty hack to check filesystem directly instead of using the crl-storer... -+ files, err := os.ReadDir("/opt/wwwstatic/crl/") -+ if err != nil { -+ return err -+ } -+ present := false -+ for _, file := range files { -+ if file.Name() != "root-ca.crl" { -+ present = true -+ } -+ } -+ if !present { -+ select { -+ case <-ctx.Done(): -+ return ctx.Err() -+ case <-time.After(2 * time.Minute): -+ } -+ -+ cu.Tick(ctx, cu.clk.Now()) -+ } -+ - // We don't want the times at which crlUpdater runs to be dependent on when - // the process starts. So wait until the appropriate time before kicking off - // the first run and the main ticker loop. -@@ -157,7 +181,7 @@ func (cu *crlUpdater) Run(ctx context.Context) error { - // counting from the appropriate time. - ticker := time.NewTicker(cu.updatePeriod) - atTime := cu.clk.Now() -- err := cu.Tick(ctx, atTime) -+ err = cu.Tick(ctx, atTime) - if err != nil { - // We only log, rather than return, so that the long-lived process can - // continue and try again at the next tick. -@@ -398,7 +422,7 @@ func (cu *crlUpdater) tickShard(ctx context.Context, atTime time.Time, issuerNam +@@ -228,7 +228,7 @@ func (cu *crlUpdater) updateShard(ctx context.Context, atTime time.Time, issuerN crlEntries = append(crlEntries, entry) }