Skip to content

Commit

Permalink
test: add more complete e2e testing
Browse files Browse the repository at this point in the history
  • Loading branch information
aschmahmann committed Aug 29, 2024
1 parent 21fbff0 commit 5653d6c
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 1 deletion.
166 changes: 166 additions & 0 deletions cmd/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,28 @@ package main

import (
"context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/base64"
"encoding/pem"
"errors"
"fmt"
libp2pws "github.com/libp2p/go-libp2p/p2p/transport/websocket"
"github.com/multiformats/go-multiaddr"
madns "github.com/multiformats/go-multiaddr-dns"
"log"
"math/big"
"net"
"net/http"
"os"
"strings"
"testing"
"time"

"github.com/coredns/caddy"
"github.com/coredns/coredns/core/dnsserver"
Expand All @@ -23,6 +37,11 @@ import (
_ "github.com/coredns/coredns/core/plugin" // Load all managed plugins in github.com/coredns/coredns.
_ "github.com/ipshipyard/p2p-forge/acme"
_ "github.com/ipshipyard/p2p-forge/ipparser"

pebbleCA "github.com/letsencrypt/pebble/v2/ca"
pebbleDB "github.com/letsencrypt/pebble/v2/db"
pebbleVA "github.com/letsencrypt/pebble/v2/va"
pebbleWFE "github.com/letsencrypt/pebble/v2/wfe"
)

const forge = "libp2p.direct"
Expand Down Expand Up @@ -332,6 +351,153 @@ func TestIPv6Lookup(t *testing.T) {
}
}

func TestLibp2pACMEE2E(t *testing.T) {
db := pebbleDB.NewMemoryStore()
logger := log.New(os.Stdout, "", 0)
ca := pebbleCA.New(logger, db, "", 0, 1, 0)
va := pebbleVA.New(logger, 0, 0, false, dnsServerAddress, db)

wfeImpl := pebbleWFE.New(logger, db, va, ca, false, false, 3, 5)
muxHandler := wfeImpl.Handler()

acmeHTTPListener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatal(err)
}
defer acmeHTTPListener.Close()

// Generate the self-signed certificate and private key
certPEM, privPEM, err := generateSelfSignedCert("127.0.0.1")
if err != nil {
log.Fatalf("Failed to generate self-signed certificate: %v", err)
}

// Load the certificate and key into tls.Certificate
cert, err := tls.X509KeyPair(certPEM, privPEM)
if err != nil {
log.Fatalf("Failed to load key pair: %v", err)
}

// Create a TLS configuration with the certificate
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
}

// Wrap the listener with TLS
acmeHTTPListener = tls.NewListener(acmeHTTPListener, tlsConfig)

go func() {
http.Serve(acmeHTTPListener, muxHandler)
}()

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

cas := x509.NewCertPool()
cas.AppendCertsFromPEM(certPEM)

acmeEndpoint := fmt.Sprintf("https://%s%s", acmeHTTPListener.Addr(), pebbleWFE.DirectoryPath)
certLoaded := make(chan bool, 1)
h, err := client.NewHostWithP2PForge(forge, fmt.Sprintf("http://127.0.0.1:%d", httpPort), acmeEndpoint, "foo@bar.com", cas, func() {
certLoaded <- true
}, true)
if err != nil {
t.Fatal(err)
}

cp := x509.NewCertPool()
cp.AddCert(ca.GetRootCert(0).Cert)
tlsCfgWithTestCA := &tls.Config{RootCAs: cp}

localDnsResolver, err := madns.NewResolver(madns.WithDefaultResolver(&net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{
Timeout: time.Second * 5, // Set a timeout for the connection
}
return d.DialContext(ctx, network, dnsServerAddress)
},
}))
if err != nil {
t.Fatal(err)
}
customResolver, err := madns.NewResolver(madns.WithDomainResolver("libp2p.direct.", localDnsResolver))
if err != nil {
t.Fatal(err)
}

h2, err := libp2p.New(libp2p.Transport(libp2pws.New, libp2pws.WithTLSClientConfig(tlsCfgWithTestCA)),
libp2p.MultiaddrResolver(customResolver))
if err != nil {
t.Fatal(err)
}

