How to Set Up Port Knocking for SSH on RHEL 7
Port knocking is a stealthy technique for controlling access to network services by requiring a client to send connection attempts to a predefined sequence of closed ports before a firewall rule opens the target port. When applied to SSH, it effectively hides port 22 from port scanners and automated brute-force bots — the SSH daemon is completely invisible until the correct knock sequence is performed. On RHEL 7, port knocking is implemented using the knockd daemon from the EPEL repository, combined with iptables rules to enforce the default-deny policy on the SSH port. This guide walks through the complete setup, from installing knockd to testing the sequence and layering it with Fail2Ban for defense-in-depth.
Prerequisites
- A running RHEL 7 system with root or sudo access
- An active internet connection or local EPEL mirror
- SSH access to the server — do not close your existing session until the configuration is verified
- Basic familiarity with
iptablesand firewall concepts - The
firewalldservice should be stopped or configured to use iptables backend, asknockdworks directly withiptables
Step 1: Enable the EPEL Repository and Install knockd
The knockd package is not available in the default RHEL 7 repositories. You must first enable the Extra Packages for Enterprise Linux (EPEL) repository. If your system is registered with Red Hat Subscription Manager, you can enable the optional channel; otherwise, install the EPEL release RPM directly.
# Install EPEL release for RHEL 7
yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
# Verify the repository is enabled
yum repolist | grep epel
# Install knockd
yum install -y knock-server
The package name on RHEL 7/EPEL is knock-server, which provides both the knockd daemon and the knock client utility. Confirm the installation succeeded:
rpm -qa | grep knock
knock --version
Step 2: Configure the Default-Deny iptables Rule for SSH
Port knocking only works if SSH is blocked by default. Before configuring knockd, add an iptables rule that drops all new incoming connections to port 22. This must be done carefully to avoid locking yourself out — ensure you have an active session or out-of-band console access.
# First, save the current iptables rules as a baseline
iptables-save > /root/iptables-baseline.rules
# Drop all new incoming TCP connections to SSH port 22
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -j DROP
# Verify the rule is in place
iptables -L INPUT -n --line-numbers
To make this rule persistent across reboots, save it with iptables-save and restore it at boot via the iptables service:
yum install -y iptables-services
systemctl enable iptables
iptables-save > /etc/sysconfig/iptables
Step 3: Create the knockd Configuration File
The main configuration file for knockd is /etc/knockd.conf. This file defines one or more sequences. Each sequence specifies the ports to knock, the TCP flags to match, and the commands to execute when the sequence succeeds or times out. Edit the file as follows:
vi /etc/knockd.conf
Add the following configuration:
[options]
UseSyslog
logfile = /var/log/knockd.log
interface = eth0
[openSSH]
sequence = 7000,8000,9000
seq_timeout = 10
tcpflags = syn
command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
[closeSSH]
sequence = 9000,8000,7000
seq_timeout = 10
tcpflags = syn
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
Key configuration options explained:
- sequence: The ordered list of ports to knock. Choose ports that are not in use on your system. Avoid common ports like 80 or 443.
- seq_timeout: All knocks in the sequence must arrive within this many seconds.
- tcpflags: Match only SYN packets, which are the initial packets of a TCP connection attempt.
- %IP%:
knockdsubstitutes the source IP address of the client that completed the knock sequence. - interface: Replace
eth0with your actual network interface (check withip link).
For stronger security, use a longer sequence with higher port numbers and vary the protocols:
[openSSH]
sequence = 12345,23456,34567,45678
seq_timeout = 15
tcpflags = syn
command = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -m state --state NEW -j ACCEPT
Step 4: Start and Enable the knockd Service
With the configuration file in place, start the knockd service and enable it to start at boot:
systemctl start knockd
systemctl enable knockd
systemctl status knockd
The output should show the service as active and running. Check the log file to confirm knockd is listening:
tail -f /var/log/knockd.log
You should see a line indicating it has started and is watching on the configured interface.
Step 5: Test Port Knocking from a Client
From a separate machine (or using a second terminal with an existing SSH session as a safety net), test the knock sequence using the knock client:
# Install the knock client on the remote machine
yum install -y knock
# Send the opening knock sequence to the server
knock -v 192.168.1.100 7000 8000 9000
# Immediately attempt SSH connection
ssh [email protected]
# After the session, close the firewall rule
knock -v 192.168.1.100 9000 8000 7000
Check the server-side log to see the knock sequence being registered:
tail /var/log/knockd.log
# Example output:
# [2026-05-17 12:00:01] 10.0.0.5: openSSH: Stage 1
# [2026-05-17 12:00:01] 10.0.0.5: openSSH: Stage 2
# [2026-05-17 12:00:02] 10.0.0.5: openSSH: Stage 3
# [2026-05-17 12:00:02] 10.0.0.5: openSSH: OPEN SESAME
# [2026-05-17 12:00:02] 10.0.0.5: running command: /sbin/iptables -I INPUT ...
You can also verify the dynamic iptables rule was inserted:
iptables -L INPUT -n --line-numbers
Step 6: Combining Port Knocking with Fail2Ban
Port knocking reduces exposure significantly, but any client that successfully knocks is then permitted to attempt SSH login. Adding Fail2Ban provides a second layer of defence by banning IPs after repeated failed authentication attempts.
yum install -y fail2ban
# Create a local override configuration
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
vi /etc/fail2ban/jail.local
Ensure the SSH jail is enabled in jail.local:
[sshd]
enabled = true
port = ssh
logpath = /var/log/secure
maxretry = 3
bantime = 3600
systemctl start fail2ban
systemctl enable fail2ban
systemctl status fail2ban
Security Considerations
Port knocking is a security-through-obscurity technique and should never replace strong SSH hardening. The following additional measures are recommended:
- Disable password authentication in
/etc/ssh/sshd_config— use SSH key pairs only (PasswordAuthentication no). - Change the sequence ports regularly, especially if they may have been observed by network monitoring.
- Use a longer, more complex knock sequence with a mix of UDP and TCP packets to thwart replay attacks.
- Consider using
fwknop(Single Packet Authorization) as a more cryptographically robust alternative to simple port knocking. - Monitor
/var/log/knockd.logand/var/log/secureregularly for anomalies. - Ensure the
iptables-savestate is updated whenever you make persistent rule changes.
Port knocking on RHEL 7 is a powerful complement to standard SSH hardening. By keeping SSH completely invisible to casual scanners and automated attack tools, and combining the sequence-based access control of knockd with the brute-force mitigation of Fail2Ban, you create a robust, layered access control system that dramatically reduces your server’s attack surface. Regularly audit your knock logs and SSH authentication logs to catch any unusual access patterns early.