Port knocking is a technique to selectively allow for connections by sending a semi-secret sequence of packets, often called a “knocking” sequence.
On a *nix system, nc
(netcat) is useful for port knocking. Individual knocks can be sent by nc -w 1 -z host port
; this will send a TCP connection attempt to the specified host and port, with a timeout of 1 second, and without sending any data.
To use nc
to send a TCP knock sequence of ports 10000, 2345, 3456, 1234 to 192.0.2.234, you might do something like
nc -w 1 -z 192.0.2.234 10000 nc -w 1 -z 192.0.2.234 2345 nc -w 1 -z 192.0.2.234 3456 nc -w 1 -z 192.0.2.234 1234
Doing the same thing in Microsoft’s Powershell is rather more verbose:
Start-Job -ScriptBlock {Test-NetConnection -ComputerName "192.0.2.234" -Port 10000 -InformationLevel Quiet} | Wait-Job -Timeout 1 Start-Job -ScriptBlock {Test-NetConnection -ComputerName "192.0.2.234" -Port 2345 -InformationLevel Quiet} | Wait-Job -Timeout 1 Start-Job -ScriptBlock {Test-NetConnection -ComputerName "192.0.2.234" -Port 3456 -InformationLevel Quiet} | Wait-Job -Timeout 1 Start-Job -ScriptBlock {Test-NetConnection -ComputerName "192.0.2.234" -Port 1234 -InformationLevel Quiet} | Wait-Job -Timeout 1
A simple bash shell script to perform port knocking and then connect and hand a connected pipe to the calling process might look something like:
#!/bin/bash host=$1 port=$2 nport=$3 while test -n "$nport" do nc -w 1 -z $host $port shift port=$2 nport=$3 done test "$port" != "0" && exec nc $host $port
The above script takes the host name or IP address of the remote host as the first parameter, followed by a series of TCP port numbers; the last port number is the final connection port. This can be used for example with OpenSSH’s ProxyCommand
directive:
$ cat .ssh/config Host 192.0.2.234 ProxyCommand ~/.local/bin/portknock-connect %h 10000 2345 3456 1234 %p $