Remote access security with single-packet port knocking

Testing Fwknop

To test your setup, you need a client as well as a server. Again, you will need to install libpcap-dev on the client machine and then install fwknop as above; however, answer client during the installation process.

For an initial test, confirm that you cannot log in to your server via SSH:

$ ssh username@example.com

Although you should get no response, if you do, check your iptables setup on the server with iptables -L to list the rules.

Next, try sending the "knock" packet:

$ fwknop -A tcp/22 -a client.example.com -D server.example.com

-A specifies which port on the server you want to access – and with which protocol. The -a specifies the machine (or IP address) that fwknop should allow to connect.

This option is useful in preventing a man-in-the-middle attack by ensuring that the source address is duplicated within the encrypted packet, so that if an attacker fakes the packet headers, they will not be successful (because the faked header would not match the encrypted packet). -D specifies the server to connect to.

After you are challenged for and have provided the passphrase that you set in access.conf on the server, you will see that a packet is sent to the server. After the packet is sent, you have 30 seconds to connect to the server with the use of a standard SSH connection (ssh username@server.example.com). The 30-second time limit is the default. As with the passphrase, you can change this in access.conf on the server. If the test does not succeed, it is possible that the setup packet was sent over a high-value UDP port.

If your client and server are on different networks with an external firewall between them that blocks these ports, your "knock" packet will not get through. If this is the case, you can edit the PCAP_FILTER value in /etc/fwknop/fwknop.conf on the server to set a port value that is allowed through, and then use the --Server-port <port> switch with the client fwknop command:

$ fwknop -A tcp/22 --Server-port 330 -a client.example.com -k server.example.com

To get more information on what is happening, you can run the daemon on the server in debug or verbose mode: fwknopd -d -v . With this, you should see connection attempts being logged and the firewall being opened.

Note that the FWKNOP_INPUT chain in iptables will not be set up until the first connection attempt occurs – so it is not a problem when you do not see that chain initially. By opening a new terminal window and issuing the command watch -n1 iptables -L -n, you can watch the changes in iptables as a connection occurs.

Using a GPG key

A plaintext key might not be the ideal form of authentication. Fwknop also supports GPG authorization, but you probably don't want to use your regular GPG key on the server end, since the password for decrypting it must be stored in /etc/fwknop/access.conf. However, you can use an existing GPG key on the client end if you have one.

In this example, I will assume you don't have one, and I'll go through the steps to set up a new key at both ends.

To create the server key, use:

$ gpg --gen-key
$ gpg --list-keys

The default options for the first command (DSA and Elgamal key, 2,048-bit key size, and no key expiry) are fine. Because the key needs to fit in a single packet, you shouldn't use a key larger than 2,048 bits.

Give an appropriate name and email address for the server (e.g., server.example.com fwknop and fwknop@example.com) and make a note of your passphrase. The key generation will take a few seconds. GPG will suggest that you do things on the keyboard to generate entropy while you're waiting, so go browse the Internet and check your email for a while! The output from the second command will look a bit like:

pub  1024D/AAAAAAAA 2008-03-07
uid        server.example.com fwknop <username@example.com>
sub  2048g/BBBBBBBB 2008-03-07

Now you need to export that key to ASCII with the command

$ gpg -a --export AAAAAAAA > server.asc

and go through the same process on the client to create and export the key:

$ gpg --gen-key
$ gpg --list-keys
pub   1024D/CCCCCCCC 2008-03-07
uid    test fwknop <username-test@example.com>
sub   2048g/DDDDDDDD 2008-03-07
$ gpg -a --export CCCCCCCC > client.asc

Now you need to transfer the client.asc and server.asc files, each to the other machine (using any secure transfer method you fancy).

Remember that if you've already set up fwknop as above on the server, you'll need to knock appropriately for an SCP or SFTP transfer to succeed! (Or, you could turn fwknop off and change the iptables setup back to normal for this transfer.)

Next, import and sign each key. On the client, use

$ gpg --import server.asc
$ gpg --edit-key fwknop
Command> sign
Command> save

and replace fwknop in the second line with whatever user ID you have given your key or with the hexadecimal key ID – AAAAAAAA in this example.

Then, repeat this on the server with the client key. Now edit your /etc/fwknop/access.conf on the server:

SOURCE: ANY;
OPEN_PORTS: tcp/22;
DATA_COLLECT_MODE: PCAP;
FW_ACCESS_TIMEOUT: 30;
GPG_HOME_DIR: /root/.gnupg;
GPG_DECRYPT_ID: AAAAAAAA;
GPG_DECRYPT_PW: myGpgPassword;
GPG_REMOTE_ID: CCCCCCCC;

__GPG_DECRYPT_ID__ is the server GPG key id, and __GPG_DECRYPT_PW__ is the password for that key. The characters after __GPG_REMOTE_ID__ compose the client GPG key id.

Restart fwknop and test it. The command line you need from the client is:

fwknop -A tcp/22 --gpg-recip AAAAAAAA --gpg-sign CCCCCCCC -w -D server.example.com

The server key id is --gpg-recip, and the client key id is --gpg-sign. After a challenge for your GPG passphrase, you'll see a message that a message has been sent to the server. Then, if you type ssh username@server.example.com, you should be able to log on again.

As this stands, only one key, and thus one individual, can access the server. The addition of more

GPG_REMOTE_ID: xxxxxxxx;

lines in access.conf permits as many keys as you want to access the server.

However, each key that is permitted to access the server must be imported and signed on the server. (In addition, the server key must be imported and signed by the client/user wanting to access the server.) This might be a bit much in a regular multi-user setup, although it would probably be acceptable with only a small number of admins needing to connect to the server (or, of course, if it's a single-user machine!).

Also, you can add the requirement to use a particular username when connecting, with the directive

REQUIRE_USERNAME: username

in the /etc/fwknop/access.conf file. Similarly, you can require a particular operating system or source address; or, you can change the time that fwknopd will keep the port open. Check the man page for details of all of these.

Although it is possible to use fwknop in port-knocking mode (which is called legacy port-knocking mode in the docs), this practice is not recommended; therefore, I won't cover it here.

With the --Server-cmd <cmd> switch for fwknop (client-side), you can send a command to the server to be executed as root. You must edit access.conf on the server to include the ENABLE_CMD_EXEC keyword, and you can restrict what commands are permitted with the CMD_REGEX keyword. This feature could be useful for running certain admin commands from a distance or, perhaps, for backup purposes.

Multiple Users

If you intend to implement SPA (or another form of port knocking) across several machines with multiple users, you will probably come across resistance to the idea from your users, particularly if they are accustomed to being able to transparently use programs such as PuTTY. Being able to explain the benefits will be helpful, as will being able to provide an easy way to use appropriate scripts in practice. Using a plaintext password rather than GPG keys might be easier in this case, although obviously the more people know such a password, the less secure it is.

Alternatively, it might make more sense to implement port knocking only on certain machines. For example, you could create a setup in which certain user machines allow external (outside your LAN) access, but your servers both do not allow external access and require SPA for internal access. This means that a nefarious individual who breaks into one of your user machines cannot access your servers without also breaking the SPA protection.

Port knocking as a principle, and in particular SPA, is a very neat way of further restricting access to vulnerable machines and increasing security. It might not be suitable for all setups, but it is a useful technique to have available for situations in which you need or want to be particularly security conscious.

Buy this article as PDF

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

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Charly's Column

    Conventional, woodpecker-style port knocking is open to sniffing and brute force knocking attacks. Sending an encrypted packet with an access request to the server is safer and more modern. Learn more about Firewall Knock Operator, a.k.a. Fwknop.

  • Books

    Reviews of O'Reilly's Beautiful Code: Leading Programmers Explain How They Think, Prentice Hall's The Official Damn Small Linux Book, and Linux Firewalls: Attack Detection and Response with iptables, psad, and fwsnort from No Starch Press.

  • EnGarde Secure Linux Community 3.0.18 Released

    Guardian Digital, a provider of Open Source security solutions, today announced the latest release of EnGarde Secure Linux Community 3.0.18, the world's first Open Source security platform.

  • Letters

     

  • Charly's Column

    Horror stories are full of scary characters knocking on doors at night. On Linux, we just call this port knocking, and it can actually be quite useful.

comments powered by Disqus

Direct Download

Read full article as PDF:

024-028_portknocking_KORR1.pdf  (1.48 MB)

News