From 99b7757e71db3bcf5cdada8565faac859b385c6e Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Mon, 28 Oct 2024 19:20:57 +0100 Subject: [PATCH] =?UTF-8?q?refactor:=20ForgeClient=20=E2=86=92=20AutoTLS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit addressing UX/DX feedback from Daniel, switching to self-explanatory configuration section --- config/{forge.go => autotls.go} | 18 ++++++------- config/swarm.go | 7 ++--- core/node/groups.go | 10 +++---- core/node/libp2p/addrs.go | 10 +++---- docs/changelogs/v0.32.md | 2 +- docs/config.md | 47 +++++++++++++++++---------------- 6 files changed, 48 insertions(+), 46 deletions(-) rename config/{forge.go => autotls.go} (53%) diff --git a/config/forge.go b/config/autotls.go similarity index 53% rename from config/forge.go rename to config/autotls.go index 749e713ffa3..67ada23abe8 100644 --- a/config/forge.go +++ b/config/autotls.go @@ -2,29 +2,29 @@ package config import p2pforge "github.com/ipshipyard/p2p-forge/client" -// ForgeClient includes optional configuration of p2p-forge client of service +// 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 ForgeClient struct { +type AutoTLS struct { // Enables the p2p-forge feature Enabled Flag `json:",omitempty"` // Optional override of the parent domain that will be used - ForgeDomain *OptionalString `json:",omitempty"` + DomainSuffix *OptionalString `json:",omitempty"` // Optional override of HTTP API that acts as ACME DNS-01 Challenge broker - ForgeEndpoint *OptionalString `json:",omitempty"` + RegistrationEndpoint *OptionalString `json:",omitempty"` // Optional Authorization token, used with private/test instances of p2p-forge - ForgeAuth *OptionalString `json:",omitempty"` + RegistrationToken *OptionalString `json:",omitempty"` // Optional override of CA ACME API used by p2p-forge system CAEndpoint *OptionalString `json:",omitempty"` } const ( - DefaultForgeEnabled = false // experimental, opt-in for now (https://github.com/ipfs/kubo/pull/10521) - DefaultForgeDomain = p2pforge.DefaultForgeDomain - DefaultForgeEndpoint = p2pforge.DefaultForgeEndpoint - DefaultCAEndpoint = p2pforge.DefaultCAEndpoint + DefaultAutoTLSEnabled = false // experimental, opt-in for now (https://github.com/ipfs/kubo/pull/10521) + DefaultDomainSuffix = p2pforge.DefaultForgeDomain + DefaultRegistrationEndpoint = p2pforge.DefaultForgeEndpoint + DefaultCAEndpoint = p2pforge.DefaultCAEndpoint ) diff --git a/config/swarm.go b/config/swarm.go index 6ccc76cae75..ed1674f628b 100644 --- a/config/swarm.go +++ b/config/swarm.go @@ -33,9 +33,10 @@ type SwarmConfig struct { // ResourceMgr configures the libp2p Network Resource Manager ResourceMgr ResourceMgr - // ForgeClient controls the client of a service for obtaining a domain - // and TLS certificate to improve connectivity for web browser clients. - ForgeClient ForgeClient + // 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 { diff --git a/core/node/groups.go b/core/node/groups.go index 1ab5ebd43b7..5cd0fd62448 100644 --- a/core/node/groups.go +++ b/core/node/groups.go @@ -113,7 +113,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) - enableForgeClient := cfg.Swarm.ForgeClient.Enabled.WithDefault(config.DefaultForgeEnabled) + enableAutoTLS := cfg.Swarm.AutoTLS.Enabled.WithDefault(config.DefaultAutoTLSEnabled) // Log error when relay subsystem could not be initialized due to missing dependency if !enableRelayTransport { @@ -124,8 +124,8 @@ 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 enableForgeClient && !cfg.Swarm.Transports.Network.Websocket.WithDefault(true) { - logger.Fatal("Failed to enable `Swarm.ForgeClient`, it requires `Swarm.Transports.Network.Websocket` to be true.") + if enableAutoTLS && !cfg.Swarm.Transports.Network.Websocket.WithDefault(true) { + logger.Fatal("Failed to enable `Swarm.AutoTLS`, it requires `Swarm.Transports.Network.Websocket` to be true.") } // Gather all the options @@ -137,8 +137,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(cfg.Swarm.ForgeClient), enableForgeClient), - maybeInvoke(libp2p.StartP2PForgeClient, enableForgeClient), + maybeProvide(libp2p.P2PForgeCertMgr(cfg.Swarm.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)), diff --git a/core/node/libp2p/addrs.go b/core/node/libp2p/addrs.go index f7d1a1484cf..df324c8d21d 100644 --- a/core/node/libp2p/addrs.go +++ b/core/node/libp2p/addrs.go @@ -132,7 +132,7 @@ func ListenOn(addresses []string) interface{} { } } -func P2PForgeCertMgr(cfg config.ForgeClient) interface{} { +func P2PForgeCertMgr(cfg config.AutoTLS) interface{} { return func() (*p2pforge.P2PForgeCertMgr, error) { storagePath, err := config.Path("", "p2p-forge-certs") if err != nil { @@ -149,10 +149,10 @@ func P2PForgeCertMgr(cfg config.ForgeClient) interface{} { certMgr, err := p2pforge.NewP2PForgeCertMgr( p2pforge.WithLogger(forgeLogger.Sugar()), - p2pforge.WithForgeDomain(cfg.ForgeDomain.WithDefault(config.DefaultForgeDomain)), - p2pforge.WithForgeRegistrationEndpoint(cfg.ForgeEndpoint.WithDefault(config.DefaultForgeEndpoint)), + p2pforge.WithForgeDomain(cfg.DomainSuffix.WithDefault(config.DefaultDomainSuffix)), + p2pforge.WithForgeRegistrationEndpoint(cfg.RegistrationEndpoint.WithDefault(config.DefaultRegistrationEndpoint)), p2pforge.WithCAEndpoint(cfg.CAEndpoint.WithDefault(config.DefaultCAEndpoint)), - p2pforge.WithForgeAuth(cfg.ForgeAuth.WithDefault(os.Getenv(p2pforge.ForgeAuthEnv))), + p2pforge.WithForgeAuth(cfg.RegistrationToken.WithDefault(os.Getenv(p2pforge.ForgeAuthEnv))), p2pforge.WithUserAgent(version.GetUserAgentVersion()), p2pforge.WithCertificateStorage(&certmagic.FileStorage{Path: storagePath})) if err != nil { @@ -163,7 +163,7 @@ func P2PForgeCertMgr(cfg config.ForgeClient) interface{} { } } -func StartP2PForgeClient(lc fx.Lifecycle, certMgr *p2pforge.P2PForgeCertMgr, h host.Host) { +func StartP2PAutoTLS(lc fx.Lifecycle, certMgr *p2pforge.P2PForgeCertMgr, h host.Host) { lc.Append(fx.Hook{ OnStart: func(ctx context.Context) error { certMgr.ProvideHost(h) diff --git a/docs/changelogs/v0.32.md b/docs/changelogs/v0.32.md index 483bf3f9082..04884d93a0f 100644 --- a/docs/changelogs/v0.32.md +++ b/docs/changelogs/v0.32.md @@ -18,7 +18,7 @@ This release introduces an experimental feature that significantly improves how browsers can connect to Kubo node. Opt-in configuration allows Kubo node to obtain trusted certificates for Secure WebSocket (WSS) connections without manual intervention. -See [`Swarm.ForgeClient`](https://github.com/ipfs/kubo/blob/master/docs/config.md#swarmforgeclient) for details how to enable it. We appreciate you testing and providing an early feedback. +See [`Swarm.AutoTLS`](https://github.com/ipfs/kubo/blob/master/docs/config.md#swarmforgeclient) for details how to enable it. We appreciate you testing and providing an early feedback. #### go-libp2p updates diff --git a/docs/config.md b/docs/config.md index a000ffbdcdb..7bc95f36865 100644 --- a/docs/config.md +++ b/docs/config.md @@ -117,12 +117,12 @@ config file at runtime. - [`Swarm.DisableBandwidthMetrics`](#swarmdisablebandwidthmetrics) - [`Swarm.DisableNatPortMap`](#swarmdisablenatportmap) - [`Swarm.EnableHolePunching`](#swarmenableholepunching) - - [`Swarm.ForgeClient`](#swarmforgeclient) - - [`Swarm.ForgeClient.Enabled`](#swarmforgeclientenabled) - - [`Swarm.ForgeClient.ForgeDomain`](#swarmforgeclientforgedomain) - - [`Swarm.ForgeClient.ForgeEndpoint`](#swarmforgeclientforgeendpoint) - - [`Swarm.ForgeClient.ForgeAuth`](#swarmforgeclientforgeauth) - - [`Swarm.ForgeClient.CAEndpoint`](#swarmforgeclientcaendpoint) + - [`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) @@ -1722,19 +1722,20 @@ Default: `true` Type: `flag` -### `Swarm.ForgeClient` +### `Swarm.AutoTLS` -AutoTLS enables publicly reachable Kubo nodes, i.e. nodes dialable from the public internet, to get a wildcard TLS certificate unique to their PeerID at `*.[PeerID].libp2p.direct` without needing to register and configure a domain name. This enables direct libp2p connections and direct retrieval of IPFS content from browsers using Secure WebSockets. +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, the `libp2p.direct` acts as a an [ACME DNS-01 Challenge](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge) broker for getting wildcard TLS certificate for `*.[PeerID].libp2p.direct`. +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, AutoTLS requests TLS certificates from Let's Encrypt and uses a `libp2p.direct` subdomain. +By default, the certificates are requested from Let's Encrypt. Origin and rationale for this project can be found in [community.letsencrypt.org discussion]. -In short, [p2p-forge] provides a publicly diallable Kubo with a domain name for their PeerID (`peerid.libp2p.direct`), -and acts as [ACME DNS-01 Challenge](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge) -broker to allow Kubo to get a wildcard TLS cert for that domain (`*.peerid.libp2p.direct`). - > [!NOTE] > Public good infrastructure at `libp2p.direct` is run by the team at [Interplanetary Shipyard](https://ipshipyard.com). > @@ -1747,16 +1748,16 @@ Default: `{}` Type: `object` -#### `Swarm.ForgeClient.Enabled` +#### `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 if you want to help with testing. +> 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.ForgeClient.ForgeDomain`, and set up a trusted TLS certificate matching the domain name used in Secure WebSockets (WSS) listener. +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). @@ -1766,16 +1767,16 @@ Default: `false` Type: `flag` -#### `Swarm.ForgeClient.ForgeDomain` +#### `Swarm.AutoTLS.DomainSuffix` -Optional override of the parent domain that will be used in DNS+TLS+WebSockets multiaddrs generated by [p2p-forge] client. +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.ForgeClient.ForgeEndpoint` +#### `Swarm.AutoTLS.RegistrationEndpoint` Optional override of [p2p-forge] HTTP registration API. Do not change this unless you self-host [p2p-forge]. @@ -1784,16 +1785,16 @@ Default: `https://registration.libp2p.direct` (public good run by [Interplanetar Type: `optionalString` -#### `Swarm.ForgeClient.ForgeAuth` +#### `Swarm.AutoTLS.RegistrationToken` -Optional value for `Forge-Authorization` token sent with request to `ForgeEndpoint` +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.ForgeClient.CAEndpoint` +#### `Swarm.AutoTLS.CAEndpoint` Optional override of CA ACME API used by [p2p-forge] system.