Brute.Fail: Watch brute force attacks fail in real time
brute.fail
brute.fail
I felt extremely pleased with myself for about another month, and then my server address got hit with a massive DDOS attack (for me anyway) over my 6MBPS DSL line. So clearly I had hit a nerve somewhere :-). Anyway, I moved my server to a different address and used fail2ban to just note source IPs and put them into the IP tables as banned addresses. That works great and hasn't resulted in the same sort of drama as last time.
Also, it’s not just ssh, there are brute force attacks for pretty much any service that you run
Our logs show automated attempts to run exploits on our web servers everyday
It won't stop a ddos but will certainly, at some point, prevent you from logging in.
If you are logging in via ssh, the chances of being locked out arr low - using password auth is a bad idea, and once you set up ssh keys, the connection will always succeed. And in case of rare event like new system setup, you can always ssh via some other system, -J is great for that.
Not from my experience. If you have too many keys and certain ssh agents like gnome keyring don't pick up the key intelligently and will try a all the keys in some order often resulting in the server giving rejecting you due to too many failures.
But you don't live with it -- you either move the extra keys to subdir, so that gnome keyring does not pick it; or use "IdentitiesOnly yes"/"IdentityFile foo" in .ssh/config to restrict certain hosts to certain keys (and yes, those work with ssh agent caching too).
I know many people just don't care about working tool, and tolerate the pain, but hopefully if someone knows enough to setup fail2ban, they should also be able to setup ssh config. Especially since reliable ssh connections is such a high quality of life improvement.
However I think it's a good habit to make records in `~/.ssh/config` for each of your servers anyway just to keep tabs what, where, who, and with what keys.
I move my port somewhere else to reduce the clutter
> manually look at the logs every once in a while
I imagine that this is more by curiosity than anything else (which is a perfectly normal reason to do that - I do it from time to time just because). For logs analysis and alerting I have automated systems.
> using password auth is a bad idea
It is not if the password is correct, security speaking.
While I'm sure it is possible for some (mainly government) actors to brute force keys, I'm also sure these do not include the same low-hanging-fruit vandals blasting brute force attacks. And I'm also pretty sure you're not one of the select targets of these highly advanced actors.
A vulnerability in sshd is indeed possible and happens once in a while. Fail2Ban won't stop this though because a known exploit will let them through on the first attempt.
I personally view fail2ban more as nuisance control when it comes to SSH with password auth disabled. Minimizing the log crap, the wasted CPU resources by the failed handshakes. It's not really a security protection in that scenario. In other cases (e.g. web logins where passwords must be used) it of course is.
You keep using that word. I do not think it means what you think it means.
btw TCP is cheap compared to public key crypto
It feels very like a "key under the third plant on the right" kinda thing. Not a solid security measure.
It's too much bother to go find it, and the bozos will just move on to the next machine with port 22 open.
But I know I'm a bit of an absolutist on security.
But you also put it in the shed, and lock the shed.
It’s like how an adversary might launch a DDoS attack at the same time as they exploit a SQL injection vulnerability to exfiltrate credit card information. Filling up logs and alerts overwhelms the blue team and makes it harder to notice the quieter, but more dangerous attack.
Fail2ban keeps my log short enough that I can review them daily, I don't have to sift through thousands of login attempt.
> It won't stop a ddos but will certainly, at some point, prevent you from logging in.
Yup, losing my key and having no password access will do that.
I am pretty sure we turned off password authentication like 10 posts up this thread.
I have fail2ban configured to block IPs with invalid private keys after a couple attempts, and if the key is valid to email me and rate limit invalid password attempts.
This gives a more than sufficient warning if my key leaks which is already very unlikely, and this just makes it much more unlikely for both to be compromised, and only took an extra 5 minutes to configure.
logpath = /var/log/auth.log
and for the filter I use failregex = .*Connection closed by authenticating user [a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\$) <HOST> port [0-9]* \[preauth\]
and the emails are just cron with a python script that checks /var/log/fail2ban.log for any new Found|Ban|Unban IPs and sends them using smtplibIf you like I can share the full config files but the rest isn't too interesting nor different from what is here https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Jails
> Yup, losing my key and having no password access will do that.
You can also lose your password. Or forget it if you know it by heart. But in any case you can use a password instead of a key - it just needs to be good enough (= long and not in cracking dictionaries)
If it's a file that nothing on your site links to, and doesn't really "exist" how would google ever index it? Especially if you put in as a deny in robots.txt, which as far as I'm aware, Google honors.
Seriously this is both hilarious and intriguing and deserves a long form blog post or something.
I have requested /etc/shadow, cracked the hash for root password, and ssh'd back into the botnet node that was bruteforcing passwords. I then shared the information with the webhoster where the botnet was running and a local infamous antivirus company (Avast before it was leaked that they are evil) and got a t-shirt.
https://www.abclinuxu.cz/blog/jenda/2019/2/exploiting-mysql-...
As a curiosity, I found the submission link in the comments on that thread https://news.ycombinator.com/item?id=19305823
EDIT: Unless it's happening on the server side where it's being saved, I don't think they're being escaped:
col1.innerHTML = '<span class="fi fi-' + msg.cc + '" title="' + msg.cc + '"></span> ' + msg.src;
col2.innerHTML = msg.proto;
col3.innerHTML = '<code>' + msg.u + '</code>';
col4.innerHTML = '<code>' + msg.p + '</code>';Since there's multiple opportunities to inject code, it's possible to split out the payload across multiple fields: https://www.highseverity.com/2011/06/xss-in-confined-spaces....
Ten characters per block is enough for:
<script>/*
*/eval(/*
*/'....'+/*
*/'....'+/*
*/'....'+/*
...
*/)/*
*/</script>
Best to escape everything at render time.JS has sane APIs where no string is "dangerous," use them.
The equivalent code is really not that hard:
const span = document.createElement('span')
span.setAttribute('class', 'fi fi'+msg.cc)
span.setAttribute('title', msg.cc)
col1.appendChild(span)
col1.appendChild(document.createTextNode(msg.src))
col2.textContent = msg.proto
let code = document.createElement('code')
code.textContent = msg.u
col3.appendChild(code)
code = code.cloneNode(true)
code.textContent = msg.p
col4.appendChild(code)
or something in these lines.. you get the ideaAlso started using Crowdsec recently, but not sure about if it's worth it...
fail2ban out of the box works fine for SSH, but for dovecot and postfix it's somehow broken, and the configuration scripts are just too obtuse.
Endlessh is an SSH tarpit that very slowly sends an endless, random SSH banner. It keeps SSH clients locked up for hours or even days at a time. The purpose is to put your real SSH server on another port and then let the script kiddies get stuck in this tarpit instead of bothering a real server.
Since the tarpit is in the banner before any cryptographic exchange occurs, this program doesn't depend on any cryptographic libraries. It's a simple, single-threaded, standalone C program. It uses poll() to trap multiple clients at a time.
https://www.abuseipdb.com/check/178.62.237.183
Unfortunately, it only wasted 30 seconds of that IP's time.
It's not clear what type of tarpit would waste the most of the operator's time. Maybe something like a "byzantine VM", that seems exploitable, takes payloads, passes initial checks, and then starts having "problems". DDOS attacks redirect to the C&C server. Coin miners report false mined coins. Hosted files have corruption, and won't complete transfer, etc. Whatever it is, it needs to somehow seem like the operator has an error in their code :)
Shodan will find and fingerprint you easily enough.
A nice aspect of wireguard is that it's "steath", meaning that it does not respond to unauthenticated connections at all, so there is no way to probe and scan for wireguard listeners at all.
I think setting up daemons behind wireguard offers a lot of security. SSHD is probably fine to expose, but something like an IRC bouncer for example really benefits from being protected I think.
I use ZNC over wireguard for this reason! It also allows to use ZNC securely without the need to setup TLS certs, which IME is actually harder than setting up wireguard!
I did not know this. That’s really cool.
Is it done over a stateless protocol like UDP, or is a TCP connection opened first? Ie. is it impossible to see if there’s even a server there at all, or is it first revealed that there’s a server accepting a TCP connection?
I just changed my server, and uninstalled the - now truly useless - fail2ban. I use SSH keys of course, but without fail2ban my server's logs were constantly flooded with hacking attempts.
No longer - wireguard for the win. Thank you, chlorion!
So I guess the problem isn't going away.
also, who has sshd without `PermitRootPassword=no`? they need to broaden their horizons and try `admin`, `ec2-user`, and `ubuntu` /s
Why?
The benefits are largely theoretical if you choose sufficiently strong randomly generated passphrases, with some symbols and numbers mixed in, which I set my password manager to do. (Actually, I have a couple of super important, super long ones I keep only in my head.)
The draw-backs however are several:
1. I find that its not uncommon I find myself having to chain together ssh tunnels and other strange things to debug networking issues and need to login to another machine from a new machine that doesn't have the ssh-key. Treating servers as cattle exacerbates this issue since it's more likely to occur.
2. If a machine or server I use to manage stuff as a gateway/proxy/vpn entry to my network has all my ssh keys on it, and it becomes compromised because of some 0-day, the attacker now basically has access to... multiple entire networks. Now, this is technically true of my password manager as well, except that the context / IP addresses, etc, is not going to be as obvious as it will be on the server where the attacker can see the running services, check logs, command histories, etc. With the password-based management, sure I could get hit by a keylogger, but everything won't be compromised by default.
3. In my experience, you're more likely to lock yourself out than let an attacker in. You basically still have to have your keys managed via some type of password manager anyway because otherwise you run the risk of getting locked out of everything in case you're away from your primary machine and need to address some emergency or something.
> gateway/proxy/vpn entry to my network has all my ssh keys on it, and it becomes compromised because of some 0-day, the attacker now basically has access to... multiple entire networks
That's why you use SSH agent forwarding https://docs.github.com/en/authentication/connecting-to-gith..., so you never need to copy the private keys to other computers, and thus they can't be stolen from there.
Your private keys shouldn't even be accessible to you, they should be on a secure enclave like a yubikey, and you should forward the token along the chains. No risks, and basically painless, especially if you switch to certs so you don't even have to know the public keys ahead of time on the servers, just all trust the same private PKI.
That’s not the only reason or way to use SSH keys. Even when stored on disk (in plaintext or encrypted) they offer advantages over password authentication, e.g. making it impossible for an MITM to steal credentials or impersonate an authenticated client even without validating host keys.
Public key authentication isn’t just providing more entropy than passwords.
Passwords (as used in SSH) are bearer tokens – send yours to the wrong server, once, and you‘re compromised, for this and future sessions. That’s not the case with public key authentication.
A man in the middle attack where you accept the server key can steal your password, but it can’t your key.
If you're asking why it would ever be worth it, there's always valuable stuff online with incompetent configuration. I don't know if shodan is still up, but I remember going on there in high school and getting access to random webcams (sometimes in peoples' homes)
Why do you ask, because it is dangerous?
I would love to learn something here.
Why isn't there (or is there) some kind of service you can use to map some crazy URL to your personalip:port, like...
http://obscuremyshit.com/393nnasjhf83u98723401 = personalip:port
And only when a connection is referred from that source, does the RDP server even expose itself? And for all other traffic that hits personalip:port, it does absolutely nothing?
A solution on top of that would be for this obscuremyshit.com service to have a client-side listener. So if I get a hit on the page obscuremyshit.com/393nnasjhf83u98723401 from IP x.y.z, the obscuremyshit client running on the target cimputer gets a signal from the obscuremyshit server to "Open port 22 and allow a connection from the IP x.y.z" (I guess that means the client would have to be in control of the firewall rules), and then the computer with the IP x.y.z would have to establish a connection within a timeframe.
Of course it would get more complicated if e.g. the above URL is hit from a different IP address (e.g. from someone's phone over 5G, and the SSH connection wants to come from a laptop over a cafe WiFi).
You might be able to do this by responding with a hyperlink which points to ssh://x.x.x.x:1234
Some browsers will recognize that format and pass to an ssh client application to spawn an appropriate ssh connection.
The reason why it's not a worthwhile idea is that there is a limit of 65535 ports to chose from on a given IP address and they all can be scanned pretty quickly in order to locate an active SSH service port. This really makes the URL idea ineffective.
Port-knocking may be a little bit more effective because the SSH service will not reply to a connection request unless you've attempted to establish a connection on a different port first. Scanning for an open SSH service becomes much more difficult.
Is code available anywhere?
I run a slowly growing network of SSH honeypots that do central logging (Greylog), that I’ve been meaning to document the setup of for here somewhen.
Bolting something like this onto that would be pretty funny.
It is only processing SSH attempts from 3 hosts right now (one in colo, one EC2, one DigitalOcean) because when I pointed the full firehose at it the user experience of the website wasn't great.
(I've tried 2 years ago: at that time even aws is not able to provide a reliable EU ip list)
A custom fail2ban jail adds all IPs that get blocked by the Tcp Wrappers to the system's firewall.
I did get one report that it was blocked by a corporate network because the domain was newly registered.
You could push an updated list to Cloudflare KV every few seconds and have the front end poll it from there for cheap and near unlimited scalability.
I actually much prefer the projects that give the caller a fake shell, and watch what they type after "breaking in." It'd be the Kitboga of ssh attacks :-D
Oh YES! Do it, please! We could learn a lot!
That said, the fail2ban defaults are way too low and I've locked myself out with them. They can be turned way up (ban after way many more attempts) so that there's no risk of locking out legitimate users. (Assuming your users didn't forget their exact password and then generated a small dictionary to try with.) On a server with potential misconfiguration, accepting passwords is one of them.
Even if someone was to steal my keys or knock at my ssh servers with a zero-day, I will be alerted[0] of any successful login(s).
Once there are more than thirty rows, you fade rows in like this:
row.style.opacity = 0;
let intervalId = setInterval(function() {
opacity = Number(window.getComputedStyle(row).getPropertyValue("opacity"));
if (opacity < 1) {
opacity = opacity + 0.1;
row.style.opacity = opacity;
} else {
clearInterval(intervalId);
}
}, 100);
This would be better done with a CSS animation or transition—it takes less code, and is smoother.My suggestion: use animation. Replace the JavaScript with this:
row.classList.add("fade-in");
And add this CSS: .fade-in {
animation: 1s fade-in;
}
@keyframes fade-in {
from { opacity: 0; }
}
This does behave a little differently, as if the window isn’t visible, it’ll (roughly) wait until you focus the window before playing the animation. Frankly this is even mildly more desirable.The alternative: use transitions, which are a tad more involved because you have to trigger the value change one frame later, so that it recognises that something has changed and interpolates to it, rather than it just being the initial value and applied instantly. This JS would do:
row.style.transition = "1s opacity";
row.style.opacity = 0;
requestAnimationFrame(() => {
row.style.opacity = 1;
});
Or you could express it with more CSS, like with this CSS + JS: tr {
transition: 1s opacity;
}
.invisible {
opacity: 0;
}
row.classList.add("invisible");
requestAnimationFrame(() => {
row.classList.remove("invisible");
});
—⁂—You might also like `vertical-align: middle` on your spin.svg.
—⁂—
On the flag icons, here’s a cool alternative technique: https://en.wikipedia.org/wiki/Regional_indicator_symbol. Lets you avoid needing even images. Unfortunately, I think Windows still doesn’t ship flags, so you’ll get the two-letter country code there. You can get around this by packaging a web font. It’d be nice if someone would neatly package a flags-only font so others can easily use it. Here’s what I did a few months back for https://ganintegrity.com/country-profiles/, resulting in a single 77KB font file:
/**
Copyright 2020 Twitter, Inc and other contributors
Graphics licensed under CC-BY 4.0: https://creativecommons.org/licenses/by/4.0/
Twemoji Mozilla packaging via https://github.com/mozilla/twemoji-colr, subset to only include country flags.
*/
@font-face {
font-family: flag;
/* (Generated with `pyftsubset /opt/firefox-nightly/fonts/TwemojiMozilla.ttf --unicodes="U+1F1E6-1F1FF" --output-file=static/TwemojiMozillaFlags.woff2 --flavor=woff2`.) */
src: url(/static/TwemojiMozillaFlags.woff2) format("woff2");
}
/* Why do we do this? Because at the time of writing Windows doesn’t do flags, so ‹guzzled by HN› will look like “ᴀᴜ” rather than an Australian flag. (macOS and major browsers on Linux do.) */
.flag {
font-family: flag;
}You'd think that would be enough for them to stop, but I have some IPs with 25k connection attempts over a 90 day span. (Of course it had to be someone using digitalocean)
While there may be millions of useless attempts, it only takes 1 to get through.
Of course SSH has a great option in key / certificate auth. So if that's enforced it's not such a big deal. Many other systems don't (at least not until we finally implement Passkeys everywhere).
Lets put 20 unpatched linux computers on every network and see how that goes.
Just curious, why x out the IP at all?
Trying to avoid being a jerk. The sources are likely hacked boxes where the owner has no idea.
Been there, done that. Most isps and providers don't respond or act on abuse complaints anymore.
There are lists updated in real time by white hats, sharing exact IP of machines known to be engaging in bad behavior. You can, if you want, update your servers in real-time from these lists and then act accordingly: drop the traffic, reject the trafic, serve a "your IP address is participating in brute forcing attempts" page, etc.
FWIW some ISPs may be monitoring these looking for IPs on their subnets and acting accordingly.
It's not about "being a jerk". It's about giving attackers the middle finger.
Are you open sourcing this?
Can others stream their logs to your servers and have a crowdsourced list of attackers in real time together with their activity?
Wish the ISPs would subscribe to this and blocked traffic from the abusive IPs in their networks
Clicked on a random IP on the front page, it said it’s from Palo Alto Networks in Santa Clara, that it was first reported in 2022 and the last report was 5min ago. So that IP has been doing shady stuff for months and it seems their ISP (Palo Alto Networks) doesn’t really care
> No legitimate services are offered on the addresses receiving these attempts, so there is no chance of a real user accidently submitting their credentials.
Sure, the risk of compromise goes up, but the whole culture of "we only sent those passwords once on unencrypted ftp across the internet" leads to powerful nation state spies having a field day...
If all unencrypted data sent over the internet were in a big public archive for everyone to see, then people would soon clean up their security habits.
No legitimate services are offered on the addresses receiving these attempts, so there is no chance of a real user accidently submitting their credentials. (Yes things other than SSH occasionally show up)
Like what?
Also, suppressing these logs is the same as rapidly rotating new logs.
Hi