Secure Linux services with port knocking — knockd, OpenSPA and fwknopd compared
Port knocking hides SSH and other services from attackers. This guide explains knockd, OpenSPA and fwknopd and shows a complete fwknopd setup (server + client for Windows/Linux/macOS).
Port knocking is an elegant method to hide SSH and other critical services from automated attacks and port scans. Instead of leaving the service port open permanently, the firewall remains closed until a specific sequence (a “knock pattern”) is sent to the correct ports. Only then does the server temporarily open access for the source IP.
In this post we’ll look at three popular implementations — knockd, OpenSPA and fwknopd — and show a complete, production-ready example with fwknopd (server + client for Windows, Linux and macOS).
🔐 What is port knocking?
Port knocking (literally: “knocking on the port”) works like this:
- The server listens on multiple ports but doesn’t open any of them for the actual service (e.g. SSH on port 22).
- The client sends a defined sequence of packets to specific ports (e.g. TCP-SYN to port 7000, 8000, 9000 in exactly that order).
- The port knocking daemon on the server recognizes the correct sequence and temporarily adds a firewall rule allowing the source IP access to the protected port.
- After a defined time (or when a “close sequence” is sent), the rule is removed again.
The result: SSH (or another service) is invisible to port scanners because the firewall drops all connections until the correct sequence is sent.
sequenceDiagram
participant C as Client
participant K as Port Knocking Daemon
participant F as Firewall
participant S as SSH Service
C->>K: Send SPA packet / knock sequence
K->>K: Validate signature & timestamp
K->>F: Add temporary rule for client IP
F-->>S: Allow port 22 for client IP
C->>S: Establish SSH connection
Note over F: Rule expires after timeout
F->>F: Remove client IP rule
🛠️ Three tools at a glance
knockd
knockd is the classic among port knocking daemons. It’s easy to configure and widely used.
-
How it works: The client sends TCP or UDP packets to a fixed sequence of ports (e.g. 7000, 8000, 9000). knockd recognizes the sequence and executes a script (e.g. add
iptablesrule). - Advantages: Very simple, low resources, available in many distributions.
- Disadvantages: No authentication or encryption — anyone who knows the sequence can knock. Sequences can be captured through network sniffing.
Typical use case: Quick, simple security for home servers or internal networks where the sequence remains secret.
OpenSPA (Single Packet Authorization)
OpenSPA (often mentioned as a concept in combination with fwknop) relies on Single Packet Authorization (SPA): Instead of sending multiple packets in sequence, a single encrypted and authenticated packet is sent containing all necessary information (e.g. desired port, timestamp, HMAC).
- How it works: Client generates a cryptographically signed packet and sends it to the server. The server validates signature and timestamp and opens the port on success.
- Advantages: Replay protection through timestamp, authentication via HMAC or GPG, significantly more secure than simple port sequences.
- Disadvantages: Somewhat more complex to configure than knockd.
Typical use case: Professional setups where security and replay protection are important.
fwknopd (fwknop daemon)
fwknopd is the most developed and secure variant. It implements SPA (Single Packet Authorization) and supports both HMAC and GPG-based authentication.
- How it works: The client (fwknop) sends an encrypted SPA packet to the server. fwknopd checks the signature, timestamp and temporarily opens the requested port (e.g. SSH) on success.
- Advantages: Very secure (replay protection, strong cryptography), actively maintained, multi-platform clients available (Linux, macOS, Windows, Android, iOS).
- Disadvantages: Slightly more configuration effort than knockd, but manageable.
Typical use case: Production servers that expose SSH or other services externally but need maximum protection.
⚙️ fwknopd — Complete setup (server + client)
Below I’ll show a production-ready setup with fwknopd on a Linux server (Debian/Ubuntu) and clients for Linux, macOS and Windows.
Scenario
- Server: Debian/Ubuntu server with SSH on port 22.
- Goal: SSH port is blocked from outside by default; only after successful SPA knock is the firewall temporarily opened for the client IP.
-
Client: Linux, macOS or Windows with installed
fwknopclient.
🖥️ Server setup (fwknopd on Linux)
1) Install fwknopd
1
2
sudo apt update
sudo apt install fwknop-server fwknop-client
(On RHEL/CentOS/Fedora: sudo dnf install fwknop-server fwknop-client or compile from source.)
2) Prepare firewall
Make sure SSH is blocked by default. Example with ufw:
1
2
3
4
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 62201/udp # fwknopd listens on UDP 62201 by default
sudo ufw enable
SSH port 22 is now unreachable from outside.
Alternatively with iptables:
1
2
3
sudo iptables -A INPUT -p udp --dport 62201 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j DROP
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
3) Configure fwknopd
Main configuration file: /etc/fwknop/fwknopd.conf
Important parameters (example):
1
2
3
PCAP_INTF eth0;
ENABLE_IPT_FORWARDING N;
ENABLE_IPT_OUTPUT N;
-
PCAP_INTF: Network interface on which fwknopd listens (e.g.eth0orens3). -
ENABLE_IPT_FORWARDINGandENABLE_IPT_OUTPUT: Usually leave onNif you only manage INPUT rules.
4) Access configuration
File: /etc/fwknop/access.conf
Example (HMAC-based, simplest variant):
1
2
3
4
5
6
SOURCE ANY
OPEN_PORTS tcp/22
FW_ACCESS_TIMEOUT 30
REQUIRE_SOURCE_ADDRESS Y
KEY_BASE64 <BASE64_KEY>
HMAC_KEY_BASE64 <BASE64_HMAC_KEY>
Explanation:
-
SOURCE ANY: Any IP may knock (alternatively: specific IP or subnet). -
OPEN_PORTS tcp/22: Open SSH port 22 on successful knock. -
FW_ACCESS_TIMEOUT 30: Firewall rule remains active for 30 seconds. -
REQUIRE_SOURCE_ADDRESS Y: Only the source IP of the SPA packet gets access. -
KEY_BASE64andHMAC_KEY_BASE64: Symmetric keys for encryption and HMAC.
Generate keys:
1
fwknop --key-gen
Output (example):
1
2
KEY_BASE64: <your_encryption_key_base64>
HMAC_KEY_BASE64: <your_hmac_key_base64>
Copy these values into the access.conf.
5) Start and enable fwknopd
1
2
3
sudo systemctl enable fwknopd
sudo systemctl start fwknopd
sudo systemctl status fwknopd
Check that fwknopd is running and listening on port 62201/UDP:
1
sudo ss -lunp | grep 62201
💻 Client setup (Linux / macOS / Windows)
Linux / macOS
1) Install fwknop client
Debian/Ubuntu:
1
sudo apt install fwknop-client
macOS (via Homebrew):
1
brew install fwknop
2) Create client configuration file
File: ~/.fwknoprc
1
2
3
4
5
6
[myserver]
ACCESS tcp/22
SPA_SERVER <SERVER_IP>
KEY_BASE64 <BASE64_KEY>
HMAC_KEY_BASE64 <BASE64_HMAC_KEY>
USE_HMAC Y
Replace <SERVER_IP>, <BASE64_KEY> and <BASE64_HMAC_KEY> with your values.
3) Send SPA packet (knock)
1
fwknop -n myserver
Output:
1
2
3
[+] Starting fwknop client (SPA mode)
[+] Sending SPA packet to <SERVER_IP> ...
[+] SPA packet sent.
4) Establish SSH connection
Within the next 30 seconds (or the period configured in FW_ACCESS_TIMEOUT):
1
ssh user@<SERVER_IP>
The firewall now temporarily allows access for your IP.
Windows
1) Download fwknop client for Windows
- Official pre-compiled binaries: fwknop Windows Releases (or compile yourself).
- Alternative: Use Windows Subsystem for Linux (WSL) and install fwknop as on Linux.
2) Create configuration file
Create a file C:\Users\<YourName>\.fwknoprc (or in the WSL home directory if using WSL):
1
2
3
4
5
6
[myserver]
ACCESS tcp/22
SPA_SERVER <SERVER_IP>
KEY_BASE64 <BASE64_KEY>
HMAC_KEY_BASE64 <BASE64_HMAC_KEY>
USE_HMAC Y
3) Send SPA packet
In Command Prompt or PowerShell (or WSL terminal):
fwknop.exe -n myserver
(Adjust path if fwknop is not in PATH.)
4) Establish SSH connection
Use PuTTY, OpenSSH (Windows 10+) or WSL:
ssh user@<SERVER_IP>
🧪 Testing and troubleshooting
Test 1: Check if SSH is blocked
Before knocking, a direct SSH connection should fail:
1
ssh user@<SERVER_IP>
Expected output: Timeout or “Connection refused”.
Test 2: Send knock and connect immediately
1
fwknop -n myserver && ssh user@<SERVER_IP>
If everything is configured correctly, the SSH connection should succeed.
Check logs (server)
1
sudo journalctl -u fwknopd -f
or
1
sudo tail -f /var/log/fwknop/fwknopd.log
Common errors:
- “Invalid SPA packet”: Keys don’t match.
- “Replay detected”: Timestamp too old (client and server time must be in sync; use NTP).
- “Firewall rule not added”: Check iptables/ufw status and whether fwknopd has necessary permissions.
🔒 Best practices and tips
-
Synchronize NTP: fwknopd checks timestamps. Make sure client and server use NTP.
1 2
sudo systemctl enable systemd-timesyncd sudo systemctl start systemd-timesyncd
Adjust firewall timeout: You can adjust
FW_ACCESS_TIMEOUTinaccess.confto your needs (e.g. 60 seconds for slower connections).GPG-based authentication (even more secure): Instead of HMAC you can use GPG keys. Details in the fwknop documentation.
Secure multiple services: You can define multiple stanzas in
access.confand protect different ports (e.g. HTTPS, RDP).Port change: If you want to change the default port 62201/UDP, adjust
PCAP_FILTERinfwknopd.confand open the new port in the firewall.Mobile clients: For Android and iOS there are fwknop apps that can send SPA packets (e.g. “Fwknop2” for Android).
🆚 Comparison: knockd vs. fwknopd
| Feature | knockd | fwknopd (SPA) |
|---|---|---|
| Authentication | None (sequence only) | HMAC or GPG |
| Replay protection | No | Yes (timestamp) |
| Encryption | No | Yes |
| Configuration | Very simple | Somewhat more complex |
| Security | Basic (sequence can be sniffed) | High (cryptographically signed) |
| Multi-platform clients | Limited | Linux, macOS, Windows, Android, iOS |
Recommendation: For production internet-facing servers, fwknopd is the better choice. For quick internal setups or learning purposes, knockd is sufficient.
🧠 Final thoughts
Port knocking and Single Packet Authorization (SPA) are effective methods to hide SSH and other services from automated attacks. fwknopd offers a modern, secure implementation with strong cryptography and replay protection and is usable on all common platforms.
With the setup above you can secure a Linux server so that SSH port scanners run into a wall, while you yourself get temporary access with a single command. Combine port knocking with SSH key authentication, Fail2Ban and regular updates for a robust security concept.
