this post was submitted on 06 Apr 2025
137 points (98.6% liked)

Selfhosted

45582 readers
1287 users here now

A place to share alternatives to popular online services that can be self-hosted without giving up privacy or locking you into a service you don't control.

Rules:

  1. Be civil: we're here to support and learn from one another. Insults won't be tolerated. Flame wars are frowned upon.

  2. No spam posting.

  3. Posts have to be centered around self-hosting. There are other communities for discussing hardware or home computing. If it's not obvious why your post topic revolves around selfhosting, please include details to make it clear.

  4. Don't duplicate the full text of your blog or github here. Just post the link for folks to click.

  5. Submission headline should match the article title (don’t cherry-pick information from the title to fit your agenda).

  6. No trolling.

Resources:

Any issues on the community? Report it using the report flag.

Questions? DM the mods!

founded 2 years ago
MODERATORS
 

Recently, I discovered that SSH of my VPS server is constantly battered as follows.

Apr 06 11:15:14 abastro-personal-arm sshd[102702]: Unable to negotiate with 218.92.0.201 port 53768: no matching key exchange method found. Their offer: diffie>
Apr 06 11:30:29 abastro-personal-arm sshd[102786]: Unable to negotiate with 218.92.0.207 port 18464: no matching key exchange method found. Their offer: diffie>
Apr 06 11:45:36 abastro-personal-arm sshd[102881]: Unable to negotiate with 218.92.0.209 port 59634: no matching key exchange method found. Their offer: diffie>
Apr 06 12:01:02 abastro-personal-arm sshd[103019]: Unable to negotiate with 218.92.0.203 port 16976: no matching key exchange method found. Their offer: diffie>
Apr 06 12:05:49 abastro-personal-arm sshd[103066]: Unable to negotiate with 218.92.0.212 port 49130: no matching key exchange method found. Their offer: diffie>
Apr 06 12:07:09 abastro-personal-arm sshd[103077]: Connection closed by 162.142.125.122 port 56110 [preauth]
Apr 06 12:12:18 abastro-personal-arm sshd[103154]: Connection closed by 45.79.181.223 port 22064 [preauth]
Apr 06 12:12:19 abastro-personal-arm sshd[103156]: Connection closed by 45.79.181.223 port 22078 [preauth]
Apr 06 12:12:20 abastro-personal-arm sshd[103158]: Connection closed by 45.79.181.223 port 22112 [preauth]
Apr 06 12:21:26 abastro-personal-arm sshd[103253]: Connection closed by 118.25.174.89 port 36334 [preauth]
Apr 06 12:23:39 abastro-personal-arm sshd[103282]: Unable to negotiate with 218.92.0.252 port 59622: no matching key exchange method found. Their offer: diffie>
Apr 06 12:26:38 abastro-personal-arm sshd[103312]: Connection closed by 92.118.39.73 port 44400
Apr 06 12:32:22 abastro-personal-arm sshd[103373]: Unable to negotiate with 218.92.0.203 port 57092: no matching key exchange method found. Their offer: diffie>
Apr 06 12:49:48 abastro-personal-arm sshd[103556]: error: maximum authentication attempts exceeded for root from 98.22.89.155 port 53675 ssh2 [preauth]
Apr 06 12:49:48 abastro-personal-arm sshd[103556]: Disconnecting authenticating user root 98.22.89.155 port 53675: Too many authentication failures [preauth]
Apr 06 12:49:51 abastro-personal-arm sshd[103558]: error: maximum authentication attempts exceeded for root from 98.22.89.155 port 53775 ssh2 [preauth]
Apr 06 12:49:51 abastro-personal-arm sshd[103558]: Disconnecting authenticating user root 98.22.89.155 port 53775: Too many authentication failures [preauth]
Apr 06 12:49:53 abastro-personal-arm sshd[103561]: error: maximum authentication attempts exceeded for root from 98.22.89.155 port 53829 ssh2 [preauth]
Apr 06 12:49:53 abastro-personal-arm sshd[103561]: Disconnecting authenticating user root 98.22.89.155 port 53829: Too many authentication failures [preauth]
Apr 06 12:49:54 abastro-personal-arm sshd[103563]: Connection closed by 98.22.89.155 port 53862 [preauth]
Apr 06 12:50:41 abastro-personal-arm sshd[103576]: Invalid user  from 75.12.134.50 port 36312
Apr 06 12:54:26 abastro-personal-arm sshd[103621]: Connection closed by 165.140.237.71 port 54236
Apr 06 13:01:26 abastro-personal-arm sshd[103702]: Connection closed by 193.32.162.132 port 33380
Apr 06 13:03:40 abastro-personal-arm sshd[103724]: Unable to negotiate with 218.92.0.204 port 60446: no matching key exchange method found. Their offer: diffie>
Apr 06 13:11:49 abastro-personal-arm sshd[103815]: Received disconnect from 165.140.237.71 port 50952:11:  [preauth]
Apr 06 13:11:49 abastro-personal-arm sshd[103815]: Disconnected from authenticating user root 165.140.237.71 port 50952 [preauth]
Apr 06 13:19:08 abastro-personal-arm sshd[103897]: Unable to negotiate with 218.92.0.208 port 59274: no matching key exchange method found. Their offer: diffie>
Apr 06 13:33:36 abastro-personal-arm sshd[104066]: Received disconnect from 165.140.237.71 port 50738:11:  [preauth]
Apr 06 13:33:36 abastro-personal-arm sshd[104066]: Disconnected from authenticating user ubuntu 165.140.237.71 port 50738 [preauth]
Apr 06 13:34:50 abastro-personal-arm sshd[104079]: Unable to negotiate with 218.92.0.204 port 44816: no matching key exchange method found. Their offer: diffie>
Apr 06 13:50:32 abastro-personal-arm sshd[104249]: Unable to negotiate with 218.92.0.206 port 27286: no matching key exchange method found. Their offer: diffie>
Apr 06 13:51:58 abastro-personal-arm sshd[104261]: Received disconnect from 165.140.237.71 port 50528:11:  [preauth]
Apr 06 13:51:58 abastro-personal-arm sshd[104261]: Disconnected from authenticating user root 165.140.237.71 port 50528 [preauth]
Apr 06 14:01:25 abastro-personal-arm sshd[104351]: Invalid user  from 65.49.1.29 port 18519
Apr 06 14:01:28 abastro-personal-arm sshd[104351]: Connection closed by invalid user  65.49.1.29 port 18519 [preauth]

