Fwknop, Debian and Ansible

OMG, so many attacks!
Every day is the same. I am drinking my cofee and looking at server logs. And every day I promise myself that I’ll do it something with. So let’s go. This day is the day.
Prerequsites
Server machine is a Debian-like system. I am using Debian Jessie bellow. Default user is a root.
Client machine is Ubuntu 16.04 LTS. Default user is non-root user.
I presume you are not totally noob and you know something about *nix.
I am not responsible for any damage by using this “tutorial”.
Fwknop
First of all a little warning. If don’t know what are you doing be very carefull because one mistake will cause your SSH is gone for good and there will no chance how to manage your server. Only if you have some KVM access or serial console.
Client machine
Installing fwknop client as non-root user and creating keys for our server:
sudo apt update && sudo apt install fwknop-client
fwknop -A tcp/22 -a xxx.xxx.xxx.xxx -D my.server.com --key-gen --use-hmac --save-rc-stanzaInstead of xxx.xxx.xxx.xxx put your ip adress. After -D parameter is destination server (for example my.server.com).
cat ~/.fwknoprcYou should see something like this:
[my.server.com]
ALLOW_IP xxx.xxx.xxx.xxx
ACCESS tcp/22
SPA_SERVER my.server.com
KEY_BASE64 HJ190sadflkI/auVhb7VxXAF0THSDwsKx0R+so4NLSDw=
HMAC_KEY_BASE64 FdRHaL/SDFSADF45SDA8FWSD4555/5ASDF75SDE4ASDFH4N8==
USE_HMAC YValues KEY_BASE64and HMAC_KEY_BASE64will be used later for server configuration.
Note: You can run only fwknop --key-gen but I prefer per-server configuration.
Server machine
There is a Debian Jessie. As root run:
apt-get update && apt-get install fwknop-server iptables-persistentEdit /etc/fwknop/access.confand replace __CHANGEME__string with values from ~/.fwknoprc
SOURCE ANY
REQUIRE_SOURCE_ADDRESS Y
KEY_BASE64 __CHANGEME__
HMAC_KEY_BASE64 __CHANGEME__Edit /etc/fwknop/fwknopd.conf and uncomment PCAP_INTFvariable and set your interface (probably eth0)
Important thing
There is no systemd service so you have to create it.
First, edit /etc/default/fwknop-server and set START_DAEMON="yes"
After, copy this file into /etc/systemd/system/fwknop-server.service
And enable service systemctl enable fwknop-server && systemctl start fwknop-server
Verify it’s runningservice fwknop-server status
fwknop-server.service - Firewall Knock Operator Daemon
Loaded: loaded (/etc/systemd/system/fwknop-server.service; enabled)
Active: active (running) since Wed 2017-07-26 19:59:18 CEST; 3h 14min ago
Process: 422 ExecStart=/usr/sbin/fwknopd (code=exited, status=0/SUCCESS)
Main PID: 516 (fwknopd)
CGroup: /system.slice/fwknop-server.service
└─516 /usr/sbin/fwknopdIf you see active (exited) it’s wrong and you have to fix it somehow.
Now it seems everything is ok. But it’s not because port 22 is still open.
From client machine knock the door:
fwknop -n my.server.com --verbose -R
And immediately after on server machine try fwknopd --fw-list You should see something like this
Listing rules in fwknopd iptables chains...Chain FWKNOP_INPUT (1 references)
num target prot opt source destination
1 ACCEPT tcp -- xxx.xxx.xxx.xxx 0.0.0.0/0 tcp dpt:22 /* _exp_1501103964 */
It means it works and fwknop daemon accept your single packet authorization (SPA) and port 22 is ready for incoming ssh connection.
From client try nmap sudo nmap -sS -p 22 my.server.com You should see
PORT STATE SERVICE
22/tcp open sshSSH port 22 is open. You need to close it.
WARNING!
If do the next step wrong, your server will be inaccesible and you lost chance to connect him.
Sometimes ssh terminal freeze. Be sure you have alternative connection to server like KVM or serial console.
As root on server machine create file fwknop-iptables.sh with:
#!/bin/bash
iptables -I INPUT 1 -i eth0 -p tcp — dport 22 -j DROP
iptables -I INPUT 1 -i eth0 -p tcp --dport 22 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
service fwknop-server restartDouble check that fkwnop daemon is running and accepting your SPA (single packet authorization). And you have alternative way to manage server.
Now run ./fwknop-iptables.sh
From client machine try
fwknop -n my.server.com && ssh username@my.server.comIf doesn’t work you probably screwed something up and this is a time to tear one’s hair :) Or you can try to fix it thru your KVM.
Ok. If you are in. You have to make your iptables rules permanent.
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6For sure view each rules files and check it.
Ansible, Git and others
Ok, it works! Congratulation. Your server is more secure.
But every tool which using ssh connection doesn’t work. Because ssh port 22 is closed.
Git
Git solution is pretty simple git config core.sshCommand ‘fwknop -n my.server.com && ssh'
Ansible
You need Ansible connection plugin that ensures port knocking before ssh connection.
I’ve inspired by https://github.com/berlic/ansibledaily and I’ve created my own version.
Download https://gist.github.com/wrongware/8b5a82c666a5992219f245d04a5e754f and configure your playbook ansible.cfg by adding connection_plugins = your_path_to_connection_plugins_folder
And that’s all! Congratulation!
Next challenge: Ansible role for all above.
