Port Knocking

Protect your Network with Port Knocking

Knock It Off

At this point, I'll mention that we deployed port knocking across three bastion hosts . In other words, we used servers, sitting mainly on the network perimeter (but not always), which were hardened to the extent that they could withstand most types of attacks and still hold the fort. These servers each had access to a particular segment of the network that could reach the rest of the network at large, but in between segments were several addition layers of security, in case one were to suffer a compromise.

Therefore even if one server, and therefore a network segment, was breached, in theory we would know about it before other parts of the network could be affected. We used three servers in this case for redundancy. If any of the servers were to fail for any of a number of reasons (e.g., hardware failure, connectivity, or attacks), we still hoped to have remote access.

Knocking On

TCP Wrappers mainly pays attention to the /etc/hosts.allow file these days because its counterpart, /etc/hosts.deny, essentially just says, "no one is allowed in"; that is, it uses a sensible and pragmatic default deny policy. You can either let IP addresses or DNS names gain access (please see the article that discusses TCP Wrappers [1] in greater detail).

In this case, I explicitly allow access by adding IP addresses in the /etc/hosts.allow file, prepended by the service I want to allow them to use. Conversely, I simply remove them from that file to ban access.

If the key tcpd files don't exist, then you can create them with the permissions shown in Listing 1. By way of comparison, the file /etc/hosts.deny might look like Listing 2 by default, depending on the version (just copy these lines in the ALL:ALL section if the file doesn't exist), and its close relation, /etc/hosts.allow, looks something like Listing 3 by default (simply copy in the SSHD: line if your file doesn't exist).

Listing 1

Permissions for Key tcpd Files

-rw-r--r-- 1 root root 351 Nov  3  2012 /etc/hosts.deny
-rw-r--r-- 1 root root 348 Jun 17 08:23 /etc/hosts.allow

Listing 2


# hosts.deny    This file describes the names of the
#       hosts which are *not* allowed to use the local
#       INET services, as decided by the '/usr/sbin/
#       tcpd' server.
# The portmap line is redundant, but it is left to
# remind you that the new secure portmap uses hosts.deny
# and hosts.allow.  In particular you should know that
# NFS uses portmap!

Listing 3


# hosts.allow   This file describes the names of the hosts
#       which are allowed to use the local INET services,
#       as decided by the '/usr/sbin/tcpd' server.

I should mention that I've been caught out in the past when adding TCP Wrappers to a server already running other services (back when inetd controlled many of the available services on a server) without realizing that ALL:ALL within /etc/hosts.deny had locked a service down. If my memory serves me, it was access to a POP3 mail server. If that trips you up, then change ALL:ALL to something like SSHD:ALL so it only affects SSH – at least temporarily while you're finding your way.

Someone's at the Door

Now you can consider how to trigger SSH access by opening its port, once port knocking has approved the secret door-knocking sequence. Ideally, it's as simple as adding a line to /etc/hosts.allow with the approved IP address to allow an IP address through, and then reversing the process by deleting that IP address when the magic closing sequence has been received, in much the same way as the default iptables setup shown in Figure 2.

Another consideration is to avoid triggering additional scripts that need their permissions set correctly on each server on which the script is deployed. Perl, the undisputed heavyweight champion of one-liners, will be useful here, so make sure it is installed on your system.

The default config file (Listing 4) begins with UseSyslog, which implies that the file /var/log/syslog (or /var/log/messages on some Linux flavors) receives logging information. On Debian I'm becoming more accustomed to looking inside /var/log/auth.log for all things relating to logins, but I don't like to mess with that file because it's too important.

Listing 4

Default /etc/knockd.conf File

01 [options]
03    UseSyslog
05 [openSSH]
06         sequence    = 7000,8000,9000
07         seq_timeout = 10
08         tcpflags    = syn
09         command     = /usr/sbin/iptables -A INPUT -s \
           %IP% -p tcp --dport 22 -j ACCEPT
11 [closeSSH]
12         sequence    = 9000,8000,7000
13         seq_timeout = 10
14         tcpflags    = syn
15         command     = /usr/sbin/iptables -D INPUT -s \
           %IP% -p tcp --dport 22 -j ACCEPT

In testing, I would put a hash symbol in front of the UseSyslog entry to disable it and use a knockd-specific logfile, such as:

#  UseSyslog
logfile = /var/log/knockd.log

The /etc/knockd.conf file in Figure  3 shows this change. Looking at this file closely, you need to pay most attention to the %IP% variable, a built-in variable used by knockd that is populated with the connecting IP address, which you can manipulate within your open and close access commands.

Clearly it would be madness to leave the default port-knocking sequence in place to secure a production server, almost rendering the use of port knocking useless and practically leaving your front door keys on the doormat.

However, you can configure that later; now is the time to make use of the %IP% variable in a magical Perl one-liner:

/usr/bin/perl -ni -e 'print unless /SSHD: %IP%/' /etc/hosts.allow

The -i says run the file in place (i.e., Perl opens the file, makes a quick temporary file as a backup, and uses that to replace the original file). The -e simply means to execute this command. Perl loops through your file with the -n switch and asks Perl to print what's in the file unless it matches the string of characters that follow. Because there's no substitution of characters, the line is deleted cleanly rather than adding whitespace. In other words, you don't want to use something like this,

/usr/bin/perl -pi -e 's/SSHD: %IP%/ /' /etc/hosts.allow

which replaces the matched pattern with a single space. Although this will work, it would not work as well as the print alternative, because it adds extra lines to the /etc/hosts.allow file.

In the past, I have seen /etc/hosts.allow break so that no one can log in if unusual characters are added the file. Once I had to dial in to the back of a server to get remote access again using mgetty. There's a very good reason I don't intend to add and remove commas and extra CIDR (network notations) in the /etc/hosts.allow file. All I want is a straightforward IP address appended to the bottom of that file once and then cleanly (and I mean really cleanly) removed just once from the end of the file afterward.

With the ever so slightly tweaked line

/usr/bin/perl -ni.bak -e 'print unless /SSHD: %IP%/' /etc/hosts.allow

Perl can create a potentially life-saving backup file. However, enough Perl for now. If you've altered the /etc/knockd.conf file to use TCP Wrappers, as shown in Figure 3, then you can begin to test your config.

Figure 3: The fully modified /etc/knockd.conf file uses TCP Wrappers instead of iptables.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • TCP Stealth hides open ports
    Port scans for finding vulnerable services are nothing new, and port knocking as a defense has been around for a while, too. TCP Stealth tries to do something similar, but it takes a more sophisticated approach. We take a closer look.
  • Secure Your Server with TCP Wrappers

    TCP Wrappers are versatile, sophisticated, and surprisingly easy to use, and they can secure your servers from attack with run-time ACL reconfiguration.

  • Sort out your SSH configs
    The scope and functionality of SSH and sFTP provides both secure remote access and secure file transfers.
  • Arp Cache Poisoning and Packet Sniffing

    Intruders rely on arp cache poisoning to conceal their presence on a local network. We'll show you some of the tools an attacker might use to poison the arp cache and gather information on your network.

  • Customizing PortSentry

    Do you have a sentry to keep an eye on your servers? We’ll show you how to customize PortSentry’s response to suspicious activity.

comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs

Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.