Discreet access with knockd
The problem with open ports
It is a well-known problem: If you are opening up a way in in order to reach
your target, you are also opening a gate for evil-minded people, because
anything that can be used may also be misused. It is therefore necessary to
secure any means of access in a way that makes any misuse more difficult.
This is usually accomplished by some sort of login mechanism that grants access
to authorized people only and also secures the connection against
eavesdropping. However, these access controls usually face a constant onslaught
of intrusion attempts from various directions so it is merely a question of
when one of them is finally successful. This makes it necessary to protect
the ports themselves against unauthorized access.
When you are checking on
how to properly protect tricky
services, you can make it signifcantly more difficult for an attacker to
cause mischief – but the ports are usually still publicly accessible. Here the
attacked ports would have to be shielded against unauthorized access.
Closed – and locked out...
Blocking a port is frequently way easier said than done. This can be done very
easily in case of ports that are meant to be accesses from just one particular
IP address, but that usually won't do. It is rather the norm to access the 'Net
via one of the numerous ISPs, and if a leased line is out of the question, you
usually get a new IP address assigned every time that you are connecting so
that you would have to exempt an entire subnet assigned to said ISP, because
you could be connecting from any IP address therein.
This becomes even worse when you need to connect from different places via
different ISPs, because that mandates opening even more network segments, that
is, at least one for every new provider – which again potentiates the problem.
From any addresses thus unblocked attacks could still be started that you
couldn't fend off this way. In theory you would need to keep the port
completely shut in order to keep out any attackers – but you would also lock
yourself out as well, which in turn makes everything
moot once again.
Please knock and enter!
In order to circumvent this kind of problem, some sort of mechanism is required
that tells the firewall to temporarily open a passage so that you may gain
access while keeping everyone else out. This causes any attacker who is
attempting to brute-force his way in to bounce off of the firewall whereas
someone who is polite enough is allowed to pass.
This way all access paths can be generally blocked, the only difference being
that a secret signal has been set that causes the firewall to open an access
for your point of origin so that you may connect. Exactly this signal is what
the program knockd is looking for.
The best part of this: For knockd to work you don't
even have to unblock any ports necessary for knocking.
knockd detects any activity one
layer below the firewall
and is therefore able to react even if the firewall is closed!
Preparations
Inn order to enable the server to react properly on your knocking it is necessary to install the program in the first place.
- Log in to your server as root.
- Launch YaST.
- Invoke the module Software Management.
- Enter the term knockd into the searchfield and press RETURN.
- Select the displayed package knockd.
- Click on Ok.
YaST is now going to install the selected package, and once that is done you may configure this gate guard appropriately. After this you need to provide a means on your local system to tell your server the set signal. For this you need to install a particular program that deals with this:
- Log in as root.
- Launch YaST.
- Invoke the module Software Management.
- Enter the term knock into the searchfield and press RETURN.
- Select the package knock.
- Click on Ok.
This is going to install the counterpart of knockd on your local box which enables you to send your server the set signal.
to the topConfiguration
- Switch (as root) to the directory /etc.
- Load the file knockd.conf into your editor.
- Edit the file appropriately.
It's easy to tell knockd what signals it is supposed to look out for and how it is supposed to react on it. However, some settings are necessary.
Please note that the values given have to be adjusted to the situation on your
erver. You need e. g. to replace the identifier of the network interface by the
one representing the network card that points to the 'Net. The ports required
for the knock sequence should best be changed and adjusted to your liking
(other and maybe more ports that have to be contacted in order to open the port
in question).
Furthermore, never specify ports that have been assigned, because this is going
to confuse knockd, and make sure to specify
different port sequences for opening and closing the port in order to avoid
any undesirable side effects!
Case 1: Different port sequences for opening and closing ports
Case 2: One sequence for opening and timeout for closing ports
Both cases have in common that knockd listens for
activity on arbitrary ports and, if necessary, dispatches a commmand to the
firewall that opens up the desired port. The only difference is the method of
operation.
In the firs case it is necessary to specify the port sequence 5000, 6000, and
7000 – in exactly this order to open access to port 22 (Secure Shell). The call
to iptables is set up in such a fashion that only
the IP address from which the knocks are originating is actually unblocked
while it stays closed for any other address. The only catch: When you forget to
close said port, anyone who subsequently gets this IP address assigned is able
to detect the still open port 22 and, given sufficient malevolence, try to
launch an attack.
In order to avoid this problem, variant 2 is recommended. Here it is only
necessary, linke in exmple 1, to specify to knock the sequence 5000, 6000, and
7000 – however, the protocol necessary must be taken into account (in this
example they are 5000 UDP, 6000 TCP and at last 7000 UDP) – to open port 22.
Here the port is opened for 20 seconds before it is automatically closed by
knockd. When the port is closed after the timeout
any active SSH session remains unaffected.
In order to trigger the knock sequence you just have to invoke
knock on your local box and specify the required
port sequence. In the first example the call has to be
knock <server> 5000 6000 7000.
Once you have issued the command you may connect normally to your server and
start working. However, do not forget to close the port with
knock <server> 7500 6500 5500 after you are
done!
In the second example you only have to specify the sequence for opening the
port (that is, 5000:udp 6000:tcp 7000:udp); after the timeout expires it is
automatically closed so one cannot accidentally forget to close it.
When you want to make things easier for you you can define an alias in your
shell that invokes knock with all necessary
parameters. This is especially recommended in conjunction with entirely random
port numbers as well as longer port sequences in order to avoid becoming
confused.
All ports of a particular sequence must be entered in a certain time frame (seq_timeout) to be accepted, because otherwise the started sequence is canceled and has to be started all over again. The timeout must therefore be sufficiently large so that one can knock at all desired ports even during times of high net load, but still small enogh so that random scans aren't accidentally recognized as a valid sequence that opens the protected port. Ten seconds have proven to be entirely sufficient for practical purposes. Any changes are only necessary in case very high load or interferences on the link.
Finally you merely have to activate knockd. You only have to execute the two commands systemctl enable knockd.service and systemctl start knockd.service. This immediately starts knockd, and furthermore it is integrated into the boot sequence so it gets started with each boot of the server.
to the topThwarting eavesdroppers
For the particularly paranoid as well as those who are affected by an overwhelming number of attacks there is a variant that is also capabble of thwarting electronic eavesdropping. Even if an attacker is attemting to figure out the knock sequence by logging the data stream, the information gained is nonetheless of no use for him, because next time an entirely different sequence must be chosen. For this it is necessary to put the port sequences into a file that is to be made known to knockd and from which the program can retrieve the current sequence. This file is preferrably present on your local box as well or as a hardcopy so that you don't have to guess what you have to enter now...
Case 3: List with use-once port sequences to open, timeout to close ports
Where an attacker could determine the port sequence for opening and, if
applicable, for closing the port by eavesdropping, this doesn't work any more
in this case when sufficiently disjunctive port sequences have been defined
that specify seemingly random ports (that is, entirely random jump directions
and ranges so that an attacker cannot anticipate the still active sequences,
e. g. by sustituting the starting port and applying the same offsets).
This is by far the most secure, but at the same time the most elaborate, method
to keep out any attackers. Depending on the threat level it may very well be
worth configuring knockd this way.
Selflockout – now what?
You are going to experience this nuisance sooner or later when applying
blacklists to thwart any attackers. The moment one gets locked out by one's own
security measures, one would deplore the fact that no other access path has
been implemented to gain access to the server.
In case you don't want to establish an IPsec tunnel to serve as a detour that
allows connecting to the server via Telnet if necessary,
knockd can be creatively misused for defining an
exception when required and therefore still be granted access even if you have
locked yourself out. It is necessary to define one more rule chain in
conjunction to the other chains provided by
the topic firewall that allows
knnockd to set its exception. The block should look
like follows (in case you want to grant precedence to
SSH_BAN over SSH_KNOCKD
you have to swap the calls to both chains):
Appropriately modifying case 2 yields the following configuration:
This way you may still connect normally, but in case something has gone wrong and you get stuck in your own security scheme you may still gain access to your server simply by knocking – while those who don't know the port sequence are still kept out.
to the top