mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-29 10:26:29 +02:00
* chore(deps): bump the go group across 1 directory with 44 updates Bumps the go group with 26 updates in the / directory: | Package | From | To | | --- | --- | --- | | [cloud.google.com/go/storage](https://github.com/googleapis/google-cloud-go) | `1.49.0` | `1.50.0` | | [github.com/aws/aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2) | `1.32.7` | `1.36.3` | | [github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2) | `1.28.7` | `1.29.8` | | [github.com/aws/aws-sdk-go-v2/service/s3](https://github.com/aws/aws-sdk-go-v2) | `1.71.1` | `1.78.0` | | [github.com/bits-and-blooms/bitset](https://github.com/bits-and-blooms/bitset) | `1.20.0` | `1.21.0` | | [github.com/caddyserver/certmagic](https://github.com/caddyserver/certmagic) | `0.21.4` | `0.21.7` | | [github.com/cloudflare/circl](https://github.com/cloudflare/circl) | `1.5.0` | `1.6.0` | | [github.com/coreos/go-oidc/v3](https://github.com/coreos/go-oidc) | `3.11.0` | `3.12.0` | | [github.com/docker/docker](https://github.com/docker/docker) | `27.4.1+incompatible` | `28.0.1+incompatible` | | [github.com/envoyproxy/go-control-plane/envoy](https://github.com/envoyproxy/go-control-plane) | `1.32.3` | `1.32.4` | | [github.com/exaring/otelpgx](https://github.com/exaring/otelpgx) | `0.8.0` | `0.9.0` | | [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) | `5.2.0` | `5.2.1` | | [github.com/google/go-cmp](https://github.com/google/go-cmp) | `0.6.0` | `0.7.0` | | [github.com/grpc-ecosystem/go-grpc-middleware/v2](https://github.com/grpc-ecosystem/go-grpc-middleware) | `2.2.0` | `2.3.0` | | [github.com/klauspost/compress](https://github.com/klauspost/compress) | `1.17.11` | `1.18.0` | | [github.com/minio/minio-go/v7](https://github.com/minio/minio-go) | `7.0.82` | `7.0.87` | | [github.com/open-policy-agent/opa](https://github.com/open-policy-agent/opa) | `1.0.0` | `1.2.0` | | [github.com/pomerium/envoy-custom](https://github.com/pomerium/envoy-custom) | `1.32.4-0.20250114182541-6f6d2147bea6` | `1.33.0` | | [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) | `0.48.2` | `0.50.0` | | [github.com/testcontainers/testcontainers-go](https://github.com/testcontainers/testcontainers-go) | `0.34.0` | `0.35.0` | | [go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc](https://github.com/open-telemetry/opentelemetry-go-contrib) | `0.57.0` | `0.59.0` | | [go.opentelemetry.io/contrib/propagators/autoprop](https://github.com/open-telemetry/opentelemetry-go-contrib) | `0.57.0` | `0.59.0` | | [go.opentelemetry.io/otel/bridge/opencensus](https://github.com/open-telemetry/opentelemetry-go) | `1.32.0` | `1.34.0` | | [go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc](https://github.com/open-telemetry/opentelemetry-go) | `1.32.0` | `1.34.0` | | [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp](https://github.com/open-telemetry/opentelemetry-go) | `1.32.0` | `1.34.0` | | [google.golang.org/api](https://github.com/googleapis/google-api-go-client) | `0.214.0` | `0.223.0` | Updates `cloud.google.com/go/storage` from 1.49.0 to 1.50.0 - [Release notes](https://github.com/googleapis/google-cloud-go/releases) - [Changelog](https://github.com/googleapis/google-cloud-go/blob/main/CHANGES.md) - [Commits](https://github.com/googleapis/google-cloud-go/compare/spanner/v1.49.0...spanner/v1.50.0) Updates `github.com/aws/aws-sdk-go-v2` from 1.32.7 to 1.36.3 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/main/changelog-template.json) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.32.7...v1.36.3) Updates `github.com/aws/aws-sdk-go-v2/config` from 1.28.7 to 1.29.8 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/main/changelog-template.json) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.28.7...config/v1.29.8) Updates `github.com/aws/aws-sdk-go-v2/service/s3` from 1.71.1 to 1.78.0 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/main/changelog-template.json) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.71.1...service/s3/v1.78.0) Updates `github.com/bits-and-blooms/bitset` from 1.20.0 to 1.21.0 - [Release notes](https://github.com/bits-and-blooms/bitset/releases) - [Commits](https://github.com/bits-and-blooms/bitset/compare/v1.20.0...v1.21.0) Updates `github.com/caddyserver/certmagic` from 0.21.4 to 0.21.7 - [Release notes](https://github.com/caddyserver/certmagic/releases) - [Commits](https://github.com/caddyserver/certmagic/compare/v0.21.4...v0.21.7) Updates `github.com/cloudflare/circl` from 1.5.0 to 1.6.0 - [Release notes](https://github.com/cloudflare/circl/releases) - [Commits](https://github.com/cloudflare/circl/compare/v1.5.0...v1.6.0) Updates `github.com/coreos/go-oidc/v3` from 3.11.0 to 3.12.0 - [Release notes](https://github.com/coreos/go-oidc/releases) - [Commits](https://github.com/coreos/go-oidc/compare/v3.11.0...v3.12.0) Updates `github.com/docker/docker` from 27.4.1+incompatible to 28.0.1+incompatible - [Release notes](https://github.com/docker/docker/releases) - [Commits](https://github.com/docker/docker/compare/v27.4.1...v28.0.1) Updates `github.com/envoyproxy/go-control-plane/envoy` from 1.32.3 to 1.32.4 - [Release notes](https://github.com/envoyproxy/go-control-plane/releases) - [Changelog](https://github.com/envoyproxy/go-control-plane/blob/main/CHANGELOG.md) - [Commits](https://github.com/envoyproxy/go-control-plane/compare/envoy/v1.32.3...envoy/v1.32.4) Updates `github.com/envoyproxy/protoc-gen-validate` from 1.1.0 to 1.2.1 - [Release notes](https://github.com/envoyproxy/protoc-gen-validate/releases) - [Changelog](https://github.com/bufbuild/protoc-gen-validate/blob/main/.goreleaser.yaml) - [Commits](https://github.com/envoyproxy/protoc-gen-validate/compare/v1.1.0...v1.2.1) Updates `github.com/exaring/otelpgx` from 0.8.0 to 0.9.0 - [Release notes](https://github.com/exaring/otelpgx/releases) - [Commits](https://github.com/exaring/otelpgx/compare/v0.8.0...v0.9.0) Updates `github.com/go-chi/chi/v5` from 5.2.0 to 5.2.1 - [Release notes](https://github.com/go-chi/chi/releases) - [Changelog](https://github.com/go-chi/chi/blob/master/CHANGELOG.md) - [Commits](https://github.com/go-chi/chi/compare/v5.2.0...v5.2.1) Updates `github.com/google/go-cmp` from 0.6.0 to 0.7.0 - [Release notes](https://github.com/google/go-cmp/releases) - [Commits](https://github.com/google/go-cmp/compare/v0.6.0...v0.7.0) Updates `github.com/grpc-ecosystem/go-grpc-middleware/v2` from 2.2.0 to 2.3.0 - [Release notes](https://github.com/grpc-ecosystem/go-grpc-middleware/releases) - [Commits](https://github.com/grpc-ecosystem/go-grpc-middleware/compare/v2.2.0...v2.3.0) Updates `github.com/klauspost/compress` from 1.17.11 to 1.18.0 - [Release notes](https://github.com/klauspost/compress/releases) - [Changelog](https://github.com/klauspost/compress/blob/master/.goreleaser.yml) - [Commits](https://github.com/klauspost/compress/compare/v1.17.11...v1.18.0) Updates `github.com/minio/minio-go/v7` from 7.0.82 to 7.0.87 - [Release notes](https://github.com/minio/minio-go/releases) - [Commits](https://github.com/minio/minio-go/compare/v7.0.82...v7.0.87) Updates `github.com/open-policy-agent/opa` from 1.0.0 to 1.2.0 - [Release notes](https://github.com/open-policy-agent/opa/releases) - [Changelog](https://github.com/open-policy-agent/opa/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-policy-agent/opa/compare/v1.0.0...v1.2.0) Updates `github.com/pomerium/envoy-custom` from 1.32.4-0.20250114182541-6f6d2147bea6 to 1.33.0 - [Release notes](https://github.com/pomerium/envoy-custom/releases) - [Commits](https://github.com/pomerium/envoy-custom/commits/v1.33.0) Updates `github.com/prometheus/client_golang` from 1.20.5 to 1.21.0 - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.20.5...v1.21.0) Updates `github.com/prometheus/common` from 0.61.0 to 0.62.0 - [Release notes](https://github.com/prometheus/common/releases) - [Changelog](https://github.com/prometheus/common/blob/main/RELEASE.md) - [Commits](https://github.com/prometheus/common/compare/v0.61.0...v0.62.0) Updates `github.com/quic-go/quic-go` from 0.48.2 to 0.50.0 - [Release notes](https://github.com/quic-go/quic-go/releases) - [Changelog](https://github.com/quic-go/quic-go/blob/master/Changelog.md) - [Commits](https://github.com/quic-go/quic-go/compare/v0.48.2...v0.50.0) Updates `github.com/spf13/cobra` from 1.8.1 to 1.9.1 - [Release notes](https://github.com/spf13/cobra/releases) - [Commits](https://github.com/spf13/cobra/compare/v1.8.1...v1.9.1) Updates `github.com/testcontainers/testcontainers-go` from 0.34.0 to 0.35.0 - [Release notes](https://github.com/testcontainers/testcontainers-go/releases) - [Commits](https://github.com/testcontainers/testcontainers-go/compare/v0.34.0...v0.35.0) Updates `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc` from 0.57.0 to 0.59.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go-contrib/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go-contrib/compare/zpages/v0.57.0...zpages/v0.59.0) Updates `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp` from 0.58.0 to 0.59.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go-contrib/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go-contrib/compare/zpages/v0.58.0...zpages/v0.59.0) Updates `go.opentelemetry.io/contrib/propagators/autoprop` from 0.57.0 to 0.59.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go-contrib/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go-contrib/compare/zpages/v0.57.0...zpages/v0.59.0) Updates `go.opentelemetry.io/otel/bridge/opencensus` from 1.32.0 to 1.34.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.32.0...v1.34.0) Updates `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` from 1.32.0 to 1.34.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.32.0...v1.34.0) Updates `go.opentelemetry.io/otel/exporters/otlp/otlptrace` from 1.33.0 to 1.34.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.33.0...v1.34.0) Updates `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` from 1.33.0 to 1.34.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.33.0...v1.34.0) Updates `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` from 1.32.0 to 1.34.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.32.0...v1.34.0) Updates `go.opentelemetry.io/otel/sdk` from 1.33.0 to 1.34.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.33.0...v1.34.0) Updates `go.opentelemetry.io/otel/sdk/metric` from 1.32.0 to 1.34.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.32.0...v1.34.0) Updates `go.opentelemetry.io/proto/otlp` from 1.4.0 to 1.5.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-proto-go/releases) - [Commits](https://github.com/open-telemetry/opentelemetry-proto-go/compare/v1.4.0...v1.5.0) Updates `golang.org/x/crypto` from 0.32.0 to 0.33.0 - [Commits](https://github.com/golang/crypto/compare/v0.32.0...v0.33.0) Updates `golang.org/x/net` from 0.33.0 to 0.35.0 - [Commits](https://github.com/golang/net/compare/v0.33.0...v0.35.0) Updates `golang.org/x/sync` from 0.10.0 to 0.11.0 - [Commits](https://github.com/golang/sync/compare/v0.10.0...v0.11.0) Updates `golang.org/x/sys` from 0.29.0 to 0.30.0 - [Commits](https://github.com/golang/sys/compare/v0.29.0...v0.30.0) Updates `golang.org/x/time` from 0.8.0 to 0.10.0 - [Commits](https://github.com/golang/time/compare/v0.8.0...v0.10.0) Updates `google.golang.org/api` from 0.214.0 to 0.223.0 - [Release notes](https://github.com/googleapis/google-api-go-client/releases) - [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md) - [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.214.0...v0.223.0) Updates `google.golang.org/genproto/googleapis/rpc` from 0.0.0-20241209162323-e6fa225c2576 to 0.0.0-20250219182151-9fdb1cabc7b2 - [Commits](https://github.com/googleapis/go-genproto/commits) Updates `google.golang.org/grpc` from 1.69.2 to 1.70.0 - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.69.2...v1.70.0) Updates `google.golang.org/protobuf` from 1.36.2 to 1.36.5 --- updated-dependencies: - dependency-name: cloud.google.com/go/storage dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/aws/aws-sdk-go-v2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/aws/aws-sdk-go-v2/config dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/aws/aws-sdk-go-v2/service/s3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/bits-and-blooms/bitset dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/caddyserver/certmagic dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go - dependency-name: github.com/cloudflare/circl dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/coreos/go-oidc/v3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/docker/docker dependency-type: direct:production update-type: version-update:semver-major dependency-group: go - dependency-name: github.com/envoyproxy/go-control-plane/envoy dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go - dependency-name: github.com/envoyproxy/protoc-gen-validate dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/exaring/otelpgx dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/go-chi/chi/v5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go - dependency-name: github.com/google/go-cmp dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/grpc-ecosystem/go-grpc-middleware/v2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/klauspost/compress dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/minio/minio-go/v7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go - dependency-name: github.com/open-policy-agent/opa dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/pomerium/envoy-custom dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/prometheus/common dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/quic-go/quic-go dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/spf13/cobra dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: github.com/testcontainers/testcontainers-go dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: go.opentelemetry.io/contrib/propagators/autoprop dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: go.opentelemetry.io/otel/bridge/opencensus dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: go.opentelemetry.io/otel/exporters/otlp/otlptrace dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: go.opentelemetry.io/otel/sdk dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: go.opentelemetry.io/otel/sdk/metric dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: go.opentelemetry.io/proto/otlp dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: golang.org/x/crypto dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: golang.org/x/sync dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: golang.org/x/sys dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: golang.org/x/time dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: google.golang.org/api dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: google.golang.org/genproto/googleapis/rpc dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go - dependency-name: google.golang.org/protobuf dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go ... Signed-off-by: dependabot[bot] <support@github.com> * fix go.mod * bump acmez * bump docker build * bump docker build --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Denis Mishin <dmishin@pomerium.com>
533 lines
14 KiB
Go
533 lines
14 KiB
Go
// Package autocert implements automatic management of TLS certificates.
|
|
package autocert
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"encoding/base64"
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"sort"
|
|
"strings"
|
|
"sync"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"github.com/caddyserver/certmagic"
|
|
"github.com/mholt/acmez/v3/acme"
|
|
"github.com/pires/go-proxyproto"
|
|
"github.com/rs/zerolog"
|
|
|
|
"github.com/pomerium/pomerium/config"
|
|
"github.com/pomerium/pomerium/internal/httputil"
|
|
"github.com/pomerium/pomerium/internal/log"
|
|
"github.com/pomerium/pomerium/internal/telemetry/metrics"
|
|
"github.com/pomerium/pomerium/internal/urlutil"
|
|
"github.com/pomerium/pomerium/pkg/cryptutil"
|
|
)
|
|
|
|
var (
|
|
errObtainCertFailed = errors.New("obtain cert failed")
|
|
errRenewCertFailed = errors.New("renew cert failed")
|
|
|
|
// RenewCert is not thread-safe
|
|
renewCertLock sync.Mutex
|
|
)
|
|
|
|
const (
|
|
ocspRespCacheSize = 50000
|
|
renewalInterval = time.Minute * 10
|
|
renewalTimeout = time.Hour
|
|
)
|
|
|
|
// Manager manages TLS certificates.
|
|
type Manager struct {
|
|
src config.Source
|
|
acmeTemplate certmagic.ACMEIssuer
|
|
|
|
mu sync.RWMutex
|
|
config *config.Config
|
|
certmagic *certmagic.Config
|
|
acmeMgr atomic.Pointer[certmagic.ACMEIssuer]
|
|
srv *http.Server
|
|
|
|
acmeTLSALPNLock sync.Mutex
|
|
acmeTLSALPNPort string
|
|
acmeTLSALPNListener net.Listener
|
|
acmeTLSALPNConfig *tls.Config
|
|
|
|
*ocspCache
|
|
|
|
config.ChangeDispatcher
|
|
}
|
|
|
|
// New creates a new autocert manager.
|
|
func New(ctx context.Context, src config.Source) (*Manager, error) {
|
|
return newManager(ctx, src, certmagic.DefaultACME, renewalInterval)
|
|
}
|
|
|
|
func newManager(
|
|
ctx context.Context,
|
|
src config.Source,
|
|
acmeTemplate certmagic.ACMEIssuer,
|
|
checkInterval time.Duration,
|
|
) (*Manager, error) {
|
|
ctx = log.WithContext(ctx, func(c zerolog.Context) zerolog.Context {
|
|
return c.Str("service", "autocert-manager")
|
|
})
|
|
|
|
ocspRespCache, err := newOCSPCache(ocspRespCacheSize)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
logger := getCertMagicLogger()
|
|
acmeTemplate.Logger = logger
|
|
|
|
mgr := &Manager{
|
|
src: src,
|
|
acmeTemplate: acmeTemplate,
|
|
ocspCache: ocspRespCache,
|
|
}
|
|
|
|
// set certmagic default storage cache, otherwise cert renewal loop will be based off
|
|
// certmagic's own default location
|
|
certmagicStorage, err := GetCertMagicStorage(ctx, src.GetConfig().Options.AutocertOptions.Folder)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cache := certmagic.NewCache(certmagic.CacheOptions{
|
|
GetConfigForCert: func(_ certmagic.Certificate) (*certmagic.Config, error) {
|
|
return mgr.certmagic, nil
|
|
},
|
|
Logger: logger,
|
|
})
|
|
mgr.certmagic = certmagic.New(cache, certmagic.Config{
|
|
Logger: logger,
|
|
Storage: certmagicStorage,
|
|
})
|
|
|
|
err = mgr.update(ctx, src.GetConfig())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
mgr.src.OnConfigChange(ctx, func(ctx context.Context, cfg *config.Config) {
|
|
err := mgr.update(ctx, cfg)
|
|
if err != nil {
|
|
log.Ctx(ctx).Error().Err(err).Msg("autocert: error updating config")
|
|
return
|
|
}
|
|
|
|
cfg = mgr.GetConfig()
|
|
mgr.Trigger(ctx, cfg)
|
|
})
|
|
go func() {
|
|
ticker := time.NewTicker(checkInterval)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
cache.Stop()
|
|
return
|
|
case <-ticker.C:
|
|
err := mgr.renewConfigCerts(ctx)
|
|
if err != nil {
|
|
log.Ctx(ctx).Error().Err(err).Msg("autocert: error updating config")
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
return mgr, nil
|
|
}
|
|
|
|
func (mgr *Manager) getCertMagicConfig(ctx context.Context, cfg *config.Config) (*certmagic.Config, error) {
|
|
mgr.certmagic.MustStaple = cfg.Options.AutocertOptions.MustStaple
|
|
mgr.certmagic.OnDemand = nil // disable on-demand
|
|
var err error
|
|
mgr.certmagic.Storage, err = GetCertMagicStorage(ctx, cfg.Options.AutocertOptions.Folder)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
certs, err := cfg.AllCertificates()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// add existing certs to the cache, and staple OCSP
|
|
for _, cert := range certs {
|
|
if _, err := mgr.certmagic.CacheUnmanagedTLSCertificate(ctx, cert, nil); err != nil {
|
|
return nil, fmt.Errorf("config: failed caching cert: %w", err)
|
|
}
|
|
}
|
|
acmeMgr := certmagic.NewACMEIssuer(mgr.certmagic, mgr.acmeTemplate)
|
|
acmeMgr.DisableHTTPChallenge = !shouldEnableHTTPChallenge(cfg)
|
|
err = configureCertificateAuthority(acmeMgr, cfg.Options.AutocertOptions)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = configureExternalAccountBinding(acmeMgr, cfg.Options.AutocertOptions)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = configureTrustedRoots(acmeMgr, cfg.Options.AutocertOptions)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
mgr.certmagic.Issuers = []certmagic.Issuer{acmeMgr}
|
|
mgr.acmeMgr.Store(acmeMgr)
|
|
|
|
return mgr.certmagic, nil
|
|
}
|
|
|
|
func (mgr *Manager) renewConfigCerts(ctx context.Context) error {
|
|
ctx, cancel := context.WithTimeout(ctx, renewalTimeout)
|
|
defer cancel()
|
|
|
|
mgr.mu.Lock()
|
|
defer mgr.mu.Unlock()
|
|
|
|
cfg := mgr.config
|
|
cm, err := mgr.getCertMagicConfig(ctx, cfg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
needsReload := false
|
|
var renew, ocsp []string
|
|
log.Ctx(ctx).Debug().Strs("domains", sourceHostnames(cfg)).Msg("checking domains")
|
|
for _, domain := range sourceHostnames(cfg) {
|
|
cert, err := cm.CacheManagedCertificate(ctx, domain)
|
|
if err != nil {
|
|
// this happens for unmanaged certificates
|
|
continue
|
|
}
|
|
if cert.NeedsRenewal(cm) {
|
|
renew = append(renew, domain)
|
|
needsReload = true
|
|
}
|
|
if mgr.ocspCache.updated(domain, cert.OCSPStaple) {
|
|
ocsp = append(ocsp, domain)
|
|
needsReload = true
|
|
}
|
|
}
|
|
if !needsReload {
|
|
return nil
|
|
}
|
|
|
|
ctx = log.WithContext(ctx, func(c zerolog.Context) zerolog.Context {
|
|
if len(renew) > 0 {
|
|
c = c.Strs("renew_domains", renew)
|
|
}
|
|
if len(ocsp) > 0 {
|
|
c = c.Strs("ocsp_refresh", ocsp)
|
|
}
|
|
return c
|
|
})
|
|
log.Ctx(ctx).Info().Msg("updating certificates")
|
|
|
|
cfg = mgr.src.GetConfig().Clone()
|
|
mgr.updateServer(ctx, cfg)
|
|
mgr.updateACMETLSALPNServer(ctx, cfg)
|
|
if err := mgr.updateAutocert(ctx, cfg); err != nil {
|
|
return err
|
|
}
|
|
|
|
mgr.config = cfg
|
|
mgr.Trigger(ctx, cfg)
|
|
return nil
|
|
}
|
|
|
|
func (mgr *Manager) update(ctx context.Context, cfg *config.Config) error {
|
|
cfg = cfg.Clone()
|
|
|
|
mgr.mu.Lock()
|
|
defer mgr.mu.Unlock()
|
|
defer func() { mgr.config = cfg }()
|
|
|
|
mgr.updateServer(ctx, cfg)
|
|
mgr.updateACMETLSALPNServer(ctx, cfg)
|
|
return mgr.updateAutocert(ctx, cfg)
|
|
}
|
|
|
|
// obtainCert obtains a certificate for given domain, use cached manager if cert exists there.
|
|
func (mgr *Manager) obtainCert(ctx context.Context, domain string, cm *certmagic.Config) (certmagic.Certificate, error) {
|
|
cert, err := cm.CacheManagedCertificate(ctx, domain)
|
|
if err != nil {
|
|
log.Ctx(ctx).Info().Str("domain", domain).Msg("obtaining certificate")
|
|
err = cm.ObtainCertSync(ctx, domain)
|
|
if err != nil {
|
|
log.Ctx(ctx).Error().Err(err).Msg("autocert failed to obtain client certificate")
|
|
return certmagic.Certificate{}, errObtainCertFailed
|
|
}
|
|
metrics.RecordAutocertRenewal()
|
|
cert, err = cm.CacheManagedCertificate(ctx, domain)
|
|
}
|
|
return cert, err
|
|
}
|
|
|
|
// renewCert attempts to renew given certificate.
|
|
func (mgr *Manager) renewCert(ctx context.Context, domain string, cert certmagic.Certificate, cm *certmagic.Config) (certmagic.Certificate, error) {
|
|
expired := time.Now().After(cert.Leaf.NotAfter)
|
|
log.Ctx(ctx).Info().Str("domain", domain).Msg("renewing certificate")
|
|
renewCertLock.Lock()
|
|
err := cm.RenewCertSync(ctx, domain, false)
|
|
renewCertLock.Unlock()
|
|
if err != nil {
|
|
if expired {
|
|
return certmagic.Certificate{}, errRenewCertFailed
|
|
}
|
|
log.Ctx(ctx).Error().Err(err).Msg("renew client certificated failed, use existing cert")
|
|
}
|
|
return cm.CacheManagedCertificate(ctx, domain)
|
|
}
|
|
|
|
func (mgr *Manager) updateAutocert(ctx context.Context, cfg *config.Config) error {
|
|
if !cfg.Options.AutocertOptions.Enable {
|
|
mgr.acmeMgr.Store(nil)
|
|
return nil
|
|
}
|
|
|
|
cm, err := mgr.getCertMagicConfig(ctx, cfg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, domain := range sourceHostnames(cfg) {
|
|
cert, err := mgr.obtainCert(ctx, domain, cm)
|
|
if err == nil && cert.NeedsRenewal(cm) {
|
|
cert, err = mgr.renewCert(ctx, domain, cert, cm)
|
|
}
|
|
if err != nil {
|
|
log.Ctx(ctx).Error().Err(err).Msg("autocert: failed to obtain client certificate")
|
|
continue
|
|
}
|
|
|
|
log.Ctx(ctx).Info().Strs("names", cert.Names).Msg("autocert: added certificate")
|
|
cfg.AutoCertificates = append(cfg.AutoCertificates, cert.Certificate)
|
|
}
|
|
|
|
metrics.RecordAutocertCertificates(cfg.AutoCertificates)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (mgr *Manager) updateServer(ctx context.Context, cfg *config.Config) {
|
|
if mgr.srv != nil {
|
|
// nothing to do if the address hasn't changed
|
|
if mgr.srv.Addr == cfg.Options.HTTPRedirectAddr {
|
|
return
|
|
}
|
|
// close immediately, don't care about the error
|
|
_ = mgr.srv.Close()
|
|
mgr.srv = nil
|
|
}
|
|
|
|
if cfg.Options.HTTPRedirectAddr == "" {
|
|
return
|
|
}
|
|
|
|
redirect := httputil.RedirectHandler()
|
|
|
|
hsrv := &http.Server{
|
|
Addr: cfg.Options.HTTPRedirectAddr,
|
|
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if mgr.handleHTTPChallenge(w, r) {
|
|
return
|
|
}
|
|
redirect.ServeHTTP(w, r)
|
|
}),
|
|
}
|
|
go func() {
|
|
li, err := net.Listen("tcp", cfg.Options.HTTPRedirectAddr)
|
|
if err != nil {
|
|
log.Ctx(ctx).Error().Err(err).Msg("failed to listen on http redirect addr")
|
|
return
|
|
}
|
|
defer li.Close()
|
|
|
|
if cfg.Options.UseProxyProtocol {
|
|
li = &proxyproto.Listener{
|
|
Listener: li,
|
|
ReadHeaderTimeout: 10 * time.Second,
|
|
}
|
|
}
|
|
|
|
log.Ctx(ctx).Info().Str("addr", hsrv.Addr).Msg("starting http redirect server")
|
|
err = hsrv.Serve(li)
|
|
if err != nil {
|
|
log.Ctx(ctx).Error().Err(err).Msg("failed to run http redirect server")
|
|
}
|
|
}()
|
|
mgr.srv = hsrv
|
|
}
|
|
|
|
func (mgr *Manager) updateACMETLSALPNServer(ctx context.Context, cfg *config.Config) {
|
|
mgr.acmeTLSALPNLock.Lock()
|
|
defer mgr.acmeTLSALPNLock.Unlock()
|
|
|
|
// store the updated TLS config
|
|
mgr.acmeTLSALPNConfig = mgr.certmagic.TLSConfig().Clone()
|
|
// if the port hasn't changed, we're done
|
|
if mgr.acmeTLSALPNPort == cfg.ACMETLSALPNPort {
|
|
return
|
|
}
|
|
|
|
// store the updated port
|
|
mgr.acmeTLSALPNPort = cfg.ACMETLSALPNPort
|
|
|
|
if mgr.acmeTLSALPNListener != nil {
|
|
_ = mgr.acmeTLSALPNListener.Close()
|
|
mgr.acmeTLSALPNListener = nil
|
|
}
|
|
|
|
// start the listener
|
|
addr := net.JoinHostPort("127.0.0.1", cfg.ACMETLSALPNPort)
|
|
ln, err := net.Listen("tcp", addr)
|
|
if err != nil {
|
|
log.Ctx(ctx).Error().Err(err).Msg("failed to run acme tls alpn server")
|
|
return
|
|
}
|
|
mgr.acmeTLSALPNListener = ln
|
|
|
|
// accept connections
|
|
go func() {
|
|
for {
|
|
conn, err := ln.Accept()
|
|
if errors.Is(err, net.ErrClosed) {
|
|
return
|
|
} else if err != nil {
|
|
continue
|
|
}
|
|
|
|
// initiate the TLS handshake
|
|
mgr.acmeTLSALPNLock.Lock()
|
|
tlsConfig := mgr.acmeTLSALPNConfig.Clone()
|
|
mgr.acmeTLSALPNLock.Unlock()
|
|
|
|
orig := tlsConfig.GetCertificate
|
|
tlsConfig.GetCertificate = func(chi *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
|
log.Ctx(ctx).Info().Str("server-name", chi.ServerName).
|
|
Msg("received request for ACME TLS ALPN certificate")
|
|
return orig(chi)
|
|
}
|
|
|
|
_ = tls.Server(conn, tlsConfig).HandshakeContext(ctx)
|
|
_ = conn.Close()
|
|
}
|
|
}()
|
|
}
|
|
|
|
func (mgr *Manager) handleHTTPChallenge(w http.ResponseWriter, r *http.Request) bool {
|
|
return mgr.acmeMgr.Load().HandleHTTPChallenge(w, r)
|
|
}
|
|
|
|
// GetConfig gets the config.
|
|
func (mgr *Manager) GetConfig() *config.Config {
|
|
mgr.mu.RLock()
|
|
defer mgr.mu.RUnlock()
|
|
|
|
return mgr.config
|
|
}
|
|
|
|
// configureCertificateAuthority configures the acmeMgr ACME Certificate Authority settings.
|
|
func configureCertificateAuthority(acmeMgr *certmagic.ACMEIssuer, opts config.AutocertOptions) error {
|
|
acmeMgr.Agreed = true
|
|
if opts.UseStaging {
|
|
acmeMgr.CA = acmeMgr.TestCA
|
|
}
|
|
if opts.CA != "" {
|
|
acmeMgr.CA = opts.CA // when a CA is specified, it overrides the staging setting
|
|
}
|
|
if opts.Email != "" {
|
|
acmeMgr.Email = opts.Email
|
|
} else {
|
|
acmeMgr.Email = " " // intentionally set to a space so that certmagic doesn't prompt for an email address
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// configureExternalAccountBinding configures the acmeMgr ACME External Account Binding settings.
|
|
func configureExternalAccountBinding(acmeMgr *certmagic.ACMEIssuer, opts config.AutocertOptions) error {
|
|
if opts.EABKeyID != "" || opts.EABMACKey != "" {
|
|
acmeMgr.ExternalAccount = &acme.EAB{}
|
|
}
|
|
if opts.EABKeyID != "" {
|
|
acmeMgr.ExternalAccount.KeyID = opts.EABKeyID
|
|
}
|
|
if opts.EABMACKey != "" {
|
|
_, err := base64.RawURLEncoding.DecodeString(opts.EABMACKey)
|
|
if err != nil {
|
|
return fmt.Errorf("config: decoding base64-urlencoded MAC Key: %w", err)
|
|
}
|
|
acmeMgr.ExternalAccount.MACKey = opts.EABMACKey
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// configureTrustedRoots configures the acmeMgr x509 roots to trust when communicating with an ACME CA.
|
|
func configureTrustedRoots(acmeMgr *certmagic.ACMEIssuer, opts config.AutocertOptions) error {
|
|
if opts.TrustedCA != "" {
|
|
// pool effectively contains the certificate(s) in the TrustedCA base64 PEM appended to the system roots
|
|
pool, err := cryptutil.GetCertPool(opts.TrustedCA, "")
|
|
if err != nil {
|
|
return fmt.Errorf("config: creating trusted certificate pool: %w", err)
|
|
}
|
|
acmeMgr.TrustedRoots = pool
|
|
}
|
|
if opts.TrustedCAFile != "" {
|
|
// pool effectively contains the certificate(s) in TrustedCAFile appended to the system roots
|
|
pool, err := cryptutil.GetCertPool("", opts.TrustedCAFile)
|
|
if err != nil {
|
|
return fmt.Errorf("config: creating trusted certificate pool: %w", err)
|
|
}
|
|
acmeMgr.TrustedRoots = pool
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func sourceHostnames(cfg *config.Config) []string {
|
|
if cfg.Options.NumPolicies() == 0 {
|
|
return nil
|
|
}
|
|
|
|
dedupe := map[string]struct{}{}
|
|
for p := range cfg.Options.GetAllPolicies() {
|
|
if u, _ := urlutil.ParseAndValidateURL(p.From); u != nil && !strings.Contains(u.Host, "*") {
|
|
dedupe[u.Hostname()] = struct{}{}
|
|
}
|
|
}
|
|
if cfg.Options.AuthenticateURLString != "" {
|
|
if u, _ := cfg.Options.GetAuthenticateURL(); u != nil {
|
|
dedupe[u.Hostname()] = struct{}{}
|
|
}
|
|
}
|
|
|
|
// remove any hosted authenticate URLs
|
|
for _, domain := range urlutil.HostedAuthenticateDomains {
|
|
delete(dedupe, domain)
|
|
}
|
|
|
|
var h []string
|
|
for k := range dedupe {
|
|
h = append(h, k)
|
|
}
|
|
sort.Strings(h)
|
|
|
|
return h
|
|
}
|
|
|
|
func shouldEnableHTTPChallenge(cfg *config.Config) bool {
|
|
if cfg == nil || cfg.Options == nil {
|
|
return false
|
|
}
|
|
|
|
_, p, err := net.SplitHostPort(cfg.Options.HTTPRedirectAddr)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return p == "80"
|
|
}
|