DEV Community

Cover image for Automate Port Knocking with Dynamic Port Rotation for Secure SSH Access
Richard Chamberlain
Richard Chamberlain

Posted on

Automate Port Knocking with Dynamic Port Rotation for Secure SSH Access

Introduction

Now that you have Port Knocking configured, let’s take it a step further! Instead of using a static knocking sequence, we will automatically rotate knock ports daily using a systemd timer and service.

This enhances security by making it nearly impossible for attackers to guess the correct knock sequence.

Table of Contents

  1. Introduction
  2. Creating the Port Rotation Script
  3. Setting Up a Systemd Timer
  4. Enabling the Timer
  5. Client-Side Implementation
  6. Enhancing Security with Additional Measures
  7. Conclusion

πŸ“Œ Read Part 1: Setting Up Port Knocking for Secure SSH Access

Part of the Ethical Hacking Robot Project


1. Creating the Port Rotation Script

Create /usr/local/bin/update_knockd_ports.sh and add the following:

#!/bin/bash
# Define paths
KNOCKD_MAIN_CONF="/etc/knockd.conf"
PORT_FILE="/etc/knockd_ports"

# Generate 3 unique random ports (2000-65000)
NEW_PORTS=$(shuf -i 2000-65000 -n 3 | tr '\n' ',' | sed 's/,$//')

# Store new ports
echo "$NEW_PORTS" > "$PORT_FILE"

# Update knockd configuration
cat <<EOF > "$KNOCKD_MAIN_CONF"
[options]
    UseSyslog
[openSSH]
    sequence = $NEW_PORTS
    seq_timeout = 5
    command     = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
    tcpflags    = syn
[closeSSH]
    sequence    = $(echo $NEW_PORTS | awk '{print $3","$2","$1}')
    seq_timeout = 5
    command     = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
    tcpflags    = syn
EOF

# Restart knockd to apply changes
systemctl restart knockd

# Secure files
chmod 600 "$PORT_FILE" "$KNOCKD_MAIN_CONF"
scp "$PORT_FILE" user@client-ip:~/.
echo "Knockd ports updated: $NEW_PORTS"
Enter fullscreen mode Exit fullscreen mode

2. Setting Up a Systemd Timer

Create the Service File

/etc/systemd/system/knockd-rotate.service

[Unit]
Description=Rotate Knockd Ports
After=network.target

[Service]
ExecStart=/usr/local/bin/update_knockd_ports.sh
Enter fullscreen mode Exit fullscreen mode

Create the Timer File

/etc/systemd/system/knockd-rotate.timer

[Unit]
Description=Schedule Knockd Port Rotation

[Timer]
OnCalendar=*-*-* 00:00:00
Persistent=true

[Install]
WantedBy=timers.target
Enter fullscreen mode Exit fullscreen mode

3. Enabling the Timer

sudo systemctl daemon-reload
sudo systemctl enable --now knockd-rotate.timer
Enter fullscreen mode Exit fullscreen mode

Check if the timer is running:

systemctl list-timers --all
Enter fullscreen mode Exit fullscreen mode

4. Client-Side Implementation

To automate knocking from the client side, we can create a script, /usr/local/bin/knock_server.sh, that takes either lock or unlock as an argument to control SSH access.

Client Script: /usr/local/bin/knock_server.sh

#!/bin/bash

KNOCK_FILE="$HOME/knockd_ports"
KNOCK_SERVER="192.168.178.18"  # Change to your server's hostname or IP
SSH_PORT=22  # SSH port to check

# Read and convert the knock sequence (replace commas with spaces)
KNOCK_SEQUENCE=$(cat "$KNOCK_FILE" | tr ',' ' ')


# Determine the action
case "$1" in
    unlock)
        if is_ssh_open; then
            echo "SSH is already unlocked on $KNOCK_SERVER. No need to knock."
        else
            echo "Knocking to unlock on $KNOCK_SERVER with sequence: $KNOCK_SEQUENCE"
            knock -v "$KNOCK_SERVER" $KNOCK_SEQUENCE
        fi
        ;;
    lock)
        REVERSED_SEQUENCE=$(echo "$KNOCK_SEQUENCE" | awk '{for(i=NF; i>0; i--) printf $i" "; print ""}')
        echo "Knocking to lock on $KNOCK_SERVER with sequence: $REVERSED_SEQUENCE"
        knock -v "$KNOCK_SERVER" $REVERSED_SEQUENCE
        ;;
    *)
        echo "Error: Invalid state. Use 'unlock' or 'lock'."
        exit 1
        ;;
esac
Enter fullscreen mode Exit fullscreen mode

This script:

βœ… Reads the latest knock sequence from ~/knockd_ports (which the server updates)

βœ… Unlocks SSH access with the correct port knock sequence

βœ… Locks SSH access with the reverse sequence

Usage:

./knock_server.sh unlock  # Open SSH access  
./knock_server.sh lock    # Close SSH access  
Enter fullscreen mode Exit fullscreen mode

5. Enhancing Security with Additional Measures

While Port Knocking is a powerful security feature, it should be combined with other security measures for a truly hardened SSH setup:

  • SSH Key Authentication – Disable password-based logins and use SSH keys.
  • Fail2Ban – Prevent brute-force attacks by banning repeated failed login attempts.
  • Multi-Factor Authentication (MFA) – Add an extra layer of security for SSH logins.

Code and config files available here


Conclusion

By automating Port Knocking, you’ve created an ultra-secure SSH access system that dynamically changes its lock combination daily!

πŸš€ Next Steps: Experiment with different automation intervals and explore additional SSH hardening techniques!

Top comments (0)