Skip to content

Commit

Permalink
Merge branch 'master' into use-error-channels
Browse files Browse the repository at this point in the history
  • Loading branch information
gammazero authored Nov 4, 2024
2 parents c1f09ea + 1ca0ae0 commit 28f8636
Show file tree
Hide file tree
Showing 19 changed files with 873 additions and 321 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/gotest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
make -j "$PARALLEL" test/unit/gotest.junit.xml &&
[[ ! $(jq -s -c 'map(select(.Action == "fail")) | .[]' test/unit/gotest.json) ]]
- name: Upload coverage to Codecov
uses: codecov/codecov-action@6d798873df2b1b8e5846dba6fb86631229fbcb17 # v4.4.0
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
if: failure() || success()
with:
name: unittests
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sharness.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
# increasing parallelism beyond 10 doesn't speed up the tests much
PARALLEL: ${{ github.repository == 'ipfs/kubo' && 10 || 3 }}
- name: Upload coverage report
uses: codecov/codecov-action@6d798873df2b1b8e5846dba6fb86631229fbcb17 # v4.4.0
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
if: failure() || success()
with:
name: sharness
Expand Down
30 changes: 30 additions & 0 deletions config/autotls.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package config

import p2pforge "github.com/ipshipyard/p2p-forge/client"

// AutoTLS includes optional configuration of p2p-forge client of service
// for obtaining a domain and TLS certificate to improve connectivity for web
// browser clients. More: https://github.com/ipshipyard/p2p-forge#readme
type AutoTLS struct {
// Enables the p2p-forge feature
Enabled Flag `json:",omitempty"`

// Optional override of the parent domain that will be used
DomainSuffix *OptionalString `json:",omitempty"`

// Optional override of HTTP API that acts as ACME DNS-01 Challenge broker
RegistrationEndpoint *OptionalString `json:",omitempty"`

// Optional Authorization token, used with private/test instances of p2p-forge
RegistrationToken *OptionalString `json:",omitempty"`

// Optional override of CA ACME API used by p2p-forge system
CAEndpoint *OptionalString `json:",omitempty"`
}

const (
DefaultAutoTLSEnabled = false // experimental, opt-in for now (https://github.com/ipfs/kubo/pull/10521)
DefaultDomainSuffix = p2pforge.DefaultForgeDomain
DefaultRegistrationEndpoint = p2pforge.DefaultForgeEndpoint
DefaultCAEndpoint = p2pforge.DefaultCAEndpoint
)
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type Config struct {
API API // local node's API settings
Swarm SwarmConfig
AutoNAT AutoNATConfig
AutoTLS AutoTLS
Pubsub PubsubConfig
Peering Peering
DNS DNS
Expand Down
2 changes: 0 additions & 2 deletions config/swarm.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ type RelayService struct {
// BufferSize is the size of the relayed connection buffers.
BufferSize *OptionalInteger `json:",omitempty"`

// MaxReservationsPerPeer is the maximum number of reservations originating from the same peer.
MaxReservationsPerPeer *OptionalInteger `json:",omitempty"`
// MaxReservationsPerIP is the maximum number of reservations originating from the same IP address.
MaxReservationsPerIP *OptionalInteger `json:",omitempty"`
// MaxReservationsPerASN is the maximum number of reservations origination from the same ASN.
Expand Down
21 changes: 21 additions & 0 deletions core/node/groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"strings"
"time"

"github.com/dustin/go-humanize"
Expand Down Expand Up @@ -113,6 +114,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part
enableRelayTransport := cfg.Swarm.Transports.Network.Relay.WithDefault(true) // nolint
enableRelayService := cfg.Swarm.RelayService.Enabled.WithDefault(enableRelayTransport)
enableRelayClient := cfg.Swarm.RelayClient.Enabled.WithDefault(enableRelayTransport)
enableAutoTLS := cfg.AutoTLS.Enabled.WithDefault(config.DefaultAutoTLSEnabled)

// Log error when relay subsystem could not be initialized due to missing dependency
if !enableRelayTransport {
Expand All @@ -123,6 +125,23 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part
logger.Fatal("Failed to enable `Swarm.RelayClient`, it requires `Swarm.Transports.Network.Relay` to be true.")
}
}
if enableAutoTLS {
if !cfg.Swarm.Transports.Network.Websocket.WithDefault(true) {
logger.Fatal("Invalid configuration: AutoTLS.Enabled=true requires Swarm.Transports.Network.Websocket to be true as well.")
}

wssWildcard := fmt.Sprintf("/tls/sni/*.%s/ws", cfg.AutoTLS.DomainSuffix.WithDefault(config.DefaultDomainSuffix))
wssWildcardPresent := false
for _, listener := range cfg.Addresses.Swarm {
if strings.Contains(listener, wssWildcard) {
wssWildcardPresent = true
break
}
}
if !wssWildcardPresent {
logger.Fatal(fmt.Sprintf("Invalid configuration: AutoTLS.Enabled=true requires a catch-all Addresses.Swarm listener ending with %q to be present, see https://github.com/ipfs/kubo/blob/master/docs/config.md#autotls", wssWildcard))
}
}

// Gather all the options
opts := fx.Options(
Expand All @@ -133,6 +152,8 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part

// Services (resource management)
fx.Provide(libp2p.ResourceManager(bcfg.Repo.Path(), cfg.Swarm, userResourceOverrides)),
maybeProvide(libp2p.P2PForgeCertMgr(bcfg.Repo.Path(), cfg.AutoTLS), enableAutoTLS),
maybeInvoke(libp2p.StartP2PAutoTLS, enableAutoTLS),
fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)),
fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.AppendAnnounce, cfg.Addresses.NoAnnounce)),
fx.Provide(libp2p.SmuxTransport(cfg.Swarm.Transports)),
Expand Down
67 changes: 64 additions & 3 deletions core/node/libp2p/addrs.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
package libp2p

import (
"context"
"fmt"
"os"
"path/filepath"

logging "github.com/ipfs/go-log"
version "github.com/ipfs/kubo"
"github.com/ipfs/kubo/config"
p2pforge "github.com/ipshipyard/p2p-forge/client"
"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p/core/host"
p2pbhost "github.com/libp2p/go-libp2p/p2p/host/basic"
ma "github.com/multiformats/go-multiaddr"
mamask "github.com/whyrusleeping/multiaddr-filter"

"github.com/caddyserver/certmagic"
"go.uber.org/fx"
)

func AddrFilters(filters []string) func() (*ma.Filters, Libp2pOpts, error) {
Expand Down Expand Up @@ -87,12 +98,26 @@ func makeAddrsFactory(announce []string, appendAnnouce []string, noAnnounce []st
}, nil
}

func AddrsFactory(announce []string, appendAnnouce []string, noAnnounce []string) func() (opts Libp2pOpts, err error) {
return func() (opts Libp2pOpts, err error) {
addrsFactory, err := makeAddrsFactory(announce, appendAnnouce, noAnnounce)
func AddrsFactory(announce []string, appendAnnouce []string, noAnnounce []string) interface{} {
return func(params struct {
fx.In
ForgeMgr *p2pforge.P2PForgeCertMgr `optional:"true"`
},
) (opts Libp2pOpts, err error) {
var addrsFactory p2pbhost.AddrsFactory
announceAddrsFactory, err := makeAddrsFactory(announce, appendAnnouce, noAnnounce)
if err != nil {
return opts, err
}
if params.ForgeMgr == nil {
addrsFactory = announceAddrsFactory
} else {
addrsFactory = func(multiaddrs []ma.Multiaddr) []ma.Multiaddr {
forgeProcessing := params.ForgeMgr.AddressFactory()(multiaddrs)
annouceProcessing := announceAddrsFactory(forgeProcessing)
return annouceProcessing
}
}
opts.Opts = append(opts.Opts, libp2p.AddrsFactory(addrsFactory))
return
}
Expand All @@ -107,3 +132,39 @@ func ListenOn(addresses []string) interface{} {
}
}
}

func P2PForgeCertMgr(repoPath string, cfg config.AutoTLS) interface{} {
return func() (*p2pforge.P2PForgeCertMgr, error) {
storagePath := filepath.Join(repoPath, "p2p-forge-certs")

forgeLogger := logging.Logger("autotls").Desugar()
certStorage := &certmagic.FileStorage{Path: storagePath}
certMgr, err := p2pforge.NewP2PForgeCertMgr(
p2pforge.WithLogger(forgeLogger.Sugar()),
p2pforge.WithForgeDomain(cfg.DomainSuffix.WithDefault(config.DefaultDomainSuffix)),
p2pforge.WithForgeRegistrationEndpoint(cfg.RegistrationEndpoint.WithDefault(config.DefaultRegistrationEndpoint)),
p2pforge.WithCAEndpoint(cfg.CAEndpoint.WithDefault(config.DefaultCAEndpoint)),
p2pforge.WithForgeAuth(cfg.RegistrationToken.WithDefault(os.Getenv(p2pforge.ForgeAuthEnv))),
p2pforge.WithUserAgent(version.GetUserAgentVersion()),
p2pforge.WithCertificateStorage(certStorage),
)
if err != nil {
return nil, err
}

return certMgr, nil
}
}

func StartP2PAutoTLS(lc fx.Lifecycle, certMgr *p2pforge.P2PForgeCertMgr, h host.Host) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
certMgr.ProvideHost(h)
return certMgr.Start()
},
OnStop: func(ctx context.Context) error {
certMgr.Stop()
return nil
},
})
}
3 changes: 2 additions & 1 deletion core/node/libp2p/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package libp2p

import (
"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p/p2p/net/swarm"
madns "github.com/multiformats/go-multiaddr-dns"
)

func MultiaddrResolver(rslv *madns.Resolver) (opts Libp2pOpts, err error) {
opts.Opts = append(opts.Opts, libp2p.MultiaddrResolver(rslv))
opts.Opts = append(opts.Opts, libp2p.MultiaddrResolver(swarm.ResolverFromMaDNS{Resolver: rslv}))
return opts, nil
}
13 changes: 6 additions & 7 deletions core/node/libp2p/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,12 @@ func RelayService(enable bool, relayOpts config.RelayService) func() (opts Libp2
Data: relayOpts.ConnectionDataLimit.WithDefault(def.Limit.Data),
Duration: relayOpts.ConnectionDurationLimit.WithDefault(def.Limit.Duration),
},
MaxCircuits: int(relayOpts.MaxCircuits.WithDefault(int64(def.MaxCircuits))),
BufferSize: int(relayOpts.BufferSize.WithDefault(int64(def.BufferSize))),
ReservationTTL: relayOpts.ReservationTTL.WithDefault(def.ReservationTTL),
MaxReservations: int(relayOpts.MaxReservations.WithDefault(int64(def.MaxReservations))),
MaxReservationsPerIP: int(relayOpts.MaxReservationsPerIP.WithDefault(int64(def.MaxReservationsPerIP))),
MaxReservationsPerPeer: int(relayOpts.MaxReservationsPerPeer.WithDefault(int64(def.MaxReservationsPerPeer))),
MaxReservationsPerASN: int(relayOpts.MaxReservationsPerASN.WithDefault(int64(def.MaxReservationsPerASN))),
MaxCircuits: int(relayOpts.MaxCircuits.WithDefault(int64(def.MaxCircuits))),
BufferSize: int(relayOpts.BufferSize.WithDefault(int64(def.BufferSize))),
ReservationTTL: relayOpts.ReservationTTL.WithDefault(def.ReservationTTL),
MaxReservations: int(relayOpts.MaxReservations.WithDefault(int64(def.MaxReservations))),
MaxReservationsPerIP: int(relayOpts.MaxReservationsPerIP.WithDefault(int64(def.MaxReservationsPerIP))),
MaxReservationsPerASN: int(relayOpts.MaxReservationsPerASN.WithDefault(int64(def.MaxReservationsPerASN))),
})))
}
return
Expand Down
15 changes: 10 additions & 5 deletions core/node/libp2p/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package libp2p