As you can see, it is happening quite frequently, and I am worried one might break in at some point. Since SSH access guards users with root-access, it can be quite serious once penetrated. How do I harden against these kind of attacks? Because this is VPS, disabling SSH is a no-go (SSH is my only entry of access). Are there ways to stop some of these attackers?

As always, thanks in advance!

top 50 comments
sorted by: hot top controversial new old
[–] Appoxo@lemmy.dbzer0.com 3 points 7 hours ago

You could limit the firewall to IP range(s) of your domestic (and other places of interest like work) connection.
This way they won't come even close to even logging in.
And then you could do the other hardening on top.

[–] aeternum@lemmy.blahaj.zone 5 points 16 hours ago

in addition to what others have said, disable root login

[–] lichtmetzger@discuss.tchncs.de 5 points 17 hours ago

Use knockd and iptables, gone are the fucking bots.

[–] boblemmy@lemmy.world 3 points 16 hours ago* (last edited 16 hours ago)

change port + fail2ban + totp (google-authenticator)

[–] possiblylinux127@lemmy.zip 17 points 1 day ago

Use key based auth only and then run ssh-audit.

[–] gerowen@lemmy.world 26 points 1 day ago* (last edited 1 day ago) (1 children)

I generally do a few things to protect SSH:

  1. Disable password login and use keys only
  2. Install and configure Fail2Ban
  3. Disable root login via ssh altogether. Just change "permit root login" from "no password" to just "no". You can still become root via sudo or su after you're connected, but that would trigger an additional password request. I always connect as a normal user and then use sudo if/when I need it. I don't include NOPASSWD in my sudoers to make certain sudo prompts for a password. Doesn't do any good to force normal user login if sudo doesn't require a password.
  4. If connecting via the same network or IPs, restrict the SSH open port to only the IPs you trust.
  5. I don't have SSH internet visible. I have my own Wireguard server running on a separate raspberry pi and use that to access SSH when I'm away, but SSH itself is not open to the internet or forwarded in the router.
[–] k_rol@lemmy.ca 2 points 1 day ago

I vote for wireguard here, I don't expose anything other than game servers to the internet

[–] tomsh@lemmy.world 11 points 1 day ago (1 children)

In addition to what others say, I also have ntfy notifications on successful login.

[–] joseandres42@lemmy.world 5 points 1 day ago (1 children)

That's genius. I'll do the same from now on.

[–] tomsh@lemmy.world 7 points 1 day ago

There is actually an example on their website.

ntfy ssh login alert

[–] lefixxx@lemmy.world 6 points 1 day ago

Change the port.

[–] bizdelnick@lemmy.ml 16 points 1 day ago

The best way is to disable password login and use SSH keys only. Any further steps are not required, but you may additionally install fail2ban or sshguard.

[–] kylian0087@lemmy.dbzer0.com 17 points 1 day ago (1 children)

Configure the firewall with a IP whitelist to only allow connections to ssh be made from your home IP.

Other then that, disable password logon for ssh and setup up key based authentication.

Agreed, but be careful about the whitelist. If your home IP changes, you'll be locked out until you update it, so you should consider an IP range if that's a possibility for you. Likewise, if you'll be accessing it from multiple locations (say, a family member's house), then make sure to add those as well.

[–] phoenixz@lemmy.ca 40 points 1 day ago (6 children)

Move the ssh port to higher ranges, 30-60000. That alone will stop 99% of the attacks

Disable root logins, now usernames must be guessed too which will make success even lower

Then require SSH keys

At that point it's like being in a nuclear fallout nshelter behind a 3 meter thick steel door and you can hear some zombies scratching on the outside... I'm not worried about any of that shit

[–] StructureOfChaos@lemmynsfw.com 5 points 1 day ago (3 children)

Regarding SSH Keys, I was wondering how you keep your key safe and potentially usable from another client?

[–] gerowen@lemmy.world 1 points 17 hours ago (1 children)

Generate a unique key for each client or device. SSH keys identify devices, not people, so I do not recommend sharing the same key between two different devices.

[–] StructureOfChaos@lemmynsfw.com 1 points 7 hours ago

Well, you might have only 1 main client, but if that hardware fails and need to connect from a temporary client or after a fresh install you're out of your own server...

[–] callcc@lemmy.world 5 points 1 day ago

Be sure to use a passphrase

[–] a_postmodern_hat@lemmy.world 3 points 1 day ago

You could get a hardware key (like a Yubikey) and authenticate with PIV or GPG.

[–] joshcodes@programming.dev 13 points 1 day ago (2 children)

For added funs run an SSH tarpit to fuck with the attackers, something like endlessh.

load more comments (2 replies)
[–] null_dot@lemmy.dbzer0.com 5 points 1 day ago (1 children)

This is what I do. Changing the port to a higher number will prevent almost all bots.

I understand that obscurity is not security but not getting probed is nice.

Also ssh keys are a must.

I do log in as root though.

However, I block all IPs other than mine from connecting to this port in my host's firewall. I only need to log in from home, or my office, and in a crisis I can just log in to OVH and add whitelist my IP.

I do log in as root though.

Don't do that. You're one local piece of malware away from getting your server pwned. Logging in as an unprivileged user at least requires another exploit on the server to get root permissions.

load more comments (3 replies)
[–] Xanza@lemm.ee 55 points 2 days ago (7 children)
  1. Disable passwordless login.
  2. Disable password login.
  3. Require SSH keys
  4. Move SSH port to non-standard port
  5. Reject connections to port 22
  6. Install and enable fail2ban

About the best you can do.

[–] semperverus@lemmy.world 12 points 1 day ago (5 children)

Don't reject connections to port 22, honeypot it and ban on connection attempt.

[–] downhomechunk@midwest.social 5 points 1 day ago

I'd get myself banned this way. I forget the -p flag at least once per week.

load more comments (4 replies)
load more comments (6 replies)
[–] plz1@lemmy.world 5 points 1 day ago

Does SSH have to be your only way? Could you deploy something like Tailscale? Can you restrict the allowed IP ranges on SSH with a firewall rule?

[–] CondorWonder@lemmy.ca 69 points 2 days ago (3 children)

We can’t ever stop this kind of stuff, but with something like fail2ban you can set it up to block on too many failures.

Really though - ensuring your system is kept up to date and uses strong passwords or use a SSH keys is the best defence. Blocking doesn’t prevent them from trying a few times. Moving SSH to a non standard port will stop most of the automated attacks but it won’t stop someone who is dedicated.

[–] 30p87@feddit.org 25 points 2 days ago (4 children)

Move SSH to non-standard port, make endlessh use the default port. Only use SSH keys. Only allow correct users (so eg. your user and git/forgejo). Use fail2ban to aggressively ban (redirect to default port, so 22) and report to abuseipdb everything that fails to authenticate first try (wrong user, password instead of key), has non-compatible ciphers (generally, only allow TLS1.3 etc.), or fails in any other way. Just be sure that if you accidentally get banned yourself (eg. Ctrl+C-ing during authentication), you can use another IP (eg. force v4) for connecting.

load more comments (4 replies)
load more comments (2 replies)
[–] Arghblarg@lemmy.ca 15 points 1 day ago

There's a dedicated tool named sshguard which works nicely.

[–] zr0@lemmy.dbzer0.com 19 points 1 day ago* (last edited 1 day ago) (3 children)

