Firewall and Port Configuration
Syncthing uses three distinct ports. Knowing which to open, which to never expose, and how to verify ensures both connectivity and security.
Learning Focus
Apply the minimal exposure rule: open only the data sync port (22000), keep the discovery port (21027) LAN-only, and never expose the GUI port (8384) directly to the internet.
Tool Snapshot
| Port | Protocol | Purpose | Expose Publicly? |
|---|---|---|---|
22000 | TCP + UDP | Data sync (direct P2P) | ✅ Yes — required for direct connections |
21027 | UDP (multicast) | Local LAN discovery | ❌ LAN only — block at internet firewall |
8384 | TCP | GUI / REST API | ❌ Never — SSH tunnel only |
22067 | TCP | Relay server (if self-hosted) | ✅ Yes — only if running a relay |
22070 | TCP | Relay status API | ⚠️ Only if monitoring externally |
UFW Configuration
configure-ufw-syncthing.sh
# Allow sync data port (TCP + UDP for QUIC)
sudo ufw allow 22000/tcp comment "Syncthing sync"
sudo ufw allow 22000/udp comment "Syncthing QUIC"
# Block GUI port from internet (should already be blocked if default policy is deny)
sudo ufw deny 8384/tcp comment "Syncthing GUI - block external"
# Allow local discovery only from LAN (example: 192.168.1.0/24)
sudo ufw allow from 192.168.1.0/24 to any port 21027 proto udp comment "Syncthing local discovery LAN"
# Reload and verify
sudo ufw reload
sudo ufw status numbered
Expected relevant output:
[ 1] 22000/tcp ALLOW IN Anywhere # Syncthing sync
[ 2] 22000/udp ALLOW IN Anywhere # Syncthing QUIC
[ 3] 8384/tcp DENY IN Anywhere # Syncthing GUI - block external
iptables Configuration
configure-iptables-syncthing.sh
# Allow sync
sudo iptables -A INPUT -p tcp --dport 22000 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 22000 -j ACCEPT
# Restrict GUI to loopback only
sudo iptables -A INPUT -p tcp --dport 8384 ! -i lo -j DROP
# Persist rules
sudo iptables-save | sudo tee /etc/iptables/rules.v4
Cloud Security Group Rules
| Provider | Inbound Rule |
|---|---|
| AWS EC2 | TCP 22000 from 0.0.0.0/0; UDP 22000 from 0.0.0.0/0 |
| Hetzner Cloud | TCP + UDP 22000 source: 0.0.0.0/0, ::/0 |
| DigitalOcean Firewall | TCP 22000 all sources; UDP 22000 all sources |
| All providers | Block TCP 8384 — no inbound rule for GUI port |
Binding Syncthing to a Specific Interface
On multi-homed servers (multiple network interfaces), bind Syncthing to a specific IP:
config.xml — bind to specific IP
<options>
<listenAddress>tcp://192.168.1.10:22000</listenAddress>
<listenAddress>quic://192.168.1.10:22000</listenAddress>
</options>
This prevents Syncthing from accepting connections on the public internet interface while remaining reachable on a private interface.
Verifying Port Availability
verify-ports.sh
# Confirm Syncthing is listening
ss -tlnp | grep syncthing
ss -ulnp | grep syncthing
# Test from an external machine (replace with your VPS IP)
nc -zv YOUR.VPS.IP 22000
# Check that GUI is NOT reachable externally
nc -zv YOUR.VPS.IP 8384
# Expected: Connection refused (or timeout)
# Test from local machine (should work)
curl -sk https://127.0.0.1:8384/rest/system/status | jq .version
Full Port Reference
flowchart LR
subgraph Internet
PEER[Remote Peer]
end
subgraph VPS
S[Syncthing :22000]
GUI[GUI :8384]
DISC[Discovery :21027]
end
PEER -->|TCP/UDP 22000 ✅ OPEN| S
PEER -.->|TCP 8384 ❌ BLOCKED| GUI
PEER -.->|UDP 21027 ❌ BLOCKED| DISC
Common Mistakes
| Mistake | Risk | Fix |
|---|---|---|
| Port 8384 open to internet | Remote attackers access GUI | sudo ufw deny 8384/tcp |
| UDP 22000 blocked | QUIC falls back to relay (slow) | sudo ufw allow 22000/udp |
| No firewall rules on fresh VPS | All ports open by default | Enable UFW with ufw default deny incoming |
| 21027 multicasting to internet | Exposes LAN topology info | Ensure it's blocked at the internet-facing interface |