Bump boulder version to release-2024-06-10

This commit is contained in:
Arjan H
2024-08-26 20:16:12 +02:00
parent 770db94f42
commit 18b53030a1
25 changed files with 269 additions and 145 deletions

2
build/.env.sample Normal file
View File

@@ -0,0 +1,2 @@
# You can use a .env file to set variables used in the docker-compose.yml file, e.g.:
LABCA_FQDN=ca.test.internal

View File

@@ -1,4 +1,4 @@
FROM letsencrypt/boulder-tools:go1.22.3_2024-05-13 AS boulder-tools
FROM letsencrypt/boulder-tools:go1.22.3_2024-05-22 AS boulder-tools
FROM ubuntu:focal
@@ -6,6 +6,7 @@ RUN apt-get update && \
apt-get install -y --no-install-recommends \
ca-certificates \
mariadb-client-core-10.3 \
net-tools \
python3-pip \
rsyslog \
softhsm2 \

View File

@@ -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-2024-05-20"
boulderTag="release-2024-06-10"
boulderUrl="https://github.com/letsencrypt/boulder/"
cloneDir=$(pwd)/..

View File

@@ -51,6 +51,7 @@ services:
depends_on:
- bmysql
- bconsul
- bpkilint
- control
entrypoint: labca/entrypoint.sh
working_dir: &boulder_working_dir /opt/boulder
@@ -178,6 +179,13 @@ services:
command: ./control.sh
restart: always
bpkilint:
image: ghcr.io/digicert/pkilint:v0.10.1
networks:
bouldernet:
ipv4_address: 10.77.77.9
command: "gunicorn -w 1 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:80 pkilint.rest:app"
volumes:
dbdata:
nginx_conf:

View File

@@ -1,5 +1,5 @@
diff --git a/docker-compose.yml b/docker-compose.yml
index 08d29d67c..33503bdfd 100644
index 1bffccd61..f7860d6f9 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -4,7 +4,7 @@ services:
@@ -27,15 +27,15 @@ index 08d29d67c..33503bdfd 100644
networks:
bouldernet:
ipv4_address: 10.77.77.77
@@ -52,6 +51,7 @@ services:
depends_on:
@@ -53,6 +52,7 @@ services:
- bmysql
- bconsul
- bpkilint
+ - control
entrypoint: labca/entrypoint.sh
working_dir: &boulder_working_dir /opt/boulder
logging:
@@ -62,12 +62,11 @@ services:
@@ -63,12 +63,11 @@ services:
restart: always
bsetup:
@@ -52,7 +52,7 @@ index 08d29d67c..33503bdfd 100644
entrypoint: labca/certs/generate.sh
working_dir: *boulder_working_dir
profiles:
@@ -101,34 +100,39 @@ services:
@@ -102,34 +101,39 @@ services:
bconsul:
image: hashicorp/consul:1.15.4
@@ -102,7 +102,7 @@ index 08d29d67c..33503bdfd 100644
logging:
driver: "json-file"
options:
@@ -145,27 +149,27 @@ services:
@@ -146,27 +150,27 @@ services:
- 80:80
- 443:443
volumes:
@@ -145,7 +145,7 @@ index 08d29d67c..33503bdfd 100644
expose:
- 3030
environment:
@@ -176,6 +180,15 @@ services:
@@ -184,6 +188,15 @@ services:
volumes:
dbdata:

View File

