Re: Factor

Factor: the language, the theory, and the practice.

Port Knocking

Thursday, February 17, 2011


As a followup to my last article, I wanted to show how to implement port knocking functionality in Factor. This was particularly interesting to me since I ran across a recent blog post about the “inventor” of port knocking.

"port knocking is a method of externally opening ports on a firewall by generating a connection attempt on a set of prespecified closed ports"

There are several types of port knocking, with variations using any combination of TCP, UDP, ICMP, or similar network protocols. For this implementation, we will choose to use TCP. In particular, using the open-port? word from our port-scan vocabulary. As a reminder, it looks like this:

USING: continuations io.encodings.binary io.sockets kernel ;

: open-port? ( host port -- ? )
    <inet> [ binary [ t ] with-client ] [ 2drop f ] recover ;

The idea is to knock on a sequence of ports, in order. In its simplest form, we attempt a connection to each port, ignoring whether it is open or closed (not relevant).

: knock-ports ( host ports -- )
    [ dupd open-port? drop ] each drop ;

You can imagine using it something like this (knocking on ports 10000, 10001, 10002 and then write a “Hello” message to port 12345):

IN: scratchpad "localhost"
               [ { 10000 10001 10002 } knock-ports ]
               [ 12345 <inet> ascii [ "Hello" print ] with-client ]

Some ways to improve this might be to allow “knock delay” between successive knocks, support UDP or ICMP knocks, or perhaps to encompass this functionality transparently into a reusable with-knocking-client word.