| 1 | <h1 align="center"> |
| 2 | <br> |
| 3 | <a href="#readme"><img src="https://github.com/ipfs-shipyard/nopfs/blob/41484a818e6542314f784da852fc41b76f2d48a6/logo.png?raw=true" alt="content blocking logo" title="content blocking in Kubo" width="200"></a> |
| 4 | <br> |
| 5 | Content Blocking in Kubo |
| 6 | <br> |
| 7 | </h1> |
| 8 | |
| 9 | Kubo ships with built-in support for denylist format from [IPIP-383](https://specs.ipfs.tech/ipips/ipip-0383/). |
| 10 | |
| 11 | ## Default behavior |
| 12 | |
| 13 | Official Kubo build does not ship with any denylists enabled by default. |
| 14 | |
| 15 | Content blocking is an opt-in decision made by the operator of `ipfs daemon`. |
| 16 | |
| 17 | ## How to enable blocking |
| 18 | |
| 19 | Place a `*.deny` file in one of directories: |
| 20 | |
| 21 | - `$IPFS_PATH/denylists/` (`$HOME/.ipfs/denylists/` if `IPFS_PATH` is not set) |
| 22 | - `$XDG_CONFIG_HOME/ipfs/denylists/` (`$HOME/.config/ipfs/denylists/` if `XDG_CONFIG_HOME` is not set) |
| 23 | - `/etc/ipfs/denylists/` (global) |
| 24 | |
| 25 | Files need to be present before starting the `ipfs daemon` in order to be watched for any new updates |
| 26 | appended once started. Any other changes (such as removal of entries, prepending of entries, or |
| 27 | insertion of new entries before the EOF at time of daemon starting) will not be detected or processed |
| 28 | after boot; a restart of the daemon will be required for them to be factored in. |
| 29 | |
| 30 | If an entire new denylist file is added, `ipfs daemon` also needs to be restarted to track it. |
| 31 | |
| 32 | CLI and Gateway users will receive errors in response to request impacted by a blocklist: |
| 33 | |
| 34 | ``` |
| 35 | Error: /ipfs/QmQvjk82hPkSaZsyJ8vNER5cmzKW7HyGX5XVusK7EAenCN is blocked and cannot be provided |
| 36 | ``` |
| 37 | |
| 38 | End user is not informed about the exact reason, see [How to |
| 39 | debug](#how-to-debug) if you need to find out which line of which denylist |
| 40 | caused the request to be blocked. |
| 41 | |
| 42 | ## Scope of denylists |
| 43 | |
| 44 | Denylists apply to **content retrieval and serving** by your local node: |
| 45 | |
| 46 | - Bitswap: your node neither requests blocked blocks from peers nor serves them to peers. |
| 47 | - Gateway and CLI: requests for a denied CID return an error (HTTP 410 Gone from the gateway). |
| 48 | - IPNS resolution: your node refuses to resolve a denied IPNS name locally. |
| 49 | |
| 50 | Denylists do **not** apply to the routing system. If your node runs as a DHT server (the default with `Routing.Type=auto` once your node is publicly reachable), it can still: |
| 51 | |
| 52 | - Accept and store provider records (`ADD_PROVIDER`) for denied CIDs from other peers, and return them on `GET_PROVIDERS`. |
| 53 | - Accept and store IPNS records for denied names from other peers, and serve them on `GetValue`. |
| 54 | - Forward IPNS records over pubsub when [`Ipns.UsePubsub`](https://github.com/ipfs/kubo/blob/master/docs/config.md#ipnsusepubsub) is enabled. |
| 55 | - Surface those records over the [`/routing/v1/`](https://specs.ipfs.tech/routing/http-routing-v1/) HTTP API when [`Gateway.ExposeRoutingAPI`](https://github.com/ipfs/kubo/blob/master/docs/config.md#gatewayexposeroutingapi) is enabled. |
| 56 | |
| 57 | In short, your node will not fetch or serve the content itself, but as a DHT server it still helps other peers discover providers and resolve names for that content. |
| 58 | |
| 59 | ### How to stop facilitating routing for blocked content |
| 60 | |
| 61 | Set [`Routing.Type`](https://github.com/ipfs/kubo/blob/master/docs/config.md#routingtype) to `autoclient`: |
| 62 | |
| 63 | ```sh |
| 64 | $ ipfs config Routing.Type autoclient |
| 65 | ``` |
| 66 | |
| 67 | In `autoclient` mode your node only acts as a DHT client. It never runs a DHT server, so it does not store or serve provider records or IPNS records on behalf of other peers. |
| 68 | |
| 69 | ## Denylist file format |
| 70 | |
| 71 | [NOpfs](https://github.com/ipfs-shipyard/nopfs) supports the format from [IPIP-383](https://specs.ipfs.tech/ipips/ipip-0383/). |
| 72 | |
| 73 | Clear-text rules are simple: just put content paths to block, one per line. |
| 74 | Paths with unicode and whitespace need to be percent-encoded: |
| 75 | |
| 76 | ``` |
| 77 | /ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR |
| 78 | /ipfs/bafybeihfg3d7rdltd43u3tfvncx7n5loqofbsobojcadtmokrljfthuc7y/927%20-%20Standards/927%20-%20Standards.png |
| 79 | ``` |
| 80 | |
| 81 | Sensitive content paths can be double-hashed to block without revealing them. |
| 82 | Double-hashed list example: https://badbits.dwebops.pub/badbits.deny |
| 83 | |
| 84 | See [IPIP-383](https://specs.ipfs.tech/ipips/ipip-0383/) for detailed format specification and more examples. |
| 85 | |
| 86 | ## How to suspend blocking without removing denylists |
| 87 | |
| 88 | Set `IPFS_CONTENT_BLOCKING_DISABLE` environment variable to `true` and restart the daemon. |
| 89 | |
| 90 | |
| 91 | ## How to debug |
| 92 | |
| 93 | Debug logging of `nopfs` subsystem can be enabled with `GOLOG_LOG_LEVEL="nopfs=debug"` |
| 94 | |
| 95 | All block events are logged as warnings on a separate level named `nopfs-blocks`. |
| 96 | |
| 97 | To only log requests for blocked content set `GOLOG_LOG_LEVEL="nopfs-blocks=warn"`: |
| 98 | |
| 99 | ``` |
| 100 | WARN (...) QmRFniDxwxoG2n4AcnGhRdjqDjCM5YeUcBE75K8WXmioH3: blocked (test.deny:9) |
| 101 | ``` |
| 102 | |
| 103 |