Knockd with Temporary Ports

Kaveh Mousavi Zamani
3 min readDec 21, 2016

--

When it comes to ssh and server security, whatever you do, you should still be worried of not doing enough.

First, you need to search and follow the best practice to config your ssh server. You will do changes like key-only login, no root login,.. . List is long and you can google for “best practice ssh config”

Second, go and find a 2FA solution to add to your ssh login. There are 3rd parties like Duo Security or free tools like “libpam-google-authenticator”. Pick one and don’t ignore it. Like every other service on the web, no secure key alone is trustable for login to your valuable server.

If you did those previous steps then think about closing that damn 22 port altogether. There you need a tool like knockd.

knockd is a simple tool that you can use to knock on your server door with a defined pattern. It will open port 22 for your current IP for few seconds just to login.

To see how to set it up look at the following link because I wont be able to explain it better:

https://www.digitalocean.com/community/tutorials/how-to-use-port-knocking-to-hide-your-ssh-daemon-from-attackers-on-ubuntu

But then comes a time that you think even that knock setup is not good enough. You want to have unpredictable patterns for knocking but still something easy to manage and share in the team.

For that you can mix the knock idea with 2FA. If you look at your google or github 2fa on your phone (I hope you had set them up already!) you will see a set of number.

You can use those numbers as your temporary ports for knockd.

Setup is simple.

You need a code and a tool to generate your numbers. For example if you have GNU/Linux somewhere:

$ apt-get install libpam-google-authenticator oathtool
$ google-authenticator
....
Do you want authentication tokens to be time-based (y/n) y
https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/root@ferengi%3Fsecret%3DAXOW3WXVNBL4ITF6
Your new secret key is: AXOW3WXVNBL4ITF6
Your verification code is 724344
Your emergency scratch codes are:
94157892
41829299
32815409
76467746
20847928

From that step what you need is that “AXOW3WXVNBL4ITF6” and if you like scan the QR in your 2FA app (Authy or Google Authenticator).

Now try this:

$ CODE=AXOW3WXVNBL4ITF6
$ oathtool --base32 --totp "$CODE" -d 8|sed -e 's/\(....\)\(....\)/\1,\2/g'
6049,3131

You have two usable ports that will change every 30 seconds.

From here you just need to setup your knockd in a way that its config changes every 30 seconds to reflect the new codes

#!/bin/bash
write_knockd_conf() {
cat <<EOF > /etc/knockd.conf
[options]
UseSyslog
[SSH]
sequence = $1
tcpflags = syn
seq_timeout = 15
start_command = /sbin/iptables -I INPUT 1 -s %IP% -p tcp --dport 22 -j ACCEPT
cmd_timeout = 10
stop_command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
EOF
}
while true
do
EPOCH=$(date +%s)
if [ $(($EPOCH % 30)) == "0" ]
then
echo $EPOCH
CODE=$(cat secret.code)
SEQ=$(oathtool --base32 --totp "$CODE" -d 8|sed -e 's/\(....\)\(....\)/\1,\2/g')
write_knockd_conf $SEQ
service knockd reload
fi
sleep 1
done

Now to open the port just write an script to generate those numbers for you and use knockd client to knock on your server door.

$ knockd -v example.org  $(oathtool --base32 --totp "$CODE" -d 8|sed -e 's/\(....\)\(....\)/\1 \2/g')

That is the concept. You still need to do a much better job to make sure script is correctly setup and monitored in your server.

Also if you need to have more than two ports for your sequence you can generate more codes and use them together to setup your knockd.

Stay safe

--

--