Endlessh-go: a Golang SSH tarpit that traps bots/scanners
github.com
github.com
What the author may be missing is that golang also works well for bots and scanners, for exactly the same reason. Attackers' time isn't being "wasted" by this, their goroutines are just sitting idle for longer.
Another detail is that an attacker with many idle connections to your host might not instantiate any new ones.
Of course, in the scenarios where the attacker is not using goroutines then you have the upper hand as well.
Once someone has deemed you a worthwhile target and is carefully proving all ports, these more nuanced approaches become more worthwhile. Even then, a sophisticated adversary may have many unique src IPs at their disposal.
In over 10 years I've never had a single probe on that port with ssh.
In the raw table:
-A PREROUTING -i eth0 -p tcp -m tcp --dport 22 -d [my server ip] -m string --string "SSH-2.0-libssh" --algo bm --from 10 --to 60 -j DROP
-A PREROUTING -i eth0 -p tcp -m tcp --dport 22 -d [my server ip] -m string --string "SSH-2.0-Go" --algo bm --from 10 --to 60 -j DROP
-A PREROUTING -i eth0 -p tcp -m tcp --dport 22 -d [my server ip] -m string --string "SSH-2.0-JSCH" --algo bm --from 10 --to 60 -j DROP
-A PREROUTING -i eth0 -p tcp -m tcp --dport 22 -d [my server ip] -m string --string "SSH-2.0-Gany" --algo bm --from 10 --to 60 -j DROP
-A PREROUTING -i eth0 -p tcp -m tcp --dport 22 -d [my server ip] -m string --string "ZGrab" --algo bm --from 10 --to 60 -j DROP
-A PREROUTING -i eth0 -p tcp -m tcp --dport 22 -d [my server ip] -m string --string "MGLNDD" --algo bm --from 10 --to 60 -j DROP
-A PREROUTING -i eth0 -p tcp -m tcp --dport 22 -d [my server ip] -m string --string "amiko" --algo bm --from 10 --to 60 -j DROP
Adding the server IP minimizes risks of also blocking outbound connections as raw is statelessI rarely do this any more given they rotate through so many LTE IP's. Instead I get the bot operators to block me by leaving SSH on port 22 and then giving them a really long VersionAdendum that seems to get the bots feeling broken, sticky and confused. There are far fewer SSH bot operators than it appears. They will still show up in the logs but that can be filtered out using drop patterns in rsyslog.
VersionAddendum " just put in a really long sentence in sshd_config that is at least 320 characters or more"
Try it out on a test box that you have console access to just in case your client is old enough to choke on it. Optionally use offensive words for the bots that log things to public websites. Only do this on your hobby nodes, not corporate owned nodes unless legal is cool with it, in writing.Create /etc/modprobe.d/nf_conntrack.conf
cat /etc/modprobe.d/nf_conntrack.conf
options nf_conntrack expect_hashsize=256400 hashsize=256400
And then in /etc/sysctl.conf: # from /etc/sysctl.conf: increase state table limits.
# Requires 1/4 mem to hash table plus 400 overhead because I am the cargo culting king:
# cat /etc/modprobe.d/nf_conntrack.conf
# options nf_conntrack expect_hashsize=256400 hashsize=256400
net.nf_conntrack_max = 1024000
Should people use default state table memory allocations on a busy node, everyone can be locked out of it regardless of how many TB of RAM are free. The node can appear "down".In a startup / init script / systemd unit file:
# IPv4
ipset flush bots 2>/dev/null
ipset create bots hash:ip hashsize 2048 maxelem 65536 timeout 604800 netmask 24 2>/dev/null
# IPv6
ipset flush bots6 2>/dev/null
ipset create bots6 hash:ip hashsize 2048 maxelem 65536 timeout 604800 netmask 64 family inet6 2>/dev/null
In this example I am using a bigger netmask much in the way name servers rrl rate limit.In the raw table, drop bots we saw for a week:
-A PREROUTING -i eth0 -p tcp -m tcp --dport 22:80 -d [server ip] -m set --match-set bots src,dst -j DROP
-A PREROUTING -i eth0 -p tcp -m tcp --dport 22 -d [server ip] -m string --string "SSH-2.0-libssh" --algo bm --from 10 --to 60 -j SET --add-set bots src --exist --timeout 604800
In the filter table outbound rules: -A OUTPUT -o eth0 -p tcp -m tcp --sport 22 -m set --match-set bots dst -j REJECT --reject-with tcp-reset
This should only be performed on servers that one has console / out-of-band access to, after exhaustive testing.Or am I misunderstanding this?
At the same time it's much easier to write code that just died the bare minimum. Imagine you're a bot herder, if your bot net consists of stolen CPU cycles what difference does it make if your bots are slowed down. It doesn't cost you money.
This is wrong. It does cost you money - either directly, because you paid money to use someone else's botnet, or as an opportunity cost, in that you can't use your bots on as many targets.
(Of course, the bot author could detect that behaviour too.)
There's more info from the author of Endlessh: https://nullprogram.com/blog/2019/03/22/
This is going to very slightly irritate some of the extremely low-level actors. Is setting up a tool to do that a good use of time?
If you want to effectively deter attackers using a sand-trap approach, you need to find some kind of task with asymmetric cost in your favour. This isn't that.
Please do, it would mean good karma.
I have understood that most attacks are super-simple sort of, so probably not much to learn there. But an interesting project!
" I didn't like the logging, so I re-implemented the entire thing."
I'm not mocking, I just see this often (and have done it myself!). It's interesting the things we do to get around the little things we don't like.
The stated reason is likely only the excuse they told themselves to justify the project. But the real reason was likely that they wanted to create something, and this was a good justification.
Might just be me projecting though, because I do that all the time
And did that in the "language of the week" :)
The stuff that was reinvented in eg. ruby a few years ago is now reinvented in go and rust.
eg: https://news.ycombinator.com/item?id=19276751
https://github.com/remacs/remacs
last commit, 3 years ago.
Yeah and perhaps pick up valuable skills, that might help us down the road in ways that are hard to quantify.