refactor: move AutoTLS to top level

we have AutoNAT there, and this feature could be extended in the future
to cover user-provided domains and Gateway, so moving it out of Swarm
makes it more future-proof.
This commit is contained in:
Marcin Rataj 2024-10-29 16:23:37 +01:00
parent e51d907854
commit 73c3fd3d15
No known key found for this signature in database
GPG Key ID: 222B6784D5A79E42
4 changed files with 105 additions and 96 deletions

View File

@ -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

View File

@ -32,11 +32,6 @@ type SwarmConfig struct {
// ResourceMgr configures the libp2p Network Resource Manager
ResourceMgr ResourceMgr
// AutoTLS controls the client of a service for obtaining and configuring a
// domain and TLS certificate to improve connectivity for web browser
// clients.
AutoTLS AutoTLS
}
type RelayClient struct {

View File

@ -114,7 +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.Swarm.AutoTLS.Enabled.WithDefault(config.DefaultAutoTLSEnabled)
enableAutoTLS := cfg.AutoTLS.Enabled.WithDefault(config.DefaultAutoTLSEnabled)
// Log error when relay subsystem could not be initialized due to missing dependency
if !enableRelayTransport {
@ -127,10 +127,10 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part
}
if enableAutoTLS {
if !cfg.Swarm.Transports.Network.Websocket.WithDefault(true) {
logger.Fatal("Failed to enable `Swarm.AutoTLS`, it requires `Swarm.Transports.Network.Websocket` to be 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.Swarm.AutoTLS.DomainSuffix.WithDefault(config.DefaultDomainSuffix))
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) {
@ -139,7 +139,7 @@ func LibP2P(bcfg *BuildCfg, cfg *config.Config, userResourceOverrides rcmgr.Part
}
}
if !wssWildcardPresent {
logger.Fatal(fmt.Sprintf("Failed to enable `Swarm.AutoTLS`, it requires `Addresses.Swarm` listener matching %q to be present, see https://github.com/ipfs/kubo/blob/master/docs/config.md#swarmautotls", wssWildcard))
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))
}
}
@ -152,7 +152,7 @@ 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(cfg.Swarm.AutoTLS), enableAutoTLS),
maybeProvide(libp2p.P2PForgeCertMgr(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)),

View File

