Skip to content

Commit 8f4af5e

Browse files
committed
test: add more complete e2e testing
1 parent ffae684 commit 8f4af5e

File tree

3 files changed

+177
-1
lines changed

3 files changed

+177
-1
lines changed

cmd/e2e_test.go

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,28 @@ package main
22

33
import (
44
"context"
5+
"crypto/ecdsa"
6+
"crypto/elliptic"
57
"crypto/rand"
68
"crypto/sha256"
9+
"crypto/tls"
10+
"crypto/x509"
11+
"crypto/x509/pkix"
712
"encoding/base64"
13+
"encoding/pem"
814
"errors"
915
"fmt"
16+
libp2pws "github.com/libp2p/go-libp2p/p2p/transport/websocket"
17+
"github.com/multiformats/go-multiaddr"
18+
madns "github.com/multiformats/go-multiaddr-dns"
19+
"log"
20+
"math/big"
1021
"net"
22+
"net/http"
1123
"os"
24+
"strings"
1225
"testing"
26+
"time"
1327

1428
"github.com/coredns/caddy"
1529
"github.com/coredns/coredns/core/dnsserver"
@@ -23,6 +37,11 @@ import (
2337
_ "github.com/coredns/coredns/core/plugin" // Load all managed plugins in github.com/coredns/coredns.
2438
_ "github.com/ipshipyard/p2p-forge/acme"
2539
_ "github.com/ipshipyard/p2p-forge/ipparser"
40+
41+
pebbleCA "github.com/letsencrypt/pebble/v2/ca"
42+
pebbleDB "github.com/letsencrypt/pebble/v2/db"
43+
pebbleVA "github.com/letsencrypt/pebble/v2/va"
44+
pebbleWFE "github.com/letsencrypt/pebble/v2/wfe"
2645
)
2746

2847
const forge = "libp2p.direct"
@@ -332,6 +351,153 @@ func TestIPv6Lookup(t *testing.T) {
332351
}
333352
}
334353

