tumbler is a protocol that enables a client piece of software to
securely tell a server process on a remote machine to execute a
predetermined command. tumbler is similar to port knocking and is designed
so that a remote user can securly and steathily enable and disable
server processes, or open and close firewall holes on a computer
connected to the Internet.
It differs from port knocking in the following ways:
There are two implementations available: one is in Perl and provides
both a client (tumbler) and daemon (tumblerd); the other is in Java
and provides an API for generating knocks.
- Uses a single port: the tumblerd listens on a single UDP port for
a single UDP datagram containing the 'knock' on the door.
- Secure: the 'knock' is an SHA-256 hash the includes a shared
secret (similar to a password) and other information to prevent
spoofing and replay attacks.
- Generic: the 'knock' can cause any command to be executed and is
not limited to firewall reconfiguration.
[Project Page] [Download] [JavaDoc of TumblerKnock]
The Perl implementation is discussed below.
A secure knock can be set up that opens and closes a hole in the
firewall using iptables for an
SSH server. When the user knocks on the open door the firewall is
reconfigured to allow external connections on port 22, when the user
knocks on the close door then the port is closed.
First set up the appropriate tumbler.conf (by default
# Comments start with #
# The common section contains configuration options
# for the tumblerd daemon, here we set the UDP
# port to listen on to 8675 and a log file
port = 8675
log = /var/log/tumblerd.log
# Each door that a user can knock on is defined by
# a unique [door-X] section, the first section is
# for opening the SSH port, and second for closing
# Each door has a secret (i.e. the password for this
# door that is part of the knock) and a command to
# In the command it's possible to use the macros
# %IP% for the IP address of the person who knocked and
# %NAME% for the name of the door (in the first door
# here the name is open-ssh)
# %USER% for the user name of the user opening the door
# if present
secret = open-pAsSwOrD
jgc.secret = password
command = /usr/sbin/iptables -A INPUT -p tcp -s %IP% --dport 22 -j ACCEPT
secret = close-pAsSwOrD
command = /usr/sbin/iptables -D INPUT -p tcp -s %IP% --dport 22 -j ACCEPT
Then run tumblerd (or tumblerd --config /path/to/file if
the config file isn't in the standard place).
To knock on the open door the remote user does the following:
tumbler --open tumbler://host:8675/
where host is the host on which tumblerd is running. The user
will be prompted for the secret (in this case open-pAsSwOrD).
Alternatively it's possible to specify the secret on the command line as
tumbler --open tumbler://open-pAsSwOrD@host:8675/
To close the port again the user would use the close-ssh door's secret.
The tumbler protocol consists of a single message sent as a UDP datagram that
contains a string identifying the tumbler protocol version (currently 2) and
a hash value. For example,
The hash is a SHA 256
secure hash of the following three items:
- The current zulu date/time in minutes
- The IP address of the sender of the message
- The secret
- An optional (added in v2) user name
The inclusion of the IP address of the sender means that a sniffed
message cannot be reused from a different IP address, the inclusion of
the time means that messages automatically expire and the inclusion of
the secret means that an attacker needs to obtain the password.
Hence the security of tumbler is the same as password security: choose
a good secret for each door and change it often! The tumblerd
implementation prevents the reuse of a hash within the same minute so
that each command is only executed once.
If tumblerd determines that the hash is valid it executes the
associated command. There is no response positive or negative to the
sending of a message.
The simplest invocation of tumblerd is:
and it will read the configuration file /etc/tumblerd.conf.
tumblerd also has two command line options.
Once invoked tumblerd listens for messages until terminated.
- --port specifies the UDP port to listen on (this can also be specified in
the configuration file, see below).
- --config specifies the name of the configuration to read instead of
The configuration file (default /etc/tumblerd.conf) consists
of sections that start with a line of the form [section].
Currently there are only two valid section types [common]
(for options that affect the overall tumblerd daemon) and
[door-X] (which define a door with name X).
Blank lines and anything after a # are ignored in the configuration
Within each section configuration parameters in the form param =
val are accepted. Whitespace is stripped before and after the
parameter name and value.
Each section has certain permitted parameters:
- [common] section has:
- port Specifies the UDP port on which tumblerd should listen for knocks.
- log Specifies the name of a log file that tumblerd should write to
- [door-X] section has:
- secret This is the secret that is used to unlock the door.
Treat it like a password. If more than one door has the same secret
then a single knock will open multiple doors. You can have multiple
secrets per door.
- user.secret This is a secret for a specific user (for
example you can have the entry jgc.secret = password which
would indicate that jgc can open this door with the secret
password. You can have as many users and secrets per user as
- command The command to execute when the knock on this door
is successful. It may contain the macros %IP% (the IP
address of the knocking machine) and %NAME% (the name of this
door (e.g. if this section is [door-foo] then the
%NAME% is foo).
See the example above for a complete configuration file.
tumbler client documentation
The tumbler client has the following command line options:
- --open This is followed by a tumbler URL in the form
tumbler://user:secret@host:port/ and cause a knock on the
host on the port using the secret for
optional user user. If the secret is omitted then the
tumbler client will prompt for it. You can specify as many
--open options as you wish.
- --from This sets the from IP address used inside the hash
being passed. This is only necessary if the machine you are running
on is behind a NAT device which will change the UDP packet's source IP
address. In that case --from can be specified with the
external IP address on the NAT device.
tumbler was created by John
Graham-Cumming who wrote the Perl implementation. Marty Lamb wrote
the Java implementation.
Copyright (c) 2004 John Graham-Cumming.