Some thoughts on OpenSSH 9.8's PerSourcePenalties feature
utcc.utoronto.ca
utcc.utoronto.ca
https://www.linuxtopia.org/Linux_Firewall_iptables/x4448.htm...
For example, if an attack could spoof traffic to get two different reflectors hall-of-mirror-ing each other, or using a botnet that spoofs traffic to get one collection of dupes to slam a single victim in response, etc.
So looks like this openssh feature is a decade late.
Even so, I don't know why OpenSSH hasn't implemented it instead of the the silly fail2ban theatre we're discussing in these comments.
I just checked knockd man page and it turns out it can use a one_time_sequences file that contains a sequence of port knock combinations. I wonder if this file is dynamically checked, or loaded and parsed during startup? Or could one simply echo the TOTP code straight into that file and hup the knockd service each time (let's say the TOTP interval was set to something like 5 minutes).
I'm totally gonna do this.
You're wanting to add a screen door on a sub, and its just a feel good option for those who don't understand the math involved.
The proper solution is to stop using passwords and use keys or proper cert auth.
A timed job that checks the up of your clients and updates the firewall every 30 seconds seems a much more secure method than having a magic sequence of ports that can be captured in the wild.
It’s hard to spoof a full tcp connection (with a key) needed to update your ddns.
Best part is you can leave your ddns to a separate box or service which complicates the compromise of a single host
The post says: "Right now our perimeter firewall is blind to whether a brief SSH connection was successful or not"
(I suspect there's a way to set up centralised logging and fail2ban running looking at those centralised logs and sending updates to a perimeter firewall, but that's not a typical deployment of fail2ban. Or at least is wasn't when I was heavily using it a while back.)
I've had some dreams of a "tighter" sshd for my universe and have toyed (unsuccessfully) with a Go one.
Anyone want to share their experience?
My own experience with this is not as much with SSH as with SMTP. If your particular IP emits a single non-deliverable message every 30 minutes or so, that's fine.
But: more than a handful of SPF failures for the same sender/recipient combo within 10 minutes or so? Yeah, you're now on the general-deny-list. And persisting even then? Automagically tar-pitted on the firewall, and have fun...
What is the advantage of bothering to do this?
To me, it seems like you're risking blocking legitimate traffic (as two obvious examples, in cases where a sending mailserver is temporarily misconfigured, or if a malicious mailserver is using a cloud IP that is later recycled to a completely unrelated user), for basically zero upside.
For SMTP: log optimization.
Like: yeah, I don't care that you're self-DDOSing if you're an actual spammer. But, just in case you're a legitimate sender lacking SPF records, and you just need some help, I still want some kind of signal.
For SSH, I guess you might want something similar, just to catch authorized-yet-misconfigured remotes...
Thus, the default unit of IPv6 blocking must be a /48. This situation will persist for as long as /48s are readily available at the same price as /64s.
Perversely, the reason we don't have this issue in IPv4 space is because the address space is of the same order of magnitude as the number of potential users. That artificial scarcity means that a routable /24 is x256 the cost of a end-user /32, so the unit of blocking can be a /32.
Do we not? And is it really?
There are some /32 IPv4 addresses hosting many users, e.g. with CG-NAT, and it's already an issue with regards to blocking/rate-limiting.
Just like there are single-user /48s and multi-user /64s, there can be single-user /32s and /32s hosting tons of users behind a CG-NAT.
The difference I'm pointing out between IPv4 and IPv6 is that nobody is giving single IPv4 users /24s for their own use. But IPv6 /48s (which are theoretically somewhat equivalent to IPv4 /24s) are freely available. This is a problem because it makes over-blocking even more likely than it already is. And as you point out elsewhere, over-blocking is already an issue in IPv4 space.
I guess in practice, it's more like IPv4 /24 = IPv6 /48, though. The closest analog to an IPv4 /32 would probably be an IPv6 /64.
If you have two addresses in neighboring /64s (same initial 63 bits), or in general within the same /48 (same initial 48 bits), you know almost certainly that they are somehow within the same organization. They could be within the same building, or in the same company, or using the same ISP or cloud provider; you don't know, but they are somehow related. How do you know? Well, since a /49 isn't individually routable in BGP, they have to _somehow_ originate at the same upstream network. There has to be some sort of cooperation between them (possibly through an ISP as a middleman).
But if they are in _neighboring_ /48s, you don't have this kind of guarantee. They could be from completely different organizations. Most likely, they are on the same continent (since they were given out by the same regional internet registry; RIR), but even that is not really guaranteed.
So when you are bucketing addresses for rate limiting purposes, a /48 is a reasonable place to start doing that, just like /24 is for IPv4. Of course, you may need to get smarter than that (e.g. an attacker could have access to a /32), but it's a reasonable starting spot.
I've encountered assumptions such as this one as a user, and they're really frustrating.
More than once I've found myself banned from being able to log in, view a site etc. because of somebody else's bad behavior I temporarily share a CG-NAT or large public Wi-Fi with, or more likely because somebody topologically close to me got hacked.
Meanwhile, actual attackers are using pretty much the entire IPv4 space worth of compromised embedded devices spread across the globe...
gnfargbl didn't say the _address_ was unroutable, but that effectively, routing policies mean that /48 is a common minimum unit for administrative purposes (similar to how /24 has a special “minimum size” meaning for IPv4).
ie Single Packet Authorization
Wrapping your ssh with wireguard (because wireguard doesn't respond without a full key) doesn't feel too good.
Vulnerabilities lurk in overly complex software with a thousand bells and whistles. By reducing the code paths you’re making software that is much easier to audit and fuzz.
What works in OpenSSH that doesn't work in OpenBSD? Maybe it's as simple as, though under the same umbrella OpenSSH uses a different team, methodology, etc.
More than anything else though, it's not so much that OpenBSD is less resilient than Linux (I think a case could be made), and more that OpenBSD isn't materially more secure.
They should have killed the "only N K holes in Z time" tagline a long time ago.
The OP is a prime example of the opposite happening - it's adding code to prevent repeated authentication failures. Why would this be needed in the first place? If you have configured OpenSSH correctly (that is, using public key authentication instead of password auth, which should not even be an option), then repeated authentication failures should not be a problem. At worst, they take up some CPU time.
Much of the code in OpenBSD and the wider OpenBSD projects also address memory safety issues which would not be issues in the first place if they just used a memory safe language. Yet they push ahead using C in the full knowledge that there are better options available. Java, Go, Python, Rust, I literally don't care, anything would be better than C. Developers should not need to spend hours carefully poring over each others patches to find critical mistakes when it comes to memory. They should not need to spend hours reading C development guidelines or rely on mailing list oracles. By eliminating memory errors as a class, mental capacity is freed up to identify logic errors.
I am also skeptical to your claim about removing memory bugs freeing up brain space for logic bugs, at least for Rust. Rust has grown quite a number of language features, that in my experience, result in a higher cognitive load compared to C. If you seriously reduce your reliance on the C macro system (as Plan 9 has shown possible), the language itself is quite simple.
Things have gotten better in recent years with things like pledge and doas, but they are quite lacking compared to proper MAC or sandbox implementations. Worse, many of the OpenBSD devs don't seem to know much about those technologies and are kind of dismissive. I remember an OBSD user or enthusiast trying to argue Pledge was equivalent to SELinux which was pretty bad.
I'd take a slimmed down hardened Linux install over OpenBSD any day of the week.
I'm not sure what is meant by "protect against the case where there is a remote root hole". Do you mean, to mitigate harm from existing holes? They secure things from top to bottom, but maybe you mean some kind of authorization issues? To proactively prevent holes? They do a lot of engineering around the latter (and around other attacks) - to the extent that many question the wisdom of solving 'problems' for which there is no proven exploit. And they have had very few remote holes - whatever the reason, there's not evidence that they fail to prevent them.
I don't understand how this is ambiguous. I mean limit the damage that an attacker can do if they get root - this is something RHEL can do and OBSD pretty much refuses to.
> They secure things from top to bottom
Eh. Kind of. The devs are against security technologies that they think add too much complexity to their system regardless of benefits. That's why they don't have any kind of RBAC or MAC, just plain old DAC. You get root, you get everything - pledge and unveil won't help too much there.
It wasn't an attack, but a genuine question, for which I provided two possible interpretations. I was (am) interested in what you were saying.
> That's why they don't have any kind of RBAC or MAC, just plain old DAC. You get root, you get everything - pledge and unveil won't help too much there.
Thanks for explaining.
No worries at all! I wasn't taking it as an attack and apologies if my response seemed combative. I just honestly didn't understand where the point of confusion was.
> Thanks for explaining.
My pleasure! If you're still interested in discussing, I am interested in the point you made that 'They secure things from top to bottom' - if I may ask, why do you think this is the case? It's not a statement I would ever make myself.
Does this distrust go to the extent where confronted with a public Internet-facing, stock OpenBSD with a TLS-secured SSH connection, and a GSA hardened RHEL 8 [1] with a similar SSH configuration, they’ll pick the RHEL instance?
If both OSes had a remote root hole, on OpenBSD you would have carte blanche to do whatever, on the RHEL system you would be able to do very little.
It doesn't matter if an attacker gets your (or the server's) public key.