harden sshd

More details:

  • require keys to login
  • don't allow login as root

That should be plenty, but you could go a bit further and restrict the types of algorithms allowed (e.g. disallow RSA if you're worried about quantum attacks). For this, I recommend a subtractive config (e.g. HostbasedAcceptedAlgorithms=-rsa-*). This is way over the top since an attacker is unlikely to attack the cipher directly, but it could be part of an attack.

[–] dev_null@lemmy.ml 3 points 1 day ago (1 children)

Your answer to "how to harden SSH?" is "harden SSH"?

I know your two other points gave concrete suggestions, but it's pretty funny you suggested to "harden sshd" when that is what OP is asking how to do.

[–] zr0@lemmy.dbzer0.com 1 points 1 day ago

Yeah, I see your point. No use to repeat the same you can read in other comments or in those 274772 guides online. I was trying to imply to just generally harden ssh because then brute-force attempts should be no issue, unless you log everything and the disk space gets maxed out :D

[–] om1k@sopuli.xyz 13 points 1 day ago (2 children)

did you mean crowdsec instead of crowdstrike?

load more comments (2 replies)
[–] BrianTheeBiscuiteer@lemmy.world 31 points 2 days ago (2 children)

In addition to other advice you could also use SSH over Wireguard. Wireguard basically makes the open port invisible. If you don't provide the proper key upfront you get no response. To an attacker the port might as well be closed.

Here's at least one article on the subject: https://rair.dev/wireguard-ssh/

load more comments (2 replies)
[–] irmadlad@lemmy.world 19 points 2 days ago* (last edited 2 days ago) (2 children)

OP, here is what I do. It might seem overboard, and my way doesn't make it the best, or the most right, but it seems to work for me:

  • Fail2ban
  • UFW
  • Reverse Proxy
  • IPtraf (monitor)
  • Lynis (Audit)
  • OpenVas (Audit)
  • Nessus (Audit)
  • Non standard SSH port
  • CrowdSec + Appsec
  • No root logins
  • SSH keys
  • Tailscale
  • RKHunter

The auditing packages, like Lynis, will scour your server, and make suggestions as to how to further harden your server. Crowdsec is very handy in that it covers a lot of 'stuff'. It's not the only WAF around. There is Wazuh, Bunkerweb, etc. Lots of other great comments here with great suggestions. I tend to go overboard on security because I do not like mopping up the mess after a breach.

ETA: just looked up one of your attackers:

218.92.0.201 was found in our database! This IP was reported 64,044 times. Confidence of Abuse is 100%: ISP CHINANET jiangsu province network Usage Type Fixed Line ISP ASN AS4134 Domain Name chinatelecom.cn Country China City Shanghai, Shanghai

busy little cunts.

[–] sugar_in_your_tea@sh.itjust.works 2 points 1 day ago (1 children)

It's absolutely overboard, and you can get 99% of the way there with this:

  1. WireGuard config (Tailscale in your case)
  2. Bind SSH to WireGuard IP only (so no public SSH port)
  3. SSH keys only, and disable root login over SSH

That will require breaking WireGuard and openSSH's key-based authentication, which just isn't happening. The rest looks like mostly auditing. Even a firewall isn't necessary if no ports are accessible anyway (i.e. everything only accessible over Tailscale), and you can just configure iptables to block everything on the WAN IP and call it a day.

[–] irmadlad@lemmy.world 2 points 1 day ago (1 children)

sugar_in_your_tea @sh.itjust.works

It's nice to be commented by someone famous.

Open up the window, let some air into this room I think I'm almost chokin' from the smell of stale perfume And that cigarette you're smokin' 'bout scare me half to death Open up the window, sucker, let me catch my breath

[–] sugar_in_your_tea@sh.itjust.works 1 points 1 day ago* (last edited 1 day ago)

Mama told me not to come.

Fun fact, my usernames on Reddit (I would cycle them every couple of years) were all Three Dog Night lyrics, so I continued the theme on Lemmy.

Thanks for noticing. 😀

load more comments (1 replies)
[–] Dima@feddit.uk 28 points 2 days ago* (last edited 2 days ago) (3 children)

For security disable password authentication - use public key instead, disable root login via ssh - use sudo or su from another user.

To reduce the number of attempts of others trying to get in change the ssh port and/or set-up fail2ban.

You could also set a firewall rule to only allow ssh from your IP address, if you have a static address at home and only need access from there, or have a way to VPN into your home network. Make sure you have a static address if you do this though, you don't want your IP to change and be left locked out of your server.

load more comments (3 replies)
load more comments
view more: next ›