refactor: ForgeClient → AutoTLS

addressing UX/DX feedback from Daniel, switching to self-explanatory
configuration section
This commit is contained in:
Marcin Rataj 2024-10-28 19:20:57 +01:00
parent 7eeda1bb6f
commit 99b7757e71
No known key found for this signature in database
GPG Key ID: 222B6784D5A79E42
6 changed files with 48 additions and 46 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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