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:



$ 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 $ apt-get install libpam-google-authenticator oathtool$ google-authenticator....Do you want authentication tokens to be time-based (y/n) yYour new secret key is: AXOW3WXVNBL4ITF6Your verification code is 724344Your emergency scratch codes are:9415789241829299328154097646774620847928

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