@@ -39,10 +39,11 @@ read txt
case $txt in
"docker-restart")
cd /opt/boulder
COMPOSE_HTTP_TIMEOUT=120 docker compose restart boulder bmysql bconsul gui nginx &>>$LOGFILE
COMPOSE_HTTP_TIMEOUT=120 docker compose restart boulder bmysql bconsul bpkilint gui nginx &>>$LOGFILE
sleep 45
wait_up $PS_MYSQL &>>$LOGFILE
wait_up $PS_CONSUL 2 &>>$LOGFILE
wait_up $PS_PKILINT 2 &>>$LOGFILE
wait_up $PS_LABCA &>>$LOGFILE
wait_up $PS_BOULDER $PS_BOULDER_COUNT &>>$LOGFILE
;;
@@ -146,7 +147,8 @@ case $txt in
labca=$(docker inspect $(docker ps --format "{{.Names}}" | grep -- labca-gui) | grep -i started | grep -v depends_on | sed -e "s/[^:]*:\(.*\)/\1/" | sed -e "s/.*\"\(.*\)\".*/\1/")
mysql=$(docker inspect $(docker ps --format "{{.Names}}" | grep -- -bmysql-) | grep -i started | grep -v depends_on | sed -e "s/[^:]*:\(.*\)/\1/" | sed -e "s/.*\"\(.*\)\".*/\1/")
consul=$(docker inspect $(docker ps --format "{{.Names}}" | grep -- -bconsul-) | grep -i started | grep -v depends_on | sed -e "s/[^:]*:\(.*\)/\1/" | sed -e "s/.*\"\(.*\)\".*/\1/")
echo "$nginx|$svc|$boulder|$labca|$mysql|$consul"
pkilint=$(docker inspect $(docker ps --format "{{.Names}}" | grep -- -bpkilint-) | grep -i started | grep -v depends_on | sed -e "s/[^:]*:\(.*\)/\1/" | sed -e "s/.*\"\(.*\)\".*/\1/")
echo "$nginx|$svc|$boulder|$labca|$mysql|$consul|$pkilint"
exit 0
;;
"log-uptime")
@@ -171,26 +173,29 @@ case $txt in
;;
"boulder-start")
cd /opt/boulder
COMPOSE_HTTP_TIMEOUT=120 docker compose up -d bmysql bconsul
COMPOSE_HTTP_TIMEOUT=120 docker compose up -d bmysql bconsul bpkilint
wait_up $PS_MYSQL &>>$LOGFILE
wait_up $PS_CONSUL 2 &>>$LOGFILE
wait_up $PS_PKILINT 2 &>>$LOGFILE
COMPOSE_HTTP_TIMEOUT=120 docker compose up -d boulder
wait_up $PS_BOULDER $PS_BOULDER_COUNT &>>$LOGFILE
;;
"boulder-stop")
cd /opt/boulder
docker compose stop boulder
docker compose stop bmysql bconsul
docker compose stop bmysql bconsul bpkilint
wait_down $PS_MYSQL &>>$LOGFILE
wait_down $PS_CONSUL &>>$LOGFILE
wait_down $PS_PKILINT &>>$LOGFILE
wait_down $PS_BOULDER &>>$LOGFILE
;;
"boulder-restart")
cd /opt/boulder
COMPOSE_HTTP_TIMEOUT=120 docker compose restart boulder bmysql bconsul &>>$LOGFILE
COMPOSE_HTTP_TIMEOUT=120 docker compose restart boulder bmysql bconsul bpkilint &>>$LOGFILE
sleep 30
wait_up $PS_MYSQL &>>$LOGFILE
wait_up $PS_CONSUL 2 &>>$LOGFILE
wait_up $PS_PKILINT 2 &>>$LOGFILE
wait_up $PS_BOULDER $PS_BOULDER_COUNT &>>$LOGFILE
;;
"labca-restart")
@@ -211,6 +216,12 @@ case $txt in
COMPOSE_HTTP_TIMEOUT=120 docker compose restart bconsul
set -e
;;
"pkilint-restart")
cd /opt/boulder
set +e
COMPOSE_HTTP_TIMEOUT=120 docker compose restart bpkilint
set -e
;;
"log-backups")
ls -1tr /opt/backup || /bin/true
exit 0

View File

@@ -74,6 +74,8 @@ if ([ "$PKI_DOMAIN_MODE" == "lockdown" ] && [ "$PKI_LOCKDOWN_DOMAINS" != "" ]) |
perl -i -p0e "s/(\"badResultsOnly\":[^\n]*).*?(\s+)(\"checkPeriod\":)/\1\2\"skipForbiddenDomains\": true,\2\3/igs" config/cert-checker.json
perl -i -p0e "s/(\"ignoredLints\": \[).*?(\s+)(\"w_subject_common_name_included\")/\1\2\"e_dnsname_not_valid_tld\",\2\3/igs" config/cert-checker.json
perl -i -p0e "s/(\"ignoredLints\": \[).*?(\s+)(\"w_subject_common_name_included\")/\1\2\"e_dnsname_not_valid_tld\",\2\3/igs" config/ca.json
perl -i -p0e "s/(\"SubscriberKeyUsageValidator:cabf.serverauth.subscriber_rsa_digitalsignature_and_keyencipherment_present\",).*(\])/\1\n \"GeneralNameDnsNameInternalDomainNameValidator:cabf.internal_domain_name\",\n \"GeneralNameUriInternalDomainNameValidator:cabf.internal_domain_name\",\n\2/igs" config/zlint.toml
fi
[ -e ../test/hostname-policy.yaml ] && cp ../test/hostname-policy.yaml ./ || true
@@ -161,7 +163,7 @@ rm -f config/orphan-finder.json
rm -f config/ca-a.json
rm -f config/ca-b.json
sed -i -e "s|\"issuerURL\": \".*\"|\"issuerURL\": \"http://$PKI_FQDN/aia/issuer/$PKI_ISSUER_NAME_ID\"|" config/ca.json
sed -i -e "s|\"issuerURL\": \".*\"|\"issuerURL\": \"http://$PKI_FQDN/certs/ca-int.pem\"|" config/ca.json
sed -i -e "s|\"ocspURL\": \".*\"|\"ocspURL\": \"http://$PKI_FQDN/ocsp/\"|" config/ca.json
sed -i -e "s|\"crlURLBase\": \".*\"|\"crlURLBase\": \"http://$PKI_FQDN/crl/\"|" config/ca.json
@@ -175,6 +177,10 @@ if [ "$PKI_EXTENDED_TIMEOUT" == "1" ]; then
sed -i -e "s/\"timeout\": \"20s\"/\"timeout\": \"40s\"/" config/ra.json
sed -i -e "s/\"timeout\": \"15s\"/\"timeout\": \"30s\"/" config/crl-storer.json
sed -i -e "s/\"timeout\": \"15s\"/\"timeout\": \"30s\"/" config/crl-updater.json
sed -i -e "s/pkilint_timeout = .*/pkilint_timeout = 30000000000 # 30 seconds/" config/zlint.toml
else
sed -i -e "s/pkilint_timeout = .*/pkilint_timeout = 10000000000 # 10 seconds/" config/zlint.toml
fi
sed -i -e "s/\"timeout\": \"1s\"/\"timeout\": \"5s\"/" config/health-checker.json

