Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,21 @@ can only be accessed after a successful knock sequence.
5. Server detects this and runs another iptables command to close port
22 to Client.

### EXAMPLE WITH ONE TIME PASSWORD AND SRC IP PROTECTION
Traditional knock approach does not protect the system from MITM attack. If the attacker sniffs the traffic and sends the same packet sequence to knockd, he gains access to the system. To avoid this we can change the port sequence after predefined number of seconds, pretty much like Google Authentcator does. However, even in this case, there is a chance, that the attacker will send the same knocks sequence soon after the valid user sent it and thus will gain access to the system. To completely avoid this MITM threat we have to make a random port sequence dependent not only on time of the packets sent, but also on source ip address of the sender. The example below shows the section of knockd config file, that provides exactly this scenario:

otp = AAgR%XXx30O$#, 45, 20000, on, tcp, udp, tcp

in this section

- AAgR%XXx30O$# is a seed which is used to generate one time port numbers sequence
- 45 is otp_change_time. The time in secs of how often we change our dynamic port numbers
- 20000 is a ports range starting point (unsigned short). This is a starting point of 256 numbers area, used for random port numbers generation. Usually is bigger then 1000. Each port number is generated by an algorythm in the range of 0-255 and then added to this number. So, in this examples a random port numbers within a range of 20000-20255 will be generated each time.
- on is ip_protection flag (boolean on/off). It specifies if we need additional ports generated based on mix of the key and the sender ip address to validate sender. Only in rear cases where the sender can't know for sure it's public IP address or if internet provider has several public IP addresses which are used on round-robin basis for providing internet access to its customers, this flag should be set to off. In these rear cases only time-based port generation might be used, which is less secure, but better than nothing.
- tcp, udp, tcp - protocol sequence. These are the protocols used for every generated port sequence. The number of protocol names defines the number of port numbers derived from the seed. If ip_protection flag is set to on, additional random port numbers are generated based on src ip of a sender. The number and types of these additional ports are the same as the primary ones. In this examples 3 additional port numbers will be generated resulting in total 6 port numbers seqence of these protocols: tcp, udp, tcp, tcp, udp, tcp

A simple bash script knockd.sh is included as a knocking client to illustrate the whole processs
To build knockd openssl should be installed. Usually "-lssl -lm" linker options is enough to build knockd

### KNOCKING CLIENTS

Expand Down
30 changes: 13 additions & 17 deletions knockd.conf
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
[options]
logfile = /var/log/knockd.log
LogFile = /var/log/knockd.log
[everithig]
# key = AAgR%XXx30O$#, otp change time = 45, generating port range starting from 20000, src ip address protection is on. The rest is protocol sequence
otp = AAgR%XXx30O$#, 45, 20000, on, tcp, tcp, tcp
seq_timeout = 60
command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

[openSSH]
sequence = 7000,8000,9000
seq_timeout = 5
command = /usr/sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn
[sesame]
sequence = 1911, 1152, 11531
seq_timeout = 5
tcpflags = syn
start_command = /sbin/iptables -I INPUT 1 -s %IP% -p tcp --match multiport --dports 1000,1006,22,6666,4422,4733 -j ACCEPT
cmd_timeout = 600
stop_command = /sbin/iptables -D INPUT -s %IP% -p tcp --match multiport --dports 1000,1006,22,6666,4422,4733 -j ACCEPT

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

[openHTTPS]
sequence = 12345,54321,24680,13579
seq_timeout = 5
command = /usr/local/sbin/knock_add -i -c INPUT -p tcp -d 443 -f %IP%
tcpflags = syn

52 changes: 52 additions & 0 deletions knockd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/bin/bash

# This is sh script for otp section in knocks.conf like this:
# otp = AAgR%XXx30O$#, 45, 20000, on, tcp, tcp, tcp
function hash_hmac {
digest="$1"
data="$2"
key="$3"
shift 3

a=`echo -n "$data" | openssl dgst "-$digest" -hmac "$key" "$@"`
echo ${a: -40:40}
}


tme=`date '+%s'`
key="AAgR%XXx30O$#"
tm="45"
pr="20000"
host="knockd.example.com"

otp=$((tme/tm))

myip=`dig +short myip.opendns.com @resolver1.opendns.com`

res=$(hash_hmac "sha1" $otp $key)

echo tm = \'$otp\' key = \'$key\' hmac_sha1 = \'$res\'

port1=$(($((16#${res: 0:2}))+$pr))
port2=$(($((16#${res: 2:2}))+$pr))
port3=$(($((16#${res: 4:2}))+$pr))

nkey=$key$myip

res=$(hash_hmac "sha1" $otp $nkey)

echo key = \'$nkey\' hmac_sha1 = \'$res\'

port4=$(($((16#${res: 0:2}))+$pr))
port5=$(($((16#${res: 2:2}))+$pr))
port6=$(($((16#${res: 4:2}))+$pr))

echo port = $port1 or $port2 or $port3 or $port4 or $port5 or $port6


for p in $port1 $port2 $port3 $port4 $port5 $port6; do
nmap -Pn --max-retries 0 -p $p $host >>/dev/null;
done



Loading