Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 34 additions & 11 deletions client/acme.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type P2PForgeCertMgr struct {
cfg *certmagic.Config
log *zap.SugaredLogger
allowPrivateForgeAddresses bool
resolvedDNSMultiaddrs bool

hasCert bool // tracking if we've received a certificate
certCheckMx sync.RWMutex
Expand Down Expand Up @@ -85,6 +86,7 @@ type P2PForgeCertMgrConfig struct {
onCertLoaded func()
log *zap.SugaredLogger
allowPrivateForgeAddresses bool
resolvedDNSMultiaddrs bool
}

type P2PForgeCertMgrOptions func(*P2PForgeCertMgrConfig) error
Expand Down Expand Up @@ -191,6 +193,15 @@ func WithLogger(log *zap.SugaredLogger) P2PForgeCertMgrOptions {
}
}

// WithResolvedDNSMultiaddrs enables advertising /dnsX/<escaped-ip>.<peer-id>.<forge-domain>/tcp/<port>/tls/ws addresses
// instead of the default /ipX/<ip>/tcp/<port>/tls/sni/<escaped-ip>.<peer-id>.<forge-domain>/ws.
func WithResolvedDNSMultiaddrs() P2PForgeCertMgrOptions {
return func(config *P2PForgeCertMgrConfig) error {
config.resolvedDNSMultiaddrs = true
return nil
}
}

// newCertmagicConfig is p2p-forge/client-specific version of
// certmagic.NewDefault() that ensures we have our own cert cache. This is
// necessary to ensure cert maintenance spawned by NewCache does not share
Expand Down Expand Up @@ -301,6 +312,7 @@ func NewP2PForgeCertMgr(opts ...P2PForgeCertMgrOptions) (*P2PForgeCertMgr, error
cfg: certCfg,
log: mgrCfg.log,
allowPrivateForgeAddresses: mgrCfg.allowPrivateForgeAddresses,
resolvedDNSMultiaddrs: mgrCfg.resolvedDNSMultiaddrs,
}

certCfg.OnEvent = func(ctx context.Context, event string, data map[string]any) error {
Expand Down Expand Up @@ -417,7 +429,8 @@ func (m *P2PForgeCertMgr) TLSConfig() *tls.Config {
}

func (m *P2PForgeCertMgr) AddrStrings() []string {
return []string{fmt.Sprintf("/ip4/0.0.0.0/tcp/0/tls/sni/*.%s/ws", m.forgeDomain),
return []string{
fmt.Sprintf("/ip4/0.0.0.0/tcp/0/tls/sni/*.%s/ws", m.forgeDomain),
fmt.Sprintf("/ip6/::/tcp/0/tls/sni/*.%s/ws", m.forgeDomain),
}
}
Expand All @@ -429,7 +442,7 @@ func (m *P2PForgeCertMgr) AddressFactory() config.AddrsFactory {
tlsCfg := m.cfg.TLSConfig()
tlsCfg.NextProtos = []string{"h2", "http/1.1"} // remove the ACME ALPN and set the HTTP 1.1 and 2 ALPNs

return m.createAddrsFactory(m.allowPrivateForgeAddresses)
return m.createAddrsFactory(m.allowPrivateForgeAddresses, m.resolvedDNSMultiaddrs)
}

// localCertExists returns true if a certificate matching passed name is already present in certmagic.Storage
Expand All @@ -448,8 +461,8 @@ func certName(id peer.ID, suffixDomain string) string {
return fmt.Sprintf("*.%s.%s", pb36, suffixDomain)
}

func (m *P2PForgeCertMgr) createAddrsFactory(allowPrivateForgeAddrs bool) config.AddrsFactory {
var p2pForgeWssComponent = multiaddr.StringCast(fmt.Sprintf("/tls/sni/*.%s/ws", m.forgeDomain))
func (m *P2PForgeCertMgr) createAddrsFactory(allowPrivateForgeAddrs bool, resolvedDNSMultiaddrs bool) config.AddrsFactory {
p2pForgeWssComponent := multiaddr.StringCast(fmt.Sprintf("/tls/sni/*.%s/ws", m.forgeDomain))

return func(multiaddrs []multiaddr.Multiaddr) []multiaddr.Multiaddr {
var skipForgeAddrs bool
Expand All @@ -462,7 +475,7 @@ func (m *P2PForgeCertMgr) createAddrsFactory(allowPrivateForgeAddrs bool) config
}
m.certCheckMx.RUnlock()

return addrFactoryFn(skipForgeAddrs, func() peer.ID { return m.hostFn().ID() }, m.forgeDomain, allowPrivateForgeAddrs, p2pForgeWssComponent, multiaddrs, m.log)
return addrFactoryFn(skipForgeAddrs, func() peer.ID { return m.hostFn().ID() }, m.forgeDomain, allowPrivateForgeAddrs, resolvedDNSMultiaddrs, p2pForgeWssComponent, multiaddrs, m.log)
}
}

Expand Down Expand Up @@ -526,14 +539,16 @@ func (d *dns01P2PForgeSolver) Present(ctx context.Context, challenge acme.Challe
}

func (d *dns01P2PForgeSolver) CleanUp(ctx context.Context, challenge acme.Challenge) error {
//TODO: Should we implement this, or is doing delete and Last-Writer-Wins enough?
// TODO: Should we implement this, or is doing delete and Last-Writer-Wins enough?
return nil
}

var _ acmez.Solver = (*dns01P2PForgeSolver)(nil)
var _ acmez.Waiter = (*dns01P2PForgeSolver)(nil)
var (
_ acmez.Solver = (*dns01P2PForgeSolver)(nil)
_ acmez.Waiter = (*dns01P2PForgeSolver)(nil)
)

func addrFactoryFn(skipForgeAddrs bool, peerIDFn func() peer.ID, forgeDomain string, allowPrivateForgeAddrs bool, p2pForgeWssComponent multiaddr.Multiaddr, multiaddrs []multiaddr.Multiaddr, log *zap.SugaredLogger) []multiaddr.Multiaddr {
func addrFactoryFn(skipForgeAddrs bool, peerIDFn func() peer.ID, forgeDomain string, allowPrivateForgeAddrs bool, resolvedDNSMultiaddrs bool, p2pForgeWssComponent multiaddr.Multiaddr, multiaddrs []multiaddr.Multiaddr, log *zap.SugaredLogger) []multiaddr.Multiaddr {
retAddrs := make([]multiaddr.Multiaddr, 0, len(multiaddrs))
for _, a := range multiaddrs {
if isRelayAddr(a) {
Expand All @@ -551,17 +566,20 @@ func addrFactoryFn(skipForgeAddrs bool, peerIDFn func() peer.ID, forgeDomain str

index := 0
var escapedIPStr string
var ipVersion string
var ipMaStr string
var tcpPortStr string
multiaddr.ForEach(withoutForgeWSS, func(c multiaddr.Component) bool {
switch index {
case 0:
switch c.Protocol().Code {
case multiaddr.P_IP4:
ipVersion = "4"
ipMaStr = c.String()
ipAddr := c.Value()
escapedIPStr = strings.ReplaceAll(ipAddr, ".", "-")
case multiaddr.P_IP6:
ipVersion = "6"
ipMaStr = c.String()
ipAddr := c.Value()
escapedIPStr = strings.ReplaceAll(ipAddr, ":", "-")
Expand Down Expand Up @@ -601,9 +619,14 @@ func addrFactoryFn(skipForgeAddrs bool, peerIDFn func() peer.ID, forgeDomain str
continue
}

pidStr := peer.ToCid(peerIDFn()).Encode(multibase.MustNewEncoder(multibase.Base36))
b36PidStr := peer.ToCid(peerIDFn()).Encode(multibase.MustNewEncoder(multibase.Base36))

newMaStr := fmt.Sprintf("%s/tcp/%s/tls/sni/%s.%s.%s/ws", ipMaStr, tcpPortStr, escapedIPStr, pidStr, forgeDomain)
var newMaStr string
if resolvedDNSMultiaddrs {
newMaStr = fmt.Sprintf("/dns%s/%s.%s.%s/tcp/%s/tls/ws", ipVersion, escapedIPStr, b36PidStr, forgeDomain, tcpPortStr)
} else {
newMaStr = fmt.Sprintf("%s/tcp/%s/tls/sni/%s.%s.%s/ws", ipMaStr, tcpPortStr, escapedIPStr, b36PidStr, forgeDomain)
}
newMA, err := multiaddr.NewMultiaddr(newMaStr)
if err != nil {
log.Errorf("error creating new multiaddr from %q: %s", newMaStr, err.Error())
Expand Down
Loading