Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The thing about port knocking is that if you're on a host where you don't have the ability to port-knock, then you're not able to connect.

This can turn into a footgun: you're away from your usual device, something happens and you desperately need to connect, but now you can't because all the devices in your vicinity don't have the ability to perform $SECURITY_FEATURE_X so that you can connect, and you're screaming at yourself for adding so much security at the expense of convenience.

This could happen as easily as restricting logins to SSH keys only, and not being able to use your SSH key on whatever host you have available at the time, wishing you'd have enabled password authentication.



> The thing about port knocking is that if you're on a host where you don't have the ability to port-knock, then you're not able to connect.

If that's important, one should be able to set up port knocking such that you're able to do the knocks even by changing the port in a sequence by hand on e.g. a web browser address bar.


Note that port knocking is vulnerable to replay attacks. Single Packet Authentication is better, but requires a private key (can be your SSH key).

https://www.cipherdyne.org/fwknop/


Naive knocking isn't good as a primary security mechanism, but it lowers your attack surface and adds defense in depth.

It means that people who can't intercept traffic can't talk to the ssh server-- and that's most attackers at the beginning phases of an attack. And even someone who can intercept traffic needs to wait for actual administrative activity.


Defense in depth has value I agree, but I think it can also be counterproductive in some cases. Every layer can also be buggy and have vulnerabilities, which can often leak (e.g. into code execution) and compromise the whole system (bypassing layers). What happened in this case seems to be a case of maintained hijacking and introducing vulnerabilities. Adding an additional dependency (of say a port-knocking library) doesn't look great in that regard, if the dependency can be hijacked to add remote code execution capabilities. And that library is likely a lot less scrutinized than OpenSSH!

Also underrated I think is security by simplicity. OpenSSH should be extremely simple and easy to understand, such that every proposal and change could be easily scrutinized. Cryptographic constructions themselves are almost mathematically proven invulnerable, then a small codebase can go most of the way to mathematically provable security (bonus points for formal verification).

But for this kind of system there's usually some kind of human vulnerability (e.g. system updates for your distro) in the loop such that the community needs to remain watchful. (It's fun to consider an application that's proven correct and doesn't need updating every again, but usually that's not practical)


> Adding an additional dependency (of say a port-knocking library) doesn't look great in that regard, if the dependency can be hijacked to add remote code execution capabilities.

Port knocking infrastructure can be minimal, knowing nothing but addresses knocking. It can also be completely outside the protected service on a gateway.

Indeed, it can even be no-code, e.g. https://www.digitalocean.com/community/tutorials/how-to-conf...

> OpenSSH should be extremely simple and easy to understand, such that every proposal and change could be easily scrutinized.

But OpenSSH intrinsically is going to have a much larger attack surface.

> then a small codebase can go most of the way to mathematically provable security (bonus points for formal verification).

It's worth noting this would not have helped against this attack:

* It was against another dependency, not openssh

* The actual vulnerability didn't occur in the code you'd inspect as part of verification processes today. (I don't think anyone is formally verifying build process).


Good points, I would say that defense in depth is useful when the layers of defense need to all be broken (more or less) independently for a successful attack (this fails only if you add layers that expose vulnerabities compromising your system). E.g. usually a sandbox satisfies this criterion.

Also, whenever some layers may allow compromising everything, the supply chains of the layers should be minimal or correlated (same supplier), to avoid increasing such supply chain risks.


What if the knocking sequence was derived from a TOTP secret?


Don't have to do anything too complicated. Here's the knocker code in a short Bash script, produced by GPT4:

~ % gpt4 'write a very short bash script that takes the number stored in ~/.ssh/knock_seq, increments it by 1 and saves it to the file. It then takes the new number and concatenates it with the value stored in the file ~/.ssh/secret. It pipes the resulting string to sha1sum, spitting out binary. It then takes both the resulting sha1sum and the number used and pipes their concatenation to "nc -u $host $(cat ~/.ssh/knocking_port)". be brief'

  knock_seq=$(cat ~/.ssh/knock_seq)
  let knock_seq++
  echo $knock_seq > ~/.ssh/knock_seq
  concat_seq_secret=$(echo -n "${knock_seq}$(cat ~/.ssh/secret)")
  sha1_output=$(echo -n $concat_seq_secret | sha1sum -b | awk '{print $1}')
  final_output="${sha1_output}${knock_seq}"
  host=localhost
  knocking_port=$(cat ~/.ssh/knocking_port)
  echo -n $final_output | nc -u $host $knocking_port


The knockee PoC should also be straightforward, can use socat + udp-listen + fork with a script that checks that input matches `sha1sum(secret||num)||num` and `num>previously_seen_num`, and if so, adds an iptables rule.

This should prevent against replays. Throw in some rate limits somewhere maybe to not get DDoSed, especially if you let socat `fork`.


Definitely some fun project to try


Ooo, that's a fun idea


Not if you set it up such that each knocking sequence can only be used once. Port knocking is a flexible concept.


I wonder if one could combine port knocking and TOTP in some way, so the sequence is determined by the TOTP?

(Security is not my thing; don't judge me!)


Was just having the same thought reading this thread.


Yeah you could but wouldn’t it defeat the purpose of being basically a secret knock before you can give the password? The password should be the ssh password.


This would be just to allow you to connect to the server. If there was a vulnerable sshd on port 22, an adversary would have to know the port knocking sequence to connect to sshd and run the exploit.


This looks related to some other problem: - There is Alice's server which provide service X - There are clients like Bob who needs this service. - There is Mallory who thinks clients doesn't need such service. Mallory have significant resources (more than Alice or Bob). - Mallory thinks it's ok to block access to Alice' server IF it's known that it's Alice's server and not some random site. Mallory sometimes also thinks it's ok to block if protocol is unknown.

This problem solved by XRay in all of it's versions. It could be possible (if overkill) to use mostly same methods to authenticate correct user and provide eir access.


> The thing about port knocking is that if you're on a host where you don't have the ability to port-knock, then you're not able to connect.

You can type http://hostname:porttoknock in a browser.

As long as you're not behind a super restrictive gateway that doesn't let you connect to arbitrary ports, you're golden.


I've actually been behind a firewall that blocked outgoing connections except on several well-known ports. Had to run my SSH server over the port usually used for HTTPS just to get it unblocked.


Some versions of port knocking require a specific type of packet.

https://github.com/moxie0/knockknock


Likely won't be enough if you're behind CGNAT and you get a different public IP on different connections.


Most decent CGNAT will give you the same source IP when you connect to the same dest IP repeatedly.


It seems like there’d be a pretty big overlap between those kinds of hosts.


I'm a bit of a noob about this. Can you explain what this means?


Port knocking involves sending a packet to certain ports on a host. It's overkill but typing http://host:port/ in your browser will, as part of trying to make a TCP connection, send a packet to that port.


Thanks, I didn't realize port knocking could be done manually like this as a way to "unlock" an eventual regular ssh attempt outside the browser. This makes sense now and is super clever!


TIL another interesting browser feature. Thank you.


That's just the usual way of attempting to connect to an HTTP server running on a different port. Sometimes you see websites hosted on port 8080 or something like that.


Oh. Duh.

I suppose I should have said it was a new-to-me use case for that feature.


Absolutely, everything in security is a tradeoff. I guess the real point is that there should be layers, and even though you should never rely on security through obscurity, you should still probably have a bit of obscurity in the mix.


I wouldn't really consider port knocking to be that effective of a way to block connections. It is really only obscure, but port knocking software is very accessible. So if you know a port needs to be knocked, it's not hard for an attacker to get to it.

The main benefit of port knocking is that it allows you to present your ports as normally closed. If you have a system and you are worried about it getting port scanned for whatever reason, it makes sense to have a scheme where the ports are closed unless it receives a knock. So if someone gets access they shouldn't for whatever reason and pulls a portscan off, the information they get about your system is somewhat limited.

In this scheme, it would be much better to have an access point you authenticate with and then that handles the port knocking for the other devices. So it is a kind of obscure method that is really only useful in a specific use case.

As far as SSH keys go, I would argue that SSH support is so ubiquitous, and SSH access is so powerful that it is a reasonable security tradeoff. I also don't think that SSH ports should be exposed to the internet, unless it is a specific use case where that is the whole point, like GitHub. I'm very down on connecting directly through SSH without network access. The xz situation has validated this opinion.

I personally don't know any application where you really need supreme admin access to every device, from any device, from anywhere in the world, while at the same time it has extreme security requirements. That's a pretty big task. At that point, constructing a dedicated, hardened access point that faces the internet and grants access to other devices is probably the way to go.


> I'm very down on connecting directly through SSH without network access. The xz situation has validated this opinion.

Did it? At the point an attacker has remote code execution, couldn't they just as easily pivot into an outgoing connection to some command and control server? I don't see how some intermediary access point would have alleviated this problem. If the call is coming from inside the house, the gig is already up.


> At the point an attacker has remote code execution

The attacker doesn't have remote code execution in the xz case unless they can speak to your port 22. Port knocking prevents them from doing so, provided they don't know how to knock.


Assuming they have injected code into the sshd executable, couldn't that code just do the exploit without a connection? What I'm saying is that the structure of this payload is the way it is because sshd is accessible. Had it not been accessible, the payload just wouldn't have required an external connection.


I mean, this is the twisting logic. xy hack put's a backdoor in sshd. You need to access sshd port to go through the back door and get RCE. Hacker could have put something even more nefarious that could phone home somewhere. We would like to think that would have been a little easier to spot, but who knows.

To me, that is what makes this hack so noteworthy. Hacker got access, and then kept playing the long game. Very spooky. And yes, someone capable of this probably has a plan for gaining network access if they had a target in mind. Even with best security practice, this rabbit hole goes pretty deep.


Port knocking with ssh over https using client certs.

And port knocking is one of the few effective methods against the standard distributed brute forcing slow attacks.

Note if you blanket-ban IN/RU/UK/CN/HK/TW/IR/MX/BZ/BA + tor/proxies lists, than 99.998% of your nuisance traffic issues disappear overnight. =)


> if you blanket-ban IN/RU/UK/CN/HK/TW/IR/MX/BZ/BA

The list of countries there: India, Russia, United Kingdom, China, Hong Kong, Taiwan, Iran, Mexico, Belize, Bosnia and Herzegovina

I’m amused that the UK is in that group.


I was too, but the past few years their government server blocks have been pen-testing servers without authorization.

It is apparently a free service they offer people even when told to get stuffed.

=)

My spastic ban-hammer active-response list i.e. the entire block gets temporarily black-holed with a single violation: AU BG BR BZ CN ES EE FR GB HR IL IN ID IR IQ JP KG KR KP KW LV MM MX NI NL PA PE PK PL RO RU RS SE SG TW TH TR YE VN UA ZA ZZ


can you give an example for an implementation of portnocking/ssh/over https and client certs?


In general, it is a standard shore-wall firewall rule in perl, and the standard ssh protocol wrapper mod.

These are very well documented tricks, and when combined with a standard port 22 and interleaved knock ports tripwire 5 day ban rules... are quite effective against scanners too.

I am currently on the clock, so can't write up a detailed tutorial right now.

Best regards, =)


You just described the problem with using keys for any login, like the latest fad is?

And generally with depending on a device (phone, xxxkey or whatever) for access.


At least TOTP is just a long, random, server-assigned password, where you you don't type the whole thing into during login attempts.

You can write down the full TOTP secret, and make new 'TOTP keys' whenever you want. Suggested apps: Firefox Extension named "TOTP", and Android App named "Secur". You don't need the heavier apps that want you to create accounts with their company.

Using a TOTP key only provides a little more protection than any other complex password, since you're not typing in the whole thing during a login attempt.


My solution to this has been creating a public bastion server and use Wireguard. Wireguard listens on a random UDP port (port knocking is more difficult here.) This client is set up to have a dynamic endpoint so I don't need to worry about whitelisting. The key and port information are stored in a password manager like Vaultwarden with the appropriate documentation to connect. Firewall rules are set to reject on all other ports and it doesn't respond to ICMP packets either. A lot of that is security through obscurity but I found this to be a good balance of security and practicality.


I've seen this discussed a fair bit, and always the recommendation is to use wire guard and expose ssh only to the "local network" e.g. https://bugs.gentoo.org/928134#c38

First, I don't see how this works where there's a single server (e.g. colocation).

Second, doesn't that just make Wireguard the new hack target? How does this actually mitigate the risk?


> The thing about port knocking is that if you're on a host where you don't have the ability to port-knock, then you're not able to connect.

Then you attach a device that can have port knocking to that unsupported host. Also, I remember it was called port punching not knocking.


You can as well find yourself on a host that doesn't have SSH or network that filters SSH traffic for security reasons.



What does this have to do with port knocking?


This is great but would this neutralize the xz backdoor? The backdoor circumvents authentication, doesn't it?




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

Search: