Home · Guides / 5 / Secure / 5.3

Guide 5.3

Obscure open ports with knockd

Port knocking keeps a daemon such as SSH closed until the client sends a short sequence of packets to unused ports. It is optional obscurity for a cloud host you still log into over the public internet. It is not a substitute for SSH keys, and it does not apply to the onion HTTP port (that should stay on 127.0.0.1).

Credit This page is an original Tor Onion write-up, based on How to obscure open ports with knockd by Jack Wallen on TechRepublic (11 November 2019). Wallen’s article is the source the original Tor Onion security notes linked.
Before you continue Keep two SSH sessions open (or console access) until you have tested the knock from a second machine. A bad firewall rule will lock you out. The knock sequence is visible on the network; treat it as a gate, not a secret equivalent to a private key.

Install knockd

  1. On Ubuntu or Debian:

    sudo apt update
    sudo apt install knockd iptables-persistent

    The client that will open the port also needs the knock command (same package on Debian/Ubuntu).

  2. Enable the daemon in /etc/default/knockd:

    START_KNOCKD=1

Configure a sequence

  1. Edit /etc/knockd.conf. Use your own ports — the numbers below are only an example, in the same style as Wallen’s walkthrough:

    [options]
        UseSyslog
    
    [openSSH]
        sequence    = 7000,8000,9000
        seq_timeout = 10
        command     = /sbin/iptables -I INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        tcpflags    = syn
    
    [closeSSH]
        sequence    = 9000,8000,7000
        seq_timeout = 10
        command     = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        tcpflags    = syn

    If SSH already listens on a non-default port, change --dport 22 to match. %IP% is replaced with the knocker’s address so you do not open SSH to the whole internet.

  2. Start knockd, then close the public SSH accept rule so only a successful knock inserts a temporary allow. Example with iptables (UFW users should put equivalent rules in UFW, or stop UFW from fighting iptables):

    sudo systemctl enable --now knockd
    sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    sudo iptables -A INPUT -p tcp --dport 22 -j DROP
    sudo netfilter-persistent save

    Do not run the DROP rule until knockd is running and you still have an established session (the ESTABLISHED rule keeps your current login).

Open and close from the client

  1. From another machine that has knock installed:

    knock -v SERVER_IP 7000 8000 9000
    ssh user@SERVER_IP
  2. When you are done, reverse the sequence so the allow rule is removed:

    knock -v SERVER_IP 9000 8000 7000
On an onion-only VPS If the host has no public web ports and you reach it only through a provider console or a VPN, you may not need knockd. It is for SSH that still faces the internet. HTTP for the .onion site should remain bound to localhost, not opened by knocking.