mirror of
https://github.com/caddyserver/caddy.git
synced 2025-03-09 15:39:02 -04:00
WIP
This commit is contained in:
parent
6ea36133dc
commit
b987a60f89
@ -607,10 +607,8 @@ func parseOptECH(d *caddyfile.Dispenser, _ any) (any, error) {
|
|||||||
ech.Publication = append(ech.Publication, &caddytls.ECHPublication{
|
ech.Publication = append(ech.Publication, &caddytls.ECHPublication{
|
||||||
Configs: publicNames,
|
Configs: publicNames,
|
||||||
PublishersRaw: caddy.ModuleMap{
|
PublishersRaw: caddy.ModuleMap{
|
||||||
"dns": caddyconfig.JSON(caddytls.ECHDNSPublisherList{
|
"dns": caddyconfig.JSON(caddytls.ECHDNSPublisher{
|
||||||
{
|
ProviderRaw: caddyconfig.JSONModuleObject(unm, "name", providerName, nil),
|
||||||
ProviderRaw: caddyconfig.JSONModuleObject(unm, "name", providerName, nil),
|
|
||||||
},
|
|
||||||
}, nil),
|
}, nil),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
1
go.mod
1
go.mod
@ -70,7 +70,6 @@ require (
|
|||||||
github.com/smallstep/pkcs7 v0.0.0-20231024181729-3b98ecc1ca81 // indirect
|
github.com/smallstep/pkcs7 v0.0.0-20231024181729-3b98ecc1ca81 // indirect
|
||||||
github.com/smallstep/scep v0.0.0-20231024192529-aee96d7ad34d // indirect
|
github.com/smallstep/scep v0.0.0-20231024192529-aee96d7ad34d // indirect
|
||||||
github.com/x448/float16 v0.8.4 // indirect
|
github.com/x448/float16 v0.8.4 // indirect
|
||||||
github.com/zeebo/blake3 v0.2.4 // indirect
|
|
||||||
go.opentelemetry.io/contrib/propagators/aws v1.17.0 // indirect
|
go.opentelemetry.io/contrib/propagators/aws v1.17.0 // indirect
|
||||||
go.opentelemetry.io/contrib/propagators/b3 v1.17.0 // indirect
|
go.opentelemetry.io/contrib/propagators/b3 v1.17.0 // indirect
|
||||||
go.opentelemetry.io/contrib/propagators/jaeger v1.17.0 // indirect
|
go.opentelemetry.io/contrib/propagators/jaeger v1.17.0 // indirect
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/cloudflare/circl/hpke"
|
"github.com/cloudflare/circl/hpke"
|
||||||
"github.com/cloudflare/circl/kem"
|
"github.com/cloudflare/circl/kem"
|
||||||
"github.com/libdns/libdns"
|
"github.com/libdns/libdns"
|
||||||
|
"github.com/zeebo/blake3"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"golang.org/x/crypto/cryptobyte"
|
"golang.org/x/crypto/cryptobyte"
|
||||||
|
|
||||||
@ -24,7 +25,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
caddy.RegisterModule(ECHDNSPublisherList{})
|
caddy.RegisterModule(ECHDNSPublisher{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ECH enables Encrypted ClientHello (ECH) and configures its management.
|
// ECH enables Encrypted ClientHello (ECH) and configures its management.
|
||||||
@ -49,7 +50,7 @@ type ECH struct {
|
|||||||
// DNS RRs. (This also typically requires that they use DoH or DoT.)
|
// DNS RRs. (This also typically requires that they use DoH or DoT.)
|
||||||
Publication []*ECHPublication `json:"publication,omitempty"`
|
Publication []*ECHPublication `json:"publication,omitempty"`
|
||||||
|
|
||||||
// map of public_name to list of configs ordered by date (newest first)
|
// map of public_name to list of configs
|
||||||
configs map[string][]echConfig
|
configs map[string][]echConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,6 +341,12 @@ type ECHPublication struct {
|
|||||||
publishers []ECHPublisher
|
publishers []ECHPublisher
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ECHDNSProvider can service DNS entries for ECH purposes.
|
||||||
|
type ECHDNSProvider interface {
|
||||||
|
libdns.RecordGetter
|
||||||
|
libdns.RecordSetter
|
||||||
|
}
|
||||||
|
|
||||||
// ECHDNSPublisher configures how to publish an ECH configuration to
|
// ECHDNSPublisher configures how to publish an ECH configuration to
|
||||||
// DNS records for the specified domains.
|
// DNS records for the specified domains.
|
||||||
//
|
//
|
||||||
@ -352,53 +359,32 @@ type ECHDNSPublisher struct {
|
|||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// ECHDNSProvider can service DNS entries for ECH purposes.
|
|
||||||
type ECHDNSProvider interface {
|
|
||||||
libdns.RecordGetter
|
|
||||||
libdns.RecordSetter
|
|
||||||
}
|
|
||||||
|
|
||||||
// ECHDNSPublisherList is a list of DNS publication configs,
|
|
||||||
// so that different groups of domain names may have ECH configs
|
|
||||||
// published across different DNS providers, if necessary.
|
|
||||||
//
|
|
||||||
// EXPERIMENTAL: Subject to change.
|
|
||||||
//
|
|
||||||
// TODO: Does it make sense to have multiple? Do we really need to (is it even possible to need to) set DNS records for a group of names across more than 1 provider?
|
|
||||||
// TODO: Based on a discussion on social media, it sounds like only one would be necessary.
|
|
||||||
type ECHDNSPublisherList []*ECHDNSPublisher
|
|
||||||
|
|
||||||
// CaddyModule returns the Caddy module information.
|
// CaddyModule returns the Caddy module information.
|
||||||
func (ECHDNSPublisherList) CaddyModule() caddy.ModuleInfo {
|
func (ECHDNSPublisher) CaddyModule() caddy.ModuleInfo {
|
||||||
return caddy.ModuleInfo{
|
return caddy.ModuleInfo{
|
||||||
ID: "tls.ech.publishers.dns",
|
ID: "tls.ech.publishers.dns",
|
||||||
New: func() caddy.Module { return new(ECHDNSPublisherList) },
|
New: func() caddy.Module { return new(ECHDNSPublisher) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dnsPubList ECHDNSPublisherList) Provision(ctx caddy.Context) error {
|
func (dnsPub ECHDNSPublisher) Provision(ctx caddy.Context) error {
|
||||||
for i := range dnsPubList {
|
dnsProvMod, err := ctx.LoadModule(dnsPub, "ProviderRaw")
|
||||||
dnsProvMod, err := ctx.LoadModule(dnsPubList[i], "ProviderRaw")
|
if err != nil {
|
||||||
if err != nil {
|
return fmt.Errorf("loading ECH DNS provider module: %v", err)
|
||||||
return fmt.Errorf("loading ECH DNS provider module: %v", err)
|
|
||||||
}
|
|
||||||
prov, ok := dnsProvMod.(ECHDNSProvider)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("ECH DNS provider module is not an ECH DNS Provider: %v", err)
|
|
||||||
}
|
|
||||||
dnsPubList[i].provider = prov
|
|
||||||
dnsPubList[i].logger = ctx.Logger()
|
|
||||||
}
|
}
|
||||||
|
prov, ok := dnsProvMod.(ECHDNSProvider)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("ECH DNS provider module is not an ECH DNS Provider: %v", err)
|
||||||
|
}
|
||||||
|
dnsPub.provider = prov
|
||||||
|
dnsPub.logger = ctx.Logger()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dnsPubList ECHDNSPublisherList) PublishECHConfigList(ctx context.Context, innerNames []string, echConfigList []byte) error {
|
func (dnsPub ECHDNSPublisher) PublisherKey() string {
|
||||||
for i, pub := range dnsPubList {
|
h := blake3.New()
|
||||||
if err := pub.PublishECHConfigList(ctx, innerNames, echConfigList); err != nil {
|
fmt.Fprintf(h, "%v", dnsPub.provider)
|
||||||
return fmt.Errorf("publisher %d: %v", i, err)
|
return dnsPub.provider.(caddy.Module).CaddyModule().ID.Name() + ":" + string(h.Sum(nil))
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dnsPub *ECHDNSPublisher) PublishECHConfigList(ctx context.Context, innerNames []string, configListBin []byte) error {
|
func (dnsPub *ECHDNSPublisher) PublishECHConfigList(ctx context.Context, innerNames []string, configListBin []byte) error {
|
||||||
@ -857,12 +843,21 @@ func (params svcParams) String() string {
|
|||||||
// ECHPublisher is an interface for publishing ECHConfigList values
|
// ECHPublisher is an interface for publishing ECHConfigList values
|
||||||
// so that they can be used by clients.
|
// so that they can be used by clients.
|
||||||
type ECHPublisher interface {
|
type ECHPublisher interface {
|
||||||
|
// Returns a key that is unique to this publisher and its configuration.
|
||||||
|
// A publisher's ID combined with its config is a valid key.
|
||||||
|
// It is used to prevent duplicating publications.
|
||||||
|
PublisherKey() string
|
||||||
|
|
||||||
|
// Publishes the ECH config list for the given innerNames. Some publishers
|
||||||
|
// may not need a list of inner/protected names, and can ignore the argument;
|
||||||
|
// most, however, will want to use it as guidance to ensure the inner names
|
||||||
|
// are associated with the proper ECH configs.
|
||||||
PublishECHConfigList(ctx context.Context, innerNames []string, echConfigList []byte) error
|
PublishECHConfigList(ctx context.Context, innerNames []string, echConfigList []byte) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type echConfigMeta struct {
|
type echConfigMeta struct {
|
||||||
Created time.Time `json:"created"`
|
Created time.Time `json:"created"`
|
||||||
Publications []string `json:"publications"`
|
Publications map[string]time.Time `json:"publications"` // map of publisher ID to timestamp of publication
|
||||||
}
|
}
|
||||||
|
|
||||||
// The key prefix when putting ECH configs in storage. After this
|
// The key prefix when putting ECH configs in storage. After this
|
||||||
@ -873,4 +868,4 @@ const echConfigsKey = "ech/configs"
|
|||||||
const draftTLSESNI22 = 0xfe0d
|
const draftTLSESNI22 = 0xfe0d
|
||||||
|
|
||||||
// Interface guard
|
// Interface guard
|
||||||
var _ ECHPublisher = (*ECHDNSPublisherList)(nil)
|
var _ ECHPublisher = (*ECHDNSPublisher)(nil)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user