354+
func TestLibp2pACMEE2E(t *testing.T) {
355+
db := pebbleDB.NewMemoryStore()
356+
logger := log.New(os.Stdout, "", 0)
357+
ca := pebbleCA.New(logger, db, "", 0, 1, 0)
358+
va := pebbleVA.New(logger, 0, 0, false, dnsServerAddress, db)
359+
360+
wfeImpl := pebbleWFE.New(logger, db, va, ca, false, false, 3, 5)
361+
muxHandler := wfeImpl.Handler()
362+
363+
acmeHTTPListener, err := net.Listen("tcp", "127.0.0.1:0")
364+
if err != nil {
365+
t.Fatal(err)
366+
}
367+
defer acmeHTTPListener.Close()
368+
369+
// Generate the self-signed certificate and private key
370+
certPEM, privPEM, err := generateSelfSignedCert("127.0.0.1")
371+
if err != nil {
372+
log.Fatalf("Failed to generate self-signed certificate: %v", err)
373+
}
374+
375+
// Load the certificate and key into tls.Certificate
376+
cert, err := tls.X509KeyPair(certPEM, privPEM)
377+
if err != nil {
378+
log.Fatalf("Failed to load key pair: %v", err)
379+
}
380+
381+
// Create a TLS configuration with the certificate
382+
tlsConfig := &tls.Config{
383+
Certificates: []tls.Certificate{cert},
384+
}
385+
386+
// Wrap the listener with TLS
387+
acmeHTTPListener = tls.NewListener(acmeHTTPListener, tlsConfig)
388+
389+
go func() {
390+
http.Serve(acmeHTTPListener, muxHandler)
391+
}()
392+
393+
ctx, cancel := context.WithCancel(context.Background())
394+
defer cancel()
395+
396+
cas := x509.NewCertPool()
397+
cas.AppendCertsFromPEM(certPEM)
398+
399+
acmeEndpoint := fmt.Sprintf("https://%s%s", acmeHTTPListener.Addr(), pebbleWFE.DirectoryPath)
400+
certLoaded := make(chan bool, 1)
401+
h, err := client.NewHostWithP2PForge(forge, fmt.Sprintf("http://127.0.0.1:%d", httpPort), acmeEndpoint, "foo@bar.com", cas, func() {
402+
certLoaded <- true
403+
})
404+
if err != nil {
405+
t.Fatal(err)
406+
}
407+
408+
cp := x509.NewCertPool()
409+
cp.AddCert(ca.GetRootCert(0).Cert)
410+
tlsCfgWithTestCA := &tls.Config{RootCAs: cp}
411+
412+
localDnsResolver, err := madns.NewResolver(madns.WithDefaultResolver(&net.Resolver{
413+
PreferGo: true,
414+
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
415+
d := net.Dialer{
416+
Timeout: time.Second * 5, // Set a timeout for the connection
417+
}
418+
return d.DialContext(ctx, network, dnsServerAddress)
419+
},
420+
}))
421+
if err != nil {
422+
t.Fatal(err)
423+
}
424+
customResolver, err := madns.NewResolver(madns.WithDomainResolver("libp2p.direct.", localDnsResolver))
425+
if err != nil {
426+
t.Fatal(err)
427+
}
428+
429+
h2, err := libp2p.New(libp2p.Transport(libp2pws.New, libp2pws.WithTLSClientConfig(tlsCfgWithTestCA)),
430+
libp2p.MultiaddrResolver(customResolver))
431+
if err != nil {
432+
t.Fatal(err)
433+
}
434+
435+
var dialAddr multiaddr.Multiaddr
436+
hAddrs := h.Addrs()
437+
for _, addr := range hAddrs {
438+
as := addr.String()
439+
if strings.Contains(as, "p2p-circuit") {
440+
continue
441+
}
442+
if strings.Contains(as, "libp2p.direct/ws") {
443+
dialAddr = addr
444+
break
445+
}
446+
}
447+
if dialAddr == nil {
448+
t.Fatalf("no valid wss addresses: %v", hAddrs)
449+
}
450+
451+
select {
452+
case <-certLoaded:
453+
case <-time.After(time.Second * 30):
454+
t.Fatal("timed out waiting for certificate")
455+
}
456+
457+
if err := h2.Connect(ctx, peer.AddrInfo{ID: h.ID(), Addrs: []multiaddr.Multiaddr{dialAddr}}); err != nil {
458+
t.Fatal(err)
459+
}
460+
}
461+
462+
func generateSelfSignedCert(ipAddr string) ([]byte, []byte, error) {
463+
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
464+
if err != nil {
465+
return nil, nil, err
466+
}
467+
468+
serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
469+
if err != nil {
470+
return nil, nil, err
471+
}
472+
473+
template := x509.Certificate{
474+
SerialNumber: serialNumber,
475+
Subject: pkix.Name{
476+
Organization: []string{"My Organization"},
477+
},
478+
NotBefore: time.Now(),
479+
NotAfter: time.Now().Add(365 * 24 * time.Hour), // Valid for 1 year
480+
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
481+
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
482+
BasicConstraintsValid: true,
483+
IPAddresses: []net.IP{net.ParseIP(ipAddr)},
484+
}
485+
486+
certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
487+
if err != nil {
488+
return nil, nil, err
489+
}
490+
491+
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
492+
privDER, err := x509.MarshalECPrivateKey(priv)
493+
if err != nil {
494+
return nil, nil, err
495+
}
496+
privPEM := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: privDER})
497+
498+
return certPEM, privPEM, nil
499+
}
500+
335501
// Input implements the caddy.Input interface and acts as an easy way to use a string as a Corefile.
336502
type Input struct {
337503
corefile []byte

go.mod

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ require (
1212
github.com/ipfs/go-ds-badger4 v0.1.5
1313
github.com/ipfs/go-ds-dynamodb v0.1.1
1414
github.com/ipfs/go-log/v2 v2.5.1
15+
github.com/letsencrypt/pebble/v2 v2.6.0
1516
github.com/libp2p/go-buffer-pool v0.1.0
1617
github.com/libp2p/go-libp2p v0.36.1
1718
github.com/mholt/acmez/v2 v2.0.1
1819
github.com/miekg/dns v1.1.61
1920
github.com/multiformats/go-multiaddr v0.13.0
21+
github.com/multiformats/go-multiaddr-dns v0.3.1
2022
github.com/multiformats/go-multibase v0.2.0
2123
github.com/multiformats/go-varint v0.0.7
2224
google.golang.org/protobuf v1.34.2
@@ -68,6 +70,7 @@ require (
6870
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
6971
github.com/flynn/noise v1.1.0 // indirect
7072
github.com/francoispqt/gojay v1.2.13 // indirect
73+
github.com/go-jose/go-jose/v4 v4.0.1 // indirect
7174
github.com/go-logr/logr v1.4.2 // indirect
7275
github.com/go-logr/stdr v1.2.2 // indirect
7376
github.com/go-openapi/jsonpointer v0.19.6 // indirect
@@ -108,6 +111,7 @@ require (
108111
github.com/klauspost/compress v1.17.9 // indirect
109112
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
110113
github.com/koron/go-ssdp v0.0.4 // indirect
114+
github.com/letsencrypt/challtestsrv v1.3.2 // indirect
111115
github.com/libdns/libdns v0.2.2 // indirect
112116
github.com/libp2p/go-flow-metrics v0.1.0 // indirect
113117
github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect
@@ -129,7 +133,6 @@ require (
129133
github.com/mr-tron/base58 v1.2.0 // indirect
130134
github.com/multiformats/go-base32 v0.1.0 // indirect
131135
github.com/multiformats/go-base36 v0.2.0 // indirect
132-
github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
133136
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
134137
github.com/multiformats/go-multicodec v0.9.0 // indirect
135138
github.com/multiformats/go-multihash v0.2.3 // indirect

go.sum

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
151151
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
152152
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
153153
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
154+
github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U=
155+
github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
154156
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
155157
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
156158
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
@@ -316,6 +318,10 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
316318
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
317319
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
318320
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
321+
github.com/letsencrypt/challtestsrv v1.3.2 h1:pIDLBCLXR3B1DLmOmkkqg29qVa7DDozBnsOpL9PxmAY=
322+
github.com/letsencrypt/challtestsrv v1.3.2/go.mod h1:Ur4e4FvELUXLGhkMztHOsPIsvGxD/kzSJninOrkM+zc=
323+
github.com/letsencrypt/pebble/v2 v2.6.0 h1:7xetaJ4YaesUnWWeRGSs3UHOwyfX4I4sfOfDrkvnhNw=
324+
github.com/letsencrypt/pebble/v2 v2.6.0/go.mod h1:SID2E75Cx6sQ9AXFkdzhLdQ6S1zhRUbw08Cgu7GJLSk=
319325
github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s=
320326
github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
321327
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
@@ -355,6 +361,7 @@ github.com/mholt/acmez/v2 v2.0.1/go.mod h1:fX4c9r5jYwMyMsC+7tkYRxHibkOTgta5DIFGo
355361
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
356362
github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
357363
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
364+
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
358365
github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs=
359366
github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ=
360367
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8=

0 commit comments

Comments
 (0)