logoalt Hacker News

I close SSH port 22 (and what I use instead)

52 pointsby speckxlast Monday at 7:19 PM77 commentsview on HN

Comments

teddyhtoday at 5:42 AM

Port knocking, and other bespoke middle layers in front of internet services, is stupid. It violates Kerckhoffs’s principle¹. If you want more secret bits which users need to know in order to access your system, increase your password lengths, or cryptographic key sizes. If you want to keep log sizes (or “noise”) manageable, adjust your logging levels.

Anything added in front of your normal service also complicates access, since it’s non-standard. If you want a standard solution to solve all your needs for secure access of IP-based services, use IPsec and be done with it once and for all.

1. <https://en.wikipedia.org/w/index.php?title=Kerckhoffs%27s_pr...>

(Adapted from this old post: <https://news.ycombinator.com/item?id=39898061>)

show 6 replies
kazinatortoday at 5:26 AM

What I do is laughably simple.

1. Disable all logging about break-in attempts.

2. Do not have any common user names like "root".

Say you want to be able to log in as root from anywhere, just with a password. This is a wise idea; what if you need access, but are in a situation where you are not able to use a certificate?

Make up an alternative name like roto-rooter or whatever pops into your head. Install it into the password file as an alternative name for UID 0. (Make sure it appears later than the "root" entry!). Also edit the shadow file, making sure that the entry is duplicated for the alternative name.

Then in the sshd config file, use AllowUsers to allow only a whitelisted set of users. Here if you say "AllowUsers rotorooter", then the only user id that can authenticate is exactly that one, and it's mapped to UID 0 via passwd/shadow. Add any other accounts you would like to remotely access, giving them similar aliases if they happen to land into a commonly probed space, or are something that a targeted attacker could infer from knowing something about you.

Attackers do not probe the user ID space at all. They concentrate exclusively on probing the password spaces of common user IDs like root, admin, database, www-data, etc. If your system does not support any of those IDs, they are not on a trajectory to crack anything. Your rotorooter password could be "g0d" and they will not get in, if all they ever try is root.

show 1 reply
fedposttoday at 4:42 AM

Is this actually practically reducing the attack surface? We're replacing a battle hardened service with a random one that has the ability to manipulate the firewall rules.

show 4 replies
ggmtoday at 5:02 AM

A scheme like this is in the process of being standardised by Peter Gutmann who knows what he is doing. To give that statement more context he's an NZ cryptographer and has also worked in standardisation before. So, he is promoting this model with knowledge of cryptography, risks and the standards process.

https://datatracker.ietf.org/doc/draft-gutmann-ssh-preauth/

usernametaken29today at 5:14 AM

I don’t know why this wasn’t mentioned before but why not use a Firewall. If you’re using a virtual box like Hetzner or Scaleway you can specify an ip or range at the router level. For all intents and purposes this removes public exposure. Scaleway also has a cheap VPN bridge. So you never need to connect via the public internet if you don’t want to… hardly gets more secure than that

show 2 replies
happosaitoday at 5:27 AM

I made my ssh server to listen ipv6-only, and it has been super silent in the logs ever since.

In the first iteration the IPv6 got polled by a handful of attackers as soon as the letsencrypt certificate was published. In the second iteration I just picked another IPv6 address from the /64 and made ssh.example.com to point to it. This should work until the attackers start guessing subdomain s...

show 1 reply
figmerttoday at 5:28 AM

The real solution is using something like Pangolin or Tailscale (or Headscale) for this. You can control access way better and you never have to expose ssh ever. Not even temporarily.

dosticktoday at 7:57 AM

So the best solution according to the article is to use UDP’s feature of not being sent to any port in particular. In ideal hypothetical it should work, but on any public WIFI, and remote networks would not deliver UDP.

UDP was designed as no-guarantee of delivery. Why would you rely on it for this important feature?

akshayrajeshwartoday at 5:43 AM

> If a zero-day drops in OpenSSH...

Realistically, fwknop is more likely to have a vuln than OpenSHH. Last release was two years ago and the readme dates back twelve :/ Time will tell.

show 2 replies
lormaynatoday at 8:04 AM

My checklist to secure a VPS, enforced by an Ansible playbook.

* Disable SSH root login

* Disable password login and use only certificates

* Enable fail2ban

This have been worked for more than ten years and never been hacked.

I never understand the need for port knocking.

abc42today at 7:56 AM

Seems like a wireguard port in would be a simpler solution, at least superficially. If somebody manages to break both wireguard and ssh security, they probably had access to my laptop anyway so I've lost already.

Kiboneutoday at 6:06 AM

Just wrap it in wireguard. WG won't respond to any incoming handshake without a valid and authorized client key, it's essentially invisible.

somattoday at 5:12 AM

The enlightened trick is to run ssh on port 443.

show 2 replies
mrktflast Monday at 8:15 PM

I would go with something like:

  seed=`date +%s%N`; ( echo "secretknock-20260811|$seed"|sha512sum  ; echo $seed ) | xargs nc -u 192.168.1.1
It is not secure as hmac and it can be 'trivially' brute forced, but don't require extra tools (probably nc not always readily available).

On other hand if threat vector includes network monitor with ability to replay i would use wireguard to wrap ssh traffic.

s_ting765today at 6:14 AM

If one is so worried about zero days in openssh, the more practical solution would be centered around these 2 questions:

1. "would you know if you got breached?" 2. "would you have any reaction time?"

A simple solution that answers this: https://github.com/64mb/ssh-login-alert-telegram/blob/master...

suprjamitoday at 4:46 AM

> and why it is not enough on its own

Nothing is good enough on its own.

Geoblocking, fail2ban, port obscurity, SSH keys, limiting logins to specific usernames, not using your public internet nickname, putting things behind CloudFlare tunnels or WireGuard, wildcard DNS obscurity, 2FA... There are many options.

Defense in depth is the only way to put services on the internet.

show 2 replies
orevtoday at 4:57 AM

Glad to see fwknop mentioned. Back when the idea of port knocking emerged, there was a lot of criticism about it. Then this came out, and not many seemed to notice.

This was before WireGuard and Tailscale, so the main option for remote access was IPsec or OpenVPN, which are both more complicated than most people want to deal with.

pratyahavatoday at 6:57 AM

i cannot trust tech advices from a guy who puts three ad banners (left, right and bottom, taking approx quarter of my screen space) on his personal blog.

SoftTalkertoday at 4:47 AM

This is a lot of complexity compared to just not having ssh open to the world (on whatever port you choose to use).

Restrict it to the networks where authorized users will be connecting.

show 1 reply
vekntksijdhrictoday at 6:28 AM

SSH available only via VPN is simpler and more extensible.

mmh0000today at 5:27 AM

I've been using nftables for port knocking for a while now. I run an SSH tunnel server that needs to be globally accessible. But I don't want it getting hammered by bots nonstop.

So, I have this nft script which works alongside Firewalld:

  $ systemctl enable --now nftables
  $ cat /etc/nftables/portknock.nft
  table ip portknock {}
  delete table ip portknock
  
  table ip portknock {
      set knocked {
          type ipv4_addr
          flags timeout
          timeout 6s
          gc-interval 2s
      }
  
      # Before conntrack: record the knock, then drop the packet.
      chain prerouting_knock {
          type filter hook prerouting priority raw; policy accept;
  
          tcp dport 12334 fib daddr type local tcp flags syn counter add @knocked { ip saddr } drop
      }
  
      # Decision chain for port 41444. Every branch is counted so that
      # `nft -a list table ip portknock` shows which path traffic took.
      chain gate_41444 {
          # Established/related sessions pass unconditionally.
          ct state established,related accept
  
          # Host-local. Rarely matches: host-originated traffic is DNATed in
          # the output hook before it reaches prerouting. Kept as a safeguard.
          iifname "lo" counter accept
  
          # Podman containers reaching the published port (hairpin).
          ip saddr 10.88.0.0/16 counter accept
  
          # Trusted subnets.
          ip saddr { 10.0.0.0/24, 10.1.0.0/24 } counter accept
  
          # Knocked within the last 6 seconds.
          ip saddr @knocked counter accept
  
          # Default deny. If THIS counter is 0 and the accept counters are
          # also 0, the chain is not being reached at all -- investigate.
          # Do not assume the gate is working just because nothing got in.
          counter drop
      }
  
      chain prerouting_gate {
          type filter hook prerouting priority mangle; policy accept;
  
          tcp dport 41444 fib daddr type local jump gate_41444
      }
  }


Then on the client side, I can use anything to send the knock, but usually I just script it out with `ssh` like this:

  $ ssh -p 12334 -o ConnectTimeout=1 "${sServer}" &> /dev/null
  $ sleep .5
  $ ssh -o 'ExitOnForwardFailure=yes' -o 'StrictHostKeyChecking=no' -o 'LogLevel=ERROR' -fp 41444 -R "${iPort}:localhost:22" -T "${sServer}" "sleep 14d"
The biggest benefit is that it doesn't require any non-standard tooling. If you have an SSH client and know the rules, you can connect.

Yeah, it doesn't have all the "cryptographic signatures" of the article; at the same time, it doesn't have some "random" 3rd-party application that faces the internet and directly controls firewall rules that way.

It's still an OpenSSH server with key-auth only. I'm not worried about someone carefully watching my traffic and finding it. I just need Internet bots not connecting to it a million times a second.

cpercivatoday at 5:56 AM

This is what spiped is for.

tuatorutoday at 5:49 AM

With all the world's knowledge freely available on the web, people still do this.

Unless it's an April Fool joke, in June.

cyberaxtoday at 5:48 AM

I don't close SSH. I just use port knocking on my firewall to enable the SSH.

bakugotoday at 5:32 AM

AI slop article based on a flawed premise. It's 2026, the process of correctly securing an SSH server has exactly two steps:

1. Disable password auth, only public key auth should be enabled

2. Block public access to SSH entirely, use a VPN instead (Tailscale & co. make this trivial)

And 2 is entirely optional for most people reading SSH guides who just want a server to host their hobby project. Let's be real, you're probably not reading the auth logs anyway so they don't need to be clean, and if someone discovered an OpenSSH public key auth bypass vulnerability, they absolutely wouldn't waste it on you. Just let those dumb scanners go at it all day, they're not getting in.

And a little tangent: fail2ban is 100% placebo and does nothing except clean up the logs a bit. I don't understand why it's still a common recommendation for beginners, it's a relic from the past when bruteforcing was still a concern because people used password auth.

show 1 reply
hackernud3stoday at 5:44 AM

I was expecting to hear tailscale TBH. You do you though.

streetfighter64today at 5:12 AM

AI writing, sigh...

> to be unreachable: no banner, no version string,

> It works, but it has a real weakness:

jauntywundrkindtoday at 4:41 AM

Why not just use ssh as the knock protocol too? To a bespoke ssh server. Ssh to 7000, type "mellon", and ssh 22 opens up. No other software required, and you clearly already have ssh.

show 3 replies
abofhtoday at 5:27 AM

You run ssh?

show 1 reply
IronWolvetoday at 4:56 AM

Stacking is cool, but what happened to also having a firewall in front of it?!

show 1 reply