This tutorial uses knockd and iptables on the server, as well as on the client if preferred.
The below commands are ran on the server, make sure to test before you implement so you can tweak it to your exact needs.
-Server Side-
add logfile option if you want,
Info about each,
Increase the seq_timeout appropriately, 15 may be a good number if you're going to knock on the ports manually.
In the “openSSH” section, we change the -A (append) option in the command to -I (insert). This command inserts a new firewall rule at the top of the firewall rule list. If you leave the -A option, it appends the firewall rule list and puts it at the bottom.
save n close
take note of your device name (ex: eth0)
Change, START_KNOCKD=0 to
also uncomment the KNOCKD_OPTS and enter your device name we got from the above ip addr command
save n close
start knockd service at reboot, this is important so you don't get locked out
-Client Side-
Now to test you can either use knock(comes with knockd, just install on client machine) or telnet to initiate the sequence manually. Access is only permitted FROM THE IP YOU KNOCKED FROM(not yelling xD). I couldn't get in from another box and that's cause the commands we use for open and close ssh tell the box to only allow connections from the IP we knocked from.(found that out the hard way..).
the -d is for delay, in my experience testing always use the delay to make sure each knock is heard. I wasn't able to open/close the port all the time unless I used the delay, which is scary.
to close port 22 just knock in the sequence you specified in the conf file
Simple port knocking daemons (such as knockd) are vulnerable because a sniffer may recover the port sequence that was used. A better solution is Cryptknock. Cryptknock's description says: "Cryptknock is an encrypted port knocking tool. Unlike other port knockers which use TCP ports or other protocol information to signal the knock, an encrypted string is used as the knock. This makes it extremely difficult for an eavesdropper to recover your knock (unlike other port knockers where tcpdump can be used to discover a port knock)."
That’s port knocking’s parlor trick. Treat it as a diversion and don’t do it in the real world. Or, if you must, don’t rely on it as your only form of security.
Hope this helps!
The below commands are ran on the server, make sure to test before you implement so you can tweak it to your exact needs.
-Server Side-
sudo apt-get update && apt-get upgrade
ufw disable
apt-get install iptables-persistent
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
- -A: Append the rule to the firewall rules table. That is, add it to the bottom.
- INPUT: This is a rule about incoming connections.
- -m conntrack: Firewall rules act upon network traffic (packets) that match criteria in the rule. The -m parameter causes iptables to use extra packet matching modules—in this case, the one called conntrack works with the network connection tracking capabilities of the kernel.
- –cstate ESTABLISHED,RELATED: This specifies the type of connection to which the rule will apply, namely ESTABLISHED and RELATED connections. An established connection is one that’s already in progress. A related connection is one that’s made due to an action from an established connection. Perhaps someone who is connected wants to download a file; that might happen over a new connection initiated by the host.
- -j ACCEPT: If the traffic matches the rule, jump to the ACCEPT target in the firewall. In other words, the traffic is accepted and allowed to pass through the firewall.
iptables -A INPUT -p tcp --dport 22 -j REJECT
- -A: Append the rule to the firewall rules table, i.e., add it to the bottom.
- INPUT: This rule is about incoming connections.
- -p tcp: This rule applies to traffic that uses the Transmission Control Protocol.
- –dport 22: This rule specifically applies to TCP traffic that targets port 22 (the SSH port).
- -j REJECT: If the traffic matches the rule, jump to the REJECT target in the firewall. So, if the traffic is rejected, it’s not permitted through the firewall.
sudo systemctl start netfilter-persistent
sudo netfilter-persistent save
sudo netfilter-persistent reload
sudo apt-get install knockd
sudo nano /etc/knockd.conf
add logfile option if you want,
logfile = /var/log/knockd.log
Info about each,
- sequence: The sequence of ports someone must access to open or close port 22. The default ports are 7000, 8000, and 9000 to open it, and 9000, 8000, and 7000 to close it. You can change these or add more ports to the list. For our purposes, we’ll stick with the defaults.
- seq_timeout: The time period within which someone has to access the ports to trigger it to open or close.
- command: The command sent to the iptables firewall when the open or close action is triggered. These commands either add a rule to the firewall (to open the port) or take it out (to close the port).
- tcpflags: The type of packet each port must receive in the secret sequence. A SYN (synchronize) packet is the first in a TCP connection request, called a three-way handshake.
Increase the seq_timeout appropriately, 15 may be a good number if you're going to knock on the ports manually.
In the “openSSH” section, we change the -A (append) option in the command to -I (insert). This command inserts a new firewall rule at the top of the firewall rule list. If you leave the -A option, it appends the firewall rule list and puts it at the bottom.
save n close
ip addr
take note of your device name (ex: eth0)
sudo nano /etc/default/knockd
Change, START_KNOCKD=0 to
START_KNOCKD=1
also uncomment the KNOCKD_OPTS and enter your device name we got from the above ip addr command
save n close
sudo systemctl start knockd
sudo systemctl enable knockd
start knockd service at reboot, this is important so you don't get locked out
-Client Side-
Now to test you can either use knock(comes with knockd, just install on client machine) or telnet to initiate the sequence manually. Access is only permitted FROM THE IP YOU KNOCKED FROM(not yelling xD). I couldn't get in from another box and that's cause the commands we use for open and close ssh tell the box to only allow connections from the IP we knocked from.(found that out the hard way..).
knock -v hostname port1 port2 port3 -d 500
the -d is for delay, in my experience testing always use the delay to make sure each knock is heard. I wasn't able to open/close the port all the time unless I used the delay, which is scary.
to close port 22 just knock in the sequence you specified in the conf file
Simple port knocking daemons (such as knockd) are vulnerable because a sniffer may recover the port sequence that was used. A better solution is Cryptknock. Cryptknock's description says: "Cryptknock is an encrypted port knocking tool. Unlike other port knockers which use TCP ports or other protocol information to signal the knock, an encrypted string is used as the knock. This makes it extremely difficult for an eavesdropper to recover your knock (unlike other port knockers where tcpdump can be used to discover a port knock)."
That’s port knocking’s parlor trick. Treat it as a diversion and don’t do it in the real world. Or, if you must, don’t rely on it as your only form of security.
Hope this helps!
Last edited: