I have a linux device that will be making periodic call to an API server, say everytime the system boots up. Everytime then it should authenticate itself and then do its thing.

I can either store the username/password in a .config file, or create a public id_rsa.pub SSH-key.

My question is this: Why is the SSH authorization considered better? I mean if somebody gets access to my linux machine, then they can read both username/password OR the SSH key and they can then copy these information to their own laptop.

Am I missing something here? Note These username/passwords are all generated by me and will all be random 256bit strings. So the typical reasoning of people will use weak and predicable passwords does not apply here.

Update

How about the following approach:

You have a seed number, which will be a md5 of something. This value is stored on the server and every machine.

Now, during authentication, a client will send two strings,

str1 = md5(timestamp + random());
str2 = md5(str1 + seed);

The server will receive these two numbers and will accordingly recalculate str2 from str1. If str2_from_server == str2, then a token is generated and sent back. This token will expire with one use or after a period of time.

The tokens will be saved in a table key/value pair of str1 str2 token and can never be reused again (realistically, this table will be cleared every once in a while so that it does not grow infinitely large).

Is this any superior/inferior to SSH?

  • Regarding the update: As a general principle, one should never "roll your own" crypto/auth code. The code that's built into your OS/libraries will pretty much always be more secure as it was written by experts, reviewed by many more, and passed the test of time. Second, it seems to me that this approach is even less secure than using passwords. Since, now, not only is the effective password stored in clear text on the client (as before) and can be used by another host and used to do anything on the server, BUT, now also the server stores a clear-text version of the password. :-/ Use keys. – JJC Mar 19 '15 at 14:31
up vote 6 down vote accepted

There are several differences.

First, by setting up your API server to accept username/password (as opposed to only allowing access via keys, which is increasingly a best practice to do) you potentially decrease its security in general, as, now, users with weak passwords on the system (or, worse, services that you install which may have hardcoded default passwords) will make it possible to breach your server. Brute-force attacks are suddenly an option for those wanting to break into your system (which, if you run an SSH server on a public IP you are guaranteed to see almost immediately). Disabling ssh login via passwords and requiring login keys is as simple as setting: "PasswordAuthentication no" in your sshd_config and restarting the sshd service (or your server). I do this on every linux box I build as one of the first steps. Plus, this encourages setting up a very long and random password, since (if you set up /etc/sudeoers properly) you will never actually use it for anything. :)

Second, with the ssh key option, you can easily set up the authorized_keys file in such a way that it will:

  1. Only allow access from a specific IP; and
  2. Only allow the accessing user/script to execute a certain command.

This way, even if someone compromises your client box, the stolen key can't be used to log into your server from anywhere else in the world, and, if you set it up properly, it can't even be used to login from your client for anything other than what you allowed. For example, I use this to set up accounts/keys that can do nothing except rsync with certain options from a certain folder. So, even if the key were stolen, the attacker gains nothing other than being able to execute the command that the client machine is executing itself anyway, and only from the client's IP, nowhere else. I.e., gaining the key has not allowed the attacker to compromise the API server. You might be able to restrict an account that's password-based to only execute a certain command or only login from a certain IP, but I've never seen this done and don't know how easy it is.

Third, when you want to give access to your API server to another person/system in the future, and you want to use passwords, you run into the key distribution problem (ironically enough). I.e., you have to have a secure channel to exchange the initial account password so that the user can log in. With SSH keys, all they have to do is email you their public key (which isn't something needing security), and (as long as you trust the email is from them, which there are ways to ensure), and you can give them access.

So, I hope this has convinced you that there is value to using keys (and, really, you should not be using password-only access on anything; keys or 2FA for public services are the only way to go :-)). Cheers.

  • 1
    Thanks for the response. These devices that I am talking about, are all created by me. As such, the username/password will be a very long random string. And that is my concern. A public/private key are also in a way 2 very long random strings. What's the difference of what they do, vs what I do? Also, new devices are manually created by me, and the information of username/password will be entered directly (so even better than emailing a key). Would this change any of the concerns? – Kousha Mar 19 '15 at 2:28
  • I added another update. Can you please read that as well? – Kousha Mar 19 '15 at 2:34
  • It's not just that the key is a "long string," like your password might be. The key has other cryptographic properties, including a level of entropy (which you may or may not meet with a password, depending on how you gen it), and a public/private dichotomy that allows the public key to be distributed widely and sent in the clear, giving access to systems without the systems even knowing your private key. In general, it's best to stick to time-tested and widely scrutinized security protocols rather than roll our own, as much as we sometimes want to :). Cheers. – JJC Mar 19 '15 at 14:37
  • Alright it makes sense. So how do I go about creating an SSH authentication? I'm running NodeJS on a linux machine, but not all API calls need to be authenticated; only a few need to be so. – Kousha Mar 19 '15 at 16:27
  • That sounds like a separate question. Unfortunately, it's beyond my expertise to provide an answer. But, if you ask it, they will come. :) – JJC Mar 20 '15 at 20:21

Why is the SSH authorization considered better? I mean if somebody gets access to my linux machine, then they can read both username/password OR the SSH key and they can then copy these information to their own laptop.

Yes, true, if someone gains full access to your machine, you are in trouble either way.

Am I missing something here?

Yes. All the situations in which an attacker has not already gained full access to your machine. There are easily implemented attacks that are possible with username/password authentication that are not possible with SSH keys.

Well, if you drop the idea for username/password (that is not secure at all for this use) you could implement a chrooted environment for the ssh-client to connect into. using ECDSA or RSA Public key encryption, (you ship the private key with the app, and store the authorized keys outside of the chroot).

Especially if you make a "dropbox" for the clients to write to, or make a FIFO/LIFO special file with just write acces from the chroot environment. you can let the client safely write to the server without giving it any read access whatsoever.

If it's just a file you want to upload, utilize the build-in sFTP client of ssh. This would mean you can just upload a file directly, without giving shell access at all in the chroot environment.

If you trigger the ssh connection through a script on the "client" you do not need to have a ssh.config file. You can just specify the command line arguments you want in the script.

As for why a key is better, security-wise, we just need to look at how the SSH system uses the keys:

  • SSH-client asks for SSH server (what version and key exchange / authentication types do you support)
  • SSH-server replies with capabilities and public key token.
  • SSH-client answers with a secret encoded "encryption token"(a operation of the public key token with some encryption magic) that is signed with your private key.
  • SSH-server authenticates the signature (public key decrypts the message) and validates the encryption token, it then replies its own encryption token based, using similar ways as the client.
  • SSh-client validates the received encryption token.
  • SSH-server sets up a secure tunnel using the new keys. than starts the shell.
  • ssh-client sets up the secure tunnel endpoint and starts the shell proxy.

    yaay ssh connection established.

I suggest you read up on SSH and keys and chrooting so as to better understand what you are trying to do.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.