Hacker News new | past | comments | ask | show | jobs | submit login
Port knocking (wikipedia.org)
254 points by simonpure on May 15, 2020 | hide | past | favorite | 178 comments



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:

  Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
  MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512


Put ssh on port 80 and http on port 22 - perfect security ;)


for my internet-facing machines I black-hole everything below 1024 and move SSH to something high but easy enough to remember like 22222


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.


If I was an evil hacker I would look at that port and other variants of 22 like 2200, 2222, etc for people's ssh.


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


Same with RDP. Hackers don't even bother to scan outside of 3389. My logs are empty.


Expanding on that substantive critique, i.e. complexity. Port knocking strips you of the benefits you get from session protocols like TCP.

- Fails when packet loss is high.

- Fails when lags make the attempts arrive in changed order

- Fails when multiple people try to execute the sequence at the same time (yes, you can track source IPs, but then it doesn't work from behind a NAT)

Agreed, none of this is a problem on a small scale. Agreed, you can work around that but it's a PITA.


"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.


Can't we do both? Like, the content of the UDP packet is the output of `date -uIs | gpg --sign`.


From knockknock:

> 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.

https://moxie.org/software/knockknock/


That page links to a http insecure download script, weird. (Not https, no signature)

This link: wget http://www.thoughtcrime.org/software/knockknock/knockknock-0...


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.


Thanks, seems this is the (also outdated) repo: https://github.com/moxie0/knockknock

Yes I suppose one of the forks is better nowadays


You already do both when you are concealing an ssh server. The cryptography part is the responsibility of the ssh server.

edit: That specific scheme looks naive and susceptible to replay attacks.


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.


from personal experience, simply moving ssh off of port 22 cuts your drive-by log noise by 99.9%, which makes auditing clean logs much much easier.

failed login attempts with ssh on 22: hundreds per week, after: 0. i imagine with knockd it would go negative.


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 was a long time ago but a great experience.


Fail2ban [0] bans ip addresses based on failed login attempts (works for more than ssh), minus the isolation layer.

[0]: https://www.fail2ban.org/wiki/index.php/Main_Page


fail2ban should be avoided. It does not support IPv6, so should be considered legacy software.

EDIT: Source: https://github.com/fail2ban/fail2ban/issues/1123

It appears they have moved forward a little in supporting IPv6, but it's still incomplete. It's unacceptable to not support it fully in 2020.


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.

[0]: https://github.com/fail2ban/fail2ban/blob/0.11.1/ChangeLog


With IPv6 every user gets an IPv4 internet worth of addresses for himself which makes fail2ban useless.


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?


it does more than just scanning iptables logs..


> then just dump the ip + input to a file.

There are people who do just that.. and then try connect back to that IP with the same credentials. Easy way to find some shells..


I think you're talking about something like Kippo: https://www.honeynet.org/projects/old/kippo/


You don't even need a honeypot, simply ban ip addresses for some time after X failed login attempts.


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.


> i imagine with knockd it would go negative.

So it's the people running knockd that are actually the ones generating all these ssh login attempts...


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.

https://selivan.github.io/2018/07/07/limit-new-connections-f...


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.


Let me gently challenge you: you've moved SSH to 7163/tcp. You see a pattern of login attempts. Now what, and why?


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.


Cool, thanks. I found https://blog.thinkst.com/p/canarytokensorg-quick-free-detect... is there a better writeup you have offhand? https://github.com/cowrie/cowrie has been on my todo list for a while too, but more as a toy than a serious thing.

> 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. :-(


There's:

https://canary.tools/help/canarytokens

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.


What happens when the attacker modifies /etc/resolv.conf, disables or does not use DNS while on the network.

What if the attacker does not use software that automatically loads images, like the "canary token" tracking pixels?

What is the attacker opens the files offline?

Canary tokens still work? How?

Why would anyone advise using canary token instead of port knocking? Makes no sense. Why not use both?


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.


> the sources are so diverse you couldn't even realistically block a determined scanner

thankfully, i dont have properties which attract determined scanners. and i imagine that's true for 99% of public ip addresses, too.


So then, of course, there isn't even a theoretical reason why you'd want to pay attention to SSH probes.


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.


Semantics of this is wildly different.

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.


Topically relevant (and amusing) username!

http://bash.org/?244321


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.


[flagged]


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.

And that's why port knocking is stupid.


Actually I'm receiving about 10 attempts per minute on my non-22 ssh port that I've set up


Damn, that's a shame. From what other people say when they advocate non-22, they make me believe it would be a lot less. Oh well.


Please respond to the strongest plausible interpretation of what someone says, not a weaker one that's easier to criticize.

https://news.ycombinator.com/newsguidelines.html


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.


The point is that 99% of all access attempts are done by simple skiddies or people simply crawling the internet with masscan or similar.


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.


any tips or where one would get best practice for configuring/setting up/using knockd?

I wrote up how having a server on the internet is scary now (http://redgreenrepeat.com/2020/03/20/why-you-should-secure-y...) and how to protect it (http://redgreenrepeat.com/2020/04/10/how-to-secure-your-serv...)

One thing I didn't get into more was port knocking/knockd as there were not many resources for it.

I'd love to learn more about how you have used knockd.


My default ipfw ruleset is very restrictive - no ports open.

The command that gets run when the (correct) knock comes in is an ipfw command:

  /sbin/ipfw add 01021 allow tcp from %IP% to 10.0.0.10 22,443 setup
... so now the knocking IP can see TCP 22 and 443 (and nothing else).

I then have a cron job that runs every night at midnight that deletes those rules:

  0 0 * * * /sbin/ipfw delete 01021
... so I am required to knock daily.

The following is a little lame, but I want to see who has knocked so far today (should just be me and my own IPs) so I do this every minute:

  * * * * * /sbin/ipfw show|/usr/bin/grep ^01021 | awk '{print $7}' > /tmp/.knock_list
... and then cat that list to myself every time I log in ...


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?


Yes, that's right - you'd leave your public services open by default and the knock would simply open up tcp22 ...


> So with poet knocking

Knocking a poet is bound to get you into trouble. Poets fight back, and hard. Just don't do it.


But they're just so damn eloquent all the time. It drives me nuts.


Moxie actually published a nice lighweight port knocking daemon that:

* Does not bind to sockets

* Is not written in C

* Prevents replay attacks

* The only code that runs as root is just tailing kern.log and is like 15 lines

It probably needs to roll from SHA1 to SHA256 and Python2 to Python3, but otherwise seems sound.

[1] https://moxie.org/software/knockknock/


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. :-(

Edit: It appears there may be an active fork here: https://github.com/indyprime/knockknock

Still digging through to see if the encrypt-then-authenticate change made it into this version.

Edit 2: It looks like it still uses authenticate-then-encrypt. I sent an email to the maintainer of that fork, we'll see what happens. ^__^


This is freaking genius!


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.

How I set it up specifically: https://peekread.info/tech/20190513-fwknop/


vpn + port knocking should be good enough but I am not sure how to implement it in an efficient way (I currently only use a VPN)

https://www.howtogeek.com/105693/how-to-knock-into-your-netw...


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 guess if you only have the key, you would still need to figure out how to use it


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.


There's a similar , very sneaky tool: sslh. Practically no automated tools will attempt to SSH into the HTTPS port...


I presume this connects SSH clients, and serves a fake web page to browsers?

Sounds pretty cool, but do SSH clients (e.g. PuTTY need special support for it)


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.


What do you think about single packet authorization?


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!

Needless to say, I bought a new fob.


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 think that's just good old Mr. Bob Itsaboy: https://www.youtube.com/watch?v=9JxhTnWrKYs


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!


Until you forget your phone at home and proceed to lock yourself out of your apartment with no way to call for help!


Ha, that sounds exactly like something I'd do.


This reminded me of a project Paweł Zadrożniak made on the same idea. https://www.youtube.com/watch?v=e9GWteVUYD0 http://silent.org.pl/home/2015/10/04/entry-phone-hack/


I enjoyed your story, but can you please elaborate on what your intercom is / was for?

I understand the key fob/card concept for access purposes, but have never heard of an “intercom” in the context of home/apartment/etc security.


It's a system like a local telephone system, where you dial up to a certain apartment and then they press a button that opens the door for you.


An intercom that lets someone at the gate talk to the apartment in question to try to convince them to buzz them in?


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.


It's like a phone for the yard door. Someone buzzes you, you talk to them and let them in or not.


The intercom would be for a guest to use to request access. See Seinfeld episodes for an example.


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.


*should not need to


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.


At the point where you're installing network cryptography tools to authorize access to your machine, why not just use a real cryptographic tunnel?


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.


This does basically approximate my take on port knocking. :)


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.

https://xkcd.com/538/


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".


Would you mind explaining why fail2ban is bad?


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.

http://cr.yp.to/ucspi-tcp.html


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.

Here's an example of what that would look like:

https://gist.github.com/dcorbett-haproxy/ec7059cbfccf12c8f41...


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.


interesting - would this be an effective way to block portscanners?


Yes.


A fun exercise is to integrate this with TOTP by reloading knockd with a new config every 30 sec based on the secret.


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.

https://wiki.archlinux.org/index.php/Port_knocking#Port_knoc...

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.


For nftables it's even in the upstream documentation https://wiki.nftables.org/wiki-nftables/index.php/Port_knock...


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.

More on this: https://blog.habets.se/2019/11/TCP-MD5.html


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 ```


A recent version of single-packet port knocking is the handshake in the Noise protocol: https://noiseprotocol.org/


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.


Couldn't someone (in the dataplane path) just sniff the knock and observe comms after and replay it later?


Yes but you can defend it against replay attacks if you use a rolling code https://en.wikipedia.org/wiki/Rolling_code


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.


Port knocking is pointless. Just use a password over UDP and stop feeling yourself with your cloak and dagger pretend spy nonsense.


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.


I’m unconvinced that most people use such complicated knocking schemes to contain that many bits.

It’s still trivially sniffed, since it’s sent in the clear.

And it’s hard to change, since you have to change all the places which needs it.


I have created a different approach to accomplish the (somewhat) same goal as port knocking here:

https://github.com/jftuga/gofwd

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.

Thoughts?


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/

We are now using the same technique in a network security product at AppGate which is used to protect highly sensitive workloads around the world. https://www.appgate.com/blog/dont-be-fooled-by-lowercase-sdp...

Port Knocking is great, another layer of defense.


How convoluted. Why not just send the password in a plaintext UDP packet?


Correct.


And to save other folks a search, this is pretty awesome:

https://linux.die.net/man/1/knockd


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?


I use fwknop[0] on my servers. It does single-packet authorization rather than straight port knocking, which solves the replay issue.

[0] https://www.cipherdyne.org/fwknop/


You block a MITM attack with public key cryptography. Port knocking is not meant to stop MITM attacks.


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.


Alternatively, check out "single packet authorization"


TIL. Basically you type in a password. But instead of fingers, you use HTTP requests. And instead of a keyboard, you use server ports.


What if the correct port knock sequence rotates every 15s based on the time and some PSK material, kinda like 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.

https://en.wikipedia.org/wiki/S/KEY


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!


Why is this better than an application taking open requests on one of the ports and accepting a password used to open the other port?


It's not really very secure, but it's used so little that low-end attackers don't bother to attack it.


Port knocking is literally the computer security equivalent of an ADT home security sticker in your front window.


Port knocking is great theatre but not much good for anything else. I guess it can keep logs clear feom some drive by script kiddies.


If your ssh sever had a 0day, port knocking would protect you.


What if your port knocking monitor has a zero day?


Then ssh would protect you. The two having zero days at the same time is unlikely.


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.


Or the monitor being written in c and analyzing text in the knock messages, e.g. looks and interprets a hash


I guess that sort of depends on the nature of the zero day, huh?


That's kind of the idea Moxie had with [1].

Only 15 lines of code run as root, and they basically just tail kern.log.

[1] https://moxie.org/software/knockknock/


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 would think that if you are going to disparage it, you would at least give one example of why it's unnecessary.


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.




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: