# TIP: implement web knocking to protect your sshd service



## anomie (Sep 24, 2009)

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. 

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 (Sep 25, 2009)

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 (Oct 15, 2009)

Hi you should try fwknop with uses SPA and it's a lot more secure than portknock.

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


----------



## anomie (Oct 15, 2009)

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@ (Oct 15, 2009)

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 (Oct 15, 2009)

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 (Oct 25, 2009)

That sure is an interesting way of port knocking.


----------



## AR (Nov 13, 2009)

*small problem*

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 (Nov 13, 2009)

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.


----------

