Skip to content

Commit

Permalink
refactor(client): cleanup dns01 request code
Browse files Browse the repository at this point in the history
removed duplicated/unused code, added logs
  • Loading branch information
lidel committed Dec 17, 2024
1 parent 26f81c4 commit af85ef7
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 42 deletions.
53 changes: 20 additions & 33 deletions client/acme.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@ import (
"crypto/x509"
"errors"
"fmt"
"io"
"net/http"
"strings"
"sync"
"time"

"github.com/libp2p/go-libp2p/core/network"

httppeeridauth "github.com/libp2p/go-libp2p/p2p/http/auth"
"go.uber.org/zap"

"github.com/caddyserver/certmagic"
Expand Down Expand Up @@ -280,12 +278,13 @@ func NewP2PForgeCertMgr(opts ...P2PForgeCertMgrOptions) (*P2PForgeCertMgr, error
Email: mgrCfg.userEmail,
Agreed: true,
DNS01Solver: &dns01P2PForgeSolver{
forge: mgrCfg.forgeRegistrationEndpoint,
forgeRegistrationEndpoint: mgrCfg.forgeRegistrationEndpoint,
forgeAuth: mgrCfg.forgeAuth,
hostFn: hostFn,
modifyForgeRequest: mgrCfg.modifyForgeRequest,
userAgent: mgrCfg.userAgent,
allowPrivateForgeAddresses: mgrCfg.allowPrivateForgeAddresses,
log: mgrCfg.log.Named("dns01solver"),
},
TrustedRoots: mgrCfg.trustedRoots,
Logger: certCfg.Logger,
Expand Down Expand Up @@ -468,21 +467,25 @@ func (m *P2PForgeCertMgr) createAddrsFactory(allowPrivateForgeAddrs bool) config
}

type dns01P2PForgeSolver struct {
forge string
forgeRegistrationEndpoint string
forgeAuth string
hostFn func() host.Host
modifyForgeRequest func(r *http.Request) error
userAgent string
allowPrivateForgeAddresses bool
log *zap.SugaredLogger
}

func (d *dns01P2PForgeSolver) Wait(ctx context.Context, challenge acme.Challenge) error {
d.log.Debugw("waiting for DNS-01 TXT record to be set")
// TODO: query the authoritative DNS
time.Sleep(time.Second * 5)
return nil
}

func (d *dns01P2PForgeSolver) Present(ctx context.Context, challenge acme.Challenge) error {
d.log.Debugw("getting DNS-01 challenge value from CA", "acme_challenge", challenge)
dns01value := challenge.DNS01KeyAuthorization()
h := d.hostFn()
addrs := h.Addrs()

Expand All @@ -503,38 +506,22 @@ func (d *dns01P2PForgeSolver) Present(ctx context.Context, challenge acme.Challe
} else {
advertisedAddrs = addrs
}

req, err := ChallengeRequest(ctx, d.forge, challenge.DNS01KeyAuthorization(), advertisedAddrs)
d.log.Debugw("advertised libp2p addrs for p2p-forge broker to try", "addrs", advertisedAddrs)

d.log.Debugw("asking p2p-forge broker to set DNS-01 TXT record", "url", d.forgeRegistrationEndpoint, "dns01_value", dns01value)
err := SendChallenge(ctx,
d.forgeRegistrationEndpoint,
h.Peerstore().PrivKey(h.ID()),
dns01value,
advertisedAddrs,
d.forgeAuth,
d.userAgent,
d.modifyForgeRequest,
)
if err != nil {
return err
}

// Add forge auth header if set
if d.forgeAuth != "" {
req.Header.Set(ForgeAuthHeader, d.forgeAuth)
}

// Always include User-Agent header
if d.userAgent == "" {
d.userAgent = defaultUserAgent
return fmt.Errorf("p2p-forge broker registration error: %w", err)
}
req.Header.Set("User-Agent", d.userAgent)

if d.modifyForgeRequest != nil {
if err := d.modifyForgeRequest(req); err != nil {
return err
}
}

client := &httppeeridauth.ClientPeerIDAuth{PrivKey: h.Peerstore().PrivKey(h.ID())}
_, resp, err := client.AuthenticatedDo(http.DefaultClient, req)
if err != nil {
return err
}
if resp.StatusCode != http.StatusOK {
respBody, _ := io.ReadAll(resp.Body)
return fmt.Errorf("%s : %s", resp.Status, respBody)
}
return nil
}

Expand Down
35 changes: 26 additions & 9 deletions client/challenge.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,50 @@ import (
"github.com/multiformats/go-multiaddr"
)

// SendChallenge submits a challenge to the DNS server for the given peerID.
// SendChallenge submits value for DNS-01 challenge to the p2p-forge HTTP server for the given peerID.
// It requires the corresponding private key and a list of multiaddresses that the peerID is listening on using
// publicly reachable IP addresses.
func SendChallenge(ctx context.Context, baseURL string, privKey crypto.PrivKey, challenge string, addrs []multiaddr.Multiaddr) error {
req, err := ChallengeRequest(ctx, baseURL, challenge, addrs)
func SendChallenge(ctx context.Context, baseURL string, privKey crypto.PrivKey, challenge string, addrs []multiaddr.Multiaddr, forgeAuth string, userAgent string, modifyForgeRequest func(r *http.Request) error) error {
// Create request
registrationURL := fmt.Sprintf("%s/v1/_acme-challenge", baseURL)
req, err := ChallengeRequest(ctx, registrationURL, challenge, addrs)
if err != nil {
return err
}

// Adjust headers if needed
if forgeAuth != "" {
req.Header.Set(ForgeAuthHeader, forgeAuth)
}
if userAgent == "" {
userAgent = defaultUserAgent
}
req.Header.Set("User-Agent", userAgent)
if modifyForgeRequest != nil {
if err := modifyForgeRequest(req); err != nil {
return err
}
}

// Execute request wrapped in ClientPeerIDAuth
client := &httppeeridauth.ClientPeerIDAuth{PrivKey: privKey}
_, resp, err := client.AuthenticatedDo(http.DefaultClient, req)
if err != nil {
return err
return fmt.Errorf("libp2p HTTP ClientPeerIDAuth error at %s: %w", registrationURL, err)
}
if resp.StatusCode != http.StatusOK {
respBody, _ := io.ReadAll(resp.Body)
return fmt.Errorf("%s : %s", resp.Status, respBody)
return fmt.Errorf("%s error from %s: %q", resp.Status, registrationURL, respBody)
}
return nil
}

// ChallengeRequest creates an HTTP Request object for submitting an ACME challenge to the DNS server for a given peerID.
// ChallengeRequest creates an HTTP Request object for submitting an ACME challenge to the p2p-forge HTTP server for a given peerID.
// Construction of the request requires a list of multiaddresses that the peerID is listening on using
// publicly reachable IP addresses.
//
// Sending the request to the DNS server requires performing HTTP PeerID Authentication for the corresponding peerID
func ChallengeRequest(ctx context.Context, baseURL string, challenge string, addrs []multiaddr.Multiaddr) (*http.Request, error) {
func ChallengeRequest(ctx context.Context, registrationURL string, challenge string, addrs []multiaddr.Multiaddr) (*http.Request, error) {
maStrs := make([]string, len(addrs))
for i, addr := range addrs {
maStrs[i] = addr.String()
Expand All @@ -57,9 +74,9 @@ func ChallengeRequest(ctx context.Context, baseURL string, challenge string, add
return nil, err
}

req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("%s/v1/_acme-challenge", baseURL), bytes.NewReader(body))
req, err := http.NewRequestWithContext(ctx, "POST", registrationURL, bytes.NewReader(body))
if err != nil {
return nil, err
return nil, fmt.Errorf("failed while creating a request to %s: %w", registrationURL, err)
}

return req, nil
Expand Down

0 comments on commit af85ef7

Please sign in to comment.