View File

@@ -30,7 +30,7 @@ dockerComposeVersion="v2.5.0"
labcaUrl="https://github.com/hakwerk/labca/"
boulderUrl="https://github.com/letsencrypt/boulder/"
boulderTag="release-2024-05-20"
boulderTag="release-2024-06-10"
# Feature flags
flag_skip_redis=true
@@ -773,6 +773,7 @@ startup() {
wait_down $PS_NGINX &>>$installLog || true
wait_down $PS_MYSQL &>>$installLog || true
wait_down $PS_CONSUL &>>$installLog || true
wait_down $PS_PKILINT &>>$installLog || true
wait_down $PS_LABCA &>>$installLog || true
wait_down $PS_CONTROL &>>$installLog || true
wait_down $PS_BOULDER &>>$installLog || true
@@ -807,6 +808,7 @@ startup() {
wait_up $PS_NGINX &>>$installLog || true
wait_up $PS_MYSQL &>>$installLog || true
wait_up $PS_CONSUL 2 &>>$installLog || true
wait_up $PS_PKILINT &>>$installLog || true
wait_up $PS_LABCA &>>$installLog || true
wait_up $PS_CONTROL &>>$installLog || true
docker exec -i labca-bmysql-1 mysql_upgrade &>>$installLog

View File

@@ -58,6 +58,7 @@ $SUDO patch -p1 < $cloneDir/patches/updater_continuous.patch
$SUDO patch -p1 < $cloneDir/patches/va_http.patch
$SUDO patch -p1 < $cloneDir/patches/va_va.patch
$SUDO patch -p1 < $cloneDir/patches/wfe2_main.patch
$SUDO patch -p1 < $cloneDir/patches/wfe2_wfe.patch
sed -i -e "s|./test|./labca|" start.py

View File

@@ -1,8 +1,8 @@
diff --git a/ca/ca.go b/ca/ca.go
index 252fa87d9..6630b731c 100644
index 239a5a4c3..775ffa8a4 100644
--- a/ca/ca.go
+++ b/ca/ca.go
@@ -118,10 +118,10 @@ func makeIssuerMaps(issuers []*issuance.Issuer) (issuerMaps, error) {
@@ -160,10 +160,10 @@ func makeIssuerMaps(issuers []*issuance.Issuer) (issuerMaps, error) {
}
}
if i, ok := issuersByAlg[x509.ECDSA]; !ok || len(i) == 0 {

View File

@@ -1,8 +1,8 @@
diff --git a/ca/crl.go b/ca/crl.go
index 35bf4c07d..36316235e 100644
index 5937046fe..15c144984 100644
--- a/ca/crl.go
+++ b/ca/crl.go
@@ -122,8 +122,10 @@ func (ci *crlImpl) GenerateCRL(stream capb.CRLGenerator_GenerateCRLServer) error
@@ -132,8 +132,10 @@ func (ci *crlImpl) GenerateCRL(stream grpc.BidiStreamingServer[capb.GenerateCRLR
builder = strings.Builder{}
}
}

View File

@@ -1,42 +0,0 @@
diff --git a/test/config/ca.json b/test/config/ca.json
index cbb84f385..ec28cd37d 100644
--- a/test/config/ca.json
+++ b/test/config/ca.json
@@ -58,18 +58,6 @@
"maxValidityBackdate": "1h5m"
},
"issuers": [
- {
- "useForRSALeaves": false,
- "useForECDSALeaves": true,
- "issuerURL": "http://ca.example.org:4502/int-ecdsa-a",
- "ocspURL": "http://ca.example.org:4002/",
- "crlURLBase": "http://ca.example.org:4501/ecdsa-a/",
- "location": {
- "configFile": "test/certs/webpki/int-ecdsa-a.pkcs11.json",
- "certFile": "test/certs/webpki/int-ecdsa-a.cert.pem",
- "numSessions": 2
- }
- },
{
"useForRSALeaves": true,
"useForECDSALeaves": true,
@@ -81,18 +69,6 @@
"certFile": "test/certs/webpki/int-rsa-a.cert.pem",
"numSessions": 2
}
- },
- {
- "useForRSALeaves": false,
- "useForECDSALeaves": false,
- "issuerURL": "http://ca.example.org:4502/int-rsa-b",
- "ocspURL": "http://ca.example.org:4003/",
- "crlURLBase": "http://ca.example.org:4501/rsa-b/",
- "location": {
- "configFile": "test/certs/webpki/int-rsa-b.pkcs11.json",
- "certFile": "test/certs/webpki/int-rsa-b.cert.pem",
- "numSessions": 2
- }
}
],
"ignoredLints": [

View File

@@ -1,8 +1,16 @@
diff --git a/test/config/wfe2.json b/test/config/wfe2.json
index c0093044..e8ba4263 100644
index 05d46fe95..c0e4a2a27 100644
--- a/test/config/wfe2.json
+++ b/test/config/wfe2.json
@@ -79,26 +79,6 @@
@@ -12,6 +12,7 @@
"debugAddr": ":8013",
"directoryCAAIdentity": "happy-hacker-ca.invalid",
"directoryWebsite": "https://github.com/letsencrypt/boulder",
+ "hostnamePolicyFile": "test/hostname-policy.yaml",
"legacyKeyIDPrefix": "http://boulder.service.consul:4000/reg/",
"goodkey": {
"blockedKeyFile": "test/example-blocked-keys.yaml"
@@ -79,26 +80,6 @@
[
"test/certs/webpki/int-rsa-a.cert.pem",
"test/certs/webpki/root-rsa.cert.pem"

View File

@@ -1,5 +1,5 @@
diff --git a/docker-compose.yml b/docker-compose.yml
index 79ed8c4e4..08d29d67c 100644
index 79ed8c4e4..3562b8fb8 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,3 +1,4 @@
@@ -26,14 +26,14 @@ index 79ed8c4e4..08d29d67c 100644
networks:
bouldernet:
ipv4_address: 10.77.77.77
@@ -48,20 +51,24 @@ services:
@@ -48,20 +51,25 @@ services:
- 4003:4003 # OCSP
depends_on:
- bmysql
- - bproxysql
- bconsul
- - bjaeger
- - bpkilint
- bpkilint
- entrypoint: test/entrypoint.sh
- working_dir: &boulder_working_dir /boulder
+ entrypoint: labca/entrypoint.sh
@@ -59,7 +59,7 @@ index 79ed8c4e4..08d29d67c 100644
working_dir: *boulder_working_dir
profiles:
# Adding a profile to this container means that it won't be started by a
@@ -71,6 +78,8 @@ services:
@@ -71,6 +79,8 @@ services:
bmysql:
image: mariadb:10.5
@@ -68,7 +68,7 @@ index 79ed8c4e4..08d29d67c 100644
networks:
bouldernet:
aliases:
@@ -84,46 +93,89 @@ services:
@@ -84,46 +94,96 @@ services:
# small.
command: mysqld --bind-address=0.0.0.0 --slow-query-log --log-output=TABLE --log-queries-not-using-indexes=ON
logging:
@@ -136,16 +136,11 @@ index 79ed8c4e4..08d29d67c 100644
+ max-size: "500k"
+ max-file: "5"
+ restart: always
- bpkilint:
- image: ghcr.io/digicert/pkilint:v0.10.1
+
+ nginx:
+ image: nginx:1.26.0
+ restart: always
networks:
- bouldernet:
- ipv4_address: 10.77.77.9
- command: "gunicorn -w 8 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:80 pkilint.rest:app"
+ networks:
+ - bouldernet
+ ports:
+ - 80:80
@@ -179,6 +174,14 @@ index 79ed8c4e4..08d29d67c 100644
+ working_dir: /opt/labca
+ command: ./control.sh
+ restart: always
bpkilint:
image: ghcr.io/digicert/pkilint:v0.10.1
networks:
bouldernet:
ipv4_address: 10.77.77.9
- command: "gunicorn -w 8 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:80 pkilint.rest:app"
+ command: "gunicorn -w 1 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:80 pkilint.rest:app"
+
+volumes:
+ dbdata:

View File

@@ -1,5 +1,5 @@
diff --git a/cmd/expiration-mailer/main.go b/cmd/expiration-mailer/main.go
index e1014ebab..4cf2fdbfc 100644
index 46fa939a6..03a9e6ae3 100644
--- a/cmd/expiration-mailer/main.go
+++ b/cmd/expiration-mailer/main.go
@@ -23,6 +23,7 @@ import (
@@ -33,7 +33,7 @@ index e1014ebab..4cf2fdbfc 100644
if err != nil {
m.log.Debugf("skipping invalid email %q: %s", address, err)
continue
@@ -698,6 +703,11 @@ type Config struct {
@@ -701,6 +706,11 @@ type Config struct {
TLS cmd.TLSConfig
SAService *cmd.GRPCClientConfig
@@ -45,7 +45,7 @@ index e1014ebab..4cf2fdbfc 100644
// Path to a file containing a list of trusted root certificates for use
// during the SMTP connection (as opposed to the gRPC connections).
SMTPTrustedRootFile string
@@ -851,6 +861,30 @@ func main() {
@@ -854,6 +864,30 @@ func main() {
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA")
sac := sapb.NewStorageAuthorityClient(conn)
@@ -76,7 +76,7 @@ index e1014ebab..4cf2fdbfc 100644
var smtpRoots *x509.CertPool
if c.Mailer.SMTPTrustedRootFile != "" {
pem, err := os.ReadFile(c.Mailer.SMTPTrustedRootFile)
@@ -886,6 +920,7 @@ func main() {
@@ -889,6 +923,7 @@ func main() {
c.Mailer.Username,
smtpPassword,
smtpRoots,

View File

@@ -1,8 +1,8 @@
diff --git a/linter/linter.go b/linter/linter.go
index 07ac8b029..bd0abd93e 100644
index e9bf33b85..e88cc6b7f 100644
--- a/linter/linter.go
+++ b/linter/linter.go
@@ -199,10 +199,21 @@ func makeIssuer(realIssuer *x509.Certificate, lintSigner crypto.Signer) (*x509.C
@@ -200,10 +200,21 @@ func makeIssuer(realIssuer *x509.Certificate, lintSigner crypto.Signer) (*x509.C
SubjectKeyId: realIssuer.SubjectKeyId,
URIs: realIssuer.URIs,
UnknownExtKeyUsage: realIssuer.UnknownExtKeyUsage,

View File

@@ -1,5 +1,5 @@
diff --git a/policy/pa.go b/policy/pa.go
index d872d5cbe..faa052d6c 100644
index ce7857a7d..ef29cb60e 100644
--- a/policy/pa.go
+++ b/policy/pa.go
@@ -32,6 +32,9 @@ type AuthorityImpl struct {
@@ -49,12 +49,12 @@ index d872d5cbe..faa052d6c 100644
// - exactly equal to an IANA registered TLD
//
// It does NOT ensure that the domain is absent from any PA blocked lists.
-func ValidNonWildcardDomain(domain string) error {
-func validNonWildcardDomain(domain string) error {
+func (pa *AuthorityImpl) ValidNonWildcardDomain(domain string, isContact bool) error {
if domain == "" {
return errEmptyName
}
@@ -235,7 +253,9 @@ func ValidNonWildcardDomain(domain string) error {
@@ -235,7 +253,9 @@ func validNonWildcardDomain(domain string) error {
return errTooManyLabels
}
if len(labels) < 2 {
@@ -65,7 +65,7 @@ index d872d5cbe..faa052d6c 100644
}
for _, label := range labels {
// Check that this is a valid LDH Label: "A string consisting of ASCII
@@ -279,6 +299,14 @@ func ValidNonWildcardDomain(domain string) error {
@@ -279,6 +299,14 @@ func validNonWildcardDomain(domain string) error {
}
}
@@ -80,14 +80,14 @@ index d872d5cbe..faa052d6c 100644
// Names must end in an ICANN TLD, but they must not be equal to an ICANN TLD.
icannTLD, err := iana.ExtractSuffix(domain)
if err != nil {
@@ -294,9 +322,9 @@ func ValidNonWildcardDomain(domain string) error {
@@ -294,9 +322,9 @@ func validNonWildcardDomain(domain string) error {
// ValidDomain checks that a domain is valid and that it doesn't contain any
// invalid wildcard characters. It does NOT ensure that the domain is absent
// from any PA blocked lists.
-func ValidDomain(domain string) error {
+func (pa *AuthorityImpl) ValidDomain(domain string) error {
if strings.Count(domain, "*") <= 0 {
- return ValidNonWildcardDomain(domain)
- return validNonWildcardDomain(domain)
+ return pa.ValidNonWildcardDomain(domain, false)
}
@@ -105,7 +105,7 @@ index d872d5cbe..faa052d6c 100644
if baseDomain == icannTLD {
return errICANNTLDWildcard
}
- return ValidNonWildcardDomain(baseDomain)
- return validNonWildcardDomain(baseDomain)
+ return pa.ValidNonWildcardDomain(baseDomain, false)
}
@@ -123,38 +123,45 @@ index d872d5cbe..faa052d6c 100644
}
splitEmail := strings.SplitN(email.Address, "@", -1)
domain := strings.ToLower(splitEmail[len(splitEmail)-1])
- err = ValidNonWildcardDomain(domain)
- err = validNonWildcardDomain(domain)
+ err = pa.ValidNonWildcardDomain(domain, true)
if err != nil {
return berrors.InvalidEmailError(
"contact email %q has invalid domain : %s",
@@ -416,7 +444,7 @@ func (pa *AuthorityImpl) WillingToIssue(domains []string) error {
for _, domain := range domains {
if strings.Count(domain, "*") > 0 {
// Domain contains a wildcard, check that it is valid.
- err := ValidDomain(domain)
+ err := pa.ValidDomain(domain)
if err != nil {
appendSubError(domain, err)
continue
@@ -433,12 +461,15 @@ func (pa *AuthorityImpl) WillingToIssue(domains []string) error {
}
} else {
// Validate that the domain is well-formed.
- err := ValidNonWildcardDomain(domain)
+ err := pa.ValidNonWildcardDomain(domain, false)
if err != nil {
appendSubError(domain, err)
continue
@@ -395,7 +423,7 @@ func subError(name string, err error) berrors.SubBoulderError {
//
// Precondition: all input domain names must be in lowercase.
func (pa *AuthorityImpl) WillingToIssue(domains []string) error {
- err := WellFormedDomainNames(domains)
+ err := pa.WellFormedDomainNames(domains)
if err != nil {
return err
}
@@ -414,6 +442,10 @@ func (pa *AuthorityImpl) WillingToIssue(domains []string) error {
}
}
+ if ok, _ := pa.checkWhitelist(domain, false); ok {
+ return nil
+ }
// Require no match against hostname block lists
+
// For both wildcard and non-wildcard domains, check whether any parent domain
// name is on the regular blocklist.
err := pa.checkHostLists(domain)
@@ -447,10 +479,10 @@ func (pa *AuthorityImpl) WillingToIssue(domains []string) error {
//
// If multiple domains are invalid, the error will contain suberrors specific to
// each domain.
-func WellFormedDomainNames(domains []string) error {
+func (pa *AuthorityImpl) WellFormedDomainNames(domains []string) error {
var subErrors []berrors.SubBoulderError
for _, domain := range domains {
- err := ValidDomain(domain)
+ err := pa.ValidDomain(domain)
if err != nil {
@@ -471,6 +502,34 @@ func (pa *AuthorityImpl) WillingToIssue(domains []string) error {
subErrors = append(subErrors, subError(domain, err))
}
@@ -484,6 +516,34 @@ func combineSubErrors(subErrors []berrors.SubBoulderError) error {
return nil
}
@@ -189,7 +196,7 @@ index d872d5cbe..faa052d6c 100644
// checkWildcardHostList checks the wildcardExactBlocklist for a given domain.
// If the domain is not present on the list nil is returned, otherwise
// errPolicyForbidden is returned.
@@ -500,6 +559,9 @@ func (pa *AuthorityImpl) checkHostLists(domain string) error {
@@ -513,6 +573,9 @@ func (pa *AuthorityImpl) checkHostLists(domain string) error {
labels := strings.Split(domain, ".")
for i := range labels {
joined := strings.Join(labels[i:], ".")

View File

@@ -1,5 +1,5 @@
diff --git a/ra/ra.go b/ra/ra.go
index c5cdc0c98..8d34d3325 100644
index 300610496..906573e63 100644
--- a/ra/ra.go
+++ b/ra/ra.go
@@ -44,7 +44,6 @@ import (
@@ -10,7 +10,7 @@ index c5cdc0c98..8d34d3325 100644
"github.com/letsencrypt/boulder/probs"
pubpb "github.com/letsencrypt/boulder/publisher/proto"
rapb "github.com/letsencrypt/boulder/ra/proto"
@@ -576,7 +575,7 @@ func (ra *RegistrationAuthorityImpl) validateContacts(contacts []string) error {
@@ -578,7 +577,7 @@ func (ra *RegistrationAuthorityImpl) validateContacts(contacts []string) error {
contact,
)
}

View File

@@ -1,5 +1,5 @@
diff --git a/ratelimits/names.go b/ratelimits/names.go
index 0037363b0..c2ddc6076 100644
index fdfd8e81e..636720bf2 100644
--- a/ratelimits/names.go
+++ b/ratelimits/names.go
@@ -150,7 +150,11 @@ func validateRegId(id string) error {
@@ -28,17 +28,16 @@ index 0037363b0..c2ddc6076 100644
if err != nil {
return fmt.Errorf(
"invalid domain, %q must be formatted 'regId:domain': %w", id, err)
@@ -187,8 +195,12 @@ func validateFQDNSet(id string) error {
@@ -187,7 +195,11 @@ func validateFQDNSet(id string) error {
return fmt.Errorf(
"invalid fqdnSet, %q must be formatted 'fqdnSet'", id)
}
- return policy.WellFormedDomainNames(domains)
+ pa, err := policy.New(nil, nil)
+ if err != nil {
+ return fmt.Errorf("cannot create policy authority implementation")
+ }
for _, domain := range domains {
- err := policy.ValidDomain(domain)
+ err = pa.ValidDomain(domain)
if err != nil {
return fmt.Errorf(
"invalid domain, %q must be formatted 'fqdnSet': %w", id, err)
+ return pa.WellFormedDomainNames(domains)
}
func validateIdForName(name Name, id string) error {

View File

@@ -1,5 +1,5 @@
diff --git a/crl/storer/storer.go b/crl/storer/storer.go
index 10b1753c7..2cbc2eb17 100644
index 9b41f560f..70bd63a3c 100644
--- a/crl/storer/storer.go
+++ b/crl/storer/storer.go
@@ -9,8 +9,12 @@ import (
@@ -15,15 +15,15 @@ index 10b1753c7..2cbc2eb17 100644
"time"
"github.com/aws/aws-sdk-go-v2/service/s3"
@@ -38,6 +42,7 @@ type crlStorer struct {
cspb.UnimplementedCRLStorerServer
@@ -39,6 +43,7 @@ type crlStorer struct {
cspb.UnsafeCRLStorerServer
s3Client simpleS3
s3Bucket string
+ localStorePath string
issuers map[issuance.NameID]*issuance.Certificate
uploadCount *prometheus.CounterVec
sizeHistogram *prometheus.HistogramVec
@@ -50,6 +55,7 @@ func New(
@@ -53,6 +58,7 @@ func New(
issuers []*issuance.Certificate,
s3Client simpleS3,
s3Bucket string,
@@ -31,7 +31,7 @@ index 10b1753c7..2cbc2eb17 100644
stats prometheus.Registerer,
log blog.Logger,
clk clock.Clock,
@@ -83,6 +89,7 @@ func New(
@@ -86,6 +92,7 @@ func New(
issuers: issuersByNameID,
s3Client: s3Client,
s3Bucket: s3Bucket,
@@ -39,7 +39,7 @@ index 10b1753c7..2cbc2eb17 100644
uploadCount: uploadCount,
sizeHistogram: sizeHistogram,
latencyHistogram: latencyHistogram,
@@ -218,15 +225,19 @@ func (cs *crlStorer) UploadCRL(stream cspb.CRLStorer_UploadCRLServer) error {
@@ -221,15 +228,19 @@ func (cs *crlStorer) UploadCRL(stream grpc.ClientStreamingServer[cspb.UploadCRLR
checksum := sha256.Sum256(crlBytes)
checksumb64 := base64.StdEncoding.EncodeToString(checksum[:])
crlContentType := "application/pkix-crl"
@@ -68,7 +68,7 @@ index 10b1753c7..2cbc2eb17 100644
latency := cs.clk.Now().Sub(start)
cs.latencyHistogram.WithLabelValues(issuer.Subject.CommonName).Observe(latency.Seconds())
@@ -245,3 +256,46 @@ func (cs *crlStorer) UploadCRL(stream cspb.CRLStorer_UploadCRLServer) error {
@@ -248,3 +259,46 @@ func (cs *crlStorer) UploadCRL(stream grpc.ClientStreamingServer[cspb.UploadCRLR
return stream.SendAndClose(&emptypb.Empty{})
}

View File

@@ -1,14 +1,13 @@
diff --git a/test/config/ca.json b/test/config/ca.json
index cbb84f385..ec28cd37d 100644
index cc4728363..2eb95ad81 100644
--- a/test/config/ca.json
+++ b/test/config/ca.json
@@ -58,18 +58,6 @@
@@ -58,39 +58,6 @@
"maxValidityBackdate": "1h5m"
},
"issuers": [
- {
- "useForRSALeaves": false,
- "useForECDSALeaves": true,
- "active": true,
- "issuerURL": "http://ca.example.org:4502/int-ecdsa-a",
- "ocspURL": "http://ca.example.org:4002/",
- "crlURLBase": "http://ca.example.org:4501/ecdsa-a/",
@@ -17,26 +16,58 @@ index cbb84f385..ec28cd37d 100644
- "certFile": "test/certs/webpki/int-ecdsa-a.cert.pem",
- "numSessions": 2
- }
- },
- {
- "active": true,
- "issuerURL": "http://ca.example.org:4502/int-ecdsa-b",
- "ocspURL": "http://ca.example.org:4002/",
- "crlURLBase": "http://ca.example.org:4501/ecdsa-b/",
- "location": {
- "configFile": "test/certs/webpki/int-ecdsa-b.pkcs11.json",
- "certFile": "test/certs/webpki/int-ecdsa-b.cert.pem",
- "numSessions": 2
- }
- },
- {
- "active": false,
- "issuerURL": "http://ca.example.org:4502/int-ecdsa-c",
- "ocspURL": "http://ca.example.org:4002/",
- "crlURLBase": "http://ca.example.org:4501/ecdsa-c/",
- "location": {
- "configFile": "test/certs/webpki/int-ecdsa-c.pkcs11.json",
- "certFile": "test/certs/webpki/int-ecdsa-c.cert.pem",
- "numSessions": 2
- }
- },
{
"useForRSALeaves": true,
"useForECDSALeaves": true,
@@ -81,18 +69,6 @@
"active": true,
"issuerURL": "http://ca.example.org:4502/int-rsa-a",
@@ -101,28 +68,6 @@
"certFile": "test/certs/webpki/int-rsa-a.cert.pem",
"numSessions": 2
}
- },
- {
- "useForRSALeaves": false,
- "useForECDSALeaves": false,
- "active": true,
- "issuerURL": "http://ca.example.org:4502/int-rsa-b",
- "ocspURL": "http://ca.example.org:4003/",
- "ocspURL": "http://ca.example.org:4002/",
- "crlURLBase": "http://ca.example.org:4501/rsa-b/",
- "location": {
- "configFile": "test/certs/webpki/int-rsa-b.pkcs11.json",
- "certFile": "test/certs/webpki/int-rsa-b.cert.pem",
- "numSessions": 2
- }
- },
- {
- "active": false,
- "issuerURL": "http://ca.example.org:4502/int-rsa-c",
- "ocspURL": "http://ca.example.org:4002/",
- "crlURLBase": "http://ca.example.org:4501/rsa-c/",
- "location": {
- "configFile": "test/certs/webpki/int-rsa-c.pkcs11.json",
- "certFile": "test/certs/webpki/int-rsa-c.cert.pem",
- "numSessions": 2
- }
}
],
"ignoredLints": [
"lintConfig": "test/config/zlint.toml",

View File

@@ -1,8 +1,8 @@
diff --git a/va/va.go b/va/va.go
index dd743b593..b74a313f0 100644
index d43346bbc..e0784adcb 100644
--- a/va/va.go
+++ b/va/va.go
@@ -265,6 +265,7 @@ type ValidationAuthorityImpl struct {
@@ -256,6 +256,7 @@ type ValidationAuthorityImpl struct {
maxRemoteFailures int
accountURIPrefixes []string
singleDialTimeout time.Duration
@@ -10,7 +10,7 @@ index dd743b593..b74a313f0 100644
metrics *vaMetrics
}
@@ -280,6 +281,7 @@ func NewValidationAuthorityImpl(
@@ -274,6 +275,7 @@ func NewValidationAuthorityImpl(
clk clock.Clock,
logger blog.Logger,
accountURIPrefixes []string,
@@ -18,7 +18,7 @@ index dd743b593..b74a313f0 100644
) (*ValidationAuthorityImpl, error) {
if len(accountURIPrefixes) == 0 {
@@ -306,6 +308,7 @@ func NewValidationAuthorityImpl(
@@ -300,6 +302,7 @@ func NewValidationAuthorityImpl(
// used for the DialContext operations that take place during an
// HTTP-01 challenge validation.
singleDialTimeout: 10 * time.Second,

View File

@@ -1,8 +1,8 @@
diff --git a/cmd/boulder-wfe2/main.go b/cmd/boulder-wfe2/main.go
index 13e362c8..c16b0c56 100644
index 83ff247f8..8f0449b9f 100644
--- a/cmd/boulder-wfe2/main.go
+++ b/cmd/boulder-wfe2/main.go
@@ -106,7 +106,7 @@ type Config struct {
@@ -96,7 +96,7 @@ type Config struct {
// DirectoryCAAIdentity is used for the /directory response's "meta"
// element's "caaIdentities" field. It should match the VA's "issuerDomain"
// configuration value (this value is the one used to enforce CAA)
@@ -11,3 +11,20 @@ index 13e362c8..c16b0c56 100644
// DirectoryWebsite is used for the /directory response's "meta" element's
// "website" field.
DirectoryWebsite string `validate:"required,url"`
@@ -164,6 +164,8 @@ type Config struct {
// list will be rejected. This field is optional; if unset, no profile
// names are accepted.
CertificateProfileNames []string `validate:"omitempty,dive,alphanum,min=1,max=32"`
+
+ cmd.HostnamePolicyConfig
}
Syslog cmd.SyslogConfig
@@ -382,6 +384,7 @@ func main() {
txnBuilder,
maxNames,
c.WFE.CertificateProfileNames,
+ c.WFE.HostnamePolicyFile,
)
cmd.FailOnError(err, "Unable to create WFE")

63
patches/wfe2_wfe.patch Normal file
View File

@@ -0,0 +1,63 @@
diff --git a/wfe2/wfe.go b/wfe2/wfe.go
index 756cef2f2..0e95a1dc2 100644
--- a/wfe2/wfe.go
+++ b/wfe2/wfe.go
@@ -23,6 +23,7 @@ import (
"go.opentelemetry.io/otel/trace"
"google.golang.org/protobuf/types/known/emptypb"
+ "github.com/letsencrypt/boulder/cmd"
"github.com/letsencrypt/boulder/core"
corepb "github.com/letsencrypt/boulder/core/proto"
berrors "github.com/letsencrypt/boulder/errors"
@@ -169,6 +170,8 @@ type WebFrontEndImpl struct {
// passed to the newOrder endpoint. If a profile name is not in this list,
// the request will be rejected as malformed.
certificateProfileNames []string
+
+ hostnamePolicyFile string
}
// NewWebFrontEndImpl constructs a web service for Boulder
@@ -193,6 +196,7 @@ func NewWebFrontEndImpl(
txnBuilder *ratelimits.TransactionBuilder,
maxNames int,
certificateProfileNames []string,
+ hostnamePolicyFile string,
) (WebFrontEndImpl, error) {
if len(issuerCertificates) == 0 {
return WebFrontEndImpl{}, errors.New("must provide at least one issuer certificate")
@@ -231,6 +235,7 @@ func NewWebFrontEndImpl(
txnBuilder: txnBuilder,
maxNames: maxNames,
certificateProfileNames: certificateProfileNames,
+ hostnamePolicyFile: hostnamePolicyFile,
}
return wfe, nil
@@ -2337,7 +2342,24 @@ func (wfe *WebFrontEndImpl) NewOrder(
names[i] = ident.Value
}
- err = policy.WellFormedDomainNames(names)
+ logger := cmd.NewLogger(cmd.SyslogConfig{StdoutLevel: 7})
+ pa, err := policy.New(map[core.AcmeChallenge]bool{}, logger)
+ if err != nil {
+ wfe.sendError(response, logEvent, probs.Malformed("cannot create policy authority implementation"), nil)
+ return
+ }
+
+ if wfe.hostnamePolicyFile == "" {
+ wfe.sendError(response, logEvent, probs.Malformed("HostnamePolicyFile must be provided in config"), nil)
+ return
+ }
+ err = pa.LoadHostnamePolicyFile(wfe.hostnamePolicyFile)
+ if err != nil {
+ wfe.sendError(response, logEvent, probs.Malformed("couldn't load hostname policy file"), nil)
+ return
+ }
+
+ err = pa.WellFormedDomainNames(names)
if err != nil {
wfe.sendError(response, logEvent, web.ProblemDetailsForError(err, "Invalid identifiers requested"), nil)
return

View File

@@ -9,6 +9,7 @@ export PS_MYSQL="mysqld"
export PS_CONTROL="tcpserver"
export PS_NGINX="nginx:"
export PS_CONSUL="consul"
export PS_PKILINT="pkilint"
LOOPCOUNT=120
@@ -32,6 +33,9 @@ count() {
$PS_CONSUL)
prefix="docker exec $(docker ps --format "{{.Names}}" | grep -- -bconsul-) "
;;
$PS_PKILINT)
prefix="docker exec $(docker ps --format "{{.Names}}" | grep -- -bpkilint-) "
;;
*)
;;
esac
@@ -40,6 +44,9 @@ count() {
if [ "$pattern" == "$PS_CONSUL" ]; then
res=$(${prefix}ps -eo pid,args 2>/dev/null | grep "$pattern" | grep -v grep | wc -l)
fi
if [ "$pattern" == "$PS_PKILINT" ]; then
res=$(${prefix}ls -d /proc/[1-9]* 2>/dev/null | wc -l)
fi
echo $res
}