import (
"fmt"

"github.com/ipfs/kubo/config"
"github.com/ipshipyard/p2p-forge/client"
"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p/core/metrics"
quic "github.com/libp2p/go-libp2p/p2p/transport/quic"
Expand All @@ -16,20 +16,25 @@ import (
)

func Transports(tptConfig config.Transports) interface{} {
return func(pnet struct {
return func(params struct {
fx.In
Fprint PNetFingerprint `optional:"true"`
Fprint PNetFingerprint `optional:"true"`
ForgeMgr *client.P2PForgeCertMgr `optional:"true"`
},
) (opts Libp2pOpts, err error) {
privateNetworkEnabled := pnet.Fprint != nil
privateNetworkEnabled := params.Fprint != nil

if tptConfig.Network.TCP.WithDefault(true) {
// TODO(9290): Make WithMetrics configurable
opts.Opts = append(opts.Opts, libp2p.Transport(tcp.NewTCPTransport, tcp.WithMetrics()))
}

if tptConfig.Network.Websocket.WithDefault(true) {
opts.Opts = append(opts.Opts, libp2p.Transport(websocket.New))
if params.ForgeMgr == nil {
opts.Opts = append(opts.Opts, libp2p.Transport(websocket.New))
} else {
opts.Opts = append(opts.Opts, libp2p.Transport(websocket.New, websocket.WithTLSConfig(params.ForgeMgr.TLSConfig())))
}
}

if tptConfig.Network.QUIC.WithDefault(!privateNetworkEnabled) {
Expand Down
17 changes: 16 additions & 1 deletion docs/changelogs/v0.32.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,36 @@
# Kubo changelog v0.32

- [v0.31.0](#v0320)
- [v0.32.0](#v0310)

## v0.32.0

- [Overview](#overview)
- [πŸ”¦ Highlights](#-highlights)
- [🎯 AutoTLS: Automatic Certificates for libp2p WebSockets via `libp2p.direct`](#-autotls-automatic-certificates-for-libp2p-websockets-via-libp2pdirect)
- [πŸ“¦οΈ Boxo and go-libp2p updates](#-boxo-and-go-libp2p-updates)
- [πŸ“ Changelog](#-changelog)
- [πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors](#-contributors)

### Overview

### πŸ”¦ Highlights

#### 🎯 AutoTLS: Automatic Certificates for libp2p WebSockets via `libp2p.direct`

This release introduces an experimental feature that significantly improves how browsers can connect to Kubo node.
Opt-in configuration allows Kubo nodes to obtain CA-signed TLS certificates for [libp2p Secure WebSocket (WSS)](https://github.com/libp2p/specs/blob/master/websockets/README.md) connections automatically.

See [`AutoTLS`](https://github.com/ipfs/kubo/blob/master/docs/config.md#autotls) configuration for details how to enable it. We appreciate you testing and providing an early feedback in [kubo#10560](https://github.com/ipfs/kubo/issues/10560).

#### πŸ“¦οΈ Boxo and go-libp2p updates

- update `boxo` to [v0.24.1](https://github.com/ipfs/boxo/releases/tag/v0.24.1) + [v0.24.2](https://github.com/ipfs/boxo/releases/tag/v0.24.2)
- This includes a number of fixes and bitswap improvements, and support for filtering from [IPIP-484](https://specs.ipfs.tech/ipips/ipip-0484/) in delegated HTTP routing and IPNI queries.
- update `go-libp2p` to [v0.37.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.37.0)
- This update required removal of `Swarm.RelayService.MaxReservationsPerPeer` configuration option from Kubo. If you had it set, remove it from your configuration file.
- update `go-libp2p-kad-dht` to [v0.27.0](https://github.com/libp2p/go-libp2p-kad-dht/releases/tag/v0.27.0)
- update `go-libp2p-pubsub` to [v0.12.0](https://github.com/libp2p/go-libp2p-pubsub/releases/tag/v0.12.0)

### πŸ“ Changelog

### πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Contributors
Loading

0 comments on commit 28f8636

Please sign in to comment.