I've been in this business for a long, long time and have come across all manner of innovations regarding network security.
Port knocking (which I think I learned about first at defcon ... perhaps 18 years ago ?) stands out as one of the very few things that made my network(s) substantially safer at nearly zero cost. I love, and continue to love, both the idea and the implementation.
Pay no attention to the nay-sayers and their comical straw-man argument against deploying port knocking by itself. Of course it's not deployed by itself - it is the last layer of defense-in-depth on top of all the other authentication methods you may be doing.
The substantive critique is that you add some amount of complication to your network and introduce a point of failure with knockd - and that is correct. I am happy to report that 15+ years of knockd in production use, all over the world, has produced exactly zero lock-outs or unintentional self-DoS.
For me changing the default port for SSH achieved much of the same result at an even lower cost IMO. That is, unless you're high profile enough that attackers might want to target your server specifically and you're not just randomly scanned by botnets which won't generally bother looking beyond port 22.
I had to disable "insecure" ciphers on my bastion SSH hosts at work so that we could pass a security audit. The interesting side effect was that a substantial number of scans failed because the scanning software didn't support them:
My latest trick for deciding on external ports to forward is to combine the service port and the device's internal IP address. If my desktop was 10.0.1.36 and the service was SSH on port 22, the external port would be 22136. So far it's worked well, but it only really works if you force your router to only give out 10.0.1.2 through 10.0.1.99.
and then all you'd have to do is compromise SSH on my fully patched system
of course the point is not to be able to withstand an attack by a persistent attacker. it prevents my logs from filling up with the constant scans from scripts
"Expanding on that substantive critique, i.e. complexity. Port knocking strips you of the benefits you get from session protocols like TCP."
This is correct and worth considering.
In actual practice (again, over 15 years, all over the world, etc.) I have found that the only place I ever run into this is on airplane (in-air) wifi. I don't know if they are specifically blocking random fragments or if they are just too laggy to make this scheme work.
A quick workaround is to ssh to some other host that you control that isn't behind a knock, but does have 'knock' installed and then jump through it.
You could of course just try again if it fails due to these excessively rare cases.
There are a lot of things that fail if packets arrive out of order and with random packet loss your experience is going to be awful, so both of these are rare.
I would argue that port knocking doesn't implement cryptography, but it implements steganography. It's purpose is not to cryptographically secure your service but to conceal its existence.
> When you want to open a port from a client, you run 'knockknock', which sends a single SYN packet to the server. The packet's IP and TCP headers are encoded to represent an IND-CCA secure encrypted request to open a specified port from the source IP address.
Yeah, the documentation is dated. Not only does it point to an old version, but it would probably be best to get it from the GitHub page he links to. Even then, there are more active forks, so they may be worth checking out to see which would be best to get on board with.
The suggestion is nice though since an attacker would have to break both at once. If you conceal an SSH server, you'd first break the obscurity, then proceed with attacking the SSH server. The suggestion seems to be that you would have to break the cryptographic part to reveal the server (which is then supposedly secured by "normal" cryptographic means, such as a regular SSH server). That is, you are dealing with cryptography just to be sure the server exists at all.
I'm all for defense in depth but I don't see the point of a redundant cryptographic layer. It's not trivial that it doesn't broaden the attack surface instead of narrowing it.
If the argument is that a steganographic layer that involves cryptography does a better job at concealing than a similar layer that doesn't I'm also not convinced. Cryptography helps against MITM scenarios, but at that point the existence of the service is already revealed.
What is your conclusion that port knocking has made your network substantially safer based on? Just curious how you measure the effectiveness of something like this.
Could someone point to a contest where an attacker has managed to bypass port knocking. Surely someone has tested its effectiveness at creating more work for attackers.
How can anyone measure the effectiveness of the advice given by a security consultant? It saved a client from disasters that did not happen? How can anyone prove that such disasters would have happened? Answer: Proof of concept.
To question the effectiveness of port knocking, one needs some real stories of real disasters where port knocking was being relied on. Proof of concept. Otherwise all the discussion is still just speculation.
I wonder if it would be interesting to load a ssh honeypot that would feed from the logs so it would add the logins and then just dump the ip + input to a file.
Honeypot could basically run in a some sort of isolation layer (like Sandboxie or jails) and then self-destruct after the automated script is gone... and then you slam the door on that user/ip combo for good.
I can't help but think this would be interesting...
One of my university courses offered an opportunity for a project like this and I did it with some classmates.
We started by altering the ssh daemon to disallow all logins over this ssh daemon and to log all the usernames and passwords attempted. After a week we gathered thousands of attempts to brute force into the honeypot. Interestingly enough, the passwords used were a combination of the very commonly used ones but also ones that were clearly from other popped boxes.
After a week or so of this we altered the ssh daemon again. This time it would log all attempts but also grant access on the 3rd attempt no matter what the credentials were. The few bots that managed to get in all tried to install various rootkits on the machine, all of which where targeted at a different distro of Linux than we were using so it mostly just busted up our shells output.
It looks like ipv6 matching is supported since late 2017 (version 10.0 [0]), although the changelog states that "not all ban actions are IPv6-capable now". As for IPv6 capabilities, I don't have any recent experience with the software.
Couldn't you just ban the /64 and call it good? It's not like they get a random selection of addresses, they're all going to be the same CIDR. Or am I overlooking something here?
The point of the honeypot is that there's no heuristic causing any delay or elusive attacker being missed (e.g botnet trying once per IP). You don't even need any processing time, nor even complete syn/synack/ack: any TCP connection attempt to that port triggers an instaban.
Wouldn't a reasonable rebuttal be that the log filtering rule that discards these failed login attempts would accomplish the same security goal, with less mechanism?
i prefer knowing that nothing is happening rather than filtering things i dont like.
also, lots of people sing the praises of fail2ban, which needs to watch log files to operate, but you can get most of its utility by simply rate-limiting using iptables' session tracking without any additional mechanisms.
I can tell you right now what's happening and compress all those log records into a single record:
Every exposed 22/tcp on the Internet is being continuously exposed to automated SSH scanners running from thousands of points on the Internet. There is nothing you can reasonably do to prevent it (the sources are so diverse you couldn't even realistically block a determined scanner), and, if you've turned off password authentication --- which you must do anyways --- the probes aren't a meaningful threat.
From a systems-administration standpoint, it's nice to be able to easily sift out the random bots and drive-bys from the more personal probes that maybe have a human at the other end.
There are myriad bits and bobs of software and services that promise to do anomaly detection in logs, but an easier approach for now is to just move ssh off 22. It affords basically zero extra real security but makes any subsequent login attempts more worthwhile to look at.
Sure. Direct answer: search logs across all services and nodes on the network for activity from that source or netrange. See if it's targeting particular usernames, especially anything that shouldn't be guessable. Treat it first as a source of information: did I screw something up somewhere? Have we had an incident I don't know about? If it looks like nothingburger, ignore it and get on with the day.
Broader answer after reading some of your other comments in this thread: in your ideal, highly secured network environment, none of this is necessary because everything's wired up tighter than a gnat's ass hole. Unfortunately I've never had the pleasure of working for one of those places.
I guess that's fair. But: if you buy into this idea, there's a much, much better thing to do: look into Canarytokens. Canarytokens, unlike port knocking, are criminally underused. Really, you should do something similar for your off-port SSH service; don't actually _run_ SSH there, just run a stateless unprivileged service that spoofs a bit of SSH protocol and generates loud alerts.
The networks I'm describing aren't "ideal" or "highly secured". I am describing table stakes. While I was at Latacora, most of the clients we engaged with were already at this level of maturity when we joined up.
> The networks I'm describing aren't "ideal" or "highly secured". I am describing table stakes. While I was at Latacora, most of the clients we engaged with were already at this level of maturity when we joined up.
One of the most valuable things you do here is describe things that you believe are table stakes to people and organizations that have never heard of them. Companies like Latacora tend to self-select for clients that are at least aware that security should be a sensible line item in their quarterly budget. There are many many more organizations for whom moving ssh or even port knocking amount to a real improvement to their infrastructure. :-(
But the concept is really simple: come with any kind of thing you'd want to tripwire --- the AWS key is particularly slick --- and put it somewhere in your infra, then wait for alerts.
To defend Canarytokens here (and I’m totally biased because we make it) some tokens can’t be easily avoided.
Ie. If the token is a Slack/AWS/something API key, then the only way for the attacker to profit is to use it, and the moment they do, they tip their hand.
The joy of Canarytokens is not having to set up infrastructure to get the alerting win, with very little effort.
Not "knocking" the idea but to be honest using someone else's API key and expecting that no one is going to notice sounds really dumb. I guess if that is the level of intelligence you are up against, then "winning" can indeed be quite easy. Although I would argue if the goal is to restrict access and they managed to gain access then regardless of what they do next, whether it is smart or stupid, they have "won".
I don't even understand the question. We were talking about the value of moving SSH to a different port to cut down on logged probes. That at least has the value of giving you a weak signal about IP sources that are somewhat determined to break in. Port knocking doesn't even do that.
Maybe it is not supposed to. Port knocking is not a substitute for anything. Yet most criticisms of it, like yours, seem to assume it is going to be used as a replacement for something else.
i mean, you're in the security industry, where targeted attacks are the default assumption. the overwhelming majority of web properties are not valuable enough to get this kind of attention.
even if security through obscurity is not real protection from targeted attacks, it is at minimum significant noise reduction, and quite possibly a reasonable barrier against drive-bys which assume default configurations. i'm sure you know how many scanners try to access some default php/wordpress admin route. how much of that would disappear if wordpress was simply installed behind a random 32-char route instead of /wp-admin? all it is is obscurity, sure. but is it not security?
The whole "obscurity isn't security" thing is a super interesting topic. Suppose you have a static file on a public web server and you want to control access to the file... confidentiality. Many people would agree that if you come up with a long string, don't disclose it to untrusted parties, and use it as a basic auth password, then you have secured the file to some extent. And many people would claim that if you take that same undisclosed string, and make it a path segment (parent directory) for the file, then you have merely obscured the file, or perhaps secured it to a far lesser extent. The former makes it "not available to the public" while the latter makes it "available to the public, they just don't know where to look."
I call BS. These are pretty much the same thing* which is to say: an adversary trying to get the file needs to know something that they don't know, and can't reasonably guess/discover any time soon. Did you secure it or obscure it? Whatever you call it, you require a "something you know" factor.
*Obviously, there's the fact that other parts of the stack -- browser history, access logs, rate limiting, etc. -- actually treat a password payload with the respect it deserves and assume there's nothing sensitive about a URI path... kindly pretend my example doesn't have this flaw.
You may accidentally enable the directory listing.
While you may say that certain methods of withholding the information are isomorphic at certain conditions it doesn’t mean that they are semantically equivalent.
I admit that my example is flawed for a few reasons and autoindex is another in that list. While obscurity and security are not identical by any means, and therefore not semantically equivalent in general, I'm just pointing out how the "something you know" factor inherently utilizes what common ground they do share, whether you call it a secret, a key, a password, a URL with a long random portion.
Turn on logging for failed connection to port 22 and you have just recreated the same log file, assuming you trust the underlying security in your sshd configuration. You just moved the "nothing happened" event from the sshd to the firewall, and the firewall by default do not log such events.
The best argument in favor of knockd that I can think of is the same of fail2ban, which is that ssh connection is actually a finite resource. You can only have so many simultaneous TCP connections. Rejecting packages in the firewall has no limits, and I have had servers which has received service disruption in the past because swarms of ssh bots used up the available tcp connections that the web server could handle. fail2ban in my case was a less intrusive change to our work flow so we use that rather than knockd to solve the problem.
I will add as a small note that the default of not logging firewall events has come to bite us once in a while. Just like keeping the default in ssh to log, keeping the default to not log is a trade off between resource usage and keeping logs of events.
> simply moving ssh off of port 22 cuts your drive-by log noise by 99.9%, which makes auditing clean logs much much easier.
Is there a reason you can't use some form of IP whitelisting?
I'm not a proper sysadmin, but when I play about on EC2 I always configure the security-group to block incoming connections to TCP port 22 except from whitelisted IPs.
The only time I've had to broaden the whitelist beyond just a few static IPs, is with mobile Internet tethering. They seem to frequently change my IP, so I guessed at my provider's IP range and whitelisted it with a pretty broad wildcard mask. Still much better than accepting connections from any old address.
I can see that my rather simple approach might not scale very nicely.
> I'm not a proper sysadmin, but when I play about on EC2 I always configure the security-group to block incoming connections to TCP port 22 except from whitelisted IPs.
Because I have multiple IPs I connect to, most of which are unknown. Maybe I'm connecting from a coffee shop, maybe from a tethered phone, maybe from work, maybe from an airplane, or a train, or a friend's wifi, etc.
The point is that most login attempts are automated, and the automated scripts just try port 22 and move on if they fail. If you run ssh on port 22, you see in your logs all the failed attempts from the giant sea of automated scanners, and will probably miss the one or two humans who might know something about you specifically (like your username) and are trying a targeted attack.
If you put ssh on another port, all of those automated login attempts disappear from your logs. The determined human attacker probably has port-scanned you and found ssh on another port, so you'll see just that attacker and can look into it more deeply if you feel the need. On port 22, you probably never bother to look at your failed-attempt log, because there's so much noise.
I would be interested to read about peoples process and procedures from those that regularly read their ssh failed attempts, identify human attackers, and react to that information.
My question is basically: Do they exist? How is the work flow and how much time per year do they spend on it? What incident occurred and what value did they derive from the process. Was it cost-effective?
I don't read mine at all (talking about a personal server here[0]), because there's a huge amount of noise. The email alerts for it go to a mail folder that I literally never look at, because it gets hundreds of emails per day.
If I only got an email per week or so, I'd probably not filter them to a folder, and actually look at them.
[0] At work, other people deal with intrusion detection there, and ssh access is gated behind a VPN anyway.
About a decade and a half ago it was in vogue to constantly monitor your logs for attacks. There was sophisticated software to detect the latest attacks, and they would notify you constantly, and you'd run around chasing your tail for every unusual port scan. We spent tons of money on reporting software to try to stay on top of it all.
But we realized that as attacks increased, it was pointless to look at who or how often we were being attacked, because it wasn't making our systems more secure. What did make them more secure was actually securing them: patching systems, implementing firewall rules, blocking or slowing down multiple login attempts.
Non-sophisticated attacks are trivial to prevent, and sophisticated attacks won't show up in logs. Everyone needs to stop logging ssh attempts and just secure their boxes and move on with life.
It was a response to their main point, but the subtlety was lost on people who don't think critically.
Just because you see or don't see attacks doesn't mean you are more or less secure. It just means you've finally noticed there is risk. It doesn't mean there is more or less risk. It's the same risk, it's just more visible.
The quote is not about logs making you unsafe.
The quote is about ssh login and connection attempts on port 22 which clutter your log files.
Assume you move ssh to another port, say 23. In that case, anyone trying to connect to port 22 would find a closed port and the connection would fail, on a layer before login attempts get logged.
There is this idiotic notion that any security measure that cannot stand on its own is "security by obscurity", and therefore useless.
That principle is taught in school and echoed by every junior netsec professional out there.
After almost 20 years of work, I can say that these layered techniques, are invaluable. OF COURSE, the core security has to be bulletproof. But once you've covered that base, there is an enormous value in keeping your assets under the radar.
At the very least, it reduces the number of alerts you need to review by several orders of magnitude. Logs become READABLE.
So with poet knocking, if I only have an ssh port open and a couple of ports my servers server content on like an http and https server, I'm assuming id use port knocking to get inside my ssh port right? I don't need to do port knocking for my http and https ports because they're open but not as an ssh service?
Looks like there is a pull request to change it from authenticate-then-encrypt to encrypt-then-authenticate that hasn't been merged for over five years. Thinking this project might be abandoned, unfortunately. :-(
Personally I avoid knockd and instead use something like fwknop https://github.com/mrash/fwknop. You get the advantage of port kocking while protecting yourself from re-play attacks. The main dis-advantage is it is a more complicated procedure so it may limit you a bit.
Does this have any advantages over using plain wireguard? WG operates purely over UDP and doesn't respond unless you send it packets with an authorized key, so it's essentially the VPN and port knocking all in one.
I think "attacker has a private key" is an unreasonable threat model to protect against, not least because the key is so much harder to crack than port knocking. The benefit to port knocking is against information disclosure ("this server is running Apache httpd version x.y and sshd version z"), brute force, noisy logs, and pre-auth vulnerabilities (things like heartbleed and shellshock). While in theory I suppose wireguard could be affected by pre-auth vulnerabilities and maybe a completely blind bruteforce attack, it's a listening UDP port that doesn't respond until it sees valid credentials, so it's completely invisible to an attacker.
Nope, no support needed. SSLH will proxy SSL traffic to whatever other SSL service you have running (nginx, openvpn, etc.), and send the SSH traffic to openssh. It look like it even supports recognizing plain HTTP traffic as well and proxying it accordingly.
I've been wanting to implement knockd on something for years but people always push back. I don't actually think it's incredibly useful but I love the cool factor. Good for you for actually doing it.
I implemented a physical port-knocking daemon, once. I lived in a block of flats — you needed an expensive fob to open the outer gate, and it didn’t even work reliably.
I lost my fob. So I took my intercom apart and wired a band pass filter circuit between the buzzer input and actuator output. If you pressed my buzzer with the right steady pattern, it would automatically let you in.
It worked great and I didn’t buy a replacement fob.
A few months later I started getting woken up by someone buzzing my buzzer. They would always scurry in before I could open my door to see who it was.
Turns out my upstairs neighbor saw my shenanigans a few times and started freeloading off my invention. Honestly amazed he/she reverse engineered what was going on!
I port knocked called a friend once while traveling overseas when a second friend decided to act like an idiot and got us both some attention by the local authorities.
First friend-a local-is the type who doesn’t answer his phone from numbers he doesn’t know/isn’t saved as a contact-which I knew, so I dialed him, then dialed his wife (who also doesn’t answer unknown numbers), then dialed him again. He picked up the second time and after some explaining he chuckled and goes “yeah I figured it must be important when the same number called $wife immediately after calling me”.
He was there to pick us (including drunk mutual friend) up within the hour. And yes, he’s a network engineer heh.
Back in the day of payphones and expensive long-distance calls, hitchhikers had a protocol for calling their parents/friends for free: they ring them up but don't say anything. The callee reads a list of expected answers (like the towns where the caller would stay), and the caller hangs up on the right answer, then dials again.
Not sure how payment worked and why you could listen for free—I'm only familiar with the method from written accounts.
Sounds like 1800 reverse where you could send a short 2-3 second message that’s supposed to be your name.
The other person would get an option to receive a call from <whoever> for $5, but usually <whoever> is the name or code of a location to be picked up.
I must have done this 100 times as a kid. Once an angry man clued onto it, switched my line across and told me off. This is back in the days where mobile calls were expensive and very few kids had phones.
I have one of those newer intercoms, where you first select who to call, and then it calls the correct flat. So your system wouldn't work.
But you just gave me an idea for something I'll probably never implement: an audio key. The intercom auto-responds and if the audio matches the key (hello 90s modem sounds), then it lets you in. You could add more automation on top and provide temporary keys for guests, etc. Just play the audio you received on whatsapp, it will open the door. Please someone implement this and get rich doing it so that I can just buy it. It needs to take into account when you're at home and you still want to answer the mailman.
I'd have gone the overly complicated route - throw a relay in there and tie it to something that detects whether or not your phone is connected to your WiFi network. Automatically disable it when you're already home!
Yes. They press an apartment number which dials your phone. "Hey your pizza is here", then you press a button on your phone which opens the outer gate or the front door to the building. You then meet them at your front door.
Port knocking was somewhat silly when it was introduced ~20 years ago --- at most, on a reasonably designed network, it was saving you from your own misconfigurations, but at least in 2005 it was reasonable to imagine a highly diverse network of machines that people logged into using multiple protocols, where those misconfigurations were likely.
In 2020, it's gone past "silly" and is now a design smell, in the same way that actually relying on fail2ban would be. Whatever port knocking is doing to help you is a a description of something you're doing wrong with your architecture.
We're not even comfortable with long-lived keys anymore; modern networks are built with short-lived certificates issued off 2FA from an IdP. We have good VPNs right now for the other weird cases. Our networks default to all-ports all-hosts closed. Arguably, port knocking is literally setting your security back, by making it harder for automated tooling to scream bloody murder if you've managed to expose a dev instance unexpectedly to the Internet.
Don't bother. If you've got a single system you're managing outside of a cloud provider with its own decent network firewall, just set up WireGuard and filter everything but that. If it helps, think of WireGuard as the evolution of SPA port knocking.
> modern networks are built with short-lived certificates issued off 2FA from an IdP
Modern networks are sadly far too rare; 95%+ of the industry is built on legacy networks.
My take on fail2ban and port knocking are:
* they reduce the amounts of logs produced
* they defend against fully automated at-scale scans / password stuffing attacks that a well-maintained application wouldn't need defending against, but we all know that in any sufficiently big organization, not all applications and accounts will be well maintained.
I use port knocking and I don’t take it seriously. Anyone using it in a serious setup is batshit. However, for fun home projects where users install that giant php based file sharing program, or that IoT camera, why not? They don’t have automated intrusion prevention, etc. They can’t understand the code to determine it’s quality, etc.
When the next 0day hits… will it be enough to protect them, yes. After all, they’re not a target and the automated attacks won’t affect them.
I don't understand how knocking in if itself is bad. It's just a technique to add a layer of protection.
In my case, all internal services in a kubernetes cluster have no path that allow it to be accessed from the outside. Occasionally, developers might want to do so, say to access a database or prometheus server.
The way to properly do this, imo, is to use a hardened service that functions as a networking proxy. Use proper encryption keys for access, and it should be quite hard to bust open.
Where does port knocking come in? That service should need to be exposed at all times. So, use port knocking to configure the infrastructure to temporarily allow access from your IP, to that proxy servers IP, on that particular port.
I'm more inclined to not take it serious, if such a simple mechanism isn't in place to protect infrastructure.
If you're exposing a developer instance to the network and it has port knocking deployed, why does it matter? The discoverability of such a service is basically zero.
What are the chances of the cracker finding the exact combination of ports to knock on, and then the exact key to use? If they're able to do that then they are a dedicated attacker and they're mitm'ing a presumably encrypted connection on your network, so you probably have more problems than just one bad machine, they already replicated or replaced a certificate on your machine, or worse.
And if you then expose a service that isn't via the port knocking algorithm, surely that would show up?
> We're not even comfortable with long-lived keys anymore
Can you not just change the key N number of logins and factor in 2FA as well?
I'm not sure how port knocking cannot, at least theoretically, be used in conjunction with the other measures you talked about.
The premise of your comment is that you're deploying dev instances on routable IP addresses on networks without default-closed filtering, in a configuration where it's theoretically possible that people could directly get a remote shell into that machine.
Don't do that.
In AWS (for example), have a dev VPC, and a WireGuard forwarder on it (or, if you're doing things 2010-style, an SSH bastion). If the machine needs to expose 443 directly to the Internet, give it an EIP; have the VPC prevent traffic to anything but 443 (and WireGuard).
What, in that architecture, would port knocking even be accomplishing? Keeping the wrong developer off your machine?
As for how attackers would break port knocking: if you believe attackers can't passively watch traffic, either directly or through redirection, I have good news for you about how much money you need to spend on encrypting traffic!
Re: sniffing, if I were implementing port knocking I would use the "single packet authorization" variant like in knockknock, which makes sniffing much less useful to an attacker.
I just prepend a secret letter to every possible ssh account on my server ('root' becomes 'jroot') and so that way "ssh root@myserver.com" can never work even if you know my root password. And this way my defense is opaque to attackers passively monitoring my network traffic (the username is encrypted in the ssh protocol).
Oh shit, I just gave away my secret on a public forum...
Ha ha, fooled you! I use a different secret letter in actual practice!
(Or do I?)
p.s. Pretty sure port-knocking offers less protection than this scheme.
You're telling people not to do a simple thing, instead telling them to do a far more complex thing.
You do not give a single argument on why the complex thing is meaningfully safer in practice.
If security is equal for all practical purposes in either case, this would be the wrong thing to do, because it is easier to fuck up complex things and it's more expensive to manage them.
Not just this, but they're assuming that everyone's server setups are enterprise-grade! People regularly still put raspberry pis and other kinds of low-cost computers on the public internet (William Gibson, for example, hosts hackers.town on a server setup in his (probably metaphorical) basement), and their answer to that is: "Don't do that".
One can use "port knocking" for more than remotely opening ports. It is a crude form of messaging in its own right, that can be based on some pre-determined code, like Morse code. The "secret knock" need not open any ports. It can be simply a message to the person (or program) reading the logs, to be translated according to the pre-determined code. Actions might be taken in response to the message, or not.
It is possible to do similar things with haproxy. Configured to listen for TLS connections on a large number of ports, look for a secret combination of custom headers and values, then, if found and matching, forward to a localhost ucspi tcpserver on the backend. The tcpserver may then execute some program, for example sshd or pfctl.
Good idea. You can also do it based on a sequence of ports accessed as well without headers/values which would allow you to forward directly to a tcp based service. You can track which ports are accessed and verify the sequence using stick-tables.
If you’re a fan or not of port knocking, single packet authorization is along the same lines, and has a much more robust mechanism that addresses most of the criticisms of port knocking. Your packet is cryptographically signed.
Take a look at fwknop for the implementation. The only issue with it is there’s no easy install for pfsense.
Port knocking is great. Also look into honey ports which would be somewhat opposite where you automatically block/log hosts that touch the wrong ports.
Doesn't TOTP usually allow for clock drift in either direction? This might be problematic, especially if there's some IO issue causing it to hang. What happens if the rootfs gets stuck read only?
I too am a fan of port knocking. I don’t use knockd, just iptables. I found the Arch Wiki most helpful. You’ll need to figure out which chain works for your setup but it’s pretty straightforward.
Here’s my example for a VPN running on OpenWrt. If you experience any race conditions with iptables you can pepper each rule with something like “-w 5”
This opens Wireguard port 666 for 15 seconds. I have a script that creates my ipset allowing connections from the USA only.
# The correct port sequence is 1111 -> 2222 -> 3333 -> 4444; any other sequence will drop the traffic
iptables -N WG-INONE
iptables -N WG-INTWO
iptables -N WG-INTHREE
#
iptables -A input_wan_rule -m conntrack --ctstate NEW -m udp -p udp --dport 666 -m set --match-set usa src -m recent --mask 255.255.255.0 --rcheck --name WG3 --seconds 15 -j ACCEPT
iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp -m recent --mask 255.255.255.0 --name WG3 --remove -j DROP
iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp --dport 4444 -m recent --mask 255.255.255.0 --rcheck --name WG2 -j WG-INTHREE
iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp -m recent --mask 255.255.255.0 --name WG2 --remove -j DROP
iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp --dport 3333 -m recent --mask 255.255.255.0 --rcheck --name WG1 -j WG-INTWO
iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp -m recent --mask 255.255.255.0 --name WG1 --remove -j DROP
iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp --dport 2222 -m recent --mask 255.255.255.0 --rcheck --name WG0 -j WG-INONE
iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp -m recent --mask 255.255.255.0 --name WG0 --remove -j DROP
iptables -A input_wan_rule -m conntrack --ctstate NEW -m tcp -p tcp --dport 1111 -m recent --mask 255.255.255.0 --name WG0 --set -j DROP
iptables -A WG-INONE -m recent --mask 255.255.255.0 --name WG1 --set -j DROP
iptables -A WG-INTWO -m recent --mask 255.255.255.0 --name WG2 --set -j DROP
iptables -A WG-INTHREE -m recent --mask 255.255.255.0 --name WG3 --set -j DROP
EDIT - For those wondering about the Netmask, it's for mobile connections.
FWIW I worked with a guy who insisted on doing it this way and it was extremely twitchy.
Problems included various operating systems and network tools knocking in ways that iptables hates but a knock daemon will handle (e.g. sending two requests per port); making iptables rules unnecessarily complex and hard to audit and eventually conflicting with other things that interacted with iptables; and, once, accidentally getting the knock-related rules nuked by some other software and turning a simple login into a fun little puzzle at exactly the wrong time to be solving more puzzles.
We tested both approaches early on. A working knockd implementation cost less than an hour, including getting other users set up to interact with it. The iptables implementation he switched to shortly after ended up costing dozens of hours.
Interesting. The only issue I’ve had was ensuring knocks were received in order. DDNS being the worst culprit. Ensuring an adequate delay between knocks solved my problems. However, I use this for home (friends and family only) nothing serious.
If I were to use a daemon I’d go with an SPA, like fwknop. The lack of an iOS client is the only reason I still use port knocking.
I agree with other comments that portknocking is stupid.
It's not stupid to have a tiny tiny service to unlock your bigger attack surfaces. It IS stupid to implement "IP-over-SYNpackets" (actually "password over SYN packets") when we already have a perfectly good way to send packets of information that doesn't expose even the complexities of TCP (e.g. slowlaris, SYN flood, etc…). And it's called UDP. Just send your plaintext password in a UDP packet.
It's not exactly hard to safely receive a UDP packet. In fact it's orders of magnitude easier to make a UDP server secure than a raw packet sniffer.
But also I would argue that TCP MD5 (RFC 2385) is vastly underused. It doesn't work through NAT, so maybe now that IPv6 is becoming more and more common it'll gain more traction. It's been used in production with BGP since forever (at least since the 90s), but there's nothing stopping it being used for SSH too. (in fact I run a patched OpenSSH that uses TCP MD5, see my blog post)
TCP MD5 also prevents your connection from being reset on a TCP level, once it's up and running, even by someone who can inject spoofed packets and sniff your encrypted connection.
What does port knocking look like on the client side? Does ssh have some option that makes it easy? Does everyone just write a custom bash script that wraps ssh client?
If anyone else was curious like I was, it looks like yes, most people do write a custom bash script to wrap (or use before) SSH. The makers of knockd also make a `knock` util that serves as a client, but other people also do something like:
```
for x in 9000 8000 7000; do nmap -Pn --host_timeout 201 --max-retries 0 -p $x server_ip_address; done
```
Classic! I remember using Port Knocking during the Louisiana Tech CyberStorm Hacking Competition in 2015 to completely lock down open ports on our VM Host Server since trying to use the glitchy Server KVM directly on the Rack was a test in futility. Between Port Knocking, Xpra, and knowing to disconnect the VMs from the network until after I had patched them, no one stood a chance hacking our VMs. Their VMs on the other hand often didn't withstand my scripts just constantly trying to get in with the VM default passwords, change the flags to give us credit, lockdown and take over root, leaving us a way back in after, and continuously using the root account to reclaim the flag if they noticed.
This seems brittle as hell, and is security-through-obscurity. It breaks when packets come out of order. It breaks when packets are dropped. It breaks when it gets carried away and shuts down all inbound traffic, effectively DDOSing yourself.
It seems like you would get the same benefits by moving all major at-risk services (eg SSH) to non-standard ports, and set up exponential IP bans on attempts to communicate on any other port.
I use port knocking as an emergency backup measure on my bastion host (OpenBSD w/pf). The regular sshd runs on a non standard port with key authentication only. The backup sshd needs to be knocked and allows password authentication. I only use it in emergencies when I don't have my key handy.
I have used it in the past and has saved me a few times. This is only on the bastion.
One-time knocking via changing the ports for every connection / every X seconds with a OTP is something else you can do to further contribute to the defense-in-depth idea. Port knocking is great on it's own, but curious to hear from those who have set it up this way. Love the 'honey port' idea mentioned elsewhere in the thread.
We like fwknop a lot for its cryptography implementation which can prevent MITM attacks. However, we don't like it for relatively complex client setup. (For example, there is no official iOS client).
So we built our own cheap version of port-knocking and called it "doormand". It's just a HTTP server (behind nginx) listening for a POST request from clients. If the request is valid, a new iptables rule is added for the knocking IP for 30 seconds.
It supports users with secret key (think API token) so we can knock from our workstation easily. It also supports Timebased-OTP (we can even setup so user is required to enter 2 different TOTP's when knocking) so we can knock from mobile devices.
All messages are hash'ed with timestamp making it harder to re-play attack.
It works great for us (a small team) because now we can knock over HTTPS on our phone/ipad and then SSH-connect to servers.
Port knocking is stupid. The only possible real reason anyone should have for actually using it is if they really don’t want their logs to be flooded with the normal internet attacks. Logs which the SSH daemon really shouldn’t (by default) be creating in the first place, since what’s the use? It’s like having a weather station on your roof which always says “it’s raining”, since you live on the ocean floor. It’s the internet, SSH will be attacked; there’s (by default) no purpose to logging this.
For actual security, though, it’s also woefully inadequate:
1. It adds very little security. How many bits are in a “secret knock”?
2. The security it does add is bad: It’s sent in cleartext, and easily brute-forced.
3. It complicates access, since it’s non-standard.
I agree with 1. and 3., but not 2.: It's basically like a password where ports are your alphabet.
Assuming you use most of the 2^16 ports, and a typical text password is based on an alphabet of ~70 characters, each knocking step is roughly equivalent to log_70(2^16) ≃ 2.61 traditional password characters.
For example, 5 steps of knocking already entail (2^16)^5 ≃ 1.2*10^24 steps to check. With 1000 attempts per second, that still means trying > 10^13 years until all combinations have been tried.
gofwd is a cross-platform TCP port forwarder with Duo 2FA and Geographic IP integration. Its use case is to help protect services when using a VPN is not possible. Before a connection is forwarded, the remote IP address is geographically checked against city, region (state), and/or country. Distance (in miles) can also be used. If this condition is satisfied, a Duo 2FA request can then be sent to a mobile device. The connection is only forwarded after Duo has verified the user.
Many Many Moons ago I implemented an OS version of this for windows. It was taken over a few years back and is released as KnockKnock. https://sourceforge.net/projects/knockknock/
If someone intercepts the traffic to my server, they could see the knock sequence and re-use it. Is there any way to get knockd to use a google authenticator-like sequence of port knocks?
Yes, take a look at the manual page for knockd and search for "One_Time_Sequences". It does what you are asking by using a one-time valid sequence of port knocks, but it is like HOTP rather than TOTP.
This was one of the coolest tech that I have implemented!! We used it for authenticating public facing services in a voip application. It worked really well! I was a beginner and I barely understood the benefits. It was the tech leads who guided me to the finish. Such a rewarding experience!
it's a great technique, one I used a lot in the late 90's, had a port sequence would ping and that was S/KEY and could run on an nokia or anything that could run java to get the key from the seed. then dydns and could get ssh open and connect. Probably a bit para, but hey, with security it's only paranoid in hindsight if nothing bad happened. Also added extra layer against any zero day upon ssh.
Had it on a openbsd box, firewall script deamon would monitor the firewall logs, pick up the sequence and open ssh for that ip if matched and as sequence was S/KEY, it was always changing. Still cool effective solution.
knockd is pretty easy to setup and use. I used it in a security lab class in college in the late 2000s and nobody could figure out why we didn't have any open ports!
Not necessarily, imagine a port knocking monitor that stores each port attempt it sees in a large buffer. Imagine you make many attempted connections allowing you to overflow the buffer and write arbitrary data onto the heap.
I can't believe the discussion is this long and someone hasn't said 'security by obscurity' yet.
Personally, if I was trying to prevent a break-in to a building, I would think it was a great advantage if the attackers had to work hard to even figure out where the doors and windows were.
I believe the "security by obscurity doesn't work" people fall into two types:
- those that are coming from a crypto background, where you frame things as "in principle breakable" vs "not breakable, not even in principle" and there's nothing in between, a framework according to which security by obscurity goes into the "in principle breakable" bucket,
- people who just mindlessly parrot people of the first type.
A more nuanced (and more useful) way of viewing this is one of cost vs reward: How much does it cost an attack to break your thing, and what's the maximum cost that an attacker is lilely to be willing to invest before your thing becomes unappealing. According to this view, obscurity can significantly increase the cost of the attack. It's as simple as that.
I was not disparaging it. Indeed I commended its theatrics and suggested it may help to make logs less cluttered. As for its supposed security benefits, this is something that needs to be proven by actual security research. Not by anecdotes on the internet.
Port knocking (which I think I learned about first at defcon ... perhaps 18 years ago ?) stands out as one of the very few things that made my network(s) substantially safer at nearly zero cost. I love, and continue to love, both the idea and the implementation.
Pay no attention to the nay-sayers and their comical straw-man argument against deploying port knocking by itself. Of course it's not deployed by itself - it is the last layer of defense-in-depth on top of all the other authentication methods you may be doing.
The substantive critique is that you add some amount of complication to your network and introduce a point of failure with knockd - and that is correct. I am happy to report that 15+ years of knockd in production use, all over the world, has produced exactly zero lock-outs or unintentional self-DoS.