PDA

View Full Version : TIP: implement web knocking to protect your sshd service


anomie
September 25th, 2009, 00:43
Contained in this post is an overview / downloadable .tgz file for a web knocking application I wrote called wwwknock. It is the product of discussion on this thread (http://forums.freebsd.org/showthread.php?t=7204).

I have thoroughly tested wwwknock, but there is always the possibility for insidious bugs, so if you're going to try it out be sure to do so in a low-risk test environment first! (I currently have deployed it on one production FreeBSD host and one production Fedora host; I'm continuing to keep an eye on it.)

Included in the .tgz are three important pieces of documentation (README, LICENSE, and INSTALL), the first of which I will post below.

wwwknock/README
wwwknock is an implementation of the concept of "web knocking".
The gist of it goes like this:

1. client connects to wwwknock web application with a web browser, a la:
http://host.here/knock

2. client is prompted for authentication credentials

3. upon entering said credentials correctly, an "allow" entry containing
client's IP address is added, allowing ssh access

-------

wwwknock requires a few basic pieces to work:

* apache web server (tested on v2.x and later)
* mod_python (tested on v3)
* tcp wrappers support compiled into sshd (very common on most OSes)

To confirm the tcp wrappers point, use:

# ldd `which sshd` | grep libwrap

If you don't see a result from that, you can't use wwwknock.

-------

Read the LICENSE before installing. For installation notes, see INSTALL.

If you try it out, feel free to leave comments / suggestions here. If I submit any bug fixes at a later date, I'll post a patch on this thread.

anomie
September 25th, 2009, 03:41
Sorry -- already a patch. If you happened to download wwwknock.tgz in the last couple hours (congrats, you're fast. :)), then I put together a quick patch. *

If you are downloading wwwknock_1.2.tgz then you're fine. The patch is not needed.

-------

* Patch is attached. To apply it just upload it to your host and then follow, for example:
# cd /usr/local/wwwknock
# patch < /home/someuser/patch.txt
Hmm... Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|--- process-knock-queue.sh 2009/09/25 01:14:36 1.1
|+++ process-knock-queue.sh 2009/09/25 01:03:01
--------------------------
Patching file process-knock-queue.sh using Plan A...
Hunk #1 succeeded at 175.
Hmm... Ignoring the trailing garbage.
done

Maurovale
October 15th, 2009, 16:52
Hi you should try fwknop with uses SPA and it's a lot more secure than portknock.

http://www.cipherdyne.org/fwknop/

anomie
October 15th, 2009, 17:55
Thanks for the tip. I agree that some of the features (e.g. asymmetric cipher support for the encrypted knock packet) may lead to better security, but they're also more work to implement, IMO.

One of the benefits of "wwwknock" (i.e. the "web knocking" utility I made for this thread) is that it can be accessed from anywhere, and all that is needed to open up sshd access is the right authentication credentials. I don't want to have to carry around a key.

Different utilities solve different problems. :) fwknop sounds pretty nice.

danger@
October 15th, 2009, 19:48
a kind of portknocking can be done very easily with pf:

Only open port 22 after X number of attempts to connect on port 1234:


# Table for allowed IPs - gets auto populated via portknocking
table <portknock_ssh> persist

block drop # block policy
# Allow everyone to hit 'any' on port '1234' - pf proxies tcp connection
# [if not using 'synproxy', the connection is never established to
# 'overload' the rule]
# 5 attempts in 15 seconds
pass in log quick proto tcp from any to any port {1234} synproxy state \
(max-src-conn-rate 5/15, overload <portknock_ssh>)

#Allow IPs that have been 'overload'ed into the portknock_ssh table
pass in log quick proto tcp from {<portknock_ssh>} to any port {ssh}


Then put a crontab on a per needed basis to expire all IPs in that table
that have not been referenced in 60 seconds (or use expiretable):

* * * * * /sbin/pfctl -vt portknock_ssh -T expire 60


All established sessions will be kept alive, all new sessions will need to
portknock after the IP is cleared from table

anomie
October 15th, 2009, 21:39
Cool, thanks for adding that info. It's crude, but probably very effective -- especially if you set max-src-conn-rate to something that an aggressive port scan would not trigger.

I'm using the "web knocking" utility that started this thread on both FBSD and Linux hosts, though, so it solves a slightly different problem. (Server side you need: Apache + mod_python; client side you need: a web browser.)

dennylin93
October 25th, 2009, 13:13
That sure is an interesting way of port knocking.

AR
November 13th, 2009, 04:47
This approach is great. That is, until the day you need to SSH into your remotely located server to troubleshoot and figure out why Apache decided to be down that day. :e

Really, it baffles why nobody has yet created an SSHD and SSH Client with a built-in, configurable portknocking option that does not depend on fragile bolted-on hacks.

anomie
November 13th, 2009, 05:17
Yes, that is a risk. More moving parts means more things that could fail.

I'm not sure I would call it "fragile" (Apache is very stable), but "bolted-on hack" is probably fair.