From c5c0ba3ce8d7595a4dffbc852b5d94e9fecbbe84 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 3 Apr 2023 13:46:56 +0200 Subject: [PATCH] feat(gw): trustless mode via OnlyTrustless --- config/gateway.go | 14 ++++++++- core/corehttp/gateway.go | 41 ++++++++++++++++---------- docs/examples/kubo-as-a-library/go.mod | 2 +- docs/examples/kubo-as-a-library/go.sum | 4 +-- go.mod | 2 +- go.sum | 4 +-- 6 files changed, 45 insertions(+), 22 deletions(-) diff --git a/config/gateway.go b/config/gateway.go index 8ae312b59ae..e110dcea6a1 100644 --- a/config/gateway.go +++ b/config/gateway.go @@ -1,6 +1,9 @@ package config -const DefaultInlineDNSLink = false +const ( + DefaultInlineDNSLink = false + DefaultOnlyTrustless = false +) type GatewaySpec struct { // Paths is explicit list of path prefixes that should be handled by @@ -25,6 +28,10 @@ type GatewaySpec struct { // (FQDN) into a single DNS label in order to interop with wildcard TLS certs // and Origin per CID isolation provided by rules like https://publicsuffix.org InlineDNSLink Flag + + // OnlyTrustless configures this gateway to only respond to trustless requests, + // as per: https://specs.ipfs.tech/http-gateways/trustless-gateway/ + OnlyTrustless Flag } // Gateway contains options for the HTTP gateway server. @@ -56,6 +63,11 @@ type Gateway struct { // This flag can be overridden per FQDN in PublicGateways. NoDNSLink bool + // OnlyTrustless configures this gateway to only respond to trustless requests, + // as per: https://specs.ipfs.tech/http-gateways/trustless-gateway/. This can + // be overridden per FQDN in PublicGateways. + OnlyTrustless Flag + // PublicGateways configures behavior of known public gateways. // Each key is a fully qualified domain name (FQDN). PublicGateways map[string]*GatewaySpec diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index a9c42f18573..869c48d433b 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -28,22 +28,11 @@ import ( func GatewayOption(paths ...string) ServeOption { return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { - cfg, err := n.Repo.Config() + gwConfig, err := getGatewayConfig(n) if err != nil { return nil, err } - headers := make(map[string][]string, len(cfg.Gateway.HTTPHeaders)) - for h, v := range cfg.Gateway.HTTPHeaders { - headers[http.CanonicalHeaderKey(h)] = v - } - - gateway.AddAccessControlHeaders(headers) - - gwConfig := gateway.Config{ - Headers: headers, - } - gwAPI, err := newGatewayBackend(n) if err != nil { return nil, err @@ -65,7 +54,7 @@ func GatewayOption(paths ...string) ServeOption { func HostnameOption() ServeOption { return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { - cfg, err := n.Repo.Config() + gwConfig, err := getGatewayConfig(n) if err != nil { return nil, err } @@ -75,9 +64,8 @@ func HostnameOption() ServeOption { return nil, err } - publicGateways := convertPublicGateways(cfg.Gateway.PublicGateways) childMux := http.NewServeMux() - mux.HandleFunc("/", gateway.WithHostname(childMux, gwAPI, publicGateways, cfg.Gateway.NoDNSLink).ServeHTTP) + mux.HandleFunc("/", gateway.WithHostname(gwConfig, gwAPI, childMux).ServeHTTP) return childMux, nil } } @@ -212,6 +200,28 @@ var defaultKnownGateways = map[string]*gateway.Specification{ "localhost": subdomainGatewaySpec, } +func getGatewayConfig(n *core.IpfsNode) (gateway.Config, error) { + cfg, err := n.Repo.Config() + if err != nil { + return gateway.Config{}, err + } + + headers := make(map[string][]string, len(cfg.Gateway.HTTPHeaders)) + for h, v := range cfg.Gateway.HTTPHeaders { + headers[http.CanonicalHeaderKey(h)] = v + } + gateway.AddAccessControlHeaders(headers) + + gwConfig := gateway.Config{ + Headers: headers, + TrustedMode: !cfg.Gateway.OnlyTrustless.WithDefault(config.DefaultOnlyTrustless), + NoDNSLink: cfg.Gateway.NoDNSLink, + PublicGateways: convertPublicGateways(cfg.Gateway.PublicGateways), + } + + return gwConfig, nil +} + func convertPublicGateways(publicGateways map[string]*config.GatewaySpec) map[string]*gateway.Specification { gws := map[string]*gateway.Specification{} @@ -234,6 +244,7 @@ func convertPublicGateways(publicGateways map[string]*config.GatewaySpec) map[st NoDNSLink: gw.NoDNSLink, UseSubdomains: gw.UseSubdomains, InlineDNSLink: gw.InlineDNSLink.WithDefault(config.DefaultInlineDNSLink), + TrustedMode: !gw.OnlyTrustless.WithDefault(config.DefaultOnlyTrustless), } } diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod index 1c2af115453..0624522dad2 100644 --- a/docs/examples/kubo-as-a-library/go.mod +++ b/docs/examples/kubo-as-a-library/go.mod @@ -7,7 +7,7 @@ go 1.18 replace github.com/ipfs/kubo => ./../../.. require ( - github.com/ipfs/boxo v0.8.0 + github.com/ipfs/boxo v0.8.1-0.20230411082508-165ddf6a5b04 github.com/ipfs/kubo v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.27.0 github.com/multiformats/go-multiaddr v0.9.0 diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum index 802f84be6a1..c482e911ba2 100644 --- a/docs/examples/kubo-as-a-library/go.sum +++ b/docs/examples/kubo-as-a-library/go.sum @@ -321,8 +321,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.0 h1:UdjAJmHzQHo/j3g3b1bAcAXCj/GM6iTwvSlBDvPBNBs= -github.com/ipfs/boxo v0.8.0/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= +github.com/ipfs/boxo v0.8.1-0.20230411082508-165ddf6a5b04 h1:bqAm7fa3lofmSKQUtcE9IK/H8AwZom6sJd52/vzeQAM= +github.com/ipfs/boxo v0.8.1-0.20230411082508-165ddf6a5b04/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= diff --git a/go.mod b/go.mod index 58d943ac576..6fa73a78e0d 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/google/uuid v1.3.0 github.com/hashicorp/go-multierror v1.1.1 - github.com/ipfs/boxo v0.8.0 + github.com/ipfs/boxo v0.8.1-0.20230411082508-165ddf6a5b04 github.com/ipfs/go-block-format v0.1.2 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-cidutil v0.1.0 diff --git a/go.sum b/go.sum index c623a9d4d12..39c28a9e7d9 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.8.0 h1:UdjAJmHzQHo/j3g3b1bAcAXCj/GM6iTwvSlBDvPBNBs= -github.com/ipfs/boxo v0.8.0/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= +github.com/ipfs/boxo v0.8.1-0.20230411082508-165ddf6a5b04 h1:bqAm7fa3lofmSKQUtcE9IK/H8AwZom6sJd52/vzeQAM= +github.com/ipfs/boxo v0.8.1-0.20230411082508-165ddf6a5b04/go.mod h1:RIsi4CnTyQ7AUsNn5gXljJYZlQrHBMnJp94p73liFiA= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY=