IPFS CLI connected to remote IPFS daemon

I’m running an IPFS instance remotely on my server behind an nginx reverse proxy secured with basic auth. I’d like to connect the IPFS CLI on my local computer with the remote daemon.

I changed the .Addresses.API configuration to point to my server and added the basic auth credentials to the .API.HTTPHeaders. Unfortunately the CLI doesn’t seem to connect to the server and for ipfs cat QmY7Yh4UquoXHLPFo2XbhXkhBvFoPwmQUSa92pxnxjQuPU just prints:

Error: merkledag: not found

The same command returns content in the SSH session on the remote server. I then tried to make the daemon available via TCP-forwarding over SSH and reset the settings from above.

ssh -NL 5001:localhost:5001 myuser@myserver

Still Error: merkledag: not found.

There are many points where an error could hide (basic auth wrong, wrong multiaddr, wrong ports) but maybe I’m fundamentally misunderstanding something. Did I change the right configuration parameters? Is this setup even possible?

Thanks @all

Did you first verify your nginx reverse proxy is working by just starting maybe a python SimpleHTTPServer to connect as a test (or even some “node express” example server), just to verify you have all the ports right, and then once that’s working, get the security working next, and as a final step run the IPFS CLI. That’s how I’d approach it, to troubleshoot. I mean you could also try looking at IPFS logs too.

Thanks @wclayf for taking the time,

I can access SimpleHTTPServer through SSH port forwarding. I can also access the ipfs daemon by running the above SSH command. E.g. the following command on my local computer gives me a response from the daemon:

$ curl localhost:5001
404 page not found

the ipfs cat command still doesn’t work.

To recap

  1. Remote: IPFS daemon API is running on port 5001
  2. Local: SSH forward via ssh -NL 5001:localhost:5001 my-user@my-server
  3. Remote: curl localhost:5001 returns 404 page not found (would return “Connection refused” if daemon were not running)
  4. Local: curl localhost:5001 returns 404 page not found - evidence for port forward
  5. Remote ipfs cat QmY7Yh4UquoXHLPFo2XbhXkhBvFoPwmQUSa92pxnxjQuPU returns data
  6. Local: ipfs cat QmY7Yh4UquoXHLPFo2XbhXkhBvFoPwmQUSa92pxnxjQuPU returns Error: merkledag: not found
  7. Local: ipfs config show:
  "API": {
    "HTTPHeaders": {}
  "Addresses": {
    "API": "/ip4/",
    "Announce": [],
    "Gateway": "/ip4/",
    "NoAnnounce": [],
    "Swarm": [
  "AutoNAT": {},
  "Bootstrap": [
  "Datastore": {
    "BloomFilterSize": 0,
    "GCPeriod": "1h",
    "HashOnRead": false,
    "Spec": {
      "mounts": [
          "child": {
            "path": "blocks",
            "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2",
            "sync": true,
            "type": "flatfs"
          "mountpoint": "/blocks",
          "prefix": "flatfs.datastore",
          "type": "measure"
          "child": {
            "compression": "none",
            "path": "datastore",
            "type": "levelds"
          "mountpoint": "/",
          "prefix": "leveldb.datastore",
          "type": "measure"
      "type": "mount"
    "StorageGCWatermark": 90,
    "StorageMax": "10GB"
  "Discovery": {
    "MDNS": {
      "Enabled": true,
      "Interval": 10
  "Experimental": {
    "FilestoreEnabled": false,
    "GraphsyncEnabled": false,
    "Libp2pStreamMounting": false,
    "P2pHttpProxy": false,
    "ShardingEnabled": false,
    "StrategicProviding": false,
    "UrlstoreEnabled": false
  "Gateway": {
    "APICommands": [],
    "HTTPHeaders": {
      "Access-Control-Allow-Headers": [
      "Access-Control-Allow-Methods": [
      "Access-Control-Allow-Origin": [
    "NoDNSLink": false,
    "NoFetch": false,
    "PathPrefixes": [],
    "PublicGateways": null,
    "RootRedirect": "",
    "Writable": false
  "Identity": {
    "PeerID": "my-peer-id"
  "Ipns": {
    "RecordLifetime": "",
    "RepublishPeriod": "",
    "ResolveCacheSize": 128
  "Mounts": {
    "FuseAllowOther": false,
    "IPFS": "/ipfs",
    "IPNS": "/ipns"
  "Peering": {
    "Peers": null
  "Plugins": {
    "Plugins": null
  "Provider": {
    "Strategy": ""
  "Pubsub": {
    "DisableSigning": false,
    "Router": ""
  "Reprovider": {
    "Interval": "12h",
    "Strategy": "all"
  "Routing": {
    "Type": "dht"
  "Swarm": {
    "AddrFilters": null,
    "ConnMgr": {
      "GracePeriod": "20s",
      "HighWater": 900,
      "LowWater": 600,
      "Type": "basic"
    "DisableBandwidthMetrics": false,
    "DisableNatPortMap": false,
    "EnableAutoRelay": false,
    "EnableRelayHop": false,
    "Transports": {
      "Multiplexers": {},
      "Network": {},
      "Security": {}

I don’t have any experience with “Reverse Proxy” myself I just know what they are from researching myself how I would go about adding a security layer on top of IPFS. So the only further input I could offer would be see if you can first just open all ports directly and do it first without the reverse proxy and just make sure you can. However I may know so little about it that even suggesting that proves I don’t know anything. haha. Sorry, good luck.

Alright, no worries :slight_smile: my little recap from above actually doesn’t involve the proxy anymore. I would add it to my setup again after the tcp forwarding via SSH works. Thanks a lot for your help anyways :+1:

These settings specify how the IPFS daemon’s API server behaves, not how the ipfs command as a client to the API makes requests. You need to use ipfs --api to point to a non-local/non-default endpoint.

Also see Configure --api through .ipfs/config.

I don’t think you can use ipfs to a remote endpoint with basic auth though, out of the box.

Thanks @hector I confused the roles (server, client) of the CLI.

For others I’ll recap. It works with the following command:

ipfs --api /ip4/ cat QmY7Yh4UquoXHLPFo2XbhXkhBvFoPwmQUSa92pxnxjQuPU

I have set up TCP Forwarding like:

ssh -NL 5001:localhost:5001 myuser@myserver