@cryptotaxi247 / kubo / commits / 397c346ae

feat(libp2p): shared TCP listeners and AutoTLS.AutoWSS (#10565)

* feat(libp2p): enable shared TCP listeners * docs: switch mentions of /ws to /tcp/4001 * feat: AutoTLS.AutoWSS This adds AutoTLS.AutoWSS flag that is set to true by default. It will check if Addresses.Swarm contain explicit /ws listener, and if not found, it will append one per every /tcp listener This way existing TCP ports are reused without any extra configuration, but we don't break user's who have custom / explicit /ws listener already. I also moved logger around, to include Addresses.Swarm inspection results in `autotls` logger. * chore: go-libp2p v0.38.1 https://github.com/libp2p/go-libp2p/releases/tag/v0.38.0 https://github.com/libp2p/go-libp2p/releases/tag/v0.38.1 * docs: AutoTLS.AutoWSS and go-libp2p v0.38.x * chore: p2p-forge/client v0.2.0 https://github.com/ipshipyard/p2p-forge/releases/tag/v0.2.0 * fix: disable libp2p.ShareTCPListener() in PNET * chore(ci): timeout sharness after 15m average successful run is <9 minutes, no need to wait for 20 https://github.com/ipfs/kubo/actions/workflows/sharness.yml?query=is%3Asuccess --------- Co-authored-by: Andrew Gillis <11790789+gammazero@users.noreply.github.com> Co-authored-by: Marcin Rataj <lidel@lidel.org>

Adin Schmahmann committed Dec 20, 2024 at 12:41 UTC 397c346ae033ca1629651d88ff27a0fb41424067
16 files changed +150 -48
.github/workflows/sharness.yml
+1 -1
@@ -17,7 +17,7 @@ jobs:
17 sharness-test:
18 if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch'
19 runs-on: ${{ fromJSON(github.repository == 'ipfs/kubo' && '["self-hosted", "linux", "x64", "4xlarge"]' || '"ubuntu-latest"') }}
20 - timeout-minutes: 20
20 + timeout-minutes: ${{ github.repository == 'ipfs/kubo' && 15 || 60 }}
21 defaults:
22 run:
23 shell: bash
cmd/ipfs/kubo/daemon.go
+13 -5
@@ -410,13 +410,21 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
410 }
411 }
412
413 - // Private setups can't leverage peers returned by default IPNIs (Routing.Type=auto)
414 - // To avoid breaking existing setups, switch them to DHT-only.
415 - if routingOption == routingOptionAutoKwd {
416 - if key, _ := repo.SwarmKey(); key != nil || pnet.ForcePrivateNetwork {
413 + if key, _ := repo.SwarmKey(); key != nil || pnet.ForcePrivateNetwork {
414 + // Private setups can't leverage peers returned by default IPNIs (Routing.Type=auto)
415 + // To avoid breaking existing setups, switch them to DHT-only.
416 + if routingOption == routingOptionAutoKwd {
417 log.Error("Private networking (swarm.key / LIBP2P_FORCE_PNET) does not work with public HTTP IPNIs enabled by Routing.Type=auto. Kubo will use Routing.Type=dht instead. Update config to remove this message.")
418 routingOption = routingOptionDHTKwd
419 }
420 +
421 + // Private setups should not use public AutoTLS infrastructure
422 + // as it will leak their existence and PeerID identity to CA
423 + // and they will show up at https://crt.sh/?q=libp2p.direct
424 + // Below ensures we hard fail if someone tries to enable both
425 + if cfg.AutoTLS.Enabled.WithDefault(config.DefaultAutoTLSEnabled) {
426 + return errors.New("private networking (swarm.key / LIBP2P_FORCE_PNET) does not work with AutoTLS.Enabled=true, update config to remove this message")
427 + }
428 }
429
430 switch routingOption {
@@ -467,7 +475,7 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
475 fmt.Printf("Swarm key fingerprint: %x\n", node.PNetFingerprint)
476 }
477
470 - if (pnet.ForcePrivateNetwork || node.PNetFingerprint != nil) && routingOption == routingOptionAutoKwd {
478 + if (pnet.ForcePrivateNetwork || node.PNetFingerprint != nil) && (routingOption == routingOptionAutoKwd || routingOption == routingOptionAutoClientKwd) {
479 // This should never happen, but better safe than sorry
480 log.Fatal("Private network does not work with Routing.Type=auto. Update your config to Routing.Type=dht (or none, and do manual peering)")
481 }
config/autotls.go
+5 -1
@@ -6,9 +6,12 @@ import p2pforge "github.com/ipshipyard/p2p-forge/client"
6 // for obtaining a domain and TLS certificate to improve connectivity for web
7 // browser clients. More: https://github.com/ipshipyard/p2p-forge#readme
8 type AutoTLS struct {
9 - // Enables the p2p-forge feature
9 + // Enables the p2p-forge feature and all related features.
10 Enabled Flag `json:",omitempty"`
11
12 + // Optional, controls if Kubo should add /tls/sni/.../ws listener to every /tcp port if no explicit /ws is defined in Addresses.Swarm
13 + AutoWSS Flag `json:",omitempty"`
14 +
15 // Optional override of the parent domain that will be used
16 DomainSuffix *OptionalString `json:",omitempty"`
17
@@ -27,4 +30,5 @@ const (
30 DefaultDomainSuffix = p2pforge.DefaultForgeDomain
31 DefaultRegistrationEndpoint = p2pforge.DefaultForgeEndpoint
32 DefaultCAEndpoint = p2pforge.DefaultCAEndpoint
33 + DefaultAutoWSS = true // requires AutoTLS.Enabled
34 )
core/node/groups.go
+44 -3
@@ -4,6 +4,7 @@ import (
4 "context"
5 "errors"
6 "fmt"
7 + "regexp"
8 "strings"
9 "time"
10
@@ -115,6 +116,8 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part
116 enableRelayService := cfg.Swarm.RelayService.Enabled.WithDefault(enableRelayTransport)
117 enableRelayClient := cfg.Swarm.RelayClient.Enabled.WithDefault(enableRelayTransport)
118 enableAutoTLS := cfg.AutoTLS.Enabled.WithDefault(config.DefaultAutoTLSEnabled)
119 + enableAutoWSS := cfg.AutoTLS.AutoWSS.WithDefault(config.DefaultAutoWSS)
120 + atlsLog := log.Logger("autotls")
121
122 // Log error when relay subsystem could not be initialized due to missing dependency
123 if !enableRelayTransport {
@@ -125,21 +128,59 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part
128 logger.Fatal("Failed to enable `Swarm.RelayClient`, it requires `Swarm.Transports.Network.Relay` to be true.")
129 }
130 }
131 +
132 if enableAutoTLS {
133 + if !cfg.Swarm.Transports.Network.TCP.WithDefault(true) {
134 + logger.Fatal("Invalid configuration: AutoTLS.Enabled=true requires Swarm.Transports.Network.TCP to be true as well.")
135 + }
136 if !cfg.Swarm.Transports.Network.Websocket.WithDefault(true) {
137 logger.Fatal("Invalid configuration: AutoTLS.Enabled=true requires Swarm.Transports.Network.Websocket to be true as well.")
138 }
139
140 + // AutoTLS for Secure WebSockets: ensure WSS listeners are in place (manual or automatic)
141 wssWildcard := fmt.Sprintf("/tls/sni/*.%s/ws", cfg.AutoTLS.DomainSuffix.WithDefault(config.DefaultDomainSuffix))
142 wssWildcardPresent := false
143 + customWsPresent := false
144 + customWsRegex := regexp.MustCompile(`/wss?$`)
145 + tcpRegex := regexp.MustCompile(`/tcp/\d+$`)
146 +
147 + // inspect listeners defined in config at Addresses.Swarm
148 + var tcpListeners []string
149 for _, listener := range cfg.Addresses.Swarm {
150 + // detect if user manually added /tls/sni/.../ws listener matching AutoTLS.DomainSuffix
151 if strings.Contains(listener, wssWildcard) {
152 + atlsLog.Infof("found compatible wildcard listener in Addresses.Swarm. AutoTLS will be used on %s", listener)
153 wssWildcardPresent = true
154 break
155 }
156 + // detect if user manually added own /ws or /wss listener that is
157 + // not related to AutoTLS feature
158 + if customWsRegex.MatchString(listener) {
159 + atlsLog.Infof("found custom /ws listener set by user in Addresses.Swarm. AutoTLS will not be used on %s.", listener)
160 + customWsPresent = true
161 + break
162 + }
163 + // else, remember /tcp listeners that can be reused for /tls/sni/../ws
164 + if tcpRegex.MatchString(listener) {
165 + tcpListeners = append(tcpListeners, listener)
166 + }
167 }
141 - if !wssWildcardPresent {
142 - 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))
168 +
169 + // Append AutoTLS's wildcard listener
170 + // if no manual /ws listener was set by the user
171 + if enableAutoWSS && !wssWildcardPresent && !customWsPresent {
172 + if len(tcpListeners) == 0 {
173 + logger.Fatal("Invalid configuration: AutoTLS.AutoWSS=true requires at least one /tcp listener present in Addresses.Swarm, see https://github.com/ipfs/kubo/blob/master/docs/config.md#autotls")
174 + }
175 + for _, tcpListener := range tcpListeners {
176 + wssListener := tcpListener + wssWildcard
177 + cfg.Addresses.Swarm = append(cfg.Addresses.Swarm, wssListener)
178 + atlsLog.Infof("appended AutoWSS listener: %s", wssListener)
179 + }
180 + }
181 +
182 + if !wssWildcardPresent && !enableAutoWSS {
183 + logger.Fatal(fmt.Sprintf("Invalid configuration: AutoTLS.Enabled=true requires a /tcp listener ending with %q to be present in Addresses.Swarm or AutoTLS.AutoWSS=true, see https://github.com/ipfs/kubo/blob/master/docs/config.md#autotls", wssWildcard))
184 }
185 }
186
@@ -152,7 +193,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part
193
194 // Services (resource management)
195 fx.Provide(libp2p.ResourceManager(bcfg.Repo.Path(), cfg.Swarm, userResourceOverrides)),
155 - maybeProvide(libp2p.P2PForgeCertMgr(bcfg.Repo.Path(), cfg.AutoTLS), enableAutoTLS),
196 + maybeProvide(libp2p.P2PForgeCertMgr(bcfg.Repo.Path(), cfg.AutoTLS, atlsLog), enableAutoTLS),
197 maybeInvoke(libp2p.StartP2PAutoTLS, enableAutoTLS),
198 fx.Provide(libp2p.AddrFilters(cfg.Swarm.AddrFilters)),
199 fx.Provide(libp2p.AddrsFactory(cfg.Addresses.Announce, cfg.Addresses.AppendAnnounce, cfg.Addresses.NoAnnounce)),
core/node/libp2p/addrs.go
+5 -6
@@ -133,21 +133,20 @@ func ListenOn(addresses []string) interface{} {
133 }
134 }
135
136 -func P2PForgeCertMgr(repoPath string, cfg config.AutoTLS) interface{} {
136 +func P2PForgeCertMgr(repoPath string, cfg config.AutoTLS, atlsLog *logging.ZapEventLogger) interface{} {
137 return func() (*p2pforge.P2PForgeCertMgr, error) {
138 storagePath := filepath.Join(repoPath, "p2p-forge-certs")
139
140 - forgeLogger := logging.Logger("autotls").Desugar()
141 -
140 // TODO: this should not be necessary, but we do it to help tracking
141 // down any race conditions causing
142 // https://github.com/ipshipyard/p2p-forge/issues/8
145 - certmagic.Default.Logger = forgeLogger.Named("default_fixme")
146 - certmagic.DefaultACME.Logger = forgeLogger.Named("default_acme_client_fixme")
143 + rawLogger := atlsLog.Desugar()
144 + certmagic.Default.Logger = rawLogger.Named("default_fixme")
145 + certmagic.DefaultACME.Logger = rawLogger.Named("default_acme_client_fixme")
146
147 certStorage := &certmagic.FileStorage{Path: storagePath}
148 certMgr, err := p2pforge.NewP2PForgeCertMgr(
150 - p2pforge.WithLogger(forgeLogger.Sugar()),
149 + p2pforge.WithLogger(rawLogger.Sugar()),
150 p2pforge.WithForgeDomain(cfg.DomainSuffix.WithDefault(config.DefaultDomainSuffix)),
151 p2pforge.WithForgeRegistrationEndpoint(cfg.RegistrationEndpoint.WithDefault(config.DefaultRegistrationEndpoint)),
152 p2pforge.WithCAEndpoint(cfg.CAEndpoint.WithDefault(config.DefaultCAEndpoint)),
core/node/libp2p/transport.go
+14 -2
@@ -2,6 +2,8 @@ package libp2p
2
3 import (
4 "fmt"
5 + "os"
6 +
7 "github.com/ipfs/kubo/config"
8 "github.com/ipshipyard/p2p-forge/client"
9 "github.com/libp2p/go-libp2p"
@@ -24,12 +26,14 @@ func Transports(tptConfig config.Transports) interface{} {
26 ) (opts Libp2pOpts, err error) {
27 privateNetworkEnabled := params.Fprint != nil
28
27 - if tptConfig.Network.TCP.WithDefault(true) {
29 + tcpEnabled := tptConfig.Network.TCP.WithDefault(true)
30 + wsEnabled := tptConfig.Network.Websocket.WithDefault(true)
31 + if tcpEnabled {
32 // TODO(9290): Make WithMetrics configurable
33 opts.Opts = append(opts.Opts, libp2p.Transport(tcp.NewTCPTransport, tcp.WithMetrics()))
34 }
35
32 - if tptConfig.Network.Websocket.WithDefault(true) {
36 + if wsEnabled {
37 if params.ForgeMgr == nil {
38 opts.Opts = append(opts.Opts, libp2p.Transport(websocket.New))
39 } else {
@@ -37,6 +41,14 @@ func Transports(tptConfig config.Transports) interface{} {
41 }
42 }
43
44 + if tcpEnabled && wsEnabled && os.Getenv("LIBP2P_TCP_MUX") != "false" {
45 + if privateNetworkEnabled {
46 + log.Error("libp2p.ShareTCPListener() is not supported in private networks, please disable Swarm.Transports.Network.Websocket or run with LIBP2P_TCP_MUX=false to make this message go away")
47 + } else {
48 + opts.Opts = append(opts.Opts, libp2p.ShareTCPListener())
49 + }
50 + }
51 +
52 if tptConfig.Network.QUIC.WithDefault(!privateNetworkEnabled) {
53 if privateNetworkEnabled {
54 return opts, fmt.Errorf(
docs/changelogs/v0.33.md
+24 -4
@@ -6,13 +6,15 @@
6
7 - [Overview](#overview)
8 - [🔦 Highlights](#-highlights)
9 + - [Shared TCP listeners](#shared-tcp-listeners)
10 + - [AutoTLS takes care of Secure WebSockets setup](#autotls-takes-care-of-secure-websockets-setup)
11 - [Bitswap improvements from Boxo](#bitswap-improvements-from-boxo)
12 - [Using default `libp2p_rcmgr` metrics](#using-default-libp2p_rcmgr--metrics)
13 - [Flatfs does not `sync` on each write](#flatfs-does-not-sync-on-each-write)
14 - [`ipfs add --to-files` no longer works with `--wrap`](#ipfs-add---to-files-no-longer-works-with---wrap)
15 - [New options for faster writes: `WriteThrough`, `BlockKeyCacheSize`, `BatchMaxNodes`, `BatchMaxSize`](#new-options-for-faster-writes-writethrough-blockkeycachesize-batchmaxnodes-batchmaxsize)
16 - [MFS stability with large number of writes](#mfs-stability-with-large-number-of-writes)
15 - - [📦️ Dependency updates](#-dependency-updates)
17 + - [📦️ Important dependency updates](#-important-dependency-updates)
18 - [📝 Changelog](#-changelog)
19 - [👨‍👩‍👧‍👦 Contributors](#-contributors)
20
@@ -20,6 +22,24 @@
22
23 ### 🔦 Highlights
24
25 +#### Shared TCP listeners
26 +
27 +Kubo now supports sharing the same TCP port (`4001` by default) by both [raw TCP](https://github.com/ipfs/kubo/blob/master/docs/config.md#swarmtransportsnetworktcp) and [WebSockets](https://github.com/ipfs/kubo/blob/master/docs/config.md#swarmtransportsnetworkwebsocket) libp2p transports.
28 +
29 +This feature is not yet compatible with Private Networks and can be disabled by setting `LIBP2P_TCP_MUX=false` if causes any issues.
30 +
31 +#### AutoTLS takes care of Secure WebSockets setup
32 +
33 +It is no longer necessary to manually add `/tcp/../ws` listeners to `Addresses.Swarm` when [`AutoTLS.Enabled`](https://github.com/ipfs/kubo/blob/master/docs/config.md#autotlsenabled) is set to `true`. Kubo will detect if `/ws` listener is missing and add one on the same port as pre-existing TCP (e.g. `/tcp/4001`), removing the need for any extra configuration.
34 +> [!TIP]
35 +> Give it a try:
36 +> ```console
37 +> $ ipfs config --json AutoTLS.Enabled true
38 +> ```
39 +> And restart the node. If you are behind NAT, make sure your node is publicly diallable (uPnP or port forwarding), and wait a few minutes to pass all checks and for the changes to take effect.
40 +
41 +See [`AutoTLS`](https://github.com/ipfs/kubo/blob/master/docs/config.md#autotls) for more information.
42 +
43 #### Bitswap improvements from Boxo
44
45 This release includes some refactorings and improvements affecting Bitswap which should improve reliability. One of the changes affects blocks providing. Previously, the bitswap layer took care itself of announcing new blocks -added or received- with the configured provider (i.e. DHT). This bypassed the "Reprovider", that is, the system that manages precisely "providing" the blocks stored by Kubo. The Reprovider knows how to take advantage of the [AcceleratedDHTClient](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingaccelerateddhtclient), is able to handle priorities, logs statistics and is able to resume on daemon reboot where it left off. From now on, Bitswap will not be doing any providing on-the-side and all announcements are managed by the reprovider. In some cases, when the reproviding queue is full with other elements, this may cause additional delays, but more likely this will result in improved block-providing behaviour overall.
@@ -62,11 +82,11 @@ We recommend users trying Pebble as a datastore backend to disable both blocksto
82
83 We have fixed a number of issues that were triggered by writing or copying many files onto an MFS folder: increased memory usage first, then CPU, disk usage, and eventually a deadlock on write operations. The details of the fixes can be read at [#10630](https://github.com/ipfs/kubo/pull/10630) and [#10623](https://github.com/ipfs/kubo/pull/10623). The result is that writing large amounts of files to an MFS folder should now be possible without major issues. It is possible, as before, to speed up the operations using the `ipfs files --flush=false <op> ...` flag, but it is recommended to switch to `ipfs files --flush=true <op> ...` regularly, or call `ipfs files flush` on the working directory regularly, as this will flush, clear the directory cache and speed up reads.
84
65 -#### 📦️ Dependency updates
85 +#### 📦️ Important dependency updates
86
67 -- update `boxo` to [v0.26.0](https://github.com/ipfs/boxo/releases/tag/v0.26.0)
87 +- update `boxo` to [v0.26.0](https://github.com/ipfs/boxo/releases/tag/v0.26.0) (incl. [v0.25.0](https://github.com/ipfs/boxo/releases/tag/v0.25.0))
88 - update `go-libp2p` to [v0.38.1](https://github.com/libp2p/go-libp2p/releases/tag/v0.38.1) (incl. [v0.37.1](https://github.com/libp2p/go-libp2p/releases/tag/v0.37.1) + [v0.37.2](https://github.com/libp2p/go-libp2p/releases/tag/v0.37.2) + [v0.38.0](https://github.com/libp2p/go-libp2p/releases/tag/v0.38.0))
69 -- update `p2p-forge/client` to [v0.1.0](https://github.com/ipshipyard/p2p-forge/releases/tag/v0.1.0)
89 +- update `p2p-forge/client` to [v0.2.0](https://github.com/ipshipyard/p2p-forge/releases/tag/v0.2.0) (incl. [v0.1.0](https://github.com/ipshipyard/p2p-forge/releases/tag/v0.1.0))
90 - update `ipfs-webui` to [v4.4.1](https://github.com/ipfs/ipfs-webui/releases/tag/v4.4.1)
91
92 ### 📝 Changelog
docs/config.md
+21 -14
@@ -29,6 +29,7 @@ config file at runtime.
29 - [`AutoNAT.Throttle.Interval`](#autonatthrottleinterval)
30 - [`AutoTLS`](#autotls)
31 - [`AutoTLS.Enabled`](#autotlsenabled)
32 + - [`AutoTLS.AutoWSS`](#autotlsautowss)
33 - [`AutoTLS.DomainSuffix`](#autotlsdomainsuffix)
34 - [`AutoTLS.RegistrationEndpoint`](#autotlsregistrationendpoint)
35 - [`AutoTLS.RegistrationToken`](#autotlsregistrationtoken)
@@ -496,33 +497,39 @@ Type: `object`
497 > Feel free to enable it and [report issues](https://github.com/ipfs/kubo/issues/new/choose) if you want to help with testing.
498 > Track progress in [kubo#10560](https://github.com/ipfs/kubo/issues/10560).
499
499 -Enables AutoTLS feature to get DNS+TLS for [libp2p Secure WebSocket](https://github.com/libp2p/specs/blob/master/websockets/README.md) listeners defined in [`Addresses.Swarm`](#addressesswarm), such as `/ip4/0.0.0.0/tcp/4002/tls/sni/*.libp2p.direct/ws` and `/ip6/::/tcp/4002/tls/sni/*.libp2p.direct/ws`.
500 +Enables AutoTLS feature to get DNS+TLS for [libp2p Secure WebSocket](https://github.com/libp2p/specs/blob/master/websockets/README.md) on `/tcp` port.
501
501 -If `.../tls/sni/*.libp2p.direct/ws` [multiaddr] is present in [`Addresses.Swarm`](#addressesswarm)
502 +If `AutoTLS.AutoWSS` is `true`, or `/tcp/../tls/sni/*.libp2p.direct/ws` [multiaddr] is present in [`Addresses.Swarm`](#addressesswarm)
503 with SNI segment ending with [`AutoTLS.DomainSuffix`](#autotlsdomainsuffix),
503 -Kubo will obtain and set up a trusted PKI TLS certificate for it, making it dialable from web browser's [Secure Contexts](https://w3c.github.io/webappsec-secure-contexts/).
504 +Kubo will obtain and set up a trusted PKI TLS certificate for `*.peerid.libp2p.direct`, making it dialable from web browser's [Secure Contexts](https://w3c.github.io/webappsec-secure-contexts/).
505 +
506 +> [!TIP]
507 +> - Most users don't need custom `/ws` config in `Addresses.Swarm`. Try running this with `AutoTLS.AutoWSS=true`: it will reuse preexisting catch-all `/tcp` ports that were already forwarded/safelisted on your firewall.
508 +> - Debugging can be enabled by setting environment variable `GOLOG_LOG_LEVEL="error,autotls=debug,p2p-forge/client=debug"`. Less noisy `GOLOG_LOG_LEVEL="error,autotls=info` may be informative enough.
509 +> - Certificates are stored in `$IPFS_PATH/p2p-forge-certs`. Removing directory and restarting daemon will trigger certificate rotation.
510
511 > [!IMPORTANT]
512 > Caveats:
513 > - Requires your Kubo node to be publicly dialable.
508 -> - If you want to test this with a node that is behind a NAT and uses manual port forwarding or UPnP (`Swarm.DisableNatPortMap=false`),
509 -> add catch-all `/ip4/0.0.0.0/tcp/4002/tls/sni/*.libp2p.direct/ws` and `/ip6/::/tcp/4002/tls/sni/*.libp2p.direct/ws` to [`Addresses.Swarm`](#addressesswarm)
514 +> - If you want to test this with a node that is behind a NAT and uses manual TCP port forwarding or UPnP (`Swarm.DisableNatPortMap=false`), use `AutoTLS.AutoWSS=true`, or manually
515 +> add catch-all `/ip4/0.0.0.0/tcp/4001/tls/sni/*.libp2p.direct/ws` and `/ip6/::/tcp/4001/tls/sni/*.libp2p.direct/ws` to [`Addresses.Swarm`](#addressesswarm)
516 > and **wait 5-15 minutes** for libp2p node to set up and learn about own public addresses via [AutoNAT](#autonat).
517 > - If your node is fresh and just started, the [p2p-forge] client may produce and log ERRORs during this time, but once a publicly dialable addresses are set up, a subsequent retry should be successful.
512 -> - Listeners defined in [`Addresses.Swarm`](#addressesswarm) with `/tls/sni` must use a separate port from other TCP listeners, e.g. `4002` instead of the default `4001`.
513 -> - A separate port (`/tcp/4002`) has to be used instead of `/tcp/4001` because we wait for TCP port sharing ([go-libp2p#2984](https://github.com/libp2p/go-libp2p/issues/2684)) to be implemented.
514 -> - If you use manual port forwarding, make sure incoming connections to this additional port are allowed the same way `4001` ones already are.
518 > - The TLS certificate is used only for [libp2p WebSocket](https://github.com/libp2p/specs/blob/master/websockets/README.md) connections.
519 > - Right now, this is NOT used for hosting a [Gateway](#gateway) over HTTPS (that use case still requires manual TLS setup on reverse proxy, and your own domain).
520
518 -> [!TIP]
519 -> - Debugging can be enabled by setting environment variable `GOLOG_LOG_LEVEL="error,autotls=debug,p2p-forge/client=debug"`
520 -> - Certificates are stored in `$IPFS_PATH/p2p-forge-certs`. Removing directory and restarting daemon will trigger certificate rotation.
521 -
521 Default: `false`
522
523 Type: `flag`
524
525 +### `AutoTLS.AutoWSS`
526 +
527 +Optional. Controls if Kubo should add `/tls/sni/*.libp2p.direct/ws` listener to every pre-existing `/tcp` port IFF no explicit `/ws` is defined in [`Addresses.Swarm`](#addressesswarm) already.
528 +
529 +Default: `true` (active only if `AutoTLS.Enabled` is `true` as well)
530 +
531 +Type: `flag`
532 +
533 ### `AutoTLS.DomainSuffix`
534
535 Optional override of the parent domain suffix that will be used in DNS+TLS+WebSockets multiaddrs generated by [p2p-forge] client.
@@ -2198,8 +2205,8 @@ Default: Enabled
2205 Type: `flag`
2206
2207 Listen Addresses:
2201 -* /ip4/0.0.0.0/tcp/4002/ws
2202 -* /ip6/::/tcp/4002/ws
2208 +* /ip4/0.0.0.0/tcp/4001/ws
2209 +* /ip6/::/tcp/4001/ws
2210
2211 #### `Swarm.Transports.Network.QUIC`
2212
docs/environment-variables.md
+11 -1
@@ -155,7 +155,17 @@ Kubo tries to reuse the same source port for all connections to improve NAT
155 traversal. If this is an issue, you can disable it by setting
156 `LIBP2P_TCP_REUSEPORT` to false.
157
158 -Default: true
158 +Default: `true`
159 +
160 +## `LIBP2P_TCP_MUX`
161 +
162 +By default Kubo tries to reuse the same listener port for raw TCP and WebSockers transports via experimental `libp2p.ShareTCPListener()` feature introduced in [go-libp2p#2984](https://github.com/libp2p/go-libp2p/pull/2984).
163 +If this is an issue, you can disable it by setting `LIBP2P_TCP_MUX` to `false` and use separate ports for each TCP transport.
164 +
165 +> [!CAUTION]
166 +> This configuration option may be removed once `libp2p.ShareTCPListener()` becomes default in go-libp2p.
167 +
168 +Default: `true`
169
170 ## `LIBP2P_MUX_PREFS`
171
docs/examples/kubo-as-a-library/go.mod
+1 -1
@@ -112,7 +112,7 @@ require (
112 github.com/ipld/go-car/v2 v2.14.2 // indirect
113 github.com/ipld/go-codec-dagpb v1.6.0 // indirect
114 github.com/ipld/go-ipld-prime v0.21.0 // indirect
115 - github.com/ipshipyard/p2p-forge v0.1.0 // indirect
115 + github.com/ipshipyard/p2p-forge v0.2.0 // indirect
116 github.com/jackpal/go-nat-pmp v1.0.2 // indirect
117 github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
118 github.com/jbenet/goprocess v0.1.4 // indirect
docs/examples/kubo-as-a-library/go.sum
+4 -4
@@ -407,8 +407,8 @@ github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH
407 github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ=
408 github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo=
409 github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd/go.mod h1:wZ8hH8UxeryOs4kJEJaiui/s00hDSbE37OKsL47g+Sw=
410 -github.com/ipshipyard/p2p-forge v0.1.0 h1:RjCuX5wSKOv6J+6aaKTvuGOhVw24TuCLZx7d3M4BaiI=
411 -github.com/ipshipyard/p2p-forge v0.1.0/go.mod h1:5s1MuHMh8FXrhDScKLk0F+zBaJglCAZMKn9myiWAPOU=
410 +github.com/ipshipyard/p2p-forge v0.2.0 h1:ZboFW1h6SE5ZTHz3YrCRSup/C0GMMOzHux82zMEPWtk=
411 +github.com/ipshipyard/p2p-forge v0.2.0/go.mod h1:RcA03Mn9o31M3HKBa9mrnTDthWGRlAxTipQFQjDOOvc=
412 github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
413 github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
414 github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
@@ -1081,8 +1081,8 @@ golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
1081 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
1082 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
1083 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
1084 -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
1085 -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
1084 +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
1085 +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
1086 golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
1087 golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
1088 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
go.mod
+1 -1
@@ -49,7 +49,7 @@ require (
49 github.com/ipld/go-car/v2 v2.14.2
50 github.com/ipld/go-codec-dagpb v1.6.0
51 github.com/ipld/go-ipld-prime v0.21.0
52 - github.com/ipshipyard/p2p-forge v0.1.0
52 + github.com/ipshipyard/p2p-forge v0.2.0
53 github.com/jbenet/go-temp-err-catcher v0.1.0
54 github.com/jbenet/goprocess v0.1.4
55 github.com/julienschmidt/httprouter v1.3.0
go.sum
+2 -2
@@ -475,8 +475,8 @@ github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH
475 github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ=
476 github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo=
477 github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd/go.mod h1:wZ8hH8UxeryOs4kJEJaiui/s00hDSbE37OKsL47g+Sw=
478 -github.com/ipshipyard/p2p-forge v0.1.0 h1:RjCuX5wSKOv6J+6aaKTvuGOhVw24TuCLZx7d3M4BaiI=
479 -github.com/ipshipyard/p2p-forge v0.1.0/go.mod h1:5s1MuHMh8FXrhDScKLk0F+zBaJglCAZMKn9myiWAPOU=
478 +github.com/ipshipyard/p2p-forge v0.2.0 h1:ZboFW1h6SE5ZTHz3YrCRSup/C0GMMOzHux82zMEPWtk=
479 +github.com/ipshipyard/p2p-forge v0.2.0/go.mod h1:RcA03Mn9o31M3HKBa9mrnTDthWGRlAxTipQFQjDOOvc=
480 github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
481 github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
482 github.com/jbenet/go-cienv v0.1.0 h1:Vc/s0QbQtoxX8MwwSLWWh+xNNZvM3Lw7NsTcHrvvhMc=
test/dependencies/go.mod
+1 -1
@@ -131,7 +131,7 @@ require (
131 github.com/ipfs/kubo v0.31.0 // indirect
132 github.com/ipld/go-codec-dagpb v1.6.0 // indirect
133 github.com/ipld/go-ipld-prime v0.21.0 // indirect
134 - github.com/ipshipyard/p2p-forge v0.1.0 // indirect
134 + github.com/ipshipyard/p2p-forge v0.2.0 // indirect
135 github.com/jackpal/go-nat-pmp v1.0.2 // indirect
136 github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
137 github.com/jbenet/goprocess v0.1.4 // indirect
test/dependencies/go.sum
+2 -2
@@ -364,8 +364,8 @@ github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6
364 github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s=
365 github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E=
366 github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ=
367 -github.com/ipshipyard/p2p-forge v0.1.0 h1:RjCuX5wSKOv6J+6aaKTvuGOhVw24TuCLZx7d3M4BaiI=
368 -github.com/ipshipyard/p2p-forge v0.1.0/go.mod h1:5s1MuHMh8FXrhDScKLk0F+zBaJglCAZMKn9myiWAPOU=
367 +github.com/ipshipyard/p2p-forge v0.2.0 h1:ZboFW1h6SE5ZTHz3YrCRSup/C0GMMOzHux82zMEPWtk=
368 +github.com/ipshipyard/p2p-forge v0.2.0/go.mod h1:RcA03Mn9o31M3HKBa9mrnTDthWGRlAxTipQFQjDOOvc=
369 github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
370 github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
371 github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
test/sharness/t0181-private-network.sh
+1
@@ -36,6 +36,7 @@ LIBP2P_FORCE_PNET=1 test_launch_ipfs_daemon
36 test_expect_success "set up iptb testbed" '
37 iptb testbed create -type localipfs -count 5 -force -init &&
38 iptb run -- ipfs config --json "Routing.LoopbackAddressesOnLanDHT" true &&
39 + iptb run -- ipfs config --json "Swarm.Transports.Network.Websocket" false &&
40 iptb run -- ipfs config --json Addresses.Swarm '"'"'["/ip4/127.0.0.1/tcp/0"]'"'"'
41 '
42