|
|
Subscribe / Log in / New account

A proposal for "silent" port knocking

By Jake Edge
December 18, 2013

Port knocking is a longstanding technique to evade port scans that is typically implemented in user space. A recent patch proposed for the kernel would change that by adding support for port knocking into the TCP/IP stack itself. Beyond just allowing administrators to hide open ports, the patch would also provide some ability to thwart man-in-the-middle attackers either from making their own connections to those hidden ports or from hijacking those established by friendly clients. But the patch is facing some pushback from the network developers who think that user space is a better place to handle features like port knocking.

The details of the "knock" vary, but the basic idea for port knocking is that a protected port on a server will not respond to the normal connection-establishment protocol; instead, some special steps will be required to make a connection to the port. Those steps might include making a connection attempt to a different port, or to a series of ports, that show the server that the client knows the secret knock to gain entry to the clubhouse. Since port scanning programs generally don't know the secret knock and it is expensive to try lots of possibilities, the services behind the knock are hidden from view.

There are a few different reasons to hide a service. One is that the server program may have vulnerabilities, either because it has not been kept up-to-date or because there are unknown flaws in the code. If only trusted people know about the knock, it reduces the threat of someone exploiting the hole. In addition, hiding services like SSH will avoid brute-force username/password guessing attacks.

But there is another reason to hide the existence of a service: it may be illegal in certain jurisdictions or running it may draw unwanted attention to the host and its owner. Folks running Tor bridges or other privacy-oriented services may see them blacklisted by government-controlled internet service providers—or prompt a visit from some secret service.

Existing port knocking solutions generally either monitor firewall logs or capture packets from user space, then modify the firewall to open the port when the proper knock is detected. The Knock project—a part of the GNUnet project—looks to turn that on its head. With a few-hundred-line patch, authors Maurice Leclair, Julian Kirsch, and Christian Grothoff would move the port-knocking logic into the Linux networking stack. That would allow clients and servers to communicate, while hiding behind a port knock, simply by using the new TCP_STEALTH option to setsockopt(). If the code were widely available in most Linux kernels, users could rely on the feature being available, without having to install and configure some other port knocking solution.

Knock is different than other solutions in a couple of other ways. To start with, it is meant to be undetectable to a man in the middle. It just looks like a normal connection establishment to a particular port—there is no extra sequences of connections to other ports or other special knocks. It uses a technique called "silent knocking" that requires sharing a secret between the client and server using some unspecified, out-of-band mechanism. That secret is used to calculate the sequence number of the initial SYN packet that is sent to initiate the three-way handshake that starts TCP connections. Any SYN with an improper sequence number gets an RST reply; exactly what it would get for a closed port.

In addition, using the TCP_STEALTH_INTEGRITY option allows the the first bytes of the payload data to be protected by a hash-based message authentication code (HMAC), which effectively stops active man-in-the-middle attackers from hijacking the connection once it has been established. Essentially, the top 16 bits of the sequence number in the SYN packet correspond to the HMAC, while the low 16 bits are the authentication code that comes from the MD5 of the shared secret.

The 32-bit authentication code for stealth-only mode is calculated with one round of MD5 using the shared secret along with the destination IP address and port. In stealth+integrity mode, the client and server must agree on the number of payload bytes to be covered by the HMAC, which also uses MD5. A short paper [PDF] about Knock noted that using MD5 may be something of a surprise, but that it is already used by the kernel for initial TCP sequence number calculation as well as for SYN cookies. But in the linux-kernel mailing list thread, Jacob Appelbaum (who assisted in the design of Knock) was not particularly happy with the choice of MD5:

If we believe that MD5 is not secure, we should not use it. That others use it is not a strong reason to use it. Everyone should stop using MD5 - especially truncated MD5. :)

The stealth-only mode is vulnerable to replay attacks as a man in the middle can observe the proper sequence number to unlock the port and replicate it in their own packets (without knowing the secret). Stealth-only is also vulnerable to brute force attacks (trying all possible sequence numbers), but that could be expensive in terms of time and it is not particularly stealthy, so the attack might well be noticed. The stealth+integrity mode is more resistant, as the HMAC-protected bytes could be used to transfer a public key that is used to encrypt the rest of the data.

There are some other downsides to the idea that were briefly explored in the thread. For one thing, network address translation (NAT) implementations that change the sequence number in the SYN packet will not work at all with this technique. As David Miller pointed out, sequence number alteration is done in netfilter for tracking the SIP and FTP protocols as well as for virtual server load balancing.

Others were more explicitly suggesting that handling this kind of port knocking (or, seemingly, any kind of port knocking) would be best done outside of the TCP core—in user space. Both Stephen Hemminger and Andi Kleen suggested that user space was a better home for the code. But Grothoff, who signed off on the patch and posted it, was surprised by that attitude: "I mean, if this was a patch for GNU Hurd, I'd at least understand the strong urge to do everything in userspace". Kleen, though, noted that keeping port knocking in user space meant that "the risk of adding exploitable holes to the kernel is [significantly] lower".

Eric Dumazet was also critical of the idea. He suggested allowing user space to implement parts of the TCP protocol, which would also help other proposals (like TCP Minion):

With various proposals (like TCP minion), maybe its time to be able to implement part of TCP stack in user land (Keep the mux inside the kernel, and forward raw incoming packets to user land where all the crazy things can be done without kernel patching.)

Dumazet is also concerned that reusing the initial sequence number (ISN) will make it difficult for servers to distinguish duplicated packets. He didn't mention it, but duplicate ISNs (i.e. the sequence number sent with the SYN) might also make the port knocking more obvious to a man in the middle. Overall, though, Dumazet felt that the paper was too short to explore the idea: "You really need more than 3 pages to fully investigate all the pros/cons of this idea."

He also hinted at a possible direction for getting Knock upstream: looking at TCP fast open, which is somewhat similar and was merged into the mainline. If Knock could be more like fast open, or use it directly, it might have more of a chance to be added to the networking core. The concerns raised by Dumazet and others are reflections of the complexity of the networking stack, that there are a lot of moving parts all of which need to work well together. That's part of the reasoning behind relegating features like port knocking to user space.

On the other hand, Grothoff is not convinced that the small patch he posted "really warrants moving TCP into user land". But the reception from core network developers like Miller, Hemminger, and Dumazet would seem to make it fairly unlikely the patch will make it into the kernel. Working on ways to either move some pieces of TCP handling into user space or to extend netfilter to allow for both silent knocking and payload protection would likely be the best way forward. It is an interesting idea, though not without flaws, but getting it into the kernel itself is going to be an uphill battle.


Index entries for this article
KernelNetworking/Security
KernelSecurity/Security technologies
SecurityLinux kernel
SecurityNetworking/Obfuscation


to post comments

A proposal for "silent" port knocking

Posted Dec 19, 2013 5:16 UTC (Thu) by wahern (subscriber, #37304) [Link] (2 responses)

If people invested as much time fixing bugs in server code and simplifying administration as they do in writing and configuring port knocking environments....

Ah well. It's free software. People can spend their time however they wish.

A proposal for "silent" port knocking

Posted Dec 19, 2013 8:57 UTC (Thu) by lolando (guest, #7139) [Link] (1 responses)

I'll plug my implementation (which uses a little bit of userspace but where the actual opening of ports is purely in-kernel): http://roland.entierement.nu/blog/2008/08/19/netfilter-ba...

Maybe at some point I'll make it more polished and distributable. In the meantime, as you said, free software and so on. Also, yes, I know, it doesn't protect from MITM (although the attack window can be made arbitrarily short).

A proposal for "silent" port knocking

Posted Dec 19, 2013 13:21 UTC (Thu) by jengelh (guest, #33263) [Link]

And there are already some existing codes out there, like xt_pknock.

A proposal for "silent" port knocking

Posted Dec 19, 2013 20:30 UTC (Thu) by imitev (guest, #60045) [Link]

One of the requirements of Moxie Marlinspike's (Thoughtcrime) port knock implementation [1] was

"I don't want something that runs in the kernel."

Sadly there's no explanation but one would guess he's against the added complexity of having something in the kernel.

FWIW, I've tried quite a few port knock implementations over the years (but not Marlinspike's one, which is on my todo list for months); I've eventually settled on a custom solution: since I'm running a web server anyway, I've set up an https restricted area with a cgi-bin that writes my IP/username to a temporary file. The firewall wgets the file every minute and adds/removes stuff with iptables's xt_recent. Works perfectly.

[1] http://www.thoughtcrime.org/software/knockknock/

A proposal for "silent" port knocking

Posted Dec 20, 2013 5:11 UTC (Fri) by jzbiciak (guest, #5246) [Link] (2 responses)

For ISN, if your connection rate is low, it seems like you could mix a low resolution version of the current time in the hash calculation. Allow a small range of ISNs in a defined "acceptance" interval.

Downside is that you need moderately accurate time on both sides of the link.

I can't claim this as a new idea. The two-factor authentication scheme I use at work basically uses this principle. The client generates a time-based token locally based on a shared secret and the current time. That token is good for 30 seconds. I use that token in addition to my username and password to log in.

It seems like a similar idea would work to "randomize" the ISN in a useful way.

A proposal for "silent" port knocking

Posted Dec 20, 2013 22:18 UTC (Fri) by nybble41 (subscriber, #55106) [Link] (1 responses)

By itself, a hash of the shared secret and time won't protect against a replay attack within a short time frame (like right after observing the original port knocking sequence). However, if you added in some information about the connection, like the source IP address and port, that would frustrate replay attacks from other systems. Of course, the downside of that is that it would no longer be compatible with NAT.

If the server responds to the knocks with an ICMP error, it might be possible to piggyback some challenge data in the response so that each sequence is unique after the first knock. The client would hash the challenge data with the shared secret to determine the next knock.

A proposal for "silent" port knocking

Posted Dec 20, 2013 22:34 UTC (Fri) by jzbiciak (guest, #5246) [Link]

Yeah, that's true. Of course, if you do happen to save some state server side, then you could detect a replay attack. Adding 'time' to the equation limits the length of the memory you need to have to the time window each token's valid.

TCP in userland

Posted Dec 24, 2013 16:13 UTC (Tue) by rwmj (subscriber, #5474) [Link] (2 responses)

The idea of moving TCP into userland is neither crazy nor new. It has been explored for years in (research) exokernels. There's a lot of very interesting research and potential performance gains, which I'd love to see become more mainstream.

TCP in userland

Posted Dec 24, 2013 16:15 UTC (Tue) by rwmj (subscriber, #5474) [Link]

.. and by "become more mainstream" I mean, be explored in real, production kernels. Of course the promising results of research may fail in the real world, but we'd have to try it to find out if that is the case.

TCP in userland

Posted Dec 25, 2013 14:15 UTC (Wed) by mathstuf (subscriber, #69389) [Link]

The Tor Project also wants to have their own TCP stack to avoid OS fingerprinting based on the different stacks.


Copyright © 2013, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds