Network Requirements
What Swarmfile actually talks to on the network, so you can configure a firewall allowlist before rollout instead of discovering it by trial and error. Everything below is what the desktop client (engine + Desktop App) initiates outbound - nothing here requires an inbound port opened on your network firewall for ordinary use. Host firewalls on each machine are a separate matter: LAN peer discovery needs inbound UDP from the local subnet, which the Windows installer allows for you (see LAN peer discovery).
Summary#
| Purpose | Protocol | Port | Host(s) | Required? |
|---|---|---|---|---|
| Control plane - metadata, auth, commits, presigned URLs, live sync | HTTPS | 443 | hub.swarmfile.com, or your own hub if self-hosted | Always |
| Identity - sign-in, token refresh | HTTPS | 443 | id.swarmfile.com, or your own IdP if you bring your own SSO | Always |
| File content - block upload/download | HTTPS | 443 | the org's storage origin: *.r2.cloudflarestorage.com by default, or the org's dedicated/bucket endpoint (a customer S3-compatible endpoint under BYOS) | Always - this is the actual file data; the hub only mints short-lived presigned URLs |
| Installer downloads | HTTPS | 443 | releases.swarmfile.com | Install and repair only |
| git-LFS agent installer | HTTPS | 443 | get.swarmfile.com | Only while installing/updating the git-LFS agent |
| Auto-update check | HTTPS | 443 | updates.swarmfile.com | Whenever the Desktop App is running |
| Peer-to-peer file transfer | QUIC (UDP) | OS-assigned by default | direct to other peers' IPs | Only when P2P is enabled (the default; off under cloud-only mode) |
| P2P relay and peer discovery (NAT traversal) | HTTPS/443 + UDP/7842 | third-party hosts - see below | Only when P2P is enabled | |
| LAN peer discovery | mDNS, UDP 5353 multicast | local subnet | Only when P2P is enabled | |
| Dashboard / web app | HTTPS | 443 | swarmfile.com | User-initiated browsing only, opened in your default browser - not the engine or Desktop App process |
Which exact hub/identity/releases/updates hostnames a given install uses is a per-install config.json setting, not something baked into the binary at compile time - a fresh install on the standard hosted plan defaults to the prod hosts above; check that file on a specific machine if you need to confirm. See Engine Config File.
Control plane and identity#
The engine talks to one hub host for control-plane work: browsing and editing metadata, commits, minting the short-lived presigned URLs for block transfer, and a live WebSocket (wss://, same host) that pushes changes from other users in real time. File content does not flow through the hub. For a read the hub answers with a redirect to a presigned URL and the client fetches the block bytes directly from the org's storage origin - *.r2.cloudflarestorage.com on the hosted default, a jurisdiction-pinned endpoint, or a customer-supplied S3-compatible endpoint under BYOS; uploads are presigned the same way. Sign-in and token refresh go to a separate identity host - the built-in IdP by default, or your own OIDC provider if you've configured bring-your-own SSO (see Identity).
Both are plain HTTPS on port 443. No other port is used for control-plane or identity traffic.
git-LFS#
On a project used as a git-LFS server, git lfs talks to the hub host for the Batch API, locks, and the transfer endpoint - and, for the stock basic transfer (and any push ≥ 64 MiB through the desktop agent), to the storage origin directly via a presigned URL, same as block traffic. Downloads stream through the hub. The git-LFS agent installer is fetched once from get.swarmfile.com (see the summary table). Everything stays on 443.
Peer-to-peer file transfer#
By default, machines in the same office exchange file data directly over QUIC (UDP) rather than always routing through the cloud - this is what makes LAN-first fast. The engine binds to an OS-assigned ephemeral UDP port for this; it does not listen on a fixed, predictable port unless you explicitly set one ("iroh_bind_addr" in config.json, or SWARMFILE_IROH_BIND_ADDR in the environment - an operator choice for a specific deployment, not a default).
Peer-to-peer relay and discovery#
Two pieces of this are third-party infrastructure Swarmfile doesn't operate itself, run by Number Zero (the maintainers of the P2P transport Swarmfile builds on):
- Relay fallback, used when two peers can't establish a direct connection (e.g. both behind restrictive NATs): a handful of regional relay hosts (
*.relay.n0.iroh.link), reached over HTTPS/443 with QUIC address-discovery on UDP/7842. - Peer discovery, used to look up how to reach another peer:
dns.iroh.link, over HTTPS and plain DNS.
If your firewall policy needs to name every host P2P might touch, these are worth listing alongside your own hub domain - though in practice, if UDP/QUIC is blocked entirely (common on locked-down corporate networks), the simpler answer is usually cloud-only mode rather than trying to allowlist P2P traffic through it.
LAN peer discovery#
Finding peers on the same local network uses standard mDNS (multicast DNS, the same mechanism as Bonjour/AirPlay discovery) - no custom protocol, no non-standard port. If your network already blocks mDNS multicast (some corporate/VLAN setups, and Docker bridges, do this by default), Swarmfile still works - it just can't discover LAN peers automatically, and every read falls back to the peer-relay path or the cloud. There's a separate lan_from_office setting for networks that block multicast but where you still want deliberate LAN peer placement; see Deployment Topologies.
mDNS runs only on physical LAN interfaces (Ethernet, Wi-Fi). The engine skips VPN and tunnel adapters (macOS utun*, WireGuard, OpenVPN, Tailscale, ZeroTier), Hyper-V/WSL, VMware, VirtualBox, Parallels and Docker virtual networks, and Apple's AirDrop links (awdl0, llw0), because none of them reach a colleague's machine on the office LAN. It advertises only its LAN addresses, never a VPN address. It checks interfaces again every 30 seconds, so connecting a VPN later doesn't move discovery onto it. To override the choice, set SWARMFILE_MDNS_INTERFACES (use only these interfaces, comma-separated) or SWARMFILE_MDNS_EXCLUDE_INTERFACES (never use these). swarmfile doctor's mdns listen check lists the interfaces in use and those it skipped. It warns when no LAN interface is available.
Windows Firewall. Windows filters inbound traffic per program. If swarmfile-engine.exe has no inbound rule, other machines' mDNS queries and announcements never reach it, but its own outgoing packets still leave. The result is one-sided: other machines may briefly see this one, and this one never finds anyone. Windows only offers to create a rule when someone runs the engine interactively, and then only for the Public profile, so silent/GPO installs and standard users would otherwise get nothing.
The installer (both the bundled Setup.exe and the bare .msi) therefore adds one inbound rule, and removes it on uninstall:
| Setting | Value |
|---|---|
| Display name | Swarmfile - local network file sharing |
| Group | Swarmfile |
| Program | C:\Program Files\Swarmfile\swarmfile-engine.exe |
| Direction / action | Inbound, Allow |
| Protocol / ports | UDP, any local port (mDNS on 5353, plus the QUIC port, which is ephemeral unless you pin it with iroh_bind_addr) |
| Remote addresses | Local subnet only |
| Profiles | Domain, Private (not Public) |
A second rule in the same group, Swarmfile - local network check (doctor), does the same for swarmfile-doctor.exe, so its one-second mdns listen check can hear replies when no engine is running. To include the Public profile as well, install with msiexec /i Swarmfile-x64.msi SWARMFILE_FW_PROFILES=7 /qn (the value is a bitmask: 1 = Domain, 2 = Private, 4 = Public). Check the result with:
Get-NetFirewallRule -Group Swarmfile | Format-Table DisplayName, Enabled, Profile, Direction, Action
Get-NetFirewallRule -Group Swarmfile | Get-NetFirewallAddressFilter # RemoteAddress: LocalSubnet
If you deploy from the .zip, run the engine from a different path, or your GPO sets Apply local firewall rules: No (which ignores rules an installer adds), create the equivalent rule yourself, through GPO/Intune or with:
New-NetFirewallRule -DisplayName "Swarmfile - local network file sharing" -Group "Swarmfile" `
-Direction Inbound -Action Allow -Protocol UDP `
-Program "C:\Program Files\Swarmfile\swarmfile-engine.exe" `
-RemoteAddress LocalSubnet -Profile Domain,Private
To avoid a program-scoped rule, pin the QUIC port ("iroh_bind_addr": "0.0.0.0:4433" in config.json) and open UDP 5353 and 4433 from LocalSubnet with -LocalPort 5353,4433 instead of -Program. A Block rule for swarmfile-engine.exe (created when someone clicked Cancel on a firewall prompt) overrides any allow rule, so delete it if one exists. swarmfile doctor's mdns listen check warns when the hub lists peers in your office or on your subnet but mDNS has found none of them. That usually means a firewall or a network that filters multicast.
Linux firewalls#
The .deb doesn't change your firewall. On a host running ufw or firewalld with a default-deny inbound policy, allow UDP 5353 (mDNS) and the engine's QUIC traffic from the local subnet. QUIC uses a random UDP port unless you pin it with iroh_bind_addr, so you can either allow all UDP from the subnet or pin the port and open only that one. The examples use 192.168.1.0/24. Use your own subnet, which ip -4 addr shows (an address of 192.168.1.23/24 is on 192.168.1.0/24).
The tidy option is to pin the port. Add "iroh_bind_addr": "0.0.0.0:4433" to config.json, restart the engine (systemctl --user restart swarmfile-engine), and then:
# ufw
sudo ufw allow proto udp from 192.168.1.0/24 to any port 5353 comment 'Swarmfile mDNS'
sudo ufw allow proto udp from 192.168.1.0/24 to any port 4433 comment 'Swarmfile QUIC'
# firewalld
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="mdns" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="4433" protocol="udp" accept'
sudo firewall-cmd --reload
If you leave the port unpinned, allow all UDP from the subnet instead:
# ufw
sudo ufw allow proto udp from 192.168.1.0/24 to any comment 'Swarmfile LAN'
# firewalld
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" protocol value="udp" accept'
sudo firewall-cmd --reload
Some stock rule sets already allow part of this. Ubuntu's default ufw rules accept multicast mDNS, and Fedora Workstation's default firewalld zone allows mDNS and UDP ports above 1024. The explicit rules do no harm there. They also cover the unicast replies that some mDNS responders send. If your LAN uses IPv6 only, add the same rules for your IPv6 prefix.
swarmfile doctor's host firewall check reads these firewalls without root and warns when one is active with no rule that allows UDP 5353 and the QUIC port. ufw only shows its rules to root, so as a normal user the check can't confirm them. In that case it warns only when mdns listen also reports missing LAN peers.
macOS#
The macOS Application Firewall allows the signed engine by default. Two settings stop LAN peers from reaching it: Block all incoming connections (System Settings → Network → Firewall → Options…), and a Block incoming connections entry for swarmfile-engine, which appears when someone clicks Deny on the firewall prompt. The host firewall check reports both and gives the command that reverses each one.
On macOS 15 and later, Local Network privacy also gates LAN access. The Desktop App asks for it, and the engine installed inside the app is covered by that permission (System Settings → Privacy & Security → Local Network). An engine binary running outside the app bundle, such as a render-farm or CI node, has no such permission. Unless it runs as root (a LaunchDaemon) or in the foreground of a Terminal or SSH session that stays open, macOS can deny it LAN access without telling anyone. Connections to LAN peers or a LAN hub then fail with "No route to host", and mDNS finds nobody, while internet traffic keeps working. The macos local network check warns when the engine runs this way. Apple's TN3179: Understanding local network privacy lists these rules.
Cloud-only mode (hub-only)#
For a network that blocks UDP/QUIC outright, or a security policy that wants zero peer-to-peer connections and zero peer IP exposure, cloud-only mode turns P2P off entirely - not just "prefers not to use it." (The engine and config file call it hub_only; the Desktop App and CLI label the same switch Cloud-only mode.) With it enabled, the engine never opens a QUIC endpoint, never starts mDNS, and never dials another peer. The entire network surface collapses to the HTTPS/443 rows in the summary table above - metadata to the hub, file bytes to the org's storage origin (control plane, identity, storage, and - while the Desktop App is active - installer/update checks), so a firewall must allow both, not just the hub. Nothing UDP is ever touched.
This is set per-machine ("hub_only": true in config.json, or SWARMFILE_HUB_ONLY=1 in the environment), or centrally for the whole org by an owner or admin (Settings → Network). The two combine with OR, not override: an org-enforced policy can only ever turn cloud-only on for a machine, never force it back off - a machine an operator has locally pinned to cloud-only stays cloud-only regardless of what the org policy says. See Security for how this fits the broader threat model, and Operations for where the setting shows up in your audit log.
Verifying what a specific machine actually needs#
swarmfile doctor runs a battery of connectivity checks - DNS resolution, HTTPS reachability to the hub, an authenticated round-trip, a QUIC dial test (skipped cleanly when cloud-only mode is on), and an mDNS listen test (same) - and reports pass/warn/fail for each, with a --json mode for pasting into a firewall-exception ticket. Run it from a machine on the network you're configuring rather than guessing; see swarmfile-doctor.
What's not covered here#
Self-hosted seed and NAS nodes participate in the same P2P swarm as any other machine - no additional inbound ports are required for them either. A seed node run as a headless cloud service (rather than on-prem hardware) can optionally expose a health-check HTTP endpoint for your own orchestration (Kubernetes, Fly.io, etc.) - that's an explicit opt-in for that specific deployment shape, not something a normal desktop or on-prem seed install does, and it's the one case where the engine listens on all interfaces rather than loopback-only. Even then, only /livez (a bare {"status":"ok"}) answers a non-loopback caller - /healthz's detailed body, which exposes sensitive operational detail, 403s for anything but loopback regardless of which interface the port is bound to, so a container orchestrator's liveness probe works but a remote caller can't use the same port to enumerate your fleet. Talk to us if you're deploying that way and need the specifics.