Opening ports everywhere.
Port knocking: a stealthy system for network authentication across closed ports
Port Knocking has not been seen on TV
port knocking > documentation > knockclient

Documentation

Perl prototype: v0.30

  • pcaplib support added; daemon no longer requires firewall log file

2004-Nov-14 18:59 | ...more

new Net::Pcap support added to sniff packets directly ...more

The manpages for the Perl implementation of port knocking are available here.


NAME

knockclient - a port knocking client responsible for sending knocks to remote firewall where a knockdaemon is listening


SYNOPSIS

  # read everything from the configuration file
  > knockclient -conf knockclient.conf

  # overwrite some parameters
  > knockclient -conf knockclient.conf [-remote x.x.x.x] [-client x.x.x.x] [-port n] ... 

  # produce diagnostic messages
  > knockclient -debug

  # silent operation
  > knockclient -quiet

  # do everything, but do not send knocks
  > knockclient -test

  # brief usage
  > knockclient -h
 
  # full man page
  > knockclient -man


DESCRIPTION

This is a prototype port knocking client. It is not designed for a production environment (no formal testing of scalability or throughput has been done) but as a sandbox for playing with port knocking.

The client accepts input from a configuration file and/or from command-line parameters, which override any values in the configuration file. The client encodes the information, as formatted by the -knock option, possibly encrypts it, as directed by (-cipher -encrypt -key -iv), and maps it onto a supplied port span (-portspan). The knock is sent either over the network to -remote or written to a local log file specified by (-logfile -logtofile -fileformat).


OPTIONS


Configuration File

The client will try to read configuration files from these locations: ~/.knockclient.conf, BIN/knockclient.conf, BIN/etc/knockclient.conf, BIN/../etc/knockclient.conf, where BIN is the directory in which this script resides. The client reads only the first configuration file that it finds.

The configuration file is in an Apache-like format, as understood by the Config::General module. You must have this module installed. Any parameter in the configuration file may be specified on the command line. If the configuration file contains

  port = 22

then the same effect can be achieved using

  knockclient ... -port 22 ...

For boolean flags like -test and -logtofile, to negate the argument use -notest and -nologtofile. Any definitions in the configuration file are overridden by command-line parameters. Thus, if you have port = 22 and test = yes in the configuration file use -port 23 -notest to override this. Refer to the configuration file knockclient.conf for more information.


Operation

The client can be set to deliver the knocks to a remote host over the network, or alternatively write to a local (faked) firewall log file. The latter option facilitates debugging, since it allows you to run the knockserver and knockclient on the same machine without having to configure a firewall.

sending knocks over network

To have the knocks sent over the network, specify the remote IP

  remote    = x.x.x.x
  logtofile = no

You probably want to pause some reasonable amount between knocking on successive ports in a knock, to allow for network latency. Specify this, in seconds, using

  timeout = 0.5
sending knocks to local file

To generate a faked local firewall log file, specify

  logtofile = yes
  logfile   = /tmp/portknock.log

The format of the file is defined by the 'fileformat' parameter. For example, if you want to generate an iptables-style log file,

  fileformat = _DATE_ IN=eth0 SRC=_CLIENT_ DST=_REMOTE_ PROT=TCP SPT=_CLIENTPORT_ DPT=_REMOTEPORT_ SYN

You do not need to create a complete line, only one with the sufficient number of parameters required by knockdaemon.Fields formatted like _FIELD_ will be replaced with actual run-time values. The following fields can be parsed: DATE, CLIENT, REMOTE, CLIENTPORT and REMOTEPORT.

The knockdaemon must be configured to understand whatever log file format you wish to use.

test mode

To force the client to go through the motions of preparing a knock, but not actually carrying out the final step to send the knock over the network or write it to a file, use -test on the command line or add

  test = yes

to the configuration file.

quiet mode

To supress output while the script is running, use -quiet or

  quiet = yes
diagnostics

To include diagnostic output while the script is runing use -debug or debug = yes

To force a dump of internal parameters at the start of the script, use the flag twice

  knockclient ... -debug -debug


Knock Format

The knock encodes information such as the client IP, port and anything else that you would like to communicate to the knockdaemon. If you want the knockdaemon to adjust firewall rules, then probably one of the fields in the knock will be a port number.

The knock format is specified using

  knock = FIELD1,FIELD2,FIELD3,...

where FIELDn is any of IP, PORT, FLAGm, RAND, THISYEAR, THISDAY, THISHOUR, THISMINUTE, THISSECOND, CHECKSUM. The port is expected to be in the range 0-65,535 and all other fields need to be in the range 0-255 (if their value is greater, they are reported mod 256). The values for some fields, like IP, PORT and FLAGm are specified by you. Other fields like RAND, THISYEAR, THISDAY, THISHOUR, THISMINUTE, THISSECOND and CHECKSUM have their values generated automatically. FLAGm can be any of FLAG0, FLAG1, ... and corresponds to a generic field which you can stuff with a value 0-255. The parameters are described in detail below.

The knock is just a container for information. It is up to the knockdaemon to interpret the information and act accordingly. Here are some example knocks.

  client = 10.1.1.1
  port   = 22
  knock  = CLIENT,PORT  # 10 1 1 1 22

  flag0  = 15
  knock  = CLIENT,PORT,FLAG0  # 10 1 1 1 22 15

  knock  = CLIENT,PORT,FLAG0,CHECKSUM  # 10 1 1 1 22 15 50

  flag1  = 100
  knock  = CLIENT,FLAG0,PORT,FLAG1  # 10 1 1 1 15 22 100

  knock  = CHECKSUM,FLAG1,FLAG0,CLIENT  # 128 100 15 10 1 1 1

The knock is used to generate a list of values which are subsequently encrypted and encoded.

  • CLIENT

    If you want the knockdaemon to alter firewall rules, or to use the client's IP, then you should always embed the IP in the knock. Do not use the source IP as reported in the firewall log file - this can be easily spoofed. To set the value of the IP, use

      client = x.x.x.x
    
  • PORT

    This field is a special case of FLAGm, named to remind you that it corresponds to a port, rather than some arbitrary flag. Use this field if you want the daemon to open/close/modify rules for a particular port.

      port = n
    

    Any value in the range 0-65,535 may be assigned to the port variable.

  • FLAGm

    You can embed other values in the range 0-255 in the knock. Use FLAG0, FLAG1, ... for these.

      flag0 = 5
      flag1 = 25
    
  • RAND

    To embed a random number in the range 0-255, use this field in the KNOCK format. Since the number is random, you don't know its value ahead of time and therefore you don't specify the value it in the configuration file ;)

  • THISYEAR

    Today's year, mod 256.

  • THISDAY

    Today's day of the year, mod 256.

  • THISHOUR

    Current hour in the month (24*day+hour), mod 256.

  • THISMINUTE

    Current minute of the day (60*hour+minute), mod 256.

  • THISSECOND

    Seconds since epoch, mod 256.

  • CHECKSUM

    Sum of all other fields, mod 256. You can embed multiple CHECKSUMs in the knock, but they will evaluate to the same value since the sum is performed over all non-CHECKSUM fields.


Encryption

It is strongly suggested that you encrypt the knock. An encrypted knock will protect you from replay attacks, especially if you embed the client IP address in the knock.

To encrypt the knock set

  encrypt = yes
  key     = my_secret_phrase
  cipher  = Blowfish | IDEA | DES | ...

You'll need to install the Crypt::XXX module to use cipher = XXX. If you want to include an initialization vector (IV), use

  iv = yes

The length of the knock is a function of (a) number of fields in the knock, (b) whether encryption is turned on and (c) whether the initialization vector is used. If you don't use encryption, then the length of the knock is the same as the number of fields. For an encrypted knock, the length is

  knock length = 16 * iv_yes + 8 * [ int ( knock_fields/8 ) + 1 ]

where iv_yes = 1 if IV is used, and 0 otherwise. For example

  fields   no IV    IV

   1- 7      8      24
   8-15     16      32
  16-23     24      40
    ...    ...     ...


Port Mapping

The knock, encrypted or not, is mapped onto a span of ports. The span is specified by

  portspan = a-b,c,d-e,...

You will need to reserver 2*N ports for the span. Non-contiguous ranges are supported. The encrypted knock sequence (you are encrypting the knock, right?) is mapped onto span ports, therefore the larger the value of N the fewer coding symbols.

The two examples below illustrate the process of mapping the knock onto port values.


Example


256 port span

Suppose you set

  knock  = CLIENT,PORT,FLAG0,CHECKSUM
  client = 142.103.205.1
  port   = 22
  flag0  = 15

The the list of values used to generate the knock sequence would be

  142 103 205 1 22 15 233

where the last value is a checksum (mod 255) of the first 6 values. An encrypted knock (no IV) looks like this

  221 169 50 219 86 117 62 187

This encrypted list is mapped onto ports as specified by 'portspan'. If you set

  portspan = 745-1000

then the knock port values become

  966 914 795 964 831 862 807 932

These are the ports to which the client will attempt to connect.


32,768 port span

As an example, consider this 32,768 port span

  portspan = 1024-5000,6000-25000,26000-35789

Suppose you want to encode these values. This is the encrypted knock represented by integers in the range 0-255.

  216 58 209 32 67 110 108 193 168 89 231 114 112 202 231 129

First, the integers are expressed as binary and then padded to length 8 and concatenated,

  11011000 111010 11010001 100000 1000011 1101110 1101100 11000001 ...

  110110001110101101000110000010000111101110110110011000001 ...

The concatenated string is then split into groups of N digits

  110110000011101 011010001001000 000100001101101 110011011001100 ...

As a last step, these values are converted back to their decimal representation

  27677 13384 2157 26316 3394 26525 25825 19175 129

and mapped onto the port span (e.g. the 27,677th number in the span is 30,699).

  30699 15407 3181 29338 4418 29547 28847 21198 1153

Refer to IANA for port ranges and values (http://www.iana.org/assignments/port-numbers).


AUTHORS

Martin Krzywinski (martink@bcgsc.ca), Chris Rigby (kai@chaos.gen.nz), Thom Harrison (thom@cox.net)


SEE ALSO

knockdaemon, www.portknocking.org


HISTORY

  • 5 July 2004

    v0.24: Port range expanded to 0-65,535. mod 255 bug fixed (Thom Harrison, thom@cox.net). Port span range extended beyond 256 ports to 2^N, N < 16. Knocks are therefore shorter, since the number of coding symbols is increased.

  • 17 April 2004

    v0.23.1: Timeout once again works when writing to a local file. I thought this would make the behaviour more consistent.

  • 11 April 2004

    v0.22: Port span permits non-contiguous knock ports. IP is replaced by ``client'' in the configuration file to be more consistent with ``remote''. There is now no delay between knocks when the knock is written to a file. THISYEAR added.

  • 23 February 2004

    v0.21: Minor adjustments.

  • 20 February 2004

    v0.20: Parameters now in external configuration files. Added support for custom log file format and custom knock format.

  • 25 February 2003

    v0.10: Initial Perl prototype


COPYRIGHT

(c) 2002-2004 Martin Krzywinski

All rights reserved. This port knocking implementation is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

Refer to COPYING in this distribution for the complete GPL license

last updated 2003-Jul-26 00:27
Port Knocking (c) 2002-2014 Martin Krzywinski