@ -27,6 +27,12 @@ config file at runtime.
- [`AutoNAT.Throttle.GlobalLimit`](#autonatthrottlegloballimit)
- [`AutoNAT.Throttle.PeerLimit`](#autonatthrottlepeerlimit)
- [`AutoNAT.Throttle.Interval`](#autonatthrottleinterval)
- [`AutoTLS`](#autotls)
- [`AutoTLS.Enabled`](#autotlsenabled)
- [`AutoTLS.DomainSuffix`](#autotlsdomainsuffix)
- [`AutoTLS.RegistrationEndpoint`](#autotlsregistrationendpoint)
- [`AutoTLS.RegistrationToken`](#autotlsregistrationtoken)
- [`AutoTLS.CAEndpoint`](#autotlscaendpoint)
- [`Bootstrap`](#bootstrap)
- [`Datastore`](#datastore)
- [`Datastore.StorageMax`](#datastorestoragemax)
@ -117,12 +123,6 @@ config file at runtime.
- [`Swarm.DisableBandwidthMetrics`](#swarmdisablebandwidthmetrics)
- [`Swarm.DisableNatPortMap`](#swarmdisablenatportmap)
- [`Swarm.EnableHolePunching`](#swarmenableholepunching)
- [`Swarm.AutoTLS`](#swarmautotls)
- [`Swarm.AutoTLS.Enabled`](#swarmautotlsenabled)
- [`Swarm.AutoTLS.DomainSuffix`](#swarmautotlsdomainsuffix)
- [`Swarm.AutoTLS.RegistrationEndpoint`](#swarmautotlsregistrationendpoint)
- [`Swarm.AutoTLS.RegistrationToken`](#swarmautotlsregistrationtoken)
- [`Swarm.AutoTLS.CAEndpoint`](#swarmautotlscaendpoint)
- [`Swarm.EnableAutoRelay`](#swarmenableautorelay)
- [`Swarm.RelayClient`](#swarmrelayclient)
- [`Swarm.RelayClient.Enabled`](#swarmrelayclientenabled)
@ -455,6 +455,99 @@ Default: 1 Minute
Type: `duration` (when `0`/unset, the default value is used)
## `AutoTLS`
> [!CAUTION]
> This is an **EXPERIMENTAL** opt-in feature and should not be used in production yet.
> Feel free to enable it and [report issues](https://github.com/ipfs/kubo/issues/new/choose) if you want to help with testing.
AutoTLS feature enables publicly reachable Kubo nodes (those dialable from the public
internet) to automatically obtain a wildcard TLS certificate for a DNS name
unique to their PeerID at `*.[PeerID].libp2p.direct`. This enables direct
libp2p connections and retrieval of IPFS content from browsers [Secure Context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts)
using transports such as [Secure WebSockets](https://github.com/libp2p/specs/blob/master/websockets/README.md),
without requiring user to do any manual domain registration and ceritficate configuration.
Under the hood, [p2p-forge] client uses public utility service at `libp2p.direct` as an [ACME DNS-01 Challenge](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge)
broker enabling peer to obtain a wildcard TLS certificate tied to public key of their [PeerID](https://docs.libp2p.io/concepts/fundamentals/peers/#peer-id).
By default, the certificates are requested from Let's Encrypt. Origin and rationale for this project can be found in [community.letsencrypt.org discussion](https://community.letsencrypt.org/t/feedback-on-raising-certificates-per-registered-domain-to-enable-peer-to-peer-networking/223003).
> [!NOTE]
> Public good DNS and [p2p-forge] infrastructure at `libp2p.direct` is run by the team at [Interplanetary Shipyard](https://ipshipyard.com).
>
> <a href="https://ipshipyard.com/"><img src="https://github.com/user-attachments/assets/39ed3504-bb71-47f6-9bf8-cb9a1698f272" /></a>
[p2p-forge]: https://github.com/ipshipyard/p2p-forge
Default: `{}`
Type: `object`
### `AutoTLS.Enabled`
> [!CAUTION]
> This is an **EXPERIMENTAL** opt-in feature and should not be used in production yet.
> Feel free to enable it and [report issues](https://github.com/ipfs/kubo/issues/new/choose) if you want to help with testing.
Enables AutoTLS feature to get DNS+TLS for libp2p Secure WebSocket connections.
If enabled, it will detect when `.../tls/sni/.../ws` [multiaddr] is present in [`Addresses.Swarm`](#addressesswarm)
and SNI is matching `AutoTLS.DomainSuffix`, and set up a trusted TLS certificate matching the domain name used in [libp2p Secure WebSockets (WSS)](https://github.com/libp2p/specs/blob/master/websockets/README.md) listener.
> [!IMPORTANT]
> Caveats:
> - This works only if your Kubo node is publicly diallable.
> - The TLS certificate is used only for [libp2p WebSocket](https://github.com/libp2p/specs/blob/master/websockets/README.md) connections.
> - This is NOT used for hosting a [Gateway](#gateway) over HTTPS (it still requies manual TLS setup and your own domain).
> - If you want to test this with a node that is behind a NAT and uses manual port forwarding or UPnP (`Swarm.DisableNatPortMap=false`),
> add `/ip4/0.0.0.0/tcp/4082/tls/sni/*.libp2p.direct/ws` to [`Addresses.Swarm`](#addressesswarm)
> and wait up to 5-15 minutes for libp2p node to set up and learn about own public addresses via [AutoNAT](#autonat).
> - Note: the [p2p-forge] client may produce and log ERROR during this time, but once a publicly diallable addresses are set up,
> a subsequent retry should be successful.
> [!TIP]
> Debugging can be enabled by setting environment variable `GOLOG_LOG_LEVEL="error,autotls=debug,p2p-forge/client=debug"`
Default: `false`
Type: `flag`
### `AutoTLS.DomainSuffix`
Optional override of the parent domain suffix that will be used in DNS+TLS+WebSockets multiaddrs generated by [p2p-forge] client.
Do not change this unless you self-host [p2p-forge].
Default: `libp2p.direct` (public good run by [Interplanetary Shipyard](https://ipshipyard.com))
Type: `optionalString`
### `AutoTLS.RegistrationEndpoint`
Optional override of [p2p-forge] HTTP registration API.
Do not change this unless you self-host [p2p-forge].
Default: `https://registration.libp2p.direct` (public good run by [Interplanetary Shipyard](https://ipshipyard.com))
Type: `optionalString`
### `AutoTLS.RegistrationToken`
Optional value for `Forge-Authorization` token sent with request to `RegistrationEndpoint`
(useful for private/self-hosted/test instances of [p2p-forge], unset by default).
Default: `""`
Type: `optionalString`
### `AutoTLS.CAEndpoint`
Optional override of CA ACME API used by [p2p-forge] system.
Default: [certmagic.LetsEncryptProductionCA](https://pkg.go.dev/github.com/caddyserver/certmagic#pkg-constants) (see [community.letsencrypt.org discussion](https://community.letsencrypt.org/t/feedback-on-raising-certificates-per-registered-domain-to-enable-peer-to-peer-networking/223003))
Type: `optionalString`
## `Bootstrap`
Bootstrap is an array of [multiaddrs][multiaddr] of trusted nodes that your node connects to, to fetch other nodes of the network on startup.
@ -1722,86 +1815,6 @@ Default: `true`
Type: `flag`
### `Swarm.AutoTLS`
AutoTLS enables publicly reachable Kubo nodes (those dialable from the public
internet) to automatically obtain a wildcard TLS certificate for a DNS name
unique to their PeerID at `*.[PeerID].libp2p.direct`. This enables direct
libp2p connections and retrieval of IPFS content from browsers using Secure
WebSockets, without requiring manual domain registration and configuration.
Under the hood, `libp2p.direct` acts as an [ACME DNS-01 Challenge](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge)
broker for obtaining these wildcard TLS certificates.
By default, the certificates are requested from Let's Encrypt.
Origin and rationale for this project can be found in [community.letsencrypt.org discussion].
> [!NOTE]
> Public good infrastructure at `libp2p.direct` is run by the team at [Interplanetary Shipyard](https://ipshipyard.com).
>
> <a href="http://ipshipyard.com/"><img src="https://github.com/user-attachments/assets/39ed3504-bb71-47f6-9bf8-cb9a1698f272" /></a>
[p2p-forge]: https://github.com/ipshipyard/p2p-forge
[community.letsencrypt.org discussion]: https://community.letsencrypt.org/t/feedback-on-raising-certificates-per-registered-domain-to-enable-peer-to-peer-networking/223003
Default: `{}`
Type: `object`
#### `Swarm.AutoTLS.Enabled`
> [!CAUTION]
> This is an EXPERIMENTAL feature and should not be used in production yet.
> Feel free to enable it and [report issues](https://github.com/ipfs/kubo/issues/new/choose) if you want to help with testing.
Enables **EXPERIMENTAL** [p2p-forge] client. This feature works only if your Kubo node is publicly diallable.
If enabled, it will detect when `.../tls/sni/.../ws` is present in [`Addresses.Swarm`](#addressesswarm)
and SNI is matching `Swarm.AutoTLS.DomainSuffix`, and set up a trusted TLS certificate matching the domain name used in Secure WebSockets (WSS) listener.
If you want to test this, add `/ip4/0.0.0.0/tcp/4082/tls/sni/*.libp2p.direct/ws` to [`Addresses.Swarm`](#addressesswarm).
Debugging can be enabled by setting environment variable `GOLOG_LOG_LEVEL="error,autotls=debug,p2p-forge/client=debug"`
Default: `false`
Type: `flag`
#### `Swarm.AutoTLS.DomainSuffix`
Optional override of the parent domain suffix that will be used in DNS+TLS+WebSockets multiaddrs generated by [p2p-forge] client.
Do not change this unless you self-host [p2p-forge].
Default: `libp2p.direct` (public good run by [Interplanetary Shipyard](https://ipshipyard.com))
Type: `optionalString`
#### `Swarm.AutoTLS.RegistrationEndpoint`
Optional override of [p2p-forge] HTTP registration API.
Do not change this unless you self-host [p2p-forge].
Default: `https://registration.libp2p.direct` (public good run by [Interplanetary Shipyard](https://ipshipyard.com))
Type: `optionalString`
#### `Swarm.AutoTLS.RegistrationToken`
Optional value for `Forge-Authorization` token sent with request to `RegistrationEndpoint`
(useful for private/self-hosted/test instances of [p2p-forge]).
Default: `""`
Type: `optionalString`
#### `Swarm.AutoTLS.CAEndpoint`
Optional override of CA ACME API used by [p2p-forge] system.
Default: [certmagic.LetsEncryptProductionCA](https://pkg.go.dev/github.com/caddyserver/certmagic#pkg-constants) (see [community.letsencrypt.org discussion])
Type: `optionalString`
### `Swarm.EnableAutoRelay`
**REMOVED**