@cryptotaxi247 / kubo / commits / c81317e34

docs: firewall (ufw) walkthrough for port 4001 (#11332)

Surfaced by ipfs/service-worker-gateway#1067, where operators behind a default-deny firewall hit unreachable nodes from browser peers because UDP/4001 (QUIC, WebTransport, WebRTC-Direct) was not opened alongside TCP/4001. - new docs/production/firewall.md: inspect ufw rules, open 4001/tcp and 4001/udp, optional Kubo application profile, custom-port and rule-removal notes - daemon health (ipfs diag healthy) split from reachability (ipfs swarm addrs autonat), with Swarm.DisableNatPortMap and Swarm.EnableHolePunching pointers for nodes that stay Private - link the walkthrough from Addresses.Swarm and the Security section in docs/config.md, and from the Production index in docs/README.md

Marcin Rataj committed May 19, 2026 at 17:29 UTC c81317e342d550c0aff545bd476bed78b87614db
3 files changed +211 -2
docs/README.md
+1
@@ -47,6 +47,7 @@ If you're experiencing an issue with IPFS, please [file an issue](https://github
47 ## Production
48
49 - [Reverse proxy setup](production/reverse-proxy.md)
50 +- [Firewall setup (ufw)](production/firewall.md)
51
52 ## Specifications
53
docs/config.md
+3 -2
@@ -358,7 +358,8 @@ Supported Transports:
358
359 > [!IMPORTANT]
360 > Make sure your firewall rules allow incoming connections on both TCP and UDP ports defined here.
361 -> See [Security section](#security) for network exposure considerations.
361 +> See [`docs/production/firewall.md`](./production/firewall.md) for a `ufw` walkthrough,
362 +> and the [Security section](#security) below for wider network exposure considerations.
363
364 Note that quic (Draft-29) used to be supported with the format `/ipN/.../udp/.../quic`, but has since been [removed](https://github.com/libp2p/go-libp2p/releases/tag/v0.30.0).
365
@@ -4611,7 +4612,7 @@ Several configuration options expose TCP or UDP ports that can make your Kubo no
4612
4613 - Keep admin services ([`Addresses.API`](#addressesapi)) bound to localhost unless authentication ([`API.Authorizations`](#apiauthorizations)) is configured
4614 - Use [`Gateway.NoFetch`](#gatewaynofetch) to prevent arbitrary CID retrieval if Kubo is acting as a public gateway available to anyone
4614 -- Configure firewall rules to restrict access to exposed ports. Note that [`Addresses.Swarm`](#addressesswarm) is special - all incoming traffic to swarm ports should be allowed to ensure proper P2P connectivity
4615 +- Configure firewall rules to restrict access to exposed ports. Note that [`Addresses.Swarm`](#addressesswarm) is special - all incoming traffic to swarm ports should be allowed to ensure proper P2P connectivity. See [`docs/production/firewall.md`](./production/firewall.md) for a `ufw` walkthrough.
4616 - Control which public-facing addresses are announced to other peers using [`Addresses.NoAnnounce`](#addressesnoannounce), [`Addresses.Announce`](#addressesannounce), and [`Addresses.AppendAnnounce`](#addressesappendannounce)
4617 - Consider using the [`server` profile](#server-profile) for production deployments
4618
docs/production/firewall.md new
+207
@@ -0,0 +1,207 @@
1 +# Firewall Setup for Kubo
2 +
3 +By default, kubo's libp2p swarm listens on **port 4001** over both TCP and
4 +UDP. Open both so peers can reach you:
5 +
6 +- **TCP/4001** carries the plain TCP transport (and the optional WebSocket `/ws`).
7 +- **UDP/4001** carries QUIC, WebTransport, and WebRTC-Direct.
8 +
9 +Block either one and kubo falls back to slower relayed or hole-punched
10 +connections.
11 +
12 +The defaults come from [`Addresses.Swarm`](../config.md#addressesswarm):
13 +
14 +```json
15 +[
16 + "/ip4/0.0.0.0/tcp/4001",
17 + "/ip6/::/tcp/4001",
18 + "/ip4/0.0.0.0/udp/4001/webrtc-direct",
19 + "/ip4/0.0.0.0/udp/4001/quic-v1",
20 + "/ip4/0.0.0.0/udp/4001/quic-v1/webtransport",
21 + "/ip6/::/udp/4001/webrtc-direct",
22 + "/ip6/::/udp/4001/quic-v1",
23 + "/ip6/::/udp/4001/quic-v1/webtransport"
24 +]
25 +```
26 +
27 +The examples below use [`ufw`](https://help.ubuntu.com/community/UFW), the
28 +default firewall tool on Debian and Ubuntu. The same rules translate to
29 +`firewalld`, `nftables`, or cloud security groups.
30 +
31 +## Check what rules you have
32 +
33 +List active rules:
34 +
35 +```bash
36 +sudo ufw status verbose
37 +```
38 +
39 +Or with line numbers, useful when deleting one later:
40 +
41 +```bash
42 +sudo ufw status numbered
43 +```
44 +
45 +A typical SSH-only host looks like this:
46 +
47 +```
48 +Status: active
49 +Logging: off
50 +Default: deny (incoming), allow (outgoing), disabled (routed)
51 +
52 +To Action From
53 +-- ------ ----
54 +22/tcp ALLOW IN Anywhere
55 +22/tcp (v6) ALLOW IN Anywhere (v6)
56 +```
57 +
58 +You want 4001 in that list, on both TCP and UDP.
59 +
60 +## Open port 4001
61 +
62 +The short way opens both TCP and UDP at once:
63 +
64 +```bash
65 +sudo ufw allow 4001 comment 'ipfs/libp2p swarm'
66 +```
67 +
68 +One rule per protocol reads more clearly later:
69 +
70 +```bash
71 +sudo ufw allow 4001/tcp comment 'ipfs/libp2p tcp+http+ws'
72 +sudo ufw allow 4001/udp comment 'ipfs/libp2p quic+webtransport+webrtc'
73 +```
74 +
75 +`ufw` covers IPv4 and IPv6 together when `IPV6=yes` is set in
76 +`/etc/default/ufw` (the default on Ubuntu).
77 +
78 +To limit a rule to one interface or source range:
79 +
80 +```bash
81 +sudo ufw allow in on eth0 to any port 4001 proto tcp
82 +sudo ufw allow in on eth0 to any port 4001 proto udp
83 +sudo ufw allow from 203.0.113.0/24 to any port 4001
84 +```
85 +
86 +> [!NOTE]
87 +> A public IPFS node needs to be reachable by anyone. Restrict by source IP
88 +> only on private deployments.
89 +
90 +Check the result:
91 +
92 +```bash
93 +sudo ufw status verbose
94 +```
95 +
96 +You should see `4001/tcp` and `4001/udp` (and the matching `(v6)` lines).
97 +
98 +## Optional: a `Kubo` application profile
99 +
100 +When you run kubo across many hosts, a `ufw` "application profile" lets you
101 +allow it by name. Create `/etc/ufw/applications.d/kubo`:
102 +
103 +```ini
104 +[Kubo]
105 +title=Kubo
106 +description=ipfs kubo swarm ports
107 +ports=4001/tcp|4001/udp
108 +```
109 +
110 +Allow it by name:
111 +
112 +```bash
113 +sudo ufw allow Kubo
114 +```
115 +
116 +Inspect the profile:
117 +
118 +```bash
119 +sudo ufw app info Kubo
120 +```
121 +
122 +If you later edit the `ports=` line in the profile, push the new ports
123 +into the existing rule with:
124 +
125 +```bash
126 +sudo ufw app update Kubo
127 +```
128 +
129 +## Different ports?
130 +
131 +If you changed [`Addresses.Swarm`](../config.md#addressesswarm) (for example,
132 +when running several kubo nodes on one host), open the port you chose. Open
133 +both TCP and UDP unless you explicitly disabled a transport in
134 +[`Swarm.Transports.Network`](../config.md#swarmtransportsnetwork).
135 +
136 +## Remove a rule
137 +
138 +Find the rule number:
139 +
140 +```bash
141 +sudo ufw status numbered
142 +```
143 +
144 +Numbers shift after each delete, so list again between deletes:
145 +
146 +```bash
147 +sudo ufw delete <number>
148 +```
149 +
150 +Or delete by spec:
151 +
152 +```bash
153 +sudo ufw delete allow 4001/tcp
154 +sudo ufw delete allow 4001/udp
155 +```
156 +
157 +## Is the daemon healthy?
158 +
159 +To confirm kubo is running and the local block pipeline works:
160 +
161 +```bash
162 +ipfs diag healthy
163 +```
164 +
165 +It exits 0 when the daemon is up. Use it for container healthchecks. It
166 +only checks local state; for reachability from outside, see the next
167 +section.
168 +
169 +## Can peers reach you?
170 +
171 +`ipfs id` shows the addresses your node advertises. To test them from
172 +outside, ask AutoNAT V2:
173 +
174 +```bash
175 +ipfs swarm addrs autonat
176 +```
177 +
178 +Look for `Reachability: Public`. The `Reachable` and `Unreachable` lists
179 +break things down by address, so you can see at a glance which protocol is
180 +blocked upstream.
181 +
182 +If you stay `Private` even with `ufw` open, something upstream is blocking
183 +you. Common next steps:
184 +
185 +- **Behind a home or office router (NAT):** let kubo ask the router to
186 + forward the port. Keep
187 + [`Swarm.DisableNatPortMap`](../config.md#swarmdisablenatportmap) at `false`
188 + (the default; this is UPnP / NAT-PMP). The `server` profile disables it,
189 + so if you applied that profile but you are behind a router, set it back
190 + to `false`.
191 +- **No control over the upstream NAT (CGNAT, mobile, locked-down corporate
192 + networks):** keep
193 + [`Swarm.EnableHolePunching`](../config.md#swarmenableholepunching) on
194 + (the default). Peers will then reach you through a relay using DCUtR
195 + (direct connection upgrade through relay).
196 +
197 +More background: the
198 +[libp2p AutoNAT V2 spec](https://github.com/libp2p/specs/blob/master/autonat/autonat-v2.md).
199 +
200 +## Related
201 +
202 +- [`Addresses.Swarm`](../config.md#addressesswarm): the addresses kubo
203 + listens on.
204 +- [`Swarm.Transports.Network`](../config.md#swarmtransportsnetwork): which
205 + transports are enabled.
206 +- [Security section in `config.md`](../config.md#security): port and
207 + exposure guidance for the API, Gateway, and swarm.