Skip to main content

Install KnockD

Install KnockD with the following command:

sudo apt install -y knockd

Enable the service with this command:

sudo systemctl enable knockd

Enable running KnockD by editing the following file and setting START_KNOCKD=1:

sudo nano /etc/default/knockd

Your file should look something like this:

################################################
#
# knockd's default file, for generic sys config
#
################################################

# control if we start knockd at init or not
# 1 = start
# anything else = don't start
#
# PLEASE EDIT /etc/knockd.conf BEFORE ENABLING
START_KNOCKD=1

# command line options
#KNOCKD_OPTS="-i ens160"

If using this with UFW for the firewall, edit the service to make sure it can call UFW correctly to add/remove the appropriate rules:

sudo nano /lib/systemd/system/knockd.service

Add the ReadWritePaths, Restart, and RestartSec entries to make the file look similar to this:

[Unit]
Description=Port-Knock Daemon
After=network.target
Documentation=man:knockd(1)

[Service]
EnvironmentFile=-/etc/default/knockd
ExecStart=/usr/sbin/knockd $KNOCKD_OPTS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
SuccessExitStatus=0 2 15
ProtectSystem=full
ReadWritePaths=-/etc/ufw
CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN
Restart=on-failure
RestartSec=5s

To configure the knock sequences and ports to open once a knock sequence is completed edit the configuration file:

sudo nano /etc/knockd.conf

Here's an example configuration which only looks at the ens160 interface for 2 different sequences.

  • SSH
    • Opens port 22 for 30 seconds once sequence is completed within 15 seconds
  • Web
    • Opens ports 80 and 443 for 1 hour once sequence is completed within 5 seconds
[options]
        UseSyslog

[SSH]
        sequence       = 7000:tcp,8000:tcp,9000:tcp,10000:udp
        seq_timeout    = 15
        tcpflags       = syn
        start_command  = ufw insert 1 allow from %IP% to any port 22
        cmd_timeout    = 30
        stop_command   = ufw delete allow from %IP% to any port 22

[Web]
        sequence       = 10000:tcp,9000:tcp,8000:tcp,7000:udp
        seq_timeout    = 5
        tcpflags       = syn
        start_command  = ufw insert 1 allow from %IP% to any port 80,443
        cmd_timeout    = 3600
        stop_command   = ufw delete allow from %IP% to any port 80,443

An alternative method is to manually open and close ports based upon knock sequences, but this can leave ports open permanently if forgotten to be closed. This is done in the following configuration to manually open/close SSH port 22.

[options]
        UseSyslog
        Interface = ens160

[openSSH]
        sequence       = 7000:tcp,8000:tcp,9000:tcp,10000:udp
        seq_timeout    = 15
        tcpflags       = syn
        command        = ufw insert 1 allow from %IP% to any port 22

[closeSSH]
        sequence       = 10000:tcp,9000:tcp,8000:tcp,7000:udp
        seq_timeout    = 15
        tcpflags       = syn
        command        = ufw delete allow from %IP% to any port 22

Finally, start the service:

sudo systemctl start knockd