a password-protected SSH key is also two factors
Not really. By default SSH keys are kept in a private subdirectory of $HOME. An attacker who has access to it is very likely able to modify the user’s $PATH, trojan the passphrase prompt, and so on. Thus in many real‐world situations it collapses to one factor.
Contrast that to an SSH key tied to a WebAuthn token with "ssh-keygen -t ed25519_sk"—even a fully trojaned machine would not be able to freely initiate sessions with the compromised key.
[1]: https://ubuntu.com/tutorials/configure-ssh-2fa#1-overview
Full disclosure: I work there, but I am not the author.
in a previous HN post I've copied my quick 'n dirty notes
You can set this up via the RequiredAthentications2 setting off you're just using protocol V2.
However, I still think it's valuable for the following reasons:
1) It can slow stupid attackers down, e.g.: those that don't abort a bruteforce attempt when they see password authentication is disabled. Judging by my logs there's lots of those still out there.
2) It keeps the SSH logs less cluttered.
3) You can use it to build a set of hosts to consider blocking permanently.
https://github.com/jtniehof/pam_shield
There are other, similar pam modules if this one isn't your cup of tea. There's pam_tally2, and others.
1) The very first configuration change anybody should be making to an SSH server should be disabling password-based authentication. Once you've done that you've rendered fail2ban obsolete, because the only real way in for attackers from that point in is via software security vulnerabilities, and fail2ban can't help you with that, that's your job to keep yourself patched up.
2) In an IPv6 world, fail2ban is pointless. The ranges are so vast.I personally use nft blackhole [1], which I can recommend for its ease of use.
1) Many attackers "hide" behind cloud services. So whatcha gonna do when your primary attack vector is AWS EC2 instances ? Block AWS CIDR ranges ?
2) With IPv4 exhaustion increasing numbers of people will be using IPv4 allocations across geographic boundaries.My logs and firewall greatly disagree. Please avoid comments on HN like this where it boxes solutions into a "my way or the highway" result, when it has been demonstrated to you here it's not "Absolutely pointless". Security is the layering of multiple solutions and defenses to protect your assets, there is no magic bullet or single solution.
I do, actually. There is zero reason for anyone to use EC2 instances to contact my personal public machines.
> With IPv4 exhaustion increasing numbers of people will be using IPv4 allocations across geographic boundaries.
And there will continue to be tracking of who is using which blocks, so there should be no reason for error rates to creep up too much.
You need to think about the specifics of your situation, not just blindly follow "best practices". For my personal public machines, I do know, with a high degree of specificity, who should be doing what, and from where. I exploit that to place limits on who can talk to them, and it provides a lot of benefit.
If you're running a large public service, you're in starting from a very different stance. For my $dayjob, there are good reasons why customers might contact us from a country where we don't yet offer service, so we can't wall them off. But we do occasionally use geoblocking more selectively when we're under attack.
Sure, IP address block fragmentation will remove some value, but you'd still kill a lot of juicy compromisable home IP addresses in those countries.
Regarding cloud providers - well, I hope they have some automated systems to clamp down, since it's against their own interest to serve as vectors.
Since I don't log in from there, yes sure? And if I'm hosting on AWS I can proxy through an AWS resident host. Same with any other cloud provider.
This is the most important by faaaar.
Do this experiment: Start a vm on any cloud with an open port 22, and watch the logs of sshd service. You will be amazed at the number of requests with bad credentials that will hit your machine within minutes. I watched logs to different ports, and ssh wins first place
There's no harm in that. Sure the log noise can be annoying but be in peace with it.
If there are no weak credentials which can allow access, there's no issue.
The "if" is important, but tractable.
Sometimes we got a warning from rsync that the connection was unexpectedly closed. We have traced this warning to SSH credential bruteforcers (yes, completely futile) that exhausted MaxStartups. So, we installed fail2ban.
Why are you worried about requests with bad credentials?
Having a backup sshd behind something like Wireguard is an inexpensive insurance against this kind of DoS.
Won't work for everyone, but definitely something to consider if you are offering "shell-as-a-service" internally or externally.
Point is, you can offer a secure & functional remote shell without touching Linux PAM or the Linux authx stack beyond `useradd` and a locked-down `sshd_config`. Orgs that already offer web services over HTTPS may find this route desirable.
If you only have {2fa,key,certificate} auth the number of alerts you should have from SSHD itself is (almost) zero, failed logins are (almost) _all_ _noise_. Higher level systems that monitor origin/destination/heuristics of successful logins are where its at.
Fail2ban is certainly not needed (unless there is potential that some users may use very weak passwords, which password policy shouldn’t permit that, or logs are preferred to be cleaner).
Firewalls, public key authentication (verify host keys, also rotate), hardware keys, using SSH over Wireguard, and a secure bastion host provide real security. Preventing SSH agent and X11 forwarding is good too.
This works by specifying `keyboard-interactive:pam` as the authentication method, and modifying SSH's PAM stack to call whatever PAM module handles the second factor. Notably, any PAM module which asks for a password (for example, "pam_unix") is removed from SSH's PAM stack.
With Security Keys you can get a physical device you've decided you trust to authenticate that its authorised user is present remotely.
Although the keys aren't very bright, they do understand a handful of bitflags they're signing, and two of those bitflags are "User Present" and "User Verified", by requiring "User Verified" the physical device you trust must have verified the authorised user (e.g. local PIN, fingerprint sensor) before signing the message.
This approach is more robust, because it's all happening in the SSH public key authentication layer, not in ad-hoc PAM code, and it's simpler because there is no "second factor" data living on your SSH servers, the second factor is a problem for the authenticator only, yet it also re-uses an authenticator your employees can use to e.g. authenticate to your local gitlab install, or your Google docs, or even to decrypt their laptops on startup.
I used to be SSH only, but the framework is built around simply delivering CLI commands and enabling file transfer.
So I abstracted the command request/response and now I can do it over AWS-SSM, or docker run, kubectl, salt daemon, teleport, or even AWS-SSM to a "bastion" and then ssh from there.
AWS-SSM is basically a polling mechanism, you can easily roll one of your own.
What I don't like is two factor authentications that require manual steps. Then you can't automate anything.
The connection stuff is pretty annoying to maintain.
First, I started giving certificates expiration dates, so a compromised key would only be valid for a short time even if I were unable to revoke it manually right away. It provides some confidence that my keys weren’t exfiltrated once and subsequently used behind my back for years and years.
Second, when generating a new client keypair, I only have to copy the public key to my certificate signing machine (one copy) rather than every host I plan to log into (many copies). This more than makes up for the minor certificate configuration necessary on new clients.
Third, host authenticity warnings are now a thing of the past. Since I switched to certificates, they only appear when something’s actually misconfigured, never simply because I connected to a new host. As a result, I’ve lost the habit of blindly accepting the fingerprint (and in fact I’ve now turned on strict host key checking in the config file so accepting it isn’t possible). Of course, you don’t need certificates for that… if you’re diligent at checking fingerprints. I tried to be, but sometimes I fell short. Not anymore.
Compare it to something like https://www.howtogeek.com/443156/the-best-ways-to-secure-you...
Any junior sysadmin should consider this "yeah, duh" levels of advice.
For this particular client it was a hard requirement for them to even consider allowing access from public internet.
That way you need to be on the Tailscale network, and have my Yubikey/PIN - makes it nice and easy for me to get on from pretty much anywhere if I need to.
I have a cron job which autoclears all the whitelisted ip addresses at the end of the day.
If youre a team, you can always make a similar script and share it with everyone, since aws cli is configured with your team members iam access, you can be assured that they can only whitelist themselves on instances which they have access to over iam.
If you dont use aws, just expose an api on your server, protect the endpoint with an api key and use that endpoint to send the whitelisted ip to update your iptables(/whatever firewall you're using).
If all of this sounds really complicated to you, you can always just setup wireguard on one of your machines, then make all your team members connect to that vpn, and only whitelist the ip address of that machine across all your instances. That way only people who can authenticate with your vpn can even access your ssh ports.
This has proven to be working solution for years. Any monstrous "security" constructions with keeping it open or partially open will backfire once one attack vector will be discovered.
[1] https://man.archlinux.org/man/community/ssh-audit/ssh-audit....
What happens if I lose my ssh key?
I like passwords because I can remember them so I don't have to put my key on someone else's computer (cloud). So on my server I have one user (non root) with a long password so I don't have access to my keys I can still login.
https://www.linuxjournal.com/content/ssh-key-rotation-posix-...
It seems someone was told to go market Teleport and posting to HN is free (unlike newsletter sponsorships).