Securing SSH Infrastructure: Implementing Single Packet Authorization (SPA) with Fwknop to Conceal VPS Ports from Public Scans
Introduction: The Vulnerability of Public-Facing SSH Ports
For system administrators, DevOps engineers, and security professionals, securing Secure Shell (SSH) access to Virtual Private Servers (VPS) is a foundational priority. Traditionally, protecting SSH involves basic hardening techniques such as changing the default port 22, disabling password authentication in favor of public key infrastructure (PKI), and deploying automated intrusion prevention tools like Fail2ban.
However, these traditional measures suffer from a fundamental architectural flaw: the port remains open to the Internet. As long as a port is in a LISTEN state, it is visible to malicious actors utilizing automated network scanners like Masscan or Shodan. A visible port invites continuous brute-force attempts, subjects the authentication daemon to resource exhaustion attacks, and leaves the system vulnerable to zero-day exploits within the SSH daemon (OpenSSH) itself. To achieve absolute security, the port must be rendered completely invisible, responding to public probes with absolute silence, while remaining accessible exclusively to authorized users.
Understanding Single Packet Authorization (SPA) vs. Port Knocking
Before diving into the implementation of Fwknop (FireWall Knock Operator), it is critical to distinguish between traditional Port Knocking and modern Single Packet Authorization (SPA). While both techniques aim to keep ports closed until triggered, their underlying cryptographic and operational frameworks differ significantly.
The Limitations of Traditional Port Knocking
Traditional port knocking relies on a sequence of connection attempts to a predefined set of closed ports. For example, a client might attempt to connect to TCP ports 7000, 8000, and 9000 sequentially. A daemon monitoring the firewall logs detects this specific pattern and dynamically modifies the firewall rules to temporarily open the SSH port for the client's IP address.
Despite its conceptual utility, traditional port knocking exhibits several critical vulnerabilities:
- Replay Attacks: An adversary monitoring network traffic can capture the sequence of port connection attempts and replay them from a different IP address to grant themselves access.
- IP Spoofing: Attackers can spoof the source IP addresses of the knock sequence to manipulate firewall states.
- Port Scanning Visibility: The simple sequential connection attempts can be easily intercepted, mapped, and decoded by sophisticated Network Intrusion Detection Systems (NIDS) or malicious sniffers.
- Protocol Overhead: Executing multiple connection attempts introduces latency and can be unreliable over unstable or high-packet-loss mobile networks.
The Superiority of Single Packet Authorization (SPA)
Single Packet Authorization solves these structural flaws by condensing the authorization trigger into a single, highly encrypted, and authenticated packet. Typically sent via UDP, this packet contains all necessary metadata required to authenticate the client, verify authorization parameters, and prevent unauthorized tampering.
Fwknop leverages SPA to deliver comprehensive protection by guaranteeing the following security characteristics:
- Strong Cryptography: SPA packets generated by Fwknop are encrypted using asymmetric (GnuPG/OpenPGP) or symmetric (Rijndael/AES) encryption algorithms. This ensures that the contents are unreadable to anyone sniffing the network wire.
- Message Authentication Codes (MAC): HMAC verification is built into the protocol to ensure message integrity and confirm that the packet originated from an authentic source before any decryption takes place.
- Replay Attack Immunity: Every SPA packet contains a high-resolution timestamp and a unique random nonce. The Fwknop daemon caches these elements and automatically drops any packet that falls outside a narrow time window or matches a previously processed nonce.
- Absolute Non-Responsiveness: Because the Fwknop daemon utilizes a packet capture library (libpcap) to passively sniff raw network frames directly from the interface kernel space, the server does not bind to a standard network socket. Consequently, it never sends an ACK or RST packet back to unauthorized scanners. The firewall drops all traffic by default, making the server appear completely dead or non-existent to external network scans.
Architecture and Components of Fwknop
The Fwknop ecosystem operates via a lean, decoupled architecture consisting of two primary components:
- The Client (fwknop): A command-line utility or mobile application installed on the administrator's local machine. It compiles the local system's parameters, generates the payload, signs it, encrypts it, and transmits it as a single UDP packet to the target VPS.
- The Daemon (fwknopd): A lightweight system service running on the VPS. It monitors a specified network interface via
libpcap. When it intercepts a valid SPA packet, it decrypts the payload, validates the cryptographic signatures, confirms the timestamp, and dynamically executes a local firewall command (e.g., usingiptablesornftables) to allow temporary incoming SSH connections from the client's verified IP address.
Step-by-Step Implementation Guide
This section provides a rigorous technical breakdown for installing, configuration, and validating an Fwknop deployment on a Linux VPS utilizing iptables.
Step 1: Establishing the Default-Drop Firewall Policy
To benefit from SPA, your firewall must be configured to drop all incoming SSH connections by default. Execute the following commands on your VPS to configure iptables to drop traffic on your designated SSH port (assuming standard port 22 for this demonstration, though changing it is still recommended for defense-in-depth):
# Allow established and related connections so you don't drop your active session sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # Drop all incoming SSH connections by default sudo iptables -A INPUT -p tcp --dport 22 -j DROP
Warning: Ensure that you maintain your current SSH session active while configuring these rules to avoid accidentally locking yourself out of the system before Fwknop is fully operational.
Step 2: Installing Fwknop Components
Update your package repositories and install the daemon on your VPS, and the client software on your local machine.
On the Server (Ubuntu/Debian):
sudo apt-get update sudo apt-get install fwknop-server -y
On the Client (Ubuntu/Debian Local Machine):
sudo apt-get update sudo apt-get install fwknop-client -y
Step 3: Configuring the Fwknop Daemon on the VPS
The server-side configuration relies on two core configuration files located within the /etc/fwknop/ directory: fwknopd.conf and access.conf.
First, open /etc/fwknop/fwknopd.conf to define the global operational parameters, specifically ensuring that the daemon targets the correct network interface:
# Edit /etc/fwknop/fwknopd.conf PCAP_INTF eth0;
Replace eth0 with the actual public interface identifier of your VPS, which can be verified via the ip a command.
Next, configure the authentication stanzas and cryptographic keys in /etc/fwknop/access.conf. For simplicity and reliability, this guide utilizes symmetric Rijndael encryption alongside HMAC-SHA256 authentication:
# Append to /etc/fwknop/access.conf SOURCE ANY REQUIRE_SOURCE_ADDRESS Y KEY_BASE64 [INSERT_GENERATED_BASE64_KEY] HMAC_KEY_BASE64 [INSERT_GENERATED_HMAC_KEY] FW_ACCESS_TIMEOUT 30
The FW_ACCESS_TIMEOUT directive specifies that the firewall will open the port for exactly 30 seconds. This is the window available for the client to initiate the TCP handshake. Once the SSH connection is established, the firewall rule can expire without terminating the active session, thanks to the ESTABLISHED,RELATED iptables rule configured in Step 1.
To generate secure, cryptographically random base64 keys for the fields above, run the following Fwknop utility commands on your system:
# Generate Symmetric Key fwknop --key-gen # Generate HMAC Key fwknop --hmac-key-gen
Copy the outputted strings into their respective fields within the server's access.conf file.
Step 4: Managing the Daemon Service
Enable and start the Fwknop daemon to apply the configuration adjustments:
sudo systemctl enable fwknop-server sudo systemctl start fwknop-server sudo systemctl status fwknop-server
Step 5: Configuring the Local Client Profile
On your local computer, define a structured runtime profile within the ~/.fwknoprc configuration file to streamline packet generation. Populate the profile with the identical symmetric and HMAC keys generated for the server:
[my_vps] KEY_BASE64 [YOUR_GENERATED_BASE64_KEY] HMAC_KEY_BASE64 [YOUR_GENERATED_HMAC_KEY] SPA_SERVER [YOUR_VPS_PUBLIC_IP] ACCESS tcp/22 SPA_SERVER_PROTO udp
Testing and Operational Validation
With both endpoints configured, verify the concealment by attempting a direct connection from an external machine without sending an SPA packet:
ssh user@YOUR_VPS_PUBLIC_IP
The connection attempt should stall indefinitely and eventually time out, demonstrating that the port is completely stealthy. Now, leverage the local Fwknop client to broadcast the authorization sequence:
fwknop -n my_vps
This command transmits the single, authenticated UDP packet to the VPS. The fwknopd daemon detects the frame, performs cryptographic validation, and inserts a temporary rule into the iptables chain. Immediately execute your SSH command within the designated 30-second window:
ssh user@YOUR_VPS_PUBLIC_IP
The SSH session will initialize seamlessly. If you audit the firewall rules on the server during this active window using sudo iptables -L INPUT -v -n, you will observe a dynamically injected rule explicitly permitting traffic from your specific public client IP address to TCP port 22.
Conclusion and Best Practices
Implementing Single Packet Authorization via Fwknop fundamentally changes the defensive posture of your internet-facing infrastructure. By shifting from a reactive paradigm (mitigating brute-force attacks via Fail2ban) to a proactive paradigm (complete port concealment), you effectively neutralize the primary vector for network scanning and automated exploits.
To maintain an optimal security architecture, adhere to these ongoing best practices:
- Synchronize System Clocks: Because SPA relies heavily on precise timestamps to thwart replay attacks, ensure both client and server nodes run Network Time Protocol (NTP) daemons like
chronyorsystemd-timesyncd. - Automate Client Execution: Simplify your administrative workflows by utilizing SSH configuration aliases combined with the
ProxyCommanddirective to automatically trigger an Fwknop SPA broadcast whenever you call thesshcommand. - Adopt Asymmetric Cryptography: For enterprise-grade deployments or multi-user access environments, transition from symmetric pre-shared keys to GnuPG asymmetric key-pairs within
access.confto ensure non-repudiation and isolated access control management.
