mirror of
https://github.com/outbackdingo/labca.git
synced 2026-01-27 10:19:34 +00:00
Bump boulder version to v0.20250707.0
This commit is contained in:
2
.github/workflows/build-standalone.yml
vendored
2
.github/workflows/build-standalone.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
GO_VERSION:
|
||||
- 1.24.1
|
||||
- 1.24.4
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
2
.github/workflows/golangci-lint.yml
vendored
2
.github/workflows/golangci-lint.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
GO_VERSION:
|
||||
- 1.24.1
|
||||
- 1.24.4
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
GO_VERSION:
|
||||
- 1.24.1
|
||||
- 1.24.4
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)/..
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
6
install
6
install
@@ -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/"
|
||||
|
||||
169
mail-tester.go
169
mail-tester.go
@@ -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{}})
|
||||
}
|
||||
10
patch-cfg.sh
10
patch-cfg.sh
@@ -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
|
||||
|
||||
10
patch.sh
10
patch.sh
@@ -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
|
||||
|
||||
@@ -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
81
patches/bdns_dns.patch
Normal 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++
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
@@ -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
|
||||
@@ -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,
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
@@ -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
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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:], ".")
|
||||
|
||||
@@ -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:]
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
13
patches/reversed-hostname-checker_main.patch
Normal file
13
patches/reversed-hostname-checker_main.patch
Normal 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)
|
||||
}
|
||||
@@ -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": {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user