Originally Posted By: LittleBlueThing
I've never got round to port knocking my sshd - I guess it might be time...

Code:
#!/bin/bash
#################################################################################
#
# Disable external SSH by default; require a door-knocker on tcp/$KNOCK to gain access.
#
# The current time-limited ssh_knock list can be viewed at:  /proc/net/ipt_recent/ssh_knock
#
ipt=/sbin/iptables
KNOCK=1234      ## The door-knocker port: pick a nice randomish port number here
SSHLOG="-m limit --limit 30/minute --limit-burst 20 -j LOG --log-prefix"

## ssh_add:  move somebody temporarily to the ssh_knock list.
$ipt -N ssh_add
$ipt -A ssh_add -m recent --name ssh_knock --set $SSHLOG "ssh_add: "  ## add to list
$ipt -A ssh_add -j DROP  ## pretend we ignored it

## ssh_del:  remove an IP from the ssh_knock list.
$ipt -N ssh_del
$ipt -A ssh_del -m recent --name ssh_knock --rsource --remove $SSHLOG "ssh_del: "  ## remove from list
$ipt -A ssh_del -j RETURN  ## return to caller

## ssh_accept:  accept an incoming SSH connection.
$ipt -N ssh_accept
$ipt -A ssh_accept $SSHLOG "CONNECT(ssh): "
$ipt -A ssh_accept -m recent --name ssh_knock --rcheck -j ssh_del   ## remove from list
$ipt -A ssh_accept -j ACCEPT  ## allow this one connection attempt

## ssh_filter:  restrict ssh access to only those hosts on the ssh_knock list, one attempt, 15 seconds max:
$ipt -N ssh_filter
$ipt -A ssh_filter -m recent --name ssh_knock --rcheck --seconds 15 ! --hitcount 1 -j ssh_accept
$ipt -A ssh_filter -m recent --name ssh_knock --rcheck                             -j ssh_del
$ipt -A ssh_filter -j DROP  ## ignore it

$ipt -I INPUT -p tcp --syn --dport $KNOCK -j ssh_add
$ipt -I INPUT -p tcp --syn --dport 22     -j ssh_filter


Edited by mlord (04/12/2008 02:54)
Edit Reason: Fixed $ipt