Trusting host keys... I no longer need to check (or ignore and just type yes) when I first connect to a server.. which is literally as bad as on a brand new machine hitting a web browser, going to your online bank and ignoring the certificate warning.
Distributing trust, New employee - I don't need to push public keys out to all servers or rely on centralised auth such as LDAP/AD/Kerberos.
But the real gem is time limited access.. All without touching each server separately.
Ie, I want access to your fleet of servers for 2 hours, on Sunday 18th between 10:00-12:00 UTC. I create a certificate pair with that validity, pass you the public part and you sign it using the CA. Without you needing to touch any of your servers, I now have full access for the window as agreed.
This is only true if you don't trust the machine you are connecting to.
Private key (only you know) -> signed by CA -> public key you share.
You put the public key on the server , the CA can't change that file... And they can't make that particular cert work without a private key that you hold.
Most CA can do is revoke and break the chain on you.
In the browser world.. A a rouge CA, I could generate a certificate pair for https://google.com and your web browser would trust it.
The same is true with this setup... the solution, for this is to be your own CA and add the CA to all of your clients, rather than adding all of your clients to the server. So this reverses the problem, which for many should be easier.
(I honestly can't see anyone using a public CA for this.. it would be nuts)
You might be surprised to see the nut things people would do for convenience... but in this case you are probably right as the average computer user probably don't use SSH.
What about for a home network with a laptop, desktops and many VMs? I'd like to have a better setup than manually scp'ing files around, but these systems seem like overkill. Is there a middle ground?
Consider the scenario in which your computer is stolen (and might not ever be returned, so whether the attacker installs a keylogger is irrelevant):
The fact that a private key file exists suggests that the user is very likely to be using SSH regularly.
The fact that an SSH client exists is far less informational (there's one by default on most Linuxes and Mac OS).
If I only ever use password authentication with SSH and don't save anything else, not even server keys, the attacker has far less information. That might be important in some scenarios, especially related to anonymity.
Passphrases on SSH keys used to be really easy to brute-force by default and I think they still are. Until two or three years ago the only way to slow down brute-forcing attacks was to use a complicated incantation with openssl to convert the keys to use a slower key derivation. Few people did.
Well, except I'm using "Correct Horse...". Oh. Well, I'm actually using a similar scheme to that, but I don't want to give too much away :).
Actually, I think you're probably right about the ease of brute-forcing passphrases in practice. That's not to say some random person is going to get access to your SSH key[1], but if you're actually being targeted as a "person of interest" by a nation-state you're probably SoL unless you're actually practicing due diligence... but then I think that's generally the name of the game, no? I mean OPSEC is still a thing even if you're only doing stuff that's shady-but-definitely-not-illegal.
[1] This isn't quite a "thing" yet, so some random burglar who steals your laptop isn't going to be attempting brute force.
> And FDE also suggests you may be hiding something.
No one needs to bother trying to infer from FDE that I'm hiding something. I will tell them I am if they ask. Financial records, intimate correspondence, and employer trade secrets (I'm authorized to work at home on my personal computer) immediately come to mind and there is probably more.
I'm sure I'm not unusual in this regard. Most people have things they are hiding.
Security-by-obscurity only works alongside other layers.
Do you also do things like stop all system logging? Or shell logging? Even with only user-level access, a simple 'history' will show where you're ssh'ing to, regardless of whether you use a keyfile or not.
Not these days. FDE is so common and easy to use now, it might well have been an option you blindly hit upon install. And that's just in consumer environments. In corporate environments, in any company with a half-decent infosec department, all employees' computers will simply be required to have FDE, regardless of what they do on the computers.
FDE is also apparently not entirely impossible to bypass, which leaves you in the same situation of an attacker knowing that those SSH keyfiles exist on your machine.
You may think it's all over at that point, but there's different levels of secrecy, and it'd be better that the attacker cannot even know that a further level exists beyond.
> FDE is also apparently not entirely impossible to bypass
Sounds vague, can you please elaborate or cite? (I am not aware of this and if properly set up, I doubt this is true, so I am excited to learn what you know about this)
alexk already addressed your concern: your keys, preferably issued by your org's CA (instead of being generated by you) should be short-lived, oftentimes for the duration of your "work shift". The tools listed above support this.
Which is why you generate your private key with a passphrase (which is used exclusively client side in an ssh client) and only store it on HDD, flash or SSD that uses full disk encryption.
Well you can always keep your keys in a removable drive rather than on persistent storage in your client device.
If you can't trust your client device, you probably have bigger issues with either method - for instance, can you trust that the client is not logging all keystrokes?
You must not be aware that you can set a password (which ssh-keygen calls a passphrase) on your private key file. The private key file will be encrypted and without the password will be useless, if your password is strong. Then you get the best of both.
Setting a passphrase on your key file is also actually widely considered a "best practice" and "conventional wisdom" ... so maybe those old guys knew something after all...
I'm perfectly aware that you can and almost always should encrypt the keyfile; the point I'm trying to make is that you still need a keyfile and the existence of that file can itself be a concern in some situations even it it can't be immediately used by an attacker.
That's why short lived certs are better then just private keys - even if the key is stolen, the system can cut off the access by not issuing the renewed certificate. This makes private key itself to be irrelevant, in fact it can be generated as well once a day for example.
I think this "wisdom" or "best practice" is targeted at the overwhelming amount of the population that are concerned with using SSH on a computer they control and are therefore not concerned with leaving footprints behind.
Do you frequently use a computer that you don't control?
If the key is encrypted, then it doesn't exist as long as the password is good enough to resist a bruteforce.
But password requirements in this case are definitely higher. You can restrict login attempts in the remote ssh machine, but you can't restrict bruteforcing of stolen encrypted key.
You can also use bcrypt and adjust the work factor; assuming use of ssh-agent and/or shared connections, you could add a delay of multiple minutes to each try.
Your private key should remain password protected, I don't think anyone here is recommending a passwordless login. Also usually with ssh you are more worried about the remote server being compromised than your local client machine.
i am somewhat scared to use smart cards because they might break at some point and i am loosing access... if i would use some kind of local ca to provision the keys i could just as well use them directly... so i would need some kind of secured (air gaped and what not) device to provision them. which will be unavailable when i am abroad... all in all it seems to me it doesn't solve more problems than it makes...
The CA or smart card software is only needed for provisioning smart cards for clients, and is likely to be of little concern for setting up a new server. The card itself stores a non-phishable credential which you can physically secure.
This would mean I'd have to either remember to carry around a flash drive to access my server from the computers at the college library, or keep a copy of my private key on my networking drive there, a network I don't have any reason to believe is perfectly secure.
In either case generate different private keys to use there, so you can revoke the ones used from those computers easily without revoking your more tightly controlled keys.
Private keys are like passwords, try not to re-use them.
My first server was totally exposed in the DMZ. I ran windows RDP with the password "supersecret" for a long time also. I remember at one point also realizing that I could login to ftp anonymously. It was horrendous security in those early days and I had no idea what the heck I was doing.
Don't scare everybody off because it's not a best practice. If his/her server gets pwned they'll fix, learn, and move on.
A password is fine for your fun server. It's not super secure. It you're probably not interesting enough to get pwned using it.
The problem is insecure PCs and servers are a net negative for the Internet as a whole.
I'm now on a fast enough connection with good enough hardware that if you were able to get into one of my desktops or even just the router I'd be inadvertently sending out a lot of spam or "donating" a lot of bandwidth to a DDoS.
Also, scans of the entire IPv4 internet take less than an hour now, so there's absolutely no security-through-obscurity.
I recently put up on github the latest incarnation of a password generator I've been using for over a decade now.[1]
It uses gpg to encrypt each site's username and a random password (using /dev/urandom or CryptGenRandom as the entropy source) in a separate file ~/Documents/Passwords/<domain>.gpg . At the time I first wrote it, I wanted something that was future-proof and where I could decrypt my passwords anywhere, and where a hardware fault while adding a new password was unlikely to cause corruption of pre-existing passwords.
Make your xkcd wordlist (http://google.com/search?q=oxford+3000 is a good start), one line per word, and bzip2 compress it as ~/Documents/Passwords/wordlist.txt.bz2 (or My Documents\Passwords\wordlist.txt.bz2 on Windows) and run the password generator with --alphabet 100 (restricting choices of "alphabets" to those with over 99 characters) and you'll get xkcd-style pass phrases. I also put some numbers in my word list, so I get passwords like
blood Evil pint Urge occupy short railway 38
Diagram elbow Arrest 80 Ceremony monday salt sector
It defaults to making the password/pass phrase length ceil(96 * log(2) / log(len(alphabet))) (96 bits of entropy). If you want to dial that up to 128 bits (or down to 80 bits), put { "bits" : 128 } in ~/Documents/Passwords/config.json (My Documents/Passwords/config.json on windows).
Yes, I started out with a script that used the diceware wordlist to generate passwords and manually used gpg to store my passwords, then evolved my script to combine the two steps I was doing manually.
Have a look at my script. It's all of 200 lines. Easy to audit, and I'm not doing any of my own crypto or random number generation.
Yes, it's easier, but it's completely and totally insecure.
Security is not terribly hard, but it is completely and totally unforgiving. If you slip up on security, you will suffer, or others will suffer because of you.
You can also store the key file on your phone and copy it to whatever computer you want to login to, carrying a phone is easier then an extra flash drive
1. Don't use untrusted hosts to access trusted hosts.
2. If you do, put Tails on a USB drive and use S/Key one-time passwords to access your hosts. Tails should protect you from most real-time stealing of your passwords, and S/Key should protect you from most hardware keylooggers (by the time the one-time password is exfiltrated, it's useless).
If you're accessing computers you care about from a computer you don't control, you don't really care about them. It's already game over: sufficiently-advanced software could easily permit you to log in, then execute any sequence of commands leading to the downfall of your servers.
there is no need to send the password to the server to authenticate a password in this day and age. i thought ssh was one of the first protocols to not do this.
The problem is, ssh daemon doesn't know anything about user password. It uses existing libraries to supply login and password in clear form (like Linux PAM) and they check if it's valid. How this check is done, is abstracted too: it could be /etc/shadow file lookup, it could be LDAP request or really anything.
On the other side, it could be possible to create sshd implementation which will use its own user database. But it's probably not convenient.
->ssh daemon doesn't know anything about user password
And neither should it.
auth system creates a one time usable "ticket" which is a one way function of the user password and a nonce.
The server gives the nonce to the user, who creates his own ticket based on the nonce and his password, gives his ticket to the server, which then checks if the two tickets match, if they do -> authenticated. -> at no point is the actual user password transmitted.
Kerberos extends this further (allows authentication across multiple servers with a single login)
But as far as I know the ticketing system is standard ssh protocol.
As a cloud support engineer, if you break your networking, I don't want to type a 256-character SSH key into the console to recover your server. Please use certificate-based VPNs and use internal addresses to keep connections within your own networks.
there is absolutely no reason you would need to type an ssh key by hand.
even at the very lowest level of server recovery (bare metal bios or uefi), crash carts are obsolete. you can cut and paste everywhere now through ethernetworked or emulated serial means.
you're not getting what i'm saying. it doesn't matter how old the gear you're working on is. if you're typing in long strings by hand, you're not thinking hard enough about how to do your job.
Or you have to deal with real world constraints, which can - and do - involve having equipment where e.g. attaching external KVMs etc. is not always an option that is made available to you (cost constraints; space constraints).
Password auth discloses your password to the server. Clearly this is unfortunate if you connect to the wrong server, but it also means that a compromised server can intercept the passwords of anyone logging in.
The same extends to anyone using password auth with LDAP. In practice this means that if an organization uses LDAP with passwords for SSH authentication, the ability to execute arbitrary code on one server (combined with a routine privilege escalation) implies complete access to any infrastructure accessible with the same password. Most MFA schemes simply force the attacker to act quickly to utilize an intercepted token on a higher value target. Probably this means trying to find a copy of the private key that the devops team is using to run Ansible without having to MFA to every single server.
For small scale use private keys are a simple way to combat this, but at scale they're difficult to manage, and tend to result in high value static credentials lying around on laptops.
A lot of companies are combatting this using SSH certificates. Certificates can be short-lived (as low as minutes given the right tooling), and the CA that issues them can be heavily audited and linked to an existing identity system.
The difficulty of managing ssh keys can be partially mitigated by establishing a PKI and handing out certificates to everyone, then deriving an ssh key from those. OpenSSH supports using a crl, so if you have a trusted infrastructure management of that should be fairly straightforward.
OpenSSH actually has native support for using certificates (in a custom format, not X.509), so if you're building out PKI with SSH in mind it's probably worth going that route.
Do you know of a good guide for how to set this up on Linux? Or a good book that covers the topic? I've looked into this before and it's seemed to be an absolute jungle. I'd like to explore setting this up at my company but don't know where to start.
You'd need to install and configure a FreeIPA server. They make it easy to setup master-master replication which you'll likely want to do. You'd create a user, add a HOTP secret (from a Yubikey or Authenticator app), and force the use of 2FA. Then once you add a client to the domain you'll have to log in using your password and a HOTP token.
Most of it would be applicable to any modern Linux distro.
(Speaking of someone who setup and maintained Kerberos authenticated webapps, clients and servers for the last 10 years, with Microsoft AD as the ultimate backend).
As an aside AD is fine if you have someone to maintain it, but in the past various changes in AD, Linux and Java have made for interesting times.
Yeah, that sounds like a lot of fun for a masochist. As if LDAP isn't a big enough pain in the arse to set up, Kerberos is even worse. Not to mention how much of a pain it is to integrate it in an application.
What's so hard about Kerberos? Kerberos is orders of magnitude easier to deploy and manage than LDAP. It takes literally minutes (if you have done it before and know what you are doing).
In fact it's so easy, that I recommend anyone to use Kerberos even if they don't want to manage the complexity of LDAP. If you use NFS in any meaningful capacity, you have to implement Kerberos, even if you don't have LDAP, otherwise you're implementing a security footgun. Luckily, Kerberos is easy to set up in this configuration, without LDAP.
It's true that LDAP+Kerberos is too hard to deploy and manage, but that's LDAP's fault, not Kerberos'.
What important application doesn't have Kerberos support already? If you talk about adding Kerberos support to your own applications, I have that to be pretty easy.
> So don't do that. Use kerberos auth with LDAP, and use native kerberos support in apps, don't use kerberos with pam.
Or buy into the Hashicorp ecosystem and use Vault + one-time passwords (SSH) and dynamically generated credentials (everything else like database creds).
If I understand you correctly, that's basically how SSH already works. The problems are:
1. Most people don't bother to verify the host key of the server they are connecting to.
2. An attacker with root on the server can modify or observe sshd in order to get the plaintext password.
What about the password you have entered before you press "enter" ?
I think that's a more interesting question ... presumably most SSH users know not to connect when the server keys mismatch and you get the BIG NASTY WARNING.
However, let's say you connect properly to a host you typically use, but through inattention or confusion you start to enter a password for some other SSH host ... and then hit ctrl-C.
I think I have understood that the remote SSH server actually receives the keystrokes character by character, but does it decrypt that all at once after you hit enter, or is it decrypting the characters one by one ?
Character by character occurs only after a secure channel is established.
The client program asks you for the password, in response to negotiations with the server. The password will be sent as a whole and not as typed, as part of the complete auth packet.[1]
Please correct me if I am wrong, but I would say you do not have to worry if you do not hit "Enter". In fact, I would say, that even the application, i.e. ssh doing the read(), does not see it, as sending CTRL-C (SIGINT) will destroy the process (ssh waiting for read() to return).
Until that point your password is just in the tty's buffer - so you are save (if your local machine is not owned - but then you are screwed anyway).
While this question is aimed at SSH, be careful about a similar vector happening on more standard http username/email and password logins at any website.
Most people use the same username or email address for all sites. It's pretty common to attempt to log in with the wrong password for that site, but one that is valid for other sites with the same credentials. While that password attempt shouldn't be logged, there's no guaranteeing it isn't - perhaps even via rouge admin and unbeknownst to the rest of the company.
The biggest threat here is email addresses as usernames, and attempting to login with the password that's actually used for the email account. Very easy to automate any incorrect (or correct) passwords against the original email account.
I've often wondered if this is a vulnerability in all kinds of services. Try to log in to some website with the wrong password and you're probably giving them your Facebook password by accident.
Wouldn't phishing be more like "make a site that looks like Facebook and try to get people to input their Facebook passwords?" What this person described is more abusing password recycling no?
It doesn't even have to be recycling. In fact, I have incorrectly pasted a wrong password to my Google account not realizing I had copied from one row underneath.
Personally, I place a lot of faith and trust in Google so I don't think they'd store failed password attempts about me (I've already volunteered them more information about me than I would volunteer to my own elected representatives anyway). If I ever realized I made a mistake the other way round, I'd reset the password to my Google account even though it has 2FA.
Have you ever noticed that if you enter a password previously used on a Google account it will tell you "password changed X units of time ago"? That surprised me.
It wouldn't surprise me if they're storing failed attempts at all. More data to feed the machines.
Yes. To fix this generally, we'd have to stop hashing passwords for storage so we could use a ZK proof to verify.
There is a hacky middleground whereby a ssh client could hash what you think is your password with the server's identity to derive your actual password. But there's the issue of coming up with a canonical identity for a server, and if we merely trust the server to provide it then the scheme fails to a malicious one. Nevermind it would require special setup on the server, and the utility of password auth is for before you've setup public key auth.
You can hash the password in a way that allows the server to verify but without providing the server or an interceptor with the ability to impersonate. SRP/PAKE and SCRAM are examples.
Doh. It felt like there should be a more complex method replacing the hash with an asymmetric op, but I knew it would be hard to casually describe. In retrospect, obviously the "zero knowledge" bit must imply the server does not know the password!
But yeah, general point remains that currently, crypt(3) is a black box to login methods. To make any login method not have to handle the actual password, it needs to be some well-defined function that is compatible with such math.
Thankfully, if someone is MITM'ing you, or has acquired the IP of your host, then the SSH fingerprint check against your known_hosts will prevent them from snagging your password in this manner. (provided the host's private key hasn't also been stolen)
That is, as long as you don't ignore the "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!" message.
Yes, the server knows your public key. In fact, unless you have specified which public key to use (via command line option or ~/.ssh/config), the server receives all your public keys. This is identifying information - most people have at least 1 ssh public key in github, and github makes those completely public as well.
Filippo Valsorda from Cloudflare built a demo of this - try running:
ssh whoami.filippo.io
and if you have any of your keys in github, it will identify you.
If you want to avoid this you should configure ssh to only send a single specific key.
I wish people would stop saying thay. It is an issue. Maybe not for you, but for a lot of people. It allows any server you connect to to enumerate all of your public keys and identities. If you use nasty leaky services like Github then at least one of your public keys can be used to identify you. This is bad and stupid.
This is why you should tell SSH to use specific keys for specific hosts, and fall back to a nonexistent key for unknown hosts.
Really surprised that a simple and perhaps intuitive question got 131 points. You can just reframe it to "if I send my password to the wrong website, will it be able to read it?" and answer is still yes. Maybe it's 'of course'.
There is a lot of password-based authentication schemes that enables to not share the password with the remote end. You can send a hash. Or you can answer a challenge.
Indeed, you're correct. Although the server always got something. And if it was a hashed password, well, works as if the password wasn't hashed UNLESS the hash changes AFTER some challenge prior the authentication attempt.
This seems like an odd vulnerability. I use SSH keys instead, but I always imagined that if I used a password instead then my password would be used (on both the server and the client) to help derive private keys. If I have the wrong password, the encrypted messages we send to each other would just be garbled nonsense.
It seems like it should be really easy to fix too: add a proper authentication protocol, with protocol negotiation, and then in subsequent versions of SSH, make the warning messages more and more scary. Something like
> The remote host 'ssh.overwathc.org' WANTS TO SEE YOUR PASSWORD, even though current versions of SSH can authenticate without revealing it. You have never connected to this host before -- it could be operated by an attacker. Are you sure you want to show your password to this host (yes/no)?
I think that would be "really easy" only if password hashing was done the same over all platforms SSH runs on. I wouldn't want to be the one to bolt on something like SRP on an already existing login system that uses subtly different "third party" mechanisms for authentification.
Prior to any authentication, a private session key is negotiated and used for encryption for the life of the session. The password (or proof of key ownership, or cert) used for auth is only used for auth, and is only sent after DH key negotiation is complete.
Why isn't the password hashed before it is sent to the server? Is it because the client cannot know how the passwords are hashed on the server side? If so, couldn't the password hashing method be sent to the client?
Try designing a specific means to do this and you'll find that it's not easy.
E.g. your first idea might be "ok, so the client just sends a SHA-256 hash of the password, simple." But... if you do that, then the SHA-256 hash _is_ the password. A rogue server can capture that SHA-256 hash to log in elsewhere.
So you might try and improve that scheme by having the server supply something to hash together with the password. But that means you can't use /etc/passwd anymore, since that
doesn't store the password, it just stores a hash with one particular salt.
Just thinking out loud, but what happens if the SSH server provides two salts. One is the /etc/shadow salt (including the hash type and so on) and the other is a one-time nonce salt to avoid replay attacks. So the client will first generate a crypt(3)-style string (which is equal to the one that the server has stored in /etc/shadow) and then will hash it with the connection-unique nonce to produce a hash that the server can then verify.
Now, to be fair this does mean that you have to give every client the salt for the user they're trying to authenticate as. However IMO a password storage system should still remain secure even after you get the salt for the passwords (you didn't get the hash, so the salt is not useful information to an attacker).
Would that be a viable method, or have I missed something obvious?
Your scheme successfully avoids revealing the password to a
rogue server, so it solves the immediate problem.
But your scheme has made the password hash be the password, which is unacceptable because it's equivalent to storing the plaintext password on the server.
Illustration. Here's /etc/shadow
cyphar:salt:hash
With your scheme, an attacker is allowed to log in by providing
f(nonce + hash)
so that's a red flag: the attacker doesn't need to know the password, just the hash. Looking at it another way, you've made the hash be the password.
(FWIW, I initially thought your scheme worked, but couldn't believe a solution had been overlooked and so I tried it with a concrete example and only then realised where the problem lay. )
Yeah, I see what you mean. And this would presumably allow someone who has read access to /etc/shadow to be able to log into the server with ssh (something they couldn't do with `sudo` without cracking the password first).
There's a challenge response authentication scheme. The authentication method can be enforced on the client but not sure if you can exclude completely password based authentication and enforce certifcate or challenge response authentication, servers need to be configured accordingly.
It is frightening that I never realized this up until now. I always thought that this information was not exposed during the authentication process. But I can't see how it can be an issue unless you are intentionally trying to connect to a place that you are not supposed to ...
i think one way could be if you have a coworker or someone who is able to get root on the machine you are trying to log into. if you have the same password on your own machines sshd he might even easily get back to it and read credentials stored in your browser or use your credentials to damage some part of the comapny in your name etc...
Might be somewhat far stretched but it is definitely something one should be aware of.
I wonder of we can get SSH to bcrypt/scrypt the password clientside.
Of course, if you've got a bunch of computers, you can just configure SSH to use Kerberos auth. The capability is there, IIRC, and not through PAM either.
Of course not! Because you have password authentication disabled and never type your login password in to SSH, right? You use ssh keys and ssh-agent, right? :-)
Correct answer is actually yes. And it's no different than logging in to the wrong web site. You're trusting that the server you incorrectly connected to is not capturing your failed credentials - which it absolutely does see if you're using password auth - with malicious intent.
This is true for any remote system that you're authenticating to with a password that must be verified on the server side, and isn't specific to ssh's password auth.
Here are some projects to help you roll out new infrastructure without SSH passwords:
https://github.com/gravitational/teleport ( I work on this one with our team) and https://github.com/Netflix/bless (heard great things about it, especially if you are using AWS)