From 23ca62ad2c231fec90ef4ebee67fb562928f6e38 Mon Sep 17 00:00:00 2001 From: Dominic Della Valle Date: Fri, 14 Jul 2023 14:00:59 -0400 Subject: [PATCH 1/5] fix: Unix domain socket maddrs used with `NewApi` --- client/rpc/api.go | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/client/rpc/api.go b/client/rpc/api.go index 79d42124a7b..80a309b9190 100644 --- a/client/rpc/api.go +++ b/client/rpc/api.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + "net" "net/http" "os" "path/filepath" @@ -98,11 +99,29 @@ func ApiAddr(ipfspath string) (ma.Multiaddr, error) { // NewApi constructs HttpApi with specified endpoint. func NewApi(a ma.Multiaddr) (*HttpApi, error) { + transport := &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DisableKeepAlives: true, + } + + network, address, err := manet.DialArgs(a) + if err != nil { + return nil, err + } + if network == "unix" { + transport.DialContext = func(_ context.Context, _, _ string) (net.Conn, error) { + return net.Dial("unix", address) + } + c := &http.Client{ + Transport: transport, + } + // This will create an API client which + // makes requests to `http://unix`. + return NewURLApiWithClient(network, c) + } + c := &http.Client{ - Transport: &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DisableKeepAlives: true, - }, + Transport: transport, } return NewApiWithClient(a, c) From 893a94864a280653beb8698ca7b0bc7a1f917da8 Mon Sep 17 00:00:00 2001 From: gammazero <11790789+gammazero@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:00:46 -0700 Subject: [PATCH 2/5] Add unit test for rpc over unix socket --- test/cli/harness/node.go | 11 +++++++ test/cli/rpc_unixsocket_test.go | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 test/cli/rpc_unixsocket_test.go diff --git a/test/cli/harness/node.go b/test/cli/harness/node.go index d030c7c9404..dfef4678ea8 100644 --- a/test/cli/harness/node.go +++ b/test/cli/harness/node.go @@ -349,6 +349,17 @@ func (n *Node) checkAPI(authorization string) bool { log.Debugf("node %d API addr not available yet: %s", n.ID, err.Error()) return false } + + if unixAddr, err := apiAddr.ValueForProtocol(multiaddr.P_UNIX); err == nil { + parts := strings.SplitN(unixAddr, "/", 2) + if len(parts) < 1 { + panic("malformed unix socket address") + } + fileName := "/" + parts[1] + _, err := os.Stat(fileName) + return !errors.Is(err, fs.ErrNotExist) + } + ip, err := apiAddr.ValueForProtocol(multiaddr.P_IP4) if err != nil { panic(err) diff --git a/test/cli/rpc_unixsocket_test.go b/test/cli/rpc_unixsocket_test.go new file mode 100644 index 00000000000..902ca71fbc6 --- /dev/null +++ b/test/cli/rpc_unixsocket_test.go @@ -0,0 +1,55 @@ +package cli + +import ( + "context" + //"net" + //"net/http" + "path" + "testing" + + rpcapi "github.com/ipfs/kubo/client/rpc" + ///"github.com/ipfs/kubo/client/rpc/auth" + "github.com/ipfs/kubo/config" + "github.com/ipfs/kubo/test/cli/harness" + "github.com/multiformats/go-multiaddr" + //manet "github.com/multiformats/go-multiaddr/net" + "github.com/stretchr/testify/require" +) + +func TestRPCUnixSocket(t *testing.T) { + node := harness.NewT(t).NewNode().Init() + + sockDir := node.Dir + sockAddr := path.Join("/unix", sockDir, "sock") + + node.UpdateConfig(func(cfg *config.Config) { + //cfg.Addresses.API = append(cfg.Addresses.API, sockPath) + cfg.Addresses.API = []string{sockAddr} + }) + t.Log("Starting daemon with unix socket:", sockAddr) + node.StartDaemon() + + unixMaddr, err := multiaddr.NewMultiaddr(sockAddr) + require.NoError(t, err) + + apiClient, err := rpcapi.NewApi(unixMaddr) + require.NoError(t, err) + + var ver struct { + Version string + } + err = apiClient.Request("version").Exec(context.Background(), &ver) + require.NoError(t, err) + require.NotEmpty(t, ver) + t.Log("Got version:", ver.Version) + + var res struct { + ID string + } + err = apiClient.Request("id").Exec(context.Background(), &res) + require.NoError(t, err) + require.NotEmpty(t, res) + t.Log("Got ID:", res.ID) + + node.StopDaemon() +} From a5f4d0be0241a2c71a2cf395b6b32d3bf502725d Mon Sep 17 00:00:00 2001 From: gammazero <11790789+gammazero@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:55:11 -0700 Subject: [PATCH 3/5] Cleanup commented imports --- test/cli/rpc_unixsocket_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/cli/rpc_unixsocket_test.go b/test/cli/rpc_unixsocket_test.go index 902ca71fbc6..8cead7388d5 100644 --- a/test/cli/rpc_unixsocket_test.go +++ b/test/cli/rpc_unixsocket_test.go @@ -2,17 +2,13 @@ package cli import ( "context" - //"net" - //"net/http" "path" "testing" rpcapi "github.com/ipfs/kubo/client/rpc" - ///"github.com/ipfs/kubo/client/rpc/auth" "github.com/ipfs/kubo/config" "github.com/ipfs/kubo/test/cli/harness" "github.com/multiformats/go-multiaddr" - //manet "github.com/multiformats/go-multiaddr/net" "github.com/stretchr/testify/require" ) From fdfd2bc4a16782cce96f7d057f79ba055018d893 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 20 Aug 2024 17:01:23 +0200 Subject: [PATCH 4/5] docs: document rpc over unix socket --- cmd/ipfs/kubo/daemon.go | 5 +++++ docs/changelogs/v0.30.md | 20 +++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/cmd/ipfs/kubo/daemon.go b/cmd/ipfs/kubo/daemon.go index b66e61374a3..eb9fff8e448 100644 --- a/cmd/ipfs/kubo/daemon.go +++ b/cmd/ipfs/kubo/daemon.go @@ -113,6 +113,11 @@ control your node remotely. If you need to control the node remotely, make sure to protect the port as you would other services or database (firewall, authenticated proxy, etc), or at least set API.Authorizations. +If you do not want to open any ports for RPC, and only want to use +kubo CLI client, it is possible to expose the RPC over Unix socket: + + ipfs config Addresses.API /unix/var/run/kubo.socket + HTTP Headers Kubo supports passing arbitrary headers to the RPC API and Gateway. You can diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index 314e5a2e08e..55851126302 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -10,6 +10,7 @@ - [AutoNAT V2 Service Introduced Alongside V1](#autonat-v2-service-introduced-alongside-v1) - [Automated `ipfs version check`](#automated-ipfs-version-check) - [Version Suffix Configuration](#version-suffix-configuration) + - [`/unix/` socket support in `Addresses.API`](#unix-socket-support-in-addressesapi) - [Cleaned Up `ipfs daemon` Startup Log](#cleaned-up-ipfs-daemon-startup-log) - [๐Ÿ“ Changelog](#-changelog) - [๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ Contributors](#-contributors) @@ -49,7 +50,24 @@ Defining the optional agent version suffix is now simpler. The [`Version.AgentSu > [!NOTE] > Setting a custom version suffix helps with ecosystem analysis, such as Amino DHT reports published at https://stats.ipfs.network -> + +#### `/unix/` socket support in `Addresses.API` + +This release fixes a bug which blocked users from disabling local HTTP port for [Kubo RPC](https://docs.ipfs.tech/reference/kubo/rpc/), and using a Unix socket instead. + +```console +$ ipfs config Addresses.API "/unix/tmp/kubo.socket" +$ ipfs daemon # start with rpc socket +... +RPC API server listening on /unix/tmp/kubo.socket + +$ # cli client, in different terminal can find socket via /api file +$ cat $IPFS_PATH/api +/unix/tmp/kubo.socket + +$ # or have it pased via --api +$ ipfs --api=/unix/tmp/kubo.socket id +``` #### Cleaned Up `ipfs daemon` Startup Log From 85ab35d60f07e3573cd61526201cffa80c22e17f Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Tue, 20 Aug 2024 17:39:24 +0200 Subject: [PATCH 5/5] docs: improve style Co-authored-by: djdv --- docs/changelogs/v0.30.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelogs/v0.30.md b/docs/changelogs/v0.30.md index 55851126302..7fe13e19eca 100644 --- a/docs/changelogs/v0.30.md +++ b/docs/changelogs/v0.30.md @@ -53,7 +53,7 @@ Defining the optional agent version suffix is now simpler. The [`Version.AgentSu #### `/unix/` socket support in `Addresses.API` -This release fixes a bug which blocked users from disabling local HTTP port for [Kubo RPC](https://docs.ipfs.tech/reference/kubo/rpc/), and using a Unix socket instead. +This release fixes a bug which blocked users from using Unix domain sockets for [Kubo's RPC](https://docs.ipfs.tech/reference/kubo/rpc/) (instead of a local HTTP port). ```console $ ipfs config Addresses.API "/unix/tmp/kubo.socket"