Bump boulder version to v0.20250707.0

This commit is contained in:
Arjan H
2025-07-12 20:25:18 +02:00
parent ec77c14f62
commit 1a5050b3b0
39 changed files with 386 additions and 887 deletions

View File

@@ -17,7 +17,7 @@ jobs:
fail-fast: false
matrix:
GO_VERSION:
- 1.24.1
- 1.24.4
steps:
- name: Checkout

View File

@@ -20,7 +20,7 @@ jobs:
fail-fast: false
matrix:
GO_VERSION:
- 1.24.1
- 1.24.4
steps:
- uses: actions/checkout@v4

View File

@@ -13,7 +13,7 @@ jobs:
fail-fast: false
matrix:
GO_VERSION:
- 1.24.1
- 1.24.4
steps:
- name: Checkout

View File

@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1
FROM letsencrypt/boulder-tools:go1.24.1_2025-04-30 AS boulder-tools
FROM letsencrypt/boulder-tools:go1.24.4_2025-06-06 AS boulder-tools
FROM ubuntu:noble

View File

@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1
FROM letsencrypt/boulder-tools:go1.24.1_2025-04-30 AS boulder-tools
FROM letsencrypt/boulder-tools:go1.24.4_2025-06-06 AS boulder-tools
FROM ubuntu:noble AS builder

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-2025-05-27"
boulderTag="v0.20250707.0"
boulderUrl="https://github.com/letsencrypt/boulder/"
cloneDir=$(pwd)/..

View File

@@ -12,9 +12,9 @@ services:
GO_VERSION: 1.24.1
environment:
# To solve HTTP-01 and TLS-ALPN-01 challenges, change the IP in FAKE_DNS
# to the IP address where your ACME client's solver is listening.
# FAKE_DNS: 172.17.0.1
FAKE_DNS: 10.77.77.77
# to the IP address where your ACME client's solver is listening. This is
# pointing at the boulder service's "public" IP, where challtestsrv is.
FAKE_DNS: 64.112.117.122
BOULDER_CONFIG_DIR: labca/config
GOCACHE: /boulder/.gocache/go-build
GOFLAGS: -mod=vendor
@@ -26,12 +26,10 @@ services:
networks:
bouldernet:
ipv4_address: 10.77.77.77
integrationtestnet:
ipv4_address: 10.88.88.88
redisnet:
ipv4_address: 10.33.33.33
consulnet:
ipv4_address: 10.55.55.55
publicnet:
ipv4_address: 64.112.117.122
publicnet2:
ipv4_address: 64.112.117.134
# Use consul as a backup to Docker's embedded DNS server. If there's a name
# Docker's DNS server doesn't know about, it will forward the query to this
# IP (running consul).
@@ -40,15 +38,17 @@ services:
# are configured via the ServerAddress field of cmd.GRPCClientConfig.
# TODO: Remove this when ServerAddress is deprecated in favor of SRV records
# and DNSAuthority.
dns: 10.55.55.10
dns: 10.77.77.10
extra_hosts:
# Allow the boulder container to be reached as "ca.example.org", so that
# we can put that name inside our integration test certs (e.g. as a crl
# Allow the boulder container to be reached as "ca.example.org", so we
# can put that name inside our integration test certs (e.g. as a crl
# url) and have it look like a publicly-accessible name.
- "ca.example.org:10.77.77.77"
# TODO(#8215): Move s3-test-srv to a separate service.
- "ca.example.org:64.112.117.122"
# Allow the boulder container to be reached as "integration.trust", for
# similar reasons, but intended for use as a SAN rather than a CRLDP.
- "integration.trust:10.77.77.77"
# TODO(#8215): Move observer's probe target to a separate service.
- "integration.trust:64.112.117.122"
ports:
- 4001:4001 # ACMEv2
- 4002:4002 # OCSP
@@ -69,7 +69,7 @@ services:
restart: always
bmysql:
image: mariadb:10.5
image: mariadb:10.6.22
volumes:
- dbdata:/var/lib/mysql
networks:
@@ -89,12 +89,13 @@ services:
bredis:
image: redis:6.2.7
volumes:
- ./test/:/test/:cached
- boulder_data:/opt/boulder/labca
- certificates:/opt/boulder/labca/certs
command: redis-server /opt/boulder/labca/redis-ratelimits.config
networks:
redisnet:
ipv4_address: 10.33.33.4
bouldernet:
ipv4_address: 10.77.77.4
restart: always
bconsul:
@@ -105,8 +106,6 @@ services:
- boulder_data:/opt/boulder/labca
- certificates:/opt/boulder/labca/certs
networks:
consulnet:
ipv4_address: 10.55.55.10
bouldernet:
ipv4_address: 10.77.77.10
command: "consul agent -dev -config-format=hcl -config-file=/opt/boulder/labca/consul/config.hcl"
@@ -182,8 +181,7 @@ services:
bpkimetal:
image: ghcr.io/pkimetal/pkimetal:v1.20.0
networks:
bouldernet:
ipv4_address: 10.77.77.9
- bouldernet
restart: always
volumes:
@@ -199,17 +197,34 @@ volumes:
certificates:
networks:
# This network is primarily used for boulder services. It is also used by
# challtestsrv, which is used in the integration tests.
# This network represents the data-center internal network. It is used for
# boulder services and their infrastructure, such as consul, mariadb, and
# redis.
bouldernet:
driver: bridge
ipam:
driver: default
config:
- subnet: 10.77.77.0/24
# Only issue DHCP addresses in the top half of the range, to avoid
# conflict with static addresses.
ip_range: 10.77.77.128/25
# This network represents the public internet. It uses a real public IP space
# (that Let's Encrypt controls) so that our integration tests are happy to
# validate and issue for it. It is used by challtestsrv, which binds to
# 64.112.117.122:80 and :443 for its HTTP-01 challenge responder.
#
# TODO(#8215): Put akamai-test-srv and s3-test-srv on this network.
publicnet:
driver: bridge
ipam:
driver: default
config:
- subnet: 64.112.117.0/25
# This network is used for two things in the integration tests:
# - challtestsrv binds to 10.88.88.88:443 for its tls-alpn-01 challenge
# - challtestsrv binds to 64.112.117.134:443 for its tls-alpn-01 challenge
# responder, to avoid interfering with the HTTPS port used for testing
# HTTP->HTTPS redirects during http-01 challenges. Note: this could
# probably be updated in the future so that challtestsrv can handle
@@ -217,24 +232,13 @@ networks:
# - test/v2_integration.py has some test cases that start their own HTTP
# server instead of relying on challtestsrv, because they want very
# specific behavior. For these cases, v2_integration.py creates a Python
# HTTP server and binds it to 10.88.88.88:80.
integrationtestnet:
# HTTP server and binds it to 64.112.117.134:80.
#
# TODO(#8215): Deprecate this network, replacing it with individual IPs within
# the existing publicnet.
publicnet2:
driver: bridge
ipam:
driver: default
config:
- subnet: 10.88.88.0/24
redisnet:
driver: bridge
ipam:
driver: default
config:
- subnet: 10.33.33.0/24
consulnet:
driver: bridge
ipam:
driver: default
config:
- subnet: 10.55.55.0/24
- subnet: 64.112.117.128/25

View File

@@ -1,5 +1,5 @@
diff --git a/docker-compose.yml b/docker-compose.yml
index e981e30ec..cf6585c65 100644
index b9a8ac069..71ca7e0be 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -4,7 +4,7 @@ services:
@@ -27,17 +27,17 @@ index e981e30ec..cf6585c65 100644
networks:
bouldernet:
ipv4_address: 10.77.77.77
@@ -90,7 +89,8 @@ services:
bredis:
@@ -91,7 +90,8 @@ services:
image: redis:6.2.7
volumes:
- ./test/:/test/:cached
- - /home/labca/boulder_labca:/opt/boulder/labca
+ - boulder_data:/opt/boulder/labca
+ - certificates:/opt/boulder/labca/certs
command: redis-server /opt/boulder/labca/redis-ratelimits.config
networks:
redisnet:
@@ -102,35 +102,37 @@ services:
bouldernet:
@@ -103,33 +103,35 @@ services:
depends_on:
- control
volumes:
@@ -45,8 +45,6 @@ index e981e30ec..cf6585c65 100644
+ - boulder_data:/opt/boulder/labca
+ - certificates:/opt/boulder/labca/certs
networks:
consulnet:
ipv4_address: 10.55.55.10
bouldernet:
ipv4_address: 10.77.77.10
command: "consul agent -dev -config-format=hcl -config-file=/opt/boulder/labca/consul/config.hcl"
@@ -86,7 +84,7 @@ index e981e30ec..cf6585c65 100644
logging:
driver: "json-file"
options:
@@ -147,30 +149,28 @@ services:
@@ -146,30 +148,28 @@ services:
- 80:80
- 443:443
volumes:
@@ -131,7 +129,7 @@ index e981e30ec..cf6585c65 100644
expose:
- 3030
environment:
@@ -188,6 +188,15 @@ services:
@@ -186,6 +186,15 @@ services:
volumes:
dbdata:
@@ -146,4 +144,4 @@ index e981e30ec..cf6585c65 100644
+ certificates:
networks:
# This network is primarily used for boulder services. It is also used by
# This network represents the data-center internal network. It is used for

View File

@@ -167,8 +167,6 @@ case $txt in
;;
"test-email")
read recipient
cd /opt/boulder
docker compose exec boulder bin/boulder mail-tester --config labca/config/expiration-mailer.json $recipient 2>&1
;;
"boulder-start")
cd /opt/boulder

View File

@@ -114,7 +114,7 @@ grep GO_VERSION ../boulder/docker-compose.yml | sed -e "s/\s*GO_VERSION:/ /"
colorGoVersion2 build/docker-compose.yml $goversion
echo
db_migrs=$(ls -1 ../boulder/sa/db/boulder_sa/ | grep -v 20240304000000_CertificateProfiles.sql | grep -v 20250115000000_AuthzProfiles.sql | wc -l)
db_migrs=$(ls -1 ../boulder/sa/db/boulder_sa/ | grep -v 20240304000000_CertificateProfiles.sql | grep -v 20250115000000_AuthzProfiles.sql | grep -v 20250519000000_NullRegistrationsContact.sql | wc -l)
db_patches=$(ls -1 ../labca/patches/db_migrations* | wc -l)
echo -n "Database migrations "
colorEqual $db_migrs $db_patches

View File

@@ -67,7 +67,6 @@ perl -i -p0e "s/(\"dnsStaticResolvers\": \[\n).*?(\s+\],)/\1\t\t\t\"$PKI_DNS\"\2
perl -i -p0e "s/(\"dnsStaticResolvers\": \[\n).*?(\s+\],)/\1\t\t\t\"$PKI_DNS\"\2/igs" config/remoteva-c.json
perl -i -p0e "s/(\"dnsStaticResolvers\": \[\n).*?(\s+\],)/\1\t\t\t\"$PKI_DNS\"\2/igs" config/va.json
perl -i -p0e "s/(\"dnsStaticResolvers\": \[\n).*?(\s+\],)/\1\t\t\t\"$PKI_DNS\"\2/igs" config/bad-key-revoker.json
perl -i -p0e "s/(\"dnsStaticResolvers\": \[\n).*?(\s+\],)/\1\t\t\t\"$PKI_DNS\"\2/igs" config/expiration-mailer.json
# Disable DOH as long as it is a feature...
sed -i -e "s/\(\"DOH\":\s*\).*/\1false/" config/remoteva-a.json
@@ -197,7 +196,6 @@ if [ "$PKI_EXTENDED_TIMEOUT" == "1" ]; then
sed -i -e "s/\"timeout\": \"15s\"/\"timeout\": \"30s\"/" config/admin.json
sed -i -e "s/\"timeout\": \"15s\"/\"timeout\": \"30s\"/" config/wfe2.json
sed -i -e "s/\"timeout\": \"20s\"/\"timeout\": \"40s\"/" config/wfe2.json
sed -i -e "s/\"timeout\": \"15s\"/\"timeout\": \"30s\"/" config/expiration-mailer.json
sed -i -e "s/\"timeout\": \"15s\"/\"timeout\": \"30s\"/" config/ra.json
sed -i -e "s/\"timeout\": \"20s\"/\"timeout\": \"40s\"/" config/ra.json
sed -i -e "s/\"timeout\": \"15s\"/\"timeout\": \"30s\"/" config/crl-storer.json
@@ -214,16 +212,6 @@ sed -i -e "s/\"port\": \".*\"/\"port\": \"$PKI_EMAIL_PORT\"/" config/bad-key-rev
sed -i -e "s/\"username\": \".*\"/\"username\": \"$PKI_EMAIL_USER\"/" config/bad-key-revoker.json
sed -i -e "s/\"from\": \".*\"/\"from\": \"$PKI_EMAIL_FROM\"/" config/bad-key-revoker.json
sed -i -e "s|\"SMTPTrustedRootFile\": \".*\"|\"SMTPTrustedRootFile\": \"$PKI_EMAIL_TRUST\"|" config/bad-key-revoker.json
sed -i -e "s/\"server\": \".*\"/\"server\": \"$PKI_EMAIL_SERVER\"/" config/expiration-mailer.json
sed -i -e "s/\"port\": \".*\"/\"port\": \"$PKI_EMAIL_PORT\"/" config/expiration-mailer.json
sed -i -e "s/\"username\": \".*\"/\"username\": \"$PKI_EMAIL_USER\"/" config/expiration-mailer.json
sed -i -e "s/\"from\": \".*\"/\"from\": \"$PKI_EMAIL_FROM\"/" config/expiration-mailer.json
sed -i -e "s|\"SMTPTrustedRootFile\": \".*\"|\"SMTPTrustedRootFile\": \"$PKI_EMAIL_TRUST\"|" config/expiration-mailer.json
sed -i -e "s/\"server\": \".*\"/\"server\": \"$PKI_EMAIL_SERVER\"/" config/notify-mailer.json
sed -i -e "s/\"port\": \".*\"/\"port\": \"$PKI_EMAIL_PORT\"/" config/notify-mailer.json
sed -i -e "s/\"username\": \".*\"/\"username\": \"$PKI_EMAIL_USER\"/" config/notify-mailer.json
sed -i -e "s/\"from\": \".*\"/\"from\": \"$PKI_EMAIL_FROM\"/" config/notify-mailer.json
sed -i -e "s|\"SMTPTrustedRootFile\": \".*\"|\"SMTPTrustedRootFile\": \"$PKI_EMAIL_TRUST\"|" config/notify-mailer.json
sed -i -e "s/\"purgeInterval\": \".*\"/\"purgeInterval\": \"1s\"/" config/akamai-purger.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-2025-05-27"
boulderTag="v0.20250707.0"
#
# Color configuration
@@ -620,10 +620,6 @@ config_boulder() {
cp core/interfaces.go "$boulderLabCADir/.backup/"
cp policy/pa.go "$boulderLabCADir/.backup/"
cp ra/ra.go "$boulderLabCADir/.backup/"
cp mail/mailer.go "$boulderLabCADir/.backup/"
cp cmd/expiration-mailer/main.go "$boulderLabCADir/.backup/"
cp cmd/notify-mailer/main.go "$boulderLabCADir/.backup/"
cp cmd/contact-auditor/main.go "$boulderLabCADir/.backup/"
cp cmd/bad-key-revoker/main.go "$boulderLabCADir/.backup/"
cp cmd/cert-checker/main.go "$boulderLabCADir/.backup/"
cp cmd/log-validator/main.go "$boulderLabCADir/.backup/"

View File

@@ -1,169 +0,0 @@
package notmain
import (
"context"
"crypto/x509"
"flag"
"fmt"
netmail "net/mail"
"os"
"time"
"github.com/letsencrypt/boulder/bdns"
"github.com/letsencrypt/boulder/cmd"
bconfig "github.com/letsencrypt/boulder/config"
"github.com/letsencrypt/boulder/features"
bmail "github.com/letsencrypt/boulder/mail"
)
const usageString = `
usage:
mail-tester --config <path> <recipient>
args:
config File path to the configuration file for this service
recipient Email address to send an email to
`
type config struct {
Mailer struct {
DebugAddr string
DB cmd.DBConfig
cmd.SMTPConfig
From string
Subject string
CertLimit int
NagTimes []string
// How much earlier (than configured nag intervals) to
// send reminders, to account for the expected delay
// before the next expiration-mailer invocation.
NagCheckInterval string
// Path to a text/template email template
EmailTemplate string
Frequency bconfig.Duration
TLS cmd.TLSConfig
SAService *cmd.GRPCClientConfig
DNSTries int
DNSStaticResolvers []string
DNSTimeout string
DNSAllowLoopbackAddresses bool
// 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
UserAgent string
Features features.Config
}
Syslog cmd.SyslogConfig
OpenTelemetry cmd.OpenTelemetryConfig
}
func main() {
usage := func() {
fmt.Fprintf(os.Stderr, usageString)
os.Exit(1)
}
configFile := flag.String("config", "", "File path to the configuration file for this service")
flag.Parse()
if len(os.Args) <= 3 || *configFile == "" {
usage()
}
args := flag.Args()
recipient := args[0]
var c config
err := cmd.ReadConfigFile(*configFile, &c)
cmd.FailOnError(err, "Reading JSON config file into config structure")
features.Set(c.Mailer.Features)
scope, logger, oTelShutdown := cmd.StatsAndLogging(c.Syslog, c.OpenTelemetry, c.Mailer.DebugAddr)
defer oTelShutdown(context.Background())
logger.Info(cmd.VersionString())
tlsConfig, err := c.Mailer.TLS.Load(scope)
cmd.FailOnError(err, "TLS config")
clk := cmd.Clock()
dnsTimeout, err := time.ParseDuration(c.Mailer.DNSTimeout)
cmd.FailOnError(err, "Couldn't parse DNS timeout")
dnsTries := c.Mailer.DNSTries
if dnsTries < 1 {
dnsTries = 1
}
var resolver bdns.Client
servers, err := bdns.NewStaticProvider(c.Mailer.DNSStaticResolvers)
cmd.FailOnError(err, "Couldn't start static DNS server resolver")
if !c.Mailer.DNSAllowLoopbackAddresses {
r := bdns.New(
dnsTimeout,
servers,
scope,
clk,
dnsTries,
c.Mailer.UserAgent,
logger,
tlsConfig)
resolver = r
} else {
r := bdns.NewTest(dnsTimeout, servers, scope, clk, dnsTries, c.Mailer.UserAgent, logger, tlsConfig)
resolver = r
}
var smtpRoots *x509.CertPool
smtpSkipVerify := false
if c.Mailer.SMTPTrustedRootFile == "InsecureSkipVerify" {
smtpSkipVerify = true
} else if c.Mailer.SMTPTrustedRootFile != "" {
pem, err := os.ReadFile(c.Mailer.SMTPTrustedRootFile)
cmd.FailOnError(err, "Loading trusted roots file")
smtpRoots = x509.NewCertPool()
if !smtpRoots.AppendCertsFromPEM(pem) {
cmd.FailOnError(nil, "Failed to parse root certs PEM")
}
}
fromAddress, err := netmail.ParseAddress(c.Mailer.From)
cmd.FailOnError(err, fmt.Sprintf("Could not parse from address: %s", c.Mailer.From))
smtpPassword, err := c.Mailer.PasswordConfig.Pass()
cmd.FailOnError(err, "Failed to load SMTP password")
mailClient := bmail.New(
c.Mailer.Server,
c.Mailer.Port,
c.Mailer.Username,
smtpPassword,
smtpRoots,
smtpSkipVerify,
resolver,
*fromAddress,
logger,
scope,
1*time.Second,
5*60*time.Second)
conn, err := mailClient.Connect()
cmd.FailOnError(err, "mail-tester failed to connect")
defer conn.Close()
recipients := []string{}
recipients = append(recipients, recipient)
err = conn.SendMail(recipients, "Test Email from LabCA", "Test sending email from the LabCA server")
cmd.FailOnError(err, "mail-tester has failed")
}
func init() {
cmd.RegisterCommand("mail-tester", main, &cmd.ConfigValidator{Config: &config{}})
}

View File

@@ -14,8 +14,6 @@ boulderLabCADir="${2:-labca}"
$SUDO patch -p1 -o "$boulderLabCADir/entrypoint.sh" < $cloneDir/patches/entrypoint.patch
cp test/startservers.py "$boulderLabCADir/startservers.py"
$SUDO patch -p1 -o "$boulderLabCADir/config/expiration-mailer.json" < $cloneDir/patches/config_expiration-mailer.patch
$SUDO patch -p1 -o "$boulderLabCADir/config/notify-mailer.json" < $cloneDir/patches/config_notify-mailer.patch
$SUDO patch -p1 -o "$boulderLabCADir/config/bad-key-revoker.json" < $cloneDir/patches/config_bad-key-revoker.patch
$SUDO patch -p1 -o "$boulderLabCADir/config/ocsp-responder.json" < $cloneDir/patches/config_ocsp-responder.patch
$SUDO patch -p1 -o "$boulderLabCADir/config/publisher.json" < $cloneDir/patches/config_publisher.patch
@@ -29,10 +27,10 @@ $SUDO patch -p1 -o "$boulderLabCADir/certs/generate.sh" < $cloneDir/patches/test
chmod +x $boulderLabCADir/certs/generate.sh
cp test/config/va*.json "$boulderLabCADir/config/"
perl -i -p0e "s/\"dnsProvider\": \{.*?\t\t},/\"dnsStaticResolvers\": [\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},/\"dnsStaticResolvers\": [\n\t\t\t\"127.0.0.1:8053\",\n\t\t\t\"127.0.0.1:8054\"\n\t\t],/igs" $boulderLabCADir/config/remoteva-a.json
perl -i -p0e "s/\"dnsProvider\": \{.*?\t\t},/\"dnsStaticResolvers\": [\n\t\t\t\"127.0.0.1:8053\",\n\t\t\t\"127.0.0.1:8054\"\n\t\t],/igs" $boulderLabCADir/config/remoteva-b.json
perl -i -p0e "s/\"dnsProvider\": \{.*?\t\t},/\"dnsStaticResolvers\": [\n\t\t\t\"127.0.0.1:8053\",\n\t\t\t\"127.0.0.1:8054\"\n\t\t],/igs" $boulderLabCADir/config/remoteva-c.json
perl -i -p0e "s/\"dnsProvider\": \{.*?\t\t},/\"dnsStaticResolvers\": [\n\t\t\t\"127.0.0.1:8053\",\n\t\t\t\"127.0.0.1:8054\"\n\t\t],\n\t\t\"dnsAllowLoopbackAddresses\": true,/igs" $boulderLabCADir/config/va.json
perl -i -p0e "s/\"dnsProvider\": \{.*?\t\t},/\"dnsStaticResolvers\": [\n\t\t\t\"127.0.0.1:8053\",\n\t\t\t\"127.0.0.1:8054\"\n\t\t],\n\t\t\"dnsAllowLoopbackAddresses\": true,/igs" $boulderLabCADir/config/remoteva-a.json
perl -i -p0e "s/\"dnsProvider\": \{.*?\t\t},/\"dnsStaticResolvers\": [\n\t\t\t\"127.0.0.1:8053\",\n\t\t\t\"127.0.0.1:8054\"\n\t\t],\n\t\t\"dnsAllowLoopbackAddresses\": true,/igs" $boulderLabCADir/config/remoteva-b.json
perl -i -p0e "s/\"dnsProvider\": \{.*?\t\t},/\"dnsStaticResolvers\": [\n\t\t\t\"127.0.0.1:8053\",\n\t\t\t\"127.0.0.1:8054\"\n\t\t],\n\t\t\"dnsAllowLoopbackAddresses\": true,/igs" $boulderLabCADir/config/remoteva-c.json
perl -i -p0e "s/(\"accountURIPrefixes\": \[\n.*?\s+\])/\1,\n\t\t\"labcaDomains\": [\n\t\t]/igs" $boulderLabCADir/config/remoteva-a.json
perl -i -p0e "s/(\"accountURIPrefixes\": \[\n.*?\s+\])/\1,\n\t\t\"labcaDomains\": [\n\t\t]/igs" $boulderLabCADir/config/remoteva-b.json
perl -i -p0e "s/(\"accountURIPrefixes\": \[\n.*?\s+\])/\1,\n\t\t\"labcaDomains\": [\n\t\t]/igs" $boulderLabCADir/config/remoteva-c.json

View File

@@ -15,6 +15,7 @@ if [ "$SUDO" == "" ]; then
fi
$SUDO patch -p1 < $cloneDir/patches/bad-key-revoker_main.patch
$SUDO patch -p1 < $cloneDir/patches/bdns_dns.patch
$SUDO patch -p1 < $cloneDir/patches/boulder-ra_main.patch
$SUDO patch -p1 < $cloneDir/patches/boulder-va_main.patch
$SUDO patch -p1 < $cloneDir/patches/ca_ca.patch
@@ -29,7 +30,6 @@ $SUDO patch -p1 < $cloneDir/patches/cert-checker_main.patch
$SUDO patch -p1 < $cloneDir/patches/cmd_config.patch
$SUDO patch -p1 < $cloneDir/patches/config_duration.patch
$SUDO patch -p1 < $cloneDir/patches/config_rocsp_config.patch
$SUDO patch -p1 < $cloneDir/patches/contact-auditor_main.patch
$SUDO patch -p1 < $cloneDir/patches/core_interfaces.patch
$SUDO patch -p1 < $cloneDir/patches/crl-storer_main.patch
$SUDO patch -p1 < $cloneDir/patches/db_migrations.patch
@@ -37,22 +37,20 @@ $SUDO patch -p1 < $cloneDir/patches/db_migrations2.patch
$SUDO patch -p1 < $cloneDir/patches/db_migrations3.patch
$SUDO patch -p1 < $cloneDir/patches/db_migrations4.patch
$SUDO patch -p1 < $cloneDir/patches/db_migrations5.patch
$SUDO patch -p1 < $cloneDir/patches/expiration-mailer_main.patch
$SUDO patch -p1 < $cloneDir/patches/issuance_crl.patch
$SUDO patch -p1 < $cloneDir/patches/issuance_issuer.patch
$SUDO patch -p1 < $cloneDir/patches/linter_linter.patch
$SUDO patch -p1 < $cloneDir/patches/log_prod_prefix.patch
$SUDO patch -p1 < $cloneDir/patches/log_test_prefix.patch
$SUDO patch -p1 < $cloneDir/patches/log_validator_validator.patch
$SUDO patch -p1 < $cloneDir/patches/mail_mailer.patch
$SUDO patch -p1 < $cloneDir/patches/makefile.patch
$SUDO patch -p1 < $cloneDir/patches/notify-mailer_main.patch
$SUDO patch -p1 < $cloneDir/patches/ocsp-responder_main.patch
$SUDO patch -p1 < $cloneDir/patches/policy_pa.patch
$SUDO patch -p1 < $cloneDir/patches/ra_ra.patch
$SUDO patch -p1 < $cloneDir/patches/ratelimits_names.patch
$SUDO patch -p1 < $cloneDir/patches/redis_config.patch
$SUDO patch -p1 < $cloneDir/patches/remoteva_main.patch
$SUDO patch -p1 < $cloneDir/patches/reversed-hostname-checker_main.patch
$SUDO patch -p1 < $cloneDir/patches/start.patch
$SUDO patch -p1 < $cloneDir/patches/test_startservers.patch
if [ "$SUDO" == "" ]; then
@@ -76,10 +74,6 @@ sed -i -e "s/proxysql:6033/mysql:3306/" sa/db/dbconfig.yml
sed -i -e "s/\(.*overrides.*\)/-- \1/" sa/db-users/boulder_sa.sql
mkdir -p "cmd/mail-tester"
cp $cloneDir/mail-tester.go cmd/mail-tester/main.go
perl -i -p0e "s/(\n\t\"github.com\/letsencrypt\/boulder\/cmd\")/\t_ \"github.com\/letsencrypt\/boulder\/cmd\/mail-tester\"\n\1/igs" cmd/boulder/main.go
perl -i -p0e "s/If you continue to encounter.*for troubleshooting and advice.//igs" sfe/pages/index.html
perl -i -p0e "s/<b>Note:<\/b> If you encounter.*troubleshooting and advice.//igs" sfe/pages/unpause-form.html
perl -i -p0e "s/If you continue to encounter.*for troubleshooting and advice.//igs" sfe/pages/unpause-invalid-request.html

View File

@@ -1,16 +1,8 @@
diff --git a/cmd/bad-key-revoker/main.go b/cmd/bad-key-revoker/main.go
index c333b88c3..8e9cc21bd 100644
index 8e6cfac85..8880ed301 100644
--- a/cmd/bad-key-revoker/main.go
+++ b/cmd/bad-key-revoker/main.go
@@ -18,6 +18,7 @@ import (
"google.golang.org/grpc"
"google.golang.org/protobuf/types/known/emptypb"
+ "github.com/letsencrypt/boulder/bdns"
"github.com/letsencrypt/boulder/cmd"
"github.com/letsencrypt/boulder/config"
"github.com/letsencrypt/boulder/core"
@@ -398,6 +399,11 @@ type Config struct {
@@ -270,6 +270,11 @@ type Config struct {
TLS cmd.TLSConfig
RAService *cmd.GRPCClientConfig
@@ -22,59 +14,12 @@ index c333b88c3..8e9cc21bd 100644
// MaximumRevocations specifies the maximum number of certificates associated with
// a key hash that bad-key-revoker will attempt to revoke. If the number of certificates
// is higher than MaximumRevocations bad-key-revoker will error out and refuse to
@@ -417,6 +423,8 @@ type Config struct {
@@ -289,6 +294,8 @@ type Config struct {
// or no work to do.
BackoffIntervalMax config.Duration `validate:"-"`
+ UserAgent string
+
// Deprecated: the bad-key-revoker no longer sends emails; we use ARI.
// TODO(#8199): Remove this config stanza entirely.
Mailer struct {
cmd.SMTPConfig
// Path to a file containing a list of trusted root certificates for use
@@ -469,8 +477,36 @@ func main() {
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to RA")
rac := rapb.NewRegistrationAuthorityClient(conn)
+ dnsTimeout, err := time.ParseDuration(config.BadKeyRevoker.DNSTimeout)
+ cmd.FailOnError(err, "Couldn't parse DNS timeout")
+ dnsTries := config.BadKeyRevoker.DNSTries
+ if dnsTries < 1 {
+ dnsTries = 1
+ }
+ var resolver bdns.Client
+ servers, err := bdns.NewStaticProvider(config.BadKeyRevoker.DNSStaticResolvers)
+ cmd.FailOnError(err, "Couldn't start static DNS server resolver")
+ if !config.BadKeyRevoker.DNSAllowLoopbackAddresses {
+ r := bdns.New(
+ dnsTimeout,
+ servers,
+ scope,
+ clk,
+ dnsTries,
+ config.BadKeyRevoker.UserAgent,
+ logger,
+ tlsConfig)
+ resolver = r
+ } else {
+ r := bdns.NewTest(dnsTimeout, servers, scope, clk, dnsTries, config.BadKeyRevoker.UserAgent, logger, tlsConfig)
+ resolver = r
+ }
+
var smtpRoots *x509.CertPool
- if config.BadKeyRevoker.Mailer.SMTPTrustedRootFile != "" {
+ smtpSkipVerify := false
+ if config.BadKeyRevoker.Mailer.SMTPTrustedRootFile == "InsecureSkipVerify" {
+ smtpSkipVerify = true
+ } else if config.BadKeyRevoker.Mailer.SMTPTrustedRootFile != "" {
pem, err := os.ReadFile(config.BadKeyRevoker.Mailer.SMTPTrustedRootFile)
cmd.FailOnError(err, "Loading trusted roots file")
smtpRoots = x509.NewCertPool()
@@ -490,6 +526,8 @@ func main() {
config.BadKeyRevoker.Mailer.Username,
smtpPassword,
smtpRoots,
+ smtpSkipVerify,
+ resolver,
*fromAddress,
logger,
scope,

81
patches/bdns_dns.patch Normal file
View File

@@ -0,0 +1,81 @@
diff --git a/bdns/dns.go b/bdns/dns.go
index 5d297f3ef..9eabf1239 100644
--- a/bdns/dns.go
+++ b/bdns/dns.go
@@ -21,6 +21,7 @@ import (
"github.com/miekg/dns"
"github.com/prometheus/client_golang/prometheus"
+ "github.com/letsencrypt/boulder/features"
"github.com/letsencrypt/boulder/iana"
blog "github.com/letsencrypt/boulder/log"
"github.com/letsencrypt/boulder/metrics"
@@ -77,22 +78,30 @@ func New(
) Client {
var client exchanger
- // Clone the default transport because it comes with various settings
- // that we like, which are different from the zero value of an
- // `http.Transport`.
- transport := http.DefaultTransport.(*http.Transport).Clone()
- transport.TLSClientConfig = tlsConfig
- // The default transport already sets this field, but it isn't
- // documented that it will always be set. Set it again to be sure,
- // because Unbound will reject non-HTTP/2 DoH requests.
- transport.ForceAttemptHTTP2 = true
- client = &dohExchanger{
- clk: clk,
- hc: http.Client{
- Timeout: readTimeout,
- Transport: transport,
- },
- userAgent: userAgent,
+ if features.Get().DOH {
+ // Clone the default transport because it comes with various settings
+ // that we like, which are different from the zero value of an
+ // `http.Transport`.
+ transport := http.DefaultTransport.(*http.Transport).Clone()
+ transport.TLSClientConfig = tlsConfig
+ // The default transport already sets this field, but it isn't
+ // documented that it will always be set. Set it again to be sure,
+ // because Unbound will reject non-HTTP/2 DoH requests.
+ transport.ForceAttemptHTTP2 = true
+ client = &dohExchanger{
+ clk: clk,
+ hc: http.Client{
+ Timeout: readTimeout,
+ Transport: transport,
+ },
+ userAgent: userAgent,
+ }
+ } else {
+ client = &dns.Client{
+ // Set timeout for underlying net.Conn
+ ReadTimeout: readTimeout,
+ Net: "udp",
+ }
}
queryTime := prometheus.NewHistogramVec(
@@ -273,10 +282,17 @@ func (dnsClient *impl) exchangeOne(ctx context.Context, hostname string, qtype u
case r := <-ch:
if r.err != nil {
var isRetryable bool
- // According to the http package documentation, retryable
- // errors emitted by the http package are of type *url.Error.
- var urlErr *url.Error
- isRetryable = errors.As(r.err, &urlErr) && urlErr.Temporary()
+ if features.Get().DOH {
+ // According to the http package documentation, retryable
+ // errors emitted by the http package are of type *url.Error.
+ var urlErr *url.Error
+ isRetryable = errors.As(r.err, &urlErr) && urlErr.Temporary()
+ } else {
+ // According to the net package documentation, retryable
+ // errors emitted by the net package are of type *net.OpError.
+ var opErr *net.OpError
+ isRetryable = errors.As(r.err, &opErr) && opErr.Temporary()
+ }
hasRetriesLeft := tries < dnsClient.maxTries
if isRetryable && hasRetriesLeft {
tries++

View File

@@ -1,8 +1,8 @@
diff --git a/cmd/boulder-va/main.go b/cmd/boulder-va/main.go
index 981c4f9b5..9d5db072d 100644
index 5086a3923..f557f33b0 100644
--- a/cmd/boulder-va/main.go
+++ b/cmd/boulder-va/main.go
@@ -52,6 +52,7 @@ type Config struct {
@@ -53,6 +53,7 @@ type Config struct {
// Deprecated and ignored
MaxRemoteValidationFailures int `validate:"omitempty,min=0,required_with=RemoteVAs"`
Features features.Config
@@ -10,12 +10,30 @@ index 981c4f9b5..9d5db072d 100644
}
Syslog cmd.SyslogConfig
@@ -152,7 +153,8 @@ func main() {
@@ -82,12 +83,16 @@ func main() {
clk := cmd.Clock()
var servers bdns.ServerProvider
+ proto := "udp"
+ if features.Get().DOH {
+ proto = "tcp"
+ }
if len(c.VA.DNSStaticResolvers) != 0 {
servers, err = bdns.NewStaticProvider(c.VA.DNSStaticResolvers)
cmd.FailOnError(err, "Couldn't start static DNS server resolver")
} else {
- servers, err = bdns.StartDynamicProvider(c.VA.DNSProvider, 60*time.Second, "tcp")
+ servers, err = bdns.StartDynamicProvider(c.VA.DNSProvider, 60*time.Second, proto)
cmd.FailOnError(err, "Couldn't start dynamic DNS server resolver")
}
defer servers.Stop()
@@ -149,7 +154,8 @@ func main() {
c.VA.AccountURIPrefixes,
va.PrimaryPerspective,
"",
- bdns.IsReservedIP)
+ bdns.IsReservedIP,
- iana.IsReservedAddr)
+ iana.IsReservedAddr,
+ c.VA.LabCADomains)
cmd.FailOnError(err, "Unable to create VA server")

View File

@@ -1,8 +1,8 @@
diff --git a/cmd/config.go b/cmd/config.go
index f8b6b847f..38ea91f33 100644
index 13842fdf9..33cb282cb 100644
--- a/cmd/config.go
+++ b/cmd/config.go
@@ -469,7 +469,7 @@ type GRPCServerConfig struct {
@@ -471,7 +471,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

View File

@@ -1,5 +1,5 @@
diff --git a/test/config/bad-key-revoker.json b/test/config/bad-key-revoker.json
index f4696dc2..b9c19ce3 100644
index d70aadc5f..99dfde454 100644
--- a/test/config/bad-key-revoker.json
+++ b/test/config/bad-key-revoker.json
@@ -5,6 +5,13 @@
@@ -11,8 +11,8 @@ index f4696dc2..b9c19ce3 100644
+ "127.0.0.1:8053",
+ "127.0.0.1:8054"
+ ],
+ "dnsTimeout": "3s",
+ "dnsAllowLoopbackAddresses": true,
+ "dnsTimeout": "3s",
"tls": {
"caCertFile": "test/certs/ipki/minica.pem",
"certFile": "test/certs/ipki/bad-key-revoker.boulder/cert.pem",

View File

@@ -1,18 +0,0 @@
diff --git a/test/config/expiration-mailer.json b/test/config/expiration-mailer.json
index 3b813060..6c709172 100644
--- a/test/config/expiration-mailer.json
+++ b/test/config/expiration-mailer.json
@@ -16,6 +16,13 @@
],
"emailTemplate": "test/config/expiration-mailer.gotmpl",
"debugAddr": ":8008",
+ "dnsTries": 3,
+ "dnsStaticResolvers": [
+ "127.0.0.1:8053",
+ "127.0.0.1:8054"
+ ],
+ "dnsTimeout": "3s",
+ "dnsAllowLoopbackAddresses": true,
"tls": {
"caCertFile": "test/certs/ipki/minica.pem",
"certFile": "test/certs/ipki/expiration-mailer.boulder/cert.pem",

View File

@@ -1,27 +0,0 @@
diff --git a/test/config/notify-mailer.json b/test/config/notify-mailer.json
index f6813a696..115d5b150 100644
--- a/test/config/notify-mailer.json
+++ b/test/config/notify-mailer.json
@@ -2,13 +2,22 @@
"notifyMailer": {
"server": "localhost",
"port": "9380",
+ "hostnamePolicyFile": "test/hostname-policy.yaml",
"username": "cert-manager@example.com",
"passwordFile": "test/secrets/smtp_password",
+ "SMTPTrustedRootFile": "test/certs/ipki/minica.pem",
"db": {
"dbConnectFile": "test/secrets/mailer_dburl",
"maxOpenConns": 10
}
},
+ "pa": {
+ "challenges": {
+ "http-01": true,
+ "dns-01": true,
+ "tls-alpn-01": true
+ }
+ },
"syslog": {
"stdoutLevel": 7,
"syslogLevel": 7

View File

@@ -1,5 +1,5 @@
diff --git a/test/config/ocsp-responder.json b/test/config/ocsp-responder.json
index c67aa41f7..92fe8a28f 100644
index 1e5d4cb70..e56719c21 100644
--- a/test/config/ocsp-responder.json
+++ b/test/config/ocsp-responder.json
@@ -4,22 +4,6 @@
@@ -10,8 +10,8 @@ index c67aa41f7..92fe8a28f 100644
- "username": "ocsp-responder",
- "passwordFile": "test/secrets/ocsp_responder_redis_password",
- "shardAddrs": {
- "shard1": "10.33.33.2:4218",
- "shard2": "10.33.33.3:4218"
- "shard1": "10.77.77.2:4218",
- "shard2": "10.77.77.3:4218"
- },
- "timeout": "5s",
- "poolSize": 100,

View File

@@ -1,5 +1,5 @@
diff --git a/test/config/ra.json b/test/config/ra.json
index c16978e12..15e8252c0 100644
index 613c5e1a1..c43053523 100644
--- a/test/config/ra.json
+++ b/test/config/ra.json
@@ -3,7 +3,8 @@
@@ -45,7 +45,7 @@ index c16978e12..15e8252c0 100644
],
"validationProfiles": {
"legacy": {
@@ -58,9 +54,9 @@
@@ -67,9 +63,9 @@
},
"defaultProfileName": "legacy",
"tls": {
@@ -58,7 +58,7 @@ index c16978e12..15e8252c0 100644
},
"vaService": {
"dnsAuthority": "consul.service.consul",
@@ -154,7 +150,7 @@
@@ -163,7 +159,7 @@
},
"ctLogs": {
"stagger": "500ms",

View File

@@ -1,32 +0,0 @@
diff --git a/cmd/contact-auditor/main.go b/cmd/contact-auditor/main.go
index fdec0c660..cc62d91c0 100644
--- a/cmd/contact-auditor/main.go
+++ b/cmd/contact-auditor/main.go
@@ -12,7 +12,9 @@ import (
"time"
"github.com/letsencrypt/boulder/cmd"
+ "github.com/letsencrypt/boulder/core"
"github.com/letsencrypt/boulder/db"
+ "github.com/letsencrypt/boulder/identifier"
blog "github.com/letsencrypt/boulder/log"
"github.com/letsencrypt/boulder/policy"
"github.com/letsencrypt/boulder/sa"
@@ -50,9 +52,16 @@ func validateContacts(id int64, createdAt string, contacts []string) error {
fmt.Fprintf(&probsBuff, "%d\t%s\tvalidation\t%q\t%q\t%q\n", id, createdAt, contact, prob, contacts)
}
+ var pa *policy.AuthorityImpl
+ logger := cmd.NewLogger(cmd.SyslogConfig{StdoutLevel: 7})
+ pa, _ = policy.New(
+ map[identifier.IdentifierType]bool{identifier.TypeDNS: true, identifier.TypeIP: true},
+ map[core.AcmeChallenge]bool{},
+ logger)
+
for _, contact := range contacts {
if strings.HasPrefix(contact, "mailto:") {
- err := policy.ValidEmail(strings.TrimPrefix(contact, "mailto:"))
+ err := pa.ValidEmail(strings.TrimPrefix(contact, "mailto:"))
if err != nil {
writeProb(contact, err.Error())
}

View File

@@ -1,5 +1,5 @@
diff --git a/docker-compose.yml b/docker-compose.yml
index 9b05172ef..e981e30ec 100644
index 8092b1522..b9a8ac069 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,3 +1,4 @@
@@ -8,9 +8,9 @@ index 9b05172ef..e981e30ec 100644
boulder:
# The `letsencrypt/boulder-tools:latest` tag is automatically built in local
@@ -14,13 +15,15 @@ services:
# to the IP address where your ACME client's solver is listening.
# FAKE_DNS: 172.17.0.1
FAKE_DNS: 10.77.77.77
# to the IP address where your ACME client's solver is listening. This is
# pointing at the boulder service's "public" IP, where challtestsrv is.
FAKE_DNS: 64.112.117.122
- BOULDER_CONFIG_DIR: test/config
+ BOULDER_CONFIG_DIR: labca/config
GOCACHE: /boulder/.gocache/go-build
@@ -26,7 +26,7 @@ index 9b05172ef..e981e30ec 100644
networks:
bouldernet:
ipv4_address: 10.77.77.77
@@ -53,121 +56,138 @@ services:
@@ -53,122 +56,136 @@ services:
- 4003:4003 # SFE
depends_on:
- bmysql
@@ -66,7 +66,7 @@ index 9b05172ef..e981e30ec 100644
+ restart: always
bmysql:
image: mariadb:10.5
image: mariadb:10.6.22
+ volumes:
+ - dbdata:/var/lib/mysql
networks:
@@ -84,6 +84,12 @@ index 9b05172ef..e981e30ec 100644
+ command: mysqld --bind-address=0.0.0.0 --log-output=TABLE
logging:
- driver: none
+ driver: "json-file"
+ options:
+ max-size: "500k"
+ max-file: "5"
+ restart: always
- bproxysql:
- image: proxysql/proxysql:2.5.4
- # The --initial flag force resets the ProxySQL database on startup. By
@@ -99,77 +105,62 @@ index 9b05172ef..e981e30ec 100644
- bouldernet:
- aliases:
- - boulder-proxysql
+ driver: "json-file"
+ options:
+ max-size: "500k"
+ max-file: "5"
+ restart: always
-
- bredis_1:
+ bredis:
image: redis:6.2.7
volumes:
- - ./test/:/test/:cached
- ./test/:/test/:cached
- command: redis-server /test/redis-ocsp.config
- networks:
- redisnet:
- ipv4_address: 10.33.33.2
-
+ - /home/labca/boulder_labca:/opt/boulder/labca
+ command: redis-server /opt/boulder/labca/redis-ratelimits.config
networks:
bouldernet:
- # TODO(#8215): Remove this static IP allocation (and similar below) when
- # we tear down ocsp-responder. We only have it because ocsp-responder
- # requires IPs in its "ShardAddrs" config, while ratelimit redis
- # supports looking up shards via hostname and SRV record.
- ipv4_address: 10.77.77.2
+ ipv4_address: 10.77.77.4
+ restart: always
- bredis_2:
- image: redis:6.2.7
- volumes:
+ bconsul:
+ image: hashicorp/consul:1.15.4
+ depends_on:
+ - control
volumes:
- - ./test/:/test/:cached
- command: redis-server /test/redis-ocsp.config
- networks:
- redisnet:
- ipv4_address: 10.33.33.3
-
+ - /home/labca/boulder_labca:/opt/boulder/labca
networks:
bouldernet:
- ipv4_address: 10.77.77.3
+ ipv4_address: 10.77.77.10
+ command: "consul agent -dev -config-format=hcl -config-file=/opt/boulder/labca/consul/config.hcl"
+ restart: always
- bredis_3:
- image: redis:6.2.7
- volumes:
- - ./test/:/test/:cached
- command: redis-server /test/redis-ratelimits.config
+ - /home/labca/boulder_labca:/opt/boulder/labca
+ command: redis-server /opt/boulder/labca/redis-ratelimits.config
networks:
redisnet:
ipv4_address: 10.33.33.4
-
- bredis_4:
- image: redis:6.2.7
- volumes:
- - ./test/:/test/:cached
- command: redis-server /test/redis-ratelimits.config
- networks:
- redisnet:
- ipv4_address: 10.33.33.5
+ restart: always
bconsul:
image: hashicorp/consul:1.15.4
+ depends_on:
+ - control
volumes:
- - ./test/:/test/:cached
+ - /home/labca/boulder_labca:/opt/boulder/labca
networks:
consulnet:
ipv4_address: 10.55.55.10
bouldernet:
ipv4_address: 10.77.77.10
- command: "consul agent -dev -config-format=hcl -config-file=/test/consul/config.hcl"
+ command: "consul agent -dev -config-format=hcl -config-file=/opt/boulder/labca/consul/config.hcl"
+ restart: always
- bjaeger:
- image: jaegertracing/all-in-one:1.50
+ gui:
+ image: *boulder_tools_image
networks:
- bouldernet:
- ipv4_address: 10.77.77.17
- ipv4_address: 10.77.77.4
-
- bredis_4:
- image: redis:6.2.7
+ - bouldernet
+ volumes:
volumes:
- - ./test/:/test/:cached
- command: redis-server /test/redis-ratelimits.config
- networks:
- bouldernet:
- ipv4_address: 10.77.77.5
+ - /var/run/docker.sock:/var/run/docker.sock
+ - /home/labca/admin:/go/src/labca
+ - ./.gocache:/root/.cache/go-build
@@ -191,11 +182,18 @@ index 9b05172ef..e981e30ec 100644
+ max-size: "500k"
+ max-file: "5"
+ restart: always
+
- bconsul:
- image: hashicorp/consul:1.15.4
- volumes:
- - ./test/:/test/:cached
+ nginx:
+ image: nginx:latest
+ restart: always
+ networks:
networks:
- bouldernet:
- ipv4_address: 10.77.77.10
- command: "consul agent -dev -config-format=hcl -config-file=/test/consul/config.hcl"
+ - bouldernet
+ ports:
+ - 80:80
@@ -206,11 +204,13 @@ index 9b05172ef..e981e30ec 100644
+ - /home/labca/nginx_data/static:/var/www/html
+ depends_on:
+ - control
+
- bjaeger:
- image: jaegertracing/all-in-one:1.50
+ control:
+ image: *boulder_tools_image
+ networks:
+ - bouldernet
networks:
- bouldernet
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ - /home/labca/admin/data:/opt/labca/data
@@ -236,12 +236,11 @@ index 9b05172ef..e981e30ec 100644
bpkimetal:
image: ghcr.io/pkimetal/pkimetal:v1.20.0
networks:
bouldernet:
ipv4_address: 10.77.77.9
- bouldernet
+ restart: always
+
+volumes:
+ dbdata:
networks:
# This network is primarily used for boulder services. It is also used by
# This network represents the data-center internal network. It is used for

View File

@@ -1,100 +0,0 @@
diff --git a/cmd/expiration-mailer/main.go b/cmd/expiration-mailer/main.go
index 8c80c8408..4102e879b 100644
--- a/cmd/expiration-mailer/main.go
+++ b/cmd/expiration-mailer/main.go
@@ -23,6 +23,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
+ "github.com/letsencrypt/boulder/bdns"
"github.com/letsencrypt/boulder/cmd"
"github.com/letsencrypt/boulder/config"
"github.com/letsencrypt/boulder/core"
@@ -40,7 +41,7 @@ import (
)
const (
- defaultExpirationSubject = "Let's Encrypt certificate expiration notice for domain {{.ExpirationSubject}}"
+ defaultExpirationSubject = "LabCA certificate expiration notice for domain {{.ExpirationSubject}}"
)
var (
@@ -162,8 +163,12 @@ func (m *mailer) sendNags(conn bmail.Conn, contacts []string, certs []*x509.Cert
if parsed.Scheme != "mailto" {
continue
}
+ pa, err := policy.New(nil, nil, nil)
+ if err != nil {
+ return fmt.Errorf("cannot create policy authority implementation")
+ }
address := parsed.Opaque
- err = policy.ValidEmail(address)
+ err = pa.ValidEmail(address)
if err != nil {
m.log.Debugf("skipping invalid email: %s", err)
continue
@@ -697,10 +702,17 @@ type Config struct {
TLS cmd.TLSConfig
SAService *cmd.GRPCClientConfig
+ DNSTries int
+ DNSStaticResolvers []string
+ DNSTimeout string
+ DNSAllowLoopbackAddresses bool
+
// 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
+ UserAgent string
+
Features features.Config
}
@@ -850,8 +862,36 @@ func main() {
cmd.FailOnError(err, "Failed to load credentials and create gRPC connection to SA")
sac := sapb.NewStorageAuthorityClient(conn)
+ dnsTimeout, err := time.ParseDuration(c.Mailer.DNSTimeout)
+ cmd.FailOnError(err, "Couldn't parse DNS timeout")
+ dnsTries := c.Mailer.DNSTries
+ if dnsTries < 1 {
+ dnsTries = 1
+ }
+ var resolver bdns.Client
+ servers, err := bdns.NewStaticProvider(c.Mailer.DNSStaticResolvers)
+ cmd.FailOnError(err, "Couldn't start static DNS server resolver")
+ if !c.Mailer.DNSAllowLoopbackAddresses {
+ r := bdns.New(
+ dnsTimeout,
+ servers,
+ scope,
+ clk,
+ dnsTries,
+ c.Mailer.UserAgent,
+ logger,
+ tlsConfig)
+ resolver = r
+ } else {
+ r := bdns.NewTest(dnsTimeout, servers, scope, clk, dnsTries, c.Mailer.UserAgent, logger, tlsConfig)
+ resolver = r
+ }
+
var smtpRoots *x509.CertPool
- if c.Mailer.SMTPTrustedRootFile != "" {
+ smtpSkipVerify := false
+ if c.Mailer.SMTPTrustedRootFile == "InsecureSkipVerify" {
+ smtpSkipVerify = true
+ } else if c.Mailer.SMTPTrustedRootFile != "" {
pem, err := os.ReadFile(c.Mailer.SMTPTrustedRootFile)
cmd.FailOnError(err, "Loading trusted roots file")
smtpRoots = x509.NewCertPool()
@@ -885,6 +925,8 @@ func main() {
c.Mailer.Username,
smtpPassword,
smtpRoots,
+ smtpSkipVerify,
+ resolver,
*fromAddress,
logger,
scope,

View File

@@ -1,110 +0,0 @@
diff --git a/mail/mailer.go b/mail/mailer.go
index 31ebd40b1..760b0b66e 100644
--- a/mail/mailer.go
+++ b/mail/mailer.go
@@ -2,6 +2,7 @@ package mail
import (
"bytes"
+ "context"
"crypto/rand"
"crypto/tls"
"crypto/x509"
@@ -23,7 +24,9 @@ import (
"github.com/jmhodges/clock"
"github.com/prometheus/client_golang/prometheus"
+ "github.com/letsencrypt/boulder/bdns"
"github.com/letsencrypt/boulder/core"
+ berrors "github.com/letsencrypt/boulder/errors"
blog "github.com/letsencrypt/boulder/log"
)
@@ -139,6 +142,8 @@ func New(
username,
password string,
rootCAs *x509.CertPool,
+ insecureSkipVerify bool,
+ resolver bdns.Client,
from mail.Address,
logger blog.Logger,
stats prometheus.Registerer,
@@ -154,11 +159,13 @@ func New(
return &mailerImpl{
config: config{
dialer: &dialerImpl{
- username: username,
- password: password,
- server: server,
- port: port,
- rootCAs: rootCAs,
+ username: username,
+ password: password,
+ server: server,
+ port: port,
+ rootCAs: rootCAs,
+ insecureSkipVerify: insecureSkipVerify,
+ dnsClient: resolver,
},
log: logger,
from: from,
@@ -202,7 +209,7 @@ func (c config) generateMessage(to []string, subject, body string) ([]byte, erro
fmt.Sprintf("To: %s", strings.Join(addrs, ", ")),
fmt.Sprintf("From: %s", c.from.String()),
fmt.Sprintf("Subject: %s", subject),
- fmt.Sprintf("Date: %s", now.Format(time.RFC822)),
+ fmt.Sprintf("Date: %s", now.Format(time.RFC1123Z)),
fmt.Sprintf("Message-Id: <%s.%s.%s>", now.Format("20060102T150405"), mid.String(), c.from.Address),
"MIME-Version: 1.0",
"Content-Type: text/plain; charset=UTF-8",
@@ -259,23 +266,41 @@ func (m *mailerImpl) Connect() (Conn, error) {
type dialerImpl struct {
username, password, server, port string
rootCAs *x509.CertPool
+ insecureSkipVerify bool
+ dnsClient bdns.Client
}
func (di *dialerImpl) Dial() (smtpClient, error) {
- hostport := net.JoinHostPort(di.server, di.port)
- var conn net.Conn
- var err error
- conn, err = tls.Dial("tcp", hostport, &tls.Config{
- RootCAs: di.rootCAs,
- })
+ deadline := time.Now().Add(30 * time.Second)
+ ctx, cancel := context.WithDeadline(context.Background(), deadline)
+ defer cancel()
+
+ addrs, _, err := di.dnsClient.LookupHost(ctx, di.server)
if err != nil {
- return nil, err
+ problem := berrors.DNSError("%v")
+ return nil, problem
+ }
+
+ if len(addrs) == 0 {
+ return nil, berrors.DNSError("No valid IP addresses found for %s", di.server)
}
- client, err := smtp.NewClient(conn, di.server)
+
+ tlsconf := &tls.Config{
+ ServerName: di.server,
+ }
+ if di.insecureSkipVerify {
+ tlsconf.InsecureSkipVerify = true
+ } else {
+ tlsconf.RootCAs = di.rootCAs
+ }
+
+ hostport := net.JoinHostPort(addrs[0].String(), di.port)
+ client, err := smtp.Dial(hostport)
if err != nil {
return nil, err
}
- auth := smtp.PlainAuth("", di.username, di.password, di.server)
+ client.StartTLS(tlsconf)
+ auth := smtp.PlainAuth("", di.username, di.password, addrs[0].String())
if err = client.Auth(auth); err != nil {
return nil, err
}

View File

@@ -1,93 +0,0 @@
diff --git a/cmd/notify-mailer/main.go b/cmd/notify-mailer/main.go
index 6c01efd64..6da77c7eb 100644
--- a/cmd/notify-mailer/main.go
+++ b/cmd/notify-mailer/main.go
@@ -2,6 +2,7 @@ package notmain
import (
"context"
+ "crypto/x509"
"encoding/csv"
"encoding/json"
"errors"
@@ -37,6 +38,7 @@ type mailer struct {
recipients []recipient
targetRange interval
sleepInterval time.Duration
+ pa *policy.AuthorityImpl
parallelSends uint
}
@@ -201,7 +203,7 @@ func (m *mailer) run(ctx context.Context) error {
continue
}
- err := policy.ValidEmail(w.address)
+ err := m.pa.ValidEmail(w.address)
if err != nil {
m.log.Infof("Skipping %q due to policy violation: %s", w.address, err)
continue
@@ -502,7 +504,12 @@ type Config struct {
NotifyMailer struct {
DB cmd.DBConfig
cmd.SMTPConfig
+ // 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
+ cmd.HostnamePolicyConfig
}
+ PA cmd.PAConfig
Syslog cmd.SyslogConfig
}
@@ -570,6 +577,15 @@ func main() {
log.Infof("While reading the recipient list file %s", probs)
}
+ // Validate PA config and set defaults if needed
+ cmd.FailOnError(cfg.PA.CheckChallenges(), "Invalid PA configuration")
+
+ logger := cmd.NewLogger(cmd.SyslogConfig{StdoutLevel: 7})
+ pa, err := policy.New(cfg.PA.Identifiers, cfg.PA.Challenges, logger)
+ cmd.FailOnError(err, "Failed to create PA")
+ err = pa.LoadHostnamePolicyFile(cfg.NotifyMailer.HostnamePolicyFile)
+ cmd.FailOnError(err, "Failed to load HostnamePolicyFile")
+
var mailClient bmail.Mailer
if *dryRun {
log.Infof("Starting %s in dry-run mode", cmd.VersionString())
@@ -579,11 +595,26 @@ func main() {
smtpPassword, err := cfg.NotifyMailer.PasswordConfig.Pass()
cmd.FailOnError(err, "Couldn't load SMTP password from file")
+ var smtpRoots *x509.CertPool
+ smtpSkipVerify := false
+ if cfg.NotifyMailer.SMTPTrustedRootFile == "InsecureSkipVerify" {
+ smtpSkipVerify = true
+ } else if cfg.NotifyMailer.SMTPTrustedRootFile != "" {
+ pem, err := os.ReadFile(cfg.NotifyMailer.SMTPTrustedRootFile)
+ cmd.FailOnError(err, "Loading trusted roots file")
+ smtpRoots = x509.NewCertPool()
+ if !smtpRoots.AppendCertsFromPEM(pem) {
+ cmd.FailOnError(nil, "Failed to parse root certs PEM")
+ }
+ }
+
mailClient = bmail.New(
cfg.NotifyMailer.Server,
cfg.NotifyMailer.Port,
cfg.NotifyMailer.Username,
smtpPassword,
+ smtpRoots,
+ smtpSkipVerify,
nil,
*address,
log,
@@ -605,6 +636,7 @@ func main() {
end: *end,
},
sleepInterval: *sleep,
+ pa: pa,
parallelSends: *parallelSends,
}

View File

@@ -1,8 +1,8 @@
diff --git a/policy/pa.go b/policy/pa.go
index 661a6b6bc..17dde317f 100644
index f53100322..107c5986e 100644
--- a/policy/pa.go
+++ b/policy/pa.go
@@ -32,6 +32,9 @@ type AuthorityImpl struct {
@@ -31,6 +31,9 @@ type AuthorityImpl struct {
blocklist map[string]bool
exactBlocklist map[string]bool
wildcardExactBlocklist map[string]bool
@@ -12,7 +12,7 @@ index 661a6b6bc..17dde317f 100644
blocklistMu sync.RWMutex
enabledChallenges map[core.AcmeChallenge]bool
@@ -75,6 +78,10 @@ type blockedNamesPolicy struct {
@@ -66,6 +69,10 @@ type blockedNamesPolicy struct {
// time above and beyond the high-risk domains. Managing these entries separately
// from HighRiskBlockedNames makes it easier to vet changes accurately.
AdminBlockedNames []string `yaml:"AdminBlockedNames"`
@@ -23,7 +23,7 @@ index 661a6b6bc..17dde317f 100644
}
// LoadHostnamePolicyFile will load the given policy file, returning an error if
@@ -134,10 +141,21 @@ func (pa *AuthorityImpl) processHostnamePolicy(policy blockedNamesPolicy) error
@@ -125,10 +132,21 @@ func (pa *AuthorityImpl) processHostnamePolicy(policy blockedNamesPolicy) error
// wildcardNameMap to block issuance for `*.`+parts[1]
wildcardNameMap[parts[1]] = true
}
@@ -45,7 +45,7 @@ index 661a6b6bc..17dde317f 100644
pa.blocklistMu.Unlock()
return nil
}
@@ -209,7 +227,7 @@ var (
@@ -199,7 +217,7 @@ var (
// - exactly equal to an IANA registered TLD
//
// It does NOT ensure that the domain is absent from any PA blocked lists.
@@ -54,7 +54,7 @@ index 661a6b6bc..17dde317f 100644
if domain == "" {
return errEmptyIdentifier
}
@@ -241,7 +259,9 @@ func validNonWildcardDomain(domain string) error {
@@ -232,7 +250,9 @@ func validNonWildcardDomain(domain string) error {
return errTooManyLabels
}
if len(labels) < 2 {
@@ -65,7 +65,7 @@ index 661a6b6bc..17dde317f 100644
}
for _, label := range labels {
// Check that this is a valid LDH Label: "A string consisting of ASCII
@@ -285,6 +305,14 @@ func validNonWildcardDomain(domain string) error {
@@ -276,6 +296,14 @@ func validNonWildcardDomain(domain string) error {
}
}
@@ -80,7 +80,7 @@ index 661a6b6bc..17dde317f 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 {
@@ -300,9 +328,9 @@ func validNonWildcardDomain(domain string) error {
@@ -291,9 +319,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.
@@ -92,7 +92,7 @@ index 661a6b6bc..17dde317f 100644
}
// Names containing more than one wildcard are invalid.
@@ -321,7 +349,7 @@ func ValidDomain(domain string) error {
@@ -312,7 +340,7 @@ func ValidDomain(domain string) error {
// Names must end in an ICANN TLD, but they must not be equal to an ICANN TLD.
icannTLD, err := iana.ExtractSuffix(baseDomain)
@@ -101,7 +101,7 @@ index 661a6b6bc..17dde317f 100644
return errNonPublic
}
// Names must have a non-wildcard label immediately adjacent to the ICANN
@@ -329,7 +357,7 @@ func ValidDomain(domain string) error {
@@ -320,7 +348,7 @@ func ValidDomain(domain string) error {
if baseDomain == icannTLD {
return errICANNTLDWildcard
}
@@ -109,8 +109,8 @@ index 661a6b6bc..17dde317f 100644
+ return pa.ValidNonWildcardDomain(baseDomain, false)
}
// validIP checks that an IP address:
@@ -375,14 +403,14 @@ var forbiddenMailDomains = map[string]bool{
// ValidIP checks that an IP address:
@@ -363,14 +391,14 @@ var forbiddenMailDomains = map[string]bool{
// ValidEmail returns an error if the input doesn't parse as an email address,
// the domain isn't a valid hostname in Preferred Name Syntax, or its on the
// list of domains forbidden for mail (because they are often used in examples).
@@ -127,7 +127,7 @@ index 661a6b6bc..17dde317f 100644
if err != nil {
return berrors.InvalidEmailError("contact email has invalid domain: %s", err)
}
@@ -424,7 +452,7 @@ func subError(ident identifier.ACMEIdentifier, err error) berrors.SubBoulderErro
@@ -412,7 +440,7 @@ func subError(ident identifier.ACMEIdentifier, err error) berrors.SubBoulderErro
//
// Precondition: all input identifier values must be in lowercase.
func (pa *AuthorityImpl) WillingToIssue(idents identifier.ACMEIdentifiers) error {
@@ -136,7 +136,7 @@ index 661a6b6bc..17dde317f 100644
if err != nil {
return err
}
@@ -454,6 +482,10 @@ func (pa *AuthorityImpl) WillingToIssue(idents identifier.ACMEIdentifiers) error
@@ -442,6 +470,10 @@ func (pa *AuthorityImpl) WillingToIssue(idents identifier.ACMEIdentifiers) error
}
}
@@ -147,7 +147,7 @@ index 661a6b6bc..17dde317f 100644
// For both wildcard and non-wildcard domains, check whether any parent domain
// name is on the regular blocklist.
err := pa.checkHostLists(ident.Value)
@@ -494,12 +526,12 @@ func (pa *AuthorityImpl) WillingToIssue(idents identifier.ACMEIdentifiers) error
@@ -483,12 +515,12 @@ func (pa *AuthorityImpl) WillingToIssue(idents identifier.ACMEIdentifiers) error
//
// If multiple identifiers are invalid, the error will contain suberrors
// specific to each identifier.
@@ -162,7 +162,7 @@ index 661a6b6bc..17dde317f 100644
if err != nil {
subErrors = append(subErrors, subError(ident, err))
}
@@ -541,6 +573,34 @@ func combineSubErrors(subErrors []berrors.SubBoulderError) error {
@@ -530,6 +562,34 @@ func combineSubErrors(subErrors []berrors.SubBoulderError) error {
return nil
}
@@ -197,7 +197,7 @@ index 661a6b6bc..17dde317f 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.
@@ -570,6 +630,9 @@ func (pa *AuthorityImpl) checkHostLists(domain string) error {
@@ -559,6 +619,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 e8acf0781..3122449be 100644
index ba993179a..04aec2370 100644
--- a/ra/ra.go
+++ b/ra/ra.go
@@ -44,7 +44,6 @@ import (
@@ -10,7 +10,7 @@ index e8acf0781..3122449be 100644
"github.com/letsencrypt/boulder/probs"
pubpb "github.com/letsencrypt/boulder/publisher/proto"
rapb "github.com/letsencrypt/boulder/ra/proto"
@@ -608,7 +607,7 @@ func (ra *RegistrationAuthorityImpl) validateContacts(contacts []string) error {
@@ -574,7 +573,7 @@ func (ra *RegistrationAuthorityImpl) validateContacts(contacts []string) error {
if !core.IsASCII(contact) {
return berrors.InvalidEmailError("contact email contains non-ASCII characters")
}
@@ -19,7 +19,7 @@ index e8acf0781..3122449be 100644
if err != nil {
return err
}
@@ -1981,6 +1980,9 @@ func crlShard(cert *x509.Certificate) (int64, error) {
@@ -1895,6 +1894,9 @@ func crlShard(cert *x509.Certificate) (int64, error) {
return 0, fmt.Errorf("malformed CRLDistributionPoint %q", url)
}
shardStr := url[lastIndex+1:]

View File

@@ -1,8 +1,8 @@
diff --git a/ratelimits/names.go b/ratelimits/names.go
index bfda772b5..971892f22 100644
index 1ce3c514c..6f72b517c 100644
--- a/ratelimits/names.go
+++ b/ratelimits/names.go
@@ -102,6 +102,9 @@ var nameToString = map[Name]string{
@@ -114,6 +114,9 @@ var nameToString = map[Name]string{
FailedAuthorizationsForPausingPerDomainPerAccount: "FailedAuthorizationsForPausingPerDomainPerAccount",
}
@@ -12,53 +12,54 @@ index bfda772b5..971892f22 100644
// isValid returns true if the Name is a valid rate limit name.
func (n Name) isValid() bool {
return n > Unknown && n < Name(len(nameToString))
@@ -163,7 +166,15 @@ func validateRegId(id string) error {
// validateDomain validates that the provided string is formatted 'domain',
// where domain is a domain name.
func validateDomain(id string) error {
- err := policy.ValidDomain(id)
@@ -195,7 +198,14 @@ func validateRegIdIdentValue(id string) error {
return fmt.Errorf(
"invalid regId, %q must be formatted 'regId:identValue'", id)
}
- domainErr := policy.ValidDomain(regIdIdentValue[1])
+ pa := PA
+ if pa == nil {
+ pa, err = policy.New(map[identifier.IdentifierType]bool{"dns": true}, nil, nil)
+ if err != nil {
+ return fmt.Errorf("cannot create policy authority implementation")
+ }
+ }
+ domainErr := pa.ValidDomain(regIdIdentValue[1])
if domainErr != nil {
ipErr := policy.ValidIP(regIdIdentValue[1])
if ipErr != nil {
@@ -209,7 +219,15 @@ func validateRegIdIdentValue(id string) error {
// name or an IP address. IPv6 addresses must be the lowest address in their
// /64, i.e. their last 64 bits must be zero.
func validateDomainOrCIDR(limit Name, id string) error {
- domainErr := policy.ValidDomain(id)
+ pa := PA
+ var err error
+ if pa == nil {
+ pa, err = policy.New(nil, nil, nil)
+ pa, err = policy.New(map[identifier.IdentifierType]bool{"dns": true}, nil, nil)
+ if err != nil {
+ return fmt.Errorf("cannot create policy authority implementation")
+ }
+ }
+ err = pa.ValidDomain(id)
if err != nil {
return fmt.Errorf("invalid domain, %q must be formatted 'domain': %w", id, err)
}
@@ -184,7 +195,14 @@ func validateRegIdDomain(id string) error {
return fmt.Errorf(
"invalid regId, %q must be formatted 'regId:domain'", id)
}
- err = policy.ValidDomain(regIdDomain[1])
+ pa := PA
+ if pa == nil {
+ pa, err = policy.New(nil, nil, nil)
+ if err != nil {
+ return fmt.Errorf("cannot create policy authority implementation")
+ }
+ }
+ err = pa.ValidDomain(regIdDomain[1])
if err != nil {
return fmt.Errorf(
"invalid domain, %q must be formatted 'regId:domain': %w", id, err)
@@ -202,7 +220,15 @@ func validateFQDNSet(id string) error {
+ domainErr := pa.ValidDomain(id)
if domainErr == nil {
// This is a valid domain.
return nil
@@ -264,8 +282,16 @@ func validateFQDNSet(id string) error {
return fmt.Errorf(
"invalid fqdnSet, %q must be formatted 'fqdnSet'", id)
}
- return policy.WellFormedIdentifiers(identifier.NewDNSSlice(domains))
+ pa := PA
+ var err error
+ pa := PA
+ if pa == nil {
+ pa, err = policy.New(nil, nil, nil)
+ pa, err = policy.New(map[identifier.IdentifierType]bool{"dns": true}, nil, nil)
+ if err != nil {
+ return fmt.Errorf("cannot create policy authority implementation")
+ }
+ }
+ return pa.WellFormedIdentifiers(identifier.NewDNSSlice(domains))
}
func validateIdForName(name Name, id string) error {
for _, value := range values {
- domainErr := policy.ValidDomain(value)
+ domainErr := pa.ValidDomain(value)
if domainErr != nil {
ipErr := policy.ValidIP(value)
if ipErr != nil {

View File

@@ -1,8 +1,8 @@
diff --git a/cmd/remoteva/main.go b/cmd/remoteva/main.go
index f99ded497..9a1033a87 100644
index f4c0cbe76..1f454f489 100644
--- a/cmd/remoteva/main.go
+++ b/cmd/remoteva/main.go
@@ -56,7 +56,8 @@ type Config struct {
@@ -57,7 +57,8 @@ type Config struct {
// For more information, see: https://pkg.go.dev/crypto/tls#ClientAuthType
SkipGRPCClientCertVerification bool
@@ -12,12 +12,30 @@ index f99ded497..9a1033a87 100644
}
Syslog cmd.SyslogConfig
@@ -141,7 +142,8 @@ func main() {
@@ -87,12 +88,16 @@ func main() {
clk := cmd.Clock()
var servers bdns.ServerProvider
+ proto := "udp"
+ if features.Get().DOH {
+ proto = "tcp"
+ }
if len(c.RVA.DNSStaticResolvers) != 0 {
servers, err = bdns.NewStaticProvider(c.RVA.DNSStaticResolvers)
cmd.FailOnError(err, "Couldn't start static DNS server resolver")
} else {
- servers, err = bdns.StartDynamicProvider(c.RVA.DNSProvider, 60*time.Second, "tcp")
+ servers, err = bdns.StartDynamicProvider(c.RVA.DNSProvider, 60*time.Second, proto)
cmd.FailOnError(err, "Couldn't start dynamic DNS server resolver")
}
defer servers.Stop()
@@ -138,7 +143,8 @@ func main() {
c.RVA.AccountURIPrefixes,
c.RVA.Perspective,
c.RVA.RIR,
- bdns.IsReservedIP)
+ bdns.IsReservedIP,
- iana.IsReservedAddr)
+ iana.IsReservedAddr,
+ c.RVA.LabCADomains)
cmd.FailOnError(err, "Unable to create Remote-VA server")

View File

@@ -0,0 +1,13 @@
diff --git a/cmd/reversed-hostname-checker/main.go b/cmd/reversed-hostname-checker/main.go
index 530dd7ca3..1235258ba 100644
--- a/cmd/reversed-hostname-checker/main.go
+++ b/cmd/reversed-hostname-checker/main.go
@@ -41,7 +41,7 @@ func main() {
scanner := bufio.NewScanner(input)
logger := cmd.NewLogger(cmd.SyslogConfig{StdoutLevel: 7})
logger.Info(cmd.VersionString())
- pa, err := policy.New(nil, nil, logger)
+ pa, err := policy.New(map[identifier.IdentifierType]bool{"dns": true}, nil, logger)
if err != nil {
log.Fatal(err)
}

View File

@@ -1,5 +1,5 @@
diff --git a/test/config/ca.json b/test/config/ca.json
index 35843b094..2d4e0c951 100644
index e9a866ee6..e44b75aed 100644
--- a/test/config/ca.json
+++ b/test/config/ca.json
@@ -1,11 +1,11 @@
@@ -139,7 +139,7 @@ index 35843b094..2d4e0c951 100644
"features": {}
},
"pa": {
@@ -194,7 +137,7 @@
@@ -197,7 +140,7 @@
}
},
"syslog": {

View File

@@ -1,8 +1,8 @@
diff --git a/va/http.go b/va/http.go
index 00942ede3..2b4ece730 100644
index e7b0ec304..2b2aa2210 100644
--- a/va/http.go
+++ b/va/http.go
@@ -341,7 +341,16 @@ func (va *ValidationAuthorityImpl) extractRequestTarget(req *http.Request) (iden
@@ -350,7 +350,16 @@ func (va *ValidationAuthorityImpl) extractRequestTarget(req *http.Request) (iden
}
if _, err := iana.ExtractSuffix(reqHost); err != nil {
@@ -20,3 +20,18 @@ index 00942ede3..2b4ece730 100644
}
return identifier.NewDNS(reqHost), reqPort, nil
@@ -398,10 +407,10 @@ func (va *ValidationAuthorityImpl) setupHTTPValidation(
// This is a backstop check to avoid connecting to reserved IP addresses.
// They should have been caught and excluded by `bdns.LookupHost`.
- err := va.isReservedIPFunc(targetIP)
- if err != nil {
- return nil, record, err
- }
+ // err := va.isReservedIPFunc(targetIP)
+ // if err != nil {
+ // return nil, record, err
+ // }
record.AddressUsed = targetIP

View File

@@ -1,24 +1,24 @@
diff --git a/va/va.go b/va/va.go
index 5e7732d69..9a908c255 100644
index 4307e57b4..c63b2dea8 100644
--- a/va/va.go
+++ b/va/va.go
@@ -217,6 +217,7 @@ type ValidationAuthorityImpl struct {
@@ -218,6 +218,7 @@ type ValidationAuthorityImpl struct {
perspective string
rir string
isReservedIPFunc func(ip net.IP) bool
isReservedIPFunc func(netip.Addr) error
+ labcaDomains []string
metrics *vaMetrics
}
@@ -237,6 +238,7 @@ func NewValidationAuthorityImpl(
@@ -238,6 +239,7 @@ func NewValidationAuthorityImpl(
perspective string,
rir string,
reservedIPChecker func(ip net.IP) bool,
reservedIPChecker func(netip.Addr) error,
+ labcaDomains []string,
) (*ValidationAuthorityImpl, error) {
if len(accountURIPrefixes) == 0 {
@@ -274,6 +276,7 @@ func NewValidationAuthorityImpl(
@@ -275,6 +277,7 @@ func NewValidationAuthorityImpl(
perspective: perspective,
rir: rir,
isReservedIPFunc: reservedIPChecker,

View File

@@ -1,5 +1,5 @@
diff --git a/cmd/boulder-wfe2/main.go b/cmd/boulder-wfe2/main.go
index 1f33c4746..1b0ad2ddb 100644
index 955fe406c..33cc238d9 100644
--- a/cmd/boulder-wfe2/main.go
+++ b/cmd/boulder-wfe2/main.go
@@ -12,14 +12,17 @@ import (
@@ -29,7 +29,7 @@ index 1f33c4746..1b0ad2ddb 100644
// DirectoryWebsite is used for the /directory response's "meta" element's
// "website" field.
DirectoryWebsite string `validate:"required,url"`
@@ -175,6 +178,8 @@ type Config struct {
@@ -180,6 +183,8 @@ type Config struct {
// to enable the pausing feature.
URL string `validate:"omitempty,required_with=HMACKey JWTLifetime,url,startswith=https://,endsnotwith=/"`
}
@@ -38,7 +38,7 @@ index 1f33c4746..1b0ad2ddb 100644
}
Syslog cmd.SyslogConfig
@@ -315,11 +320,25 @@ func main() {
@@ -324,11 +329,25 @@ func main() {
var limiter *ratelimits.Limiter
var txnBuilder *ratelimits.TransactionBuilder
var limiterRedis *bredis.Ring
@@ -64,7 +64,7 @@ index 1f33c4746..1b0ad2ddb 100644
source := ratelimits.NewRedisSource(limiterRedis.Ring, clk, stats)
limiter, err = ratelimits.NewLimiter(clk, source, stats)
cmd.FailOnError(err, "Failed to create rate limiter")
@@ -359,6 +378,7 @@ func main() {
@@ -369,6 +388,7 @@ func main() {
unpauseSigner,
c.WFE.Unpause.JWTLifetime.Duration,
c.WFE.Unpause.URL,

View File

@@ -1,8 +1,8 @@
diff --git a/wfe2/wfe.go b/wfe2/wfe.go
index 462866a1d..287e6af55 100644
index 891d165b6..1a4fda298 100644
--- a/wfe2/wfe.go
+++ b/wfe2/wfe.go
@@ -163,6 +163,8 @@ type WebFrontEndImpl struct {
@@ -166,6 +166,8 @@ type WebFrontEndImpl struct {
// descriptions (perhaps including URLs) of those profiles. NewOrder
// Requests with a profile name not present in this map will be rejected.
certProfiles map[string]string
@@ -11,7 +11,7 @@ index 462866a1d..287e6af55 100644
}
// NewWebFrontEndImpl constructs a web service for Boulder
@@ -188,6 +190,7 @@ func NewWebFrontEndImpl(
@@ -192,6 +194,7 @@ func NewWebFrontEndImpl(
unpauseSigner unpause.JWTSigner,
unpauseJWTLifetime time.Duration,
unpauseURL string,
@@ -19,7 +19,7 @@ index 462866a1d..287e6af55 100644
) (WebFrontEndImpl, error) {
if len(issuerCertificates) == 0 {
return WebFrontEndImpl{}, errors.New("must provide at least one issuer certificate")
@@ -205,6 +208,10 @@ func NewWebFrontEndImpl(
@@ -209,6 +212,10 @@ func NewWebFrontEndImpl(
return WebFrontEndImpl{}, errors.New("must provide a service for nonce redemption")
}
@@ -30,7 +30,7 @@ index 462866a1d..287e6af55 100644
wfe := WebFrontEndImpl{
log: logger,
clk: clk,
@@ -227,6 +234,7 @@ func NewWebFrontEndImpl(
@@ -232,6 +239,7 @@ func NewWebFrontEndImpl(
unpauseSigner: unpauseSigner,
unpauseJWTLifetime: unpauseJWTLifetime,
unpauseURL: unpauseURL,
@@ -38,34 +38,16 @@ index 462866a1d..287e6af55 100644
}
return wfe, nil
@@ -635,7 +643,7 @@ func link(url, relation string) string {
// contactsToEmails converts a *[]string of contacts (e.g. mailto:
// person@example.com) to a []string of valid email addresses. Non-email
// contacts or contacts with invalid email addresses are ignored.
-func contactsToEmails(contacts *[]string) []string {
+func contactsToEmails(contacts *[]string, pa *policy.AuthorityImpl) []string {
if contacts == nil {
return nil
}
@@ -645,7 +653,7 @@ func contactsToEmails(contacts *[]string) []string {
continue
@@ -678,7 +686,7 @@ func (wfe *WebFrontEndImpl) contactsToEmails(contacts []string) ([]string, error
return nil, berrors.InvalidEmailError("contact email contains non-ASCII characters")
}
address := strings.TrimPrefix(c, "mailto:")
- err := policy.ValidEmail(address)
+ err := pa.ValidEmail(address)
if err != nil {
continue
}
@@ -869,7 +877,7 @@ func (wfe *WebFrontEndImpl) NewAccount(
}
newRegistrationSuccessful = true
- emails := contactsToEmails(accountCreateRequest.Contact)
+ emails := contactsToEmails(accountCreateRequest.Contact, wfe.pa)
if wfe.ee != nil && len(emails) > 0 {
_, err := wfe.ee.SendContacts(ctx, &emailpb.SendContactsRequest{
// Note: We are explicitly using the contacts provided by the
@@ -2300,7 +2308,7 @@ func (wfe *WebFrontEndImpl) NewOrder(
- err = policy.ValidEmail(parsed.Opaque)
+ err = wfe.pa.ValidEmail(parsed.Opaque)
if err != nil {
return nil, err
}
@@ -2299,7 +2307,7 @@ func (wfe *WebFrontEndImpl) NewOrder(
idents = identifier.Normalize(idents)
logEvent.Identifiers = idents