var dialAddr multiaddr.Multiaddr
hAddrs := h.Addrs()
for _, addr := range hAddrs {
as := addr.String()
if strings.Contains(as, "p2p-circuit") {
continue
}
if strings.Contains(as, "libp2p.direct/ws") {
dialAddr = addr
break
}
}
if dialAddr == nil {
t.Fatalf("no valid wss addresses: %v", hAddrs)
}

select {
case <-certLoaded:
case <-time.After(time.Second * 30):
t.Fatal("timed out waiting for certificate")
}

if err := h2.Connect(ctx, peer.AddrInfo{ID: h.ID(), Addrs: []multiaddr.Multiaddr{dialAddr}}); err != nil {
t.Fatal(err)
}
}

func generateSelfSignedCert(ipAddr string) ([]byte, []byte, error) {
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return nil, nil, err
}

serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
if err != nil {
return nil, nil, err
}

template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"My Organization"},
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(365 * 24 * time.Hour), // Valid for 1 year
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
IPAddresses: []net.IP{net.ParseIP(ipAddr)},
}

certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
if err != nil {
return nil, nil, err
}

certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
privDER, err := x509.MarshalECPrivateKey(priv)
if err != nil {
return nil, nil, err
}
privPEM := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: privDER})

return certPEM, privPEM, nil
}

// Input implements the caddy.Input interface and acts as an easy way to use a string as a Corefile.
type Input struct {
corefile []byte
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ require (
github.com/ipfs/go-ds-badger4 v0.1.5
github.com/ipfs/go-ds-dynamodb v0.1.1
github.com/ipfs/go-log/v2 v2.5.1
github.com/letsencrypt/pebble/v2 v2.6.0
github.com/libp2p/go-buffer-pool v0.1.0
github.com/libp2p/go-libp2p v0.36.1
github.com/mholt/acmez/v2 v2.0.1
github.com/miekg/dns v1.1.61
github.com/multiformats/go-multiaddr v0.13.0
github.com/multiformats/go-multiaddr-dns v0.3.1
github.com/multiformats/go-multibase v0.2.0
github.com/multiformats/go-varint v0.0.7
google.golang.org/protobuf v1.34.2
Expand Down Expand Up @@ -68,6 +70,7 @@ require (
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
github.com/flynn/noise v1.1.0 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect
github.com/go-jose/go-jose/v4 v4.0.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
Expand Down Expand Up @@ -108,6 +111,7 @@ require (
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/koron/go-ssdp v0.0.4 // indirect
github.com/letsencrypt/challtestsrv v1.3.2 // indirect
github.com/libdns/libdns v0.2.2 // indirect
github.com/libp2p/go-flow-metrics v0.1.0 // indirect
github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect
Expand All @@ -129,7 +133,6 @@ require (
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.2.0 // indirect
github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
github.com/multiformats/go-multicodec v0.9.0 // indirect
github.com/multiformats/go-multihash v0.2.3 // indirect
Expand Down
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U=
github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
Expand Down Expand Up @@ -316,6 +318,10 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/letsencrypt/challtestsrv v1.3.2 h1:pIDLBCLXR3B1DLmOmkkqg29qVa7DDozBnsOpL9PxmAY=
github.com/letsencrypt/challtestsrv v1.3.2/go.mod h1:Ur4e4FvELUXLGhkMztHOsPIsvGxD/kzSJninOrkM+zc=
github.com/letsencrypt/pebble/v2 v2.6.0 h1:7xetaJ4YaesUnWWeRGSs3UHOwyfX4I4sfOfDrkvnhNw=
github.com/letsencrypt/pebble/v2 v2.6.0/go.mod h1:SID2E75Cx6sQ9AXFkdzhLdQ6S1zhRUbw08Cgu7GJLSk=
github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s=
github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
Expand Down Expand Up @@ -355,6 +361,7 @@ github.com/mholt/acmez/v2 v2.0.1/go.mod h1:fX4c9r5jYwMyMsC+7tkYRxHibkOTgta5DIFGo
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs=
github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ=
github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8=
Expand Down

0 comments on commit 5653d6c

Please sign in to comment.