Objective
Implement a Port Knocking system to protect SSH access. The SSH port will remain closed by default and only open after knocking a specific sequence of ports in the correct order.
This security-through-obscurity technique adds a layer of protection against port scans and SSH brute force attempts.
Prerequisites
- Debian 11 / Ubuntu server
- SSH functional and configured
- Root or sudo access
- iptables installed (usually present by default)
- Physical or rescue console access (in case of SSH lockout)
Before configuring port knocking, ensure you have:
- Physical console access or via hypervisor (VirtualBox, ESXi, etc.)
- Network configuration backup
- Parallel SSH session open for testing
Complete Procedure
Step 1: knockd Installation
Update repositories and install knockd:
apt update apt install knockd -y
Verify installation:
knockd --version
Step 2: knockd Configuration
Edit main configuration file:
nano /etc/knockd.conf
Replace content with following configuration:
[options] UseSyslog [openSSH] sequence = 7000,8000,9000 seq_timeout = 15 command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn [closeSSH] sequence = 9000,8000,7000 seq_timeout = 15 command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT tcpflags = syn
Save and exit (Ctrl+O, Enter, Ctrl+X)
- [options]: global configuration section
- UseSyslog: enables logging in system logs
- [openSSH]: rule to open SSH port
- sequence = 7000,8000,9000: port sequence to knock in order
- seq_timeout = 15: maximum time (in seconds) to complete sequence
- %IP%: variable automatically replaced by client source IP
- tcpflags = syn: listens only to TCP SYN packets
- [closeSSH]: rule to close SSH port (reverse sequence)
Step 3: Network Interface Configuration
Edit configuration file to specify network interface:
nano /etc/default/knockd
Modify following lines:
START_KNOCKD=1 KNOCKD_OPTS="-i eth0"
eth0 with your network interface name.To identify your interface:
ip a
Common interfaces: eth0, ens33, enp0s3, ens18
Step 4: Firewall Configuration (iptables)
Block SSH port by default:
iptables -A INPUT -p tcp --dport 22 -j DROP
Allow established SSH connections (important to not cut active sessions):
iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Save iptables rules:
apt install iptables-persistent -y netfilter-persistent save
- -A INPUT: adds rule to INPUT chain (incoming traffic)
- -p tcp --dport 22: targets TCP port 22 (SSH)
- -j DROP: silently rejects packets
- -m state --state ESTABLISHED,RELATED: allows already established connections
- iptables-persistent: preserves rules after reboot
Step 5: knockd Startup
Enable knockd at system startup:
systemctl enable knockd
Start service:
systemctl start knockd
Check status:
systemctl status knockd
Service should be "active (running)" and listening on specified interface.
Client-Side Usage
knock Client Installation (Linux)
On client machine (Debian/Ubuntu):
apt install knockd -y
Open SSH Port
Knock sequence to open port:
knock SERVER_IP_ADDRESS 7000 8000 9000
Example:
knock 192.168.1.100 7000 8000 9000
SSH connection immediately after:
Close SSH Port
Knock reverse sequence to close:
knock 192.168.1.100 9000 8000 7000
Alternative: nmap (if knock not available)
for PORT in 7000 8000 9000; do nmap -Pn --max-retries 0 -p $PORT 192.168.1.100; done
Alternative: telnet (Windows/Linux)
telnet 192.168.1.100 7000 (Ctrl+C to exit) telnet 192.168.1.100 8000 (Ctrl+C) telnet 192.168.1.100 9000 (Ctrl+C) ssh [email protected]
Automated bash Script
Create script to simplify usage:
nano ~/knock-ssh.sh
Script content:
#!/bin/bash SERVER="192.168.1.100" knock $SERVER 7000 8000 9000 sleep 1 ssh user@$SERVER
Make script executable:
chmod +x ~/knock-ssh.sh
Usage:
~/knock-ssh.sh
Verification
knockd Service Verification
systemctl status knockd
Should display "active (running)"
Logs Verification
tail -f /var/log/syslog | grep knockd
Should display knock attempts in real time
iptables Rules Verification
iptables -L INPUT -v -n
Should show dynamic rules added by knockd after successful knock
Test from Remote Machine
- Attempt direct SSH connection (should fail):
ssh [email protected] # Should remain blocked or display "Connection refused" - Knock sequence:
knock 192.168.1.100 7000 8000 9000 - Immediate SSH connection (should succeed):
Close Sequence Test
From another SSH session (don't close active session):
knock 192.168.1.100 9000 8000 7000
Attempt new SSH connection from another terminal: should fail
Security and Limitations
Port Knocking Advantages
- Hides SSH service from automated port scans
- Reduces SSH brute force attempts
- Adds additional security layer
- No modification of standard SSH client required
- Precise knock attempt logs
Limitations and Drawbacks
- Security through obscurity (no sequence encryption)
- Vulnerable to network sniffing (attacker can capture sequence)
- Complex for non-technical users
- Lockout risk with misconfiguration
- No protection against replay attacks
- Does NOT replace SSH key authentication
Additional Security Recommendations
- SSH key authentication (disable passwords)
- Fail2ban to ban suspicious IPs
- SSH port change (e.g., 2222 instead of 22)
- SSH user restriction (AllowUsers in sshd_config)
- Root SSH account deactivation (PermitRootLogin no)
Hardened SSH Configuration
Edit /etc/ssh/sshd_config:
nano /etc/ssh/sshd_config
Recommended parameters:
PermitRootLogin no PasswordAuthentication no PubkeyAuthentication yes AllowUsers user1 user2 MaxAuthTries 3 ClientAliveInterval 300 ClientAliveCountMax 2
Restart SSH:
systemctl restart sshd
Log Monitoring
# SSH logs tail -f /var/log/auth.log # knockd logs tail -f /var/log/syslog | grep knockd # iptables logs (if enabled) tail -f /var/log/kern.log
Variant: Port Knocking with OTP Authentication
To go further (outside standard BTS scope), solutions exist combining port knocking and OTP (One-Time Password) like fwknop (Firewall Knock Operator) using SPA (Single Packet Authorization).
More Robust Alternatives
- VPN (WireGuard, OpenVPN): SSH access via encrypted tunnel
- SSH Bastion (Jump Host): intermediate server for bouncing
- SSH via Tor: traffic anonymization
- 2FA/MFA: two-factor authentication (Google Authenticator, Yubikey)
Troubleshooting
Problem: knockd Does Not Start
journalctl -xe -u knockd
Check:
- Syntax of /etc/knockd.conf file
- Network interface name in /etc/default/knockd
- Configuration file permissions
Problem: Sequence Does Not Work
- Verify network interface is properly specified
- Check logs in real time:
tail -f /var/log/syslog - Test with tcpdump to see if packets arrive:
tcpdump -i eth0 port 7000 or port 8000 or port 9000
Problem: Locked Out After Configuration
Access via physical console or hypervisor and:
systemctl stop knockd iptables -F iptables -P INPUT ACCEPT systemctl restart sshd
Key Points for BTS Oral Exam
- Port Knocking: security-through-obscurity technique
- Principle: knock port sequence to unlock a service
- knockd: Linux daemon listening to sequences and executing iptables rules
- Limitations: vulnerable to sniffing, doesn't replace strong authentication
- Complementarity: must be combined with SSH keys, fail2ban, firewall
- Usage: protection against automated scans and SSH brute force
- Alternatives: VPN, SSH bastion, 2FA are more robust