Fwknop, Debian and Ansible

Patrik Šíma
Jul 27, 2017 · 4 min read
Credit: Pixabay

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-stanza

Instead of xxx.xxx.xxx.xxx put your ip adress. After -D parameter is destination server (for example my.server.com).

cat ~/.fwknoprc

You 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 Y

Values 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-persistent

Edit /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/fwknopd

If 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 ssh

SSH 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 restart

Double 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.com

If 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.v6

For 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.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade