Port-knocking client with multiple hosts support go cli golang client tools firewall port-knocker port-knocking portknocker portknocking Updated Sep 20, 2019. Port knocking is sending connection attempts to a device in a specific pattern to unlock a specific service. An example would be to send 3 UDP connection attempts to a Mikrotik router all on different port numbers in a specific order. It will then add your IP address to a specific address list so you can winbox in. Port:protocol Port(s) to knock on, protocol (tcp, udp) is optional. Optional arguments: -h, -help show this help message and exit -t TIMEOUT, -timeout TIMEOUT How many milliseconds to wait on hanging connection.
- Port Knock Client Download
- Port Knock Client Definition
- Port Knock Client Meaning
- Port-knock Client Debian
Generally, it is a good idea to have fewer ports open on your server. When you have ports open, you leak information about what services are running on your server, and any misconfigured or vulnerable programs listening on those ports can become targets.
Normally, a server must have open ports in order to do its job, at least when you don’t know in advance which addresses it needs to serve. Port knocking is a technique that allows you to have zero open ports on a server, while still allowing connections from trusted clients.
Port Knocking
In the simplest case, port knocking does what it sounds like: You disallow all connections to all ports on your server, using your favorite firewall. Then, you configure a simple daemon to watch for a particular sequence of “knocks”: packets sent to closed ports on the server. When it sees the appropriate sequence of knocks from some IP address, it tells your firewall to (temporarily) allow connections from that address, on whatever port your service is listening on (typically port 22, for ssh). This is like if your speakeasy had a “secret knock” that must be performed before the bouncer opens the door. Trusted clients know the secret knock, and so when connecting to your server they use the knock sequence before attempting to connect.
Avoiding Replays
As with real-life secret knocks, though, this technique is susceptible to replay attacks: if someone is able to hear the secret knock, they can repeat it easily. A person snooping on your traffic may be able to see that you sent a suspicious sequence of packets before successfully connecting, and then use the same sequence themselves.
Some knocking daemons, such as knockd, can mitigate this with a feature that lets you use “one time sequences”: A list of sequences that must be used in the appropriate order, and are then discarded. This works well when only one client needs to connect to the server: That client can keep track of the same list of knock sequences, and discard ones that it has used.
If multiple clients need to connect to the server, each client can get its own list.
But a problem with this approach is that one must generate sequence lists long enough to ensure that the client will be able to connect as many times as they wish. In principle this may not be too difficult; if you plan to connect fifty times a day for a hundred years, this amounts to less than 100 MiB of configuration. In practice I’m not entirely sure how knockd would deal with such a large list.
Using TOTP
An alternative would be to use a scheme like the TOTP system you (hopefully) use for two-factor authentication on your phone. In this scheme, the server and clients use the current time to agree on a knock sequence. The server gets a secret that’s shared with the client, and whenever the server sees a knock sequence corresponding to the current OTP value, it opens the port (and discards that value).
There are at least two implementations of this idea: one by Akshay Shah and Swapnil Kumbhar, and another by Javier Junquera Sánchez. Neither of these solutions looks very polished, but they exist as proofs-of-concept.
I haven’t looked hard at the code for either of these implementations, so I can’t recommend them. There are various pitfalls involved here; the most important is that the TOTP-generated sequence must be discarded after use, to avoid fast replay attacks. And one may want to use different TOTP keys for each client or user (to ensure that multiple clients aren’t racing for the same code if they need to connect at similar times). I suspect that the above implementations don’t deal nicely with at least one of these issues, though again I haven’t looked at them in detail.
Shah and Kumbhar’s solution above uses knockd’s one time sequences feature, but is forced to restart knockd to reload its configuration whenever the keys change. Ideally it would be great if knockd incorporated a TOTP-based configuration option, or had some other method of avoiding replays than long lists of knock sequences.
Synopsis
knockd [options]
Description
knockd is a port-knock server. It listens to all traffic on an ethernet (or PPP) interface, looking for special 'knock' sequences of port-hits. A client makes these port-hits by sending a TCP (or UDP) packet to a port on the server. This port need not be open -- since knockd listens at the link-layer level, it sees all traffic even if it's destined for a closed port. When the server detects a specific sequence of port-hits, it runs a command defined in its configuration file. This can be used to open up holes in a firewall for quick access.
Version
The current version of knockd is 0.8, released on 2021-04-24.
Download
- Source Tarball
SHA256: 698d8c965624ea2ecb1e3df4524ed05afe387f6d20ded1e8a231209ad48169c7
Other Downloads
Port Knock Client Download
Options
-i, --interface <int>Specify an interface to listen on. The default is eth0.-d, --daemon
Become a daemon. This is usually desired for normal server-like operation.-c, --config <file>
Specify an alternate location for the config file. Default is /etc/knockd.conf.-D, --debug
Ouput debugging messages.-l, --lookup
Lookup DNS names for log entries. This may be a security risk! See section SECURITY NOTES.-v, --verbose
Output verbose status messages.-V, --version
Display the version.
Port Knock Client Definition
-h, --helpSyntax help.
Configuration
knockd reads all knock/event sets from a configuration file. Each knock/event begins with a title marker, in the form [name], where name is the name of the event that will appear in the log. A special marker, [options], is used to define global options.
Example #1:
This example uses two knocks. The first will allow the knocker to access port 22 (SSH), and the second will close the port when the knocker is complete. As you can see, this could be useful if you run a very restrictive (DENY policy) firewall and would like to access it discreetly.
Example #2:
This example uses a single knock to control access to port 22 (SSH). After receiving a successful knock, the daemon will run the start_command, wait for the time specified in cmd_timeout, then execute the stop_command. This is useful to automatically close the door behind a knocker. The knock sequence uses both UDP and TCP ports.
Example #3:
This example doesn't use a single, fixed knock sequence to trigger an event, but a set of sequences taken from a sequence file (one-time sequences), specified by one_time_sequences directive. After each successful knock, the used sequence will be invalidated and the next sequence from the sequence file has to be used for a successful knock. This prevents an attacker from doing a replay attack after having discovered a sequence (eg, while sniffing the network).
Configuration: Global Directives
UseSyslogLog action messages through syslog(). This will insert log entries into your /var/log/messages or equivalent.LogFile = /path/to/file
Log actions directly to a file, usually /var/log/knockd.log.PidFile = /path/to/file
Pidfile to use when in daemon mode, default: /var/run/knockd.pid.Interface = <interface_name>
Network interface to listen on.
Configuration: Knock/Event Directives
Sequence = <port1>[:<tcp|udp>][,<port2>[:<tcp|udp>] ...]Specify the sequence of ports in the special knock. If a wrong port with the same flags is received, the knock is discarded. Optionally, you can define the protocol to be used on a per-port basis (default is TCP).One_Time_Sequences = /path/to/one_time_sequences_file
File containing the one time sequences to be used. Instead of using a fixed sequence, knockd will read the sequence to be used from that file. After each successful knock attempt this sequence will be disabled by writing a '#' character at the first position of th eline containing the used sequence. That used sequence will then be replaced by the next valid sequence from the file.
Because the first character is replaced by a '#', it is recommended that you leave a space at the beginning of each line. Otherwise the first digit in your knock sequence will be overwritten with a '#' after it has been used.
Each line in the one time sequences file contains exactly one sequence and has the same format as the one for the Sequences directive. Lines beginning with a '#' character will be ignored.
Note: Do not edit the file while knockd is running!
Seq_Timeout = <timeout>Time to wait for a sequence to complete in seconds. If the time elapses before the knock is complete, it is discarded.
TCPFlags = fin|syn|rst|psh|ack|urgPort Knock Client Meaning
Only pay attention to packets that have this flag set. When using TCP flags, knockd will IGNORE tcp packets that don't match the flags. This is different than the normal behavior, where an incorrect packet would invalidate the entire knock, forcing the client to start over. Using 'TCPFlags = syn' is useful if you are testing over an SSH connection, as the SSH traffic will usually interfere with (and thus invalidate) the knock.
Separate multiple flags with commas (eg, 'TCPFlags = syn,ack,urg'). Flags can be explicitly excluded by a '!' (eg, TCPFlags = syn,!ack).
Start_Command = <command>Specify the command to be executed when a client makes the correct port-knock. All instances of %IP% will be replaced with the knocker's IP address. The Command directive is an alias for Start_Command.
Port-knock Client Debian
Cmd_Timeout = <timeout>Time to wait between Start_Command and Stop_Command. This directive is optional, only required if Stop_Command is used.Stop_Command = <command>
Specify the command to be executed when Cmd_Timeout seconds have passed since Start_Command has been executed. All instances of %IP% will be replaced with the knocker's IP address. This directive is optional.
ChangeLog
Security Notes
Using the -l or --lookup commandline option to resolve DNS names for log entries may be a security risk! An attacker may find out the first port of a sequence if he can monitor the DNS traffic of the host running knockd. Also, a host supposed to be stealthy (eg, dropping packets to closed TCP ports instead of replying with an ACK+RST packet) may give itself away by resolving a DNS name if an attacker manages to hit the first (unknown) port of a sequence.
See Also
knock is the accompanying port-knock client, though telnet or netcat could be used for simple TCP knocks instead. For more advanced knocks, see sendip.
Author
Judd Vinet <jvinet at zeroflux dot org>