17

So first, I know, I should use key auth with SSH. No need to explain me that.

Issue here is that I have a (big) bunch of servers, and I need to have a script be able to connect each of these.

I use a key authentication whenever I can, however it's not possible on every server (I don't have control over this). So SSH with login, or sometimes telnet.

So for some I just stored the passwords in a db, and my script go take it when needed. Issue is that it doesn't look really safe to do it that way. Is there a way to make it a little safer?

Like some specific way of storing it?

wokati
  • 171
  • 1
  • 3
  • 1
    Env Variables. Duplicate from SO: http://stackoverflow.com/a/4410137/2579527 – Travis Stoll Feb 09 '15 at 13:35
  • 4
    @TravisStoll Environment variables are not secure. – Jenny D Feb 09 '15 at 13:47
  • I am afraid that for your setup storing the passwords in a db is about as secure as it gets. You could make it an encrypted db, like a keepass file (I think there is at least a perl module to access keepass dbs), but then still you would have to store the password to the database somewhere, if you do not want to enter it every time you invoke your script. Maybe a little better IFF you enter the just the master password each time you invoke your script. – Isaac Feb 09 '15 at 13:50
  • I don't have time to write a proper answer, but there are things to try: see here for ideas: http://stackoverflow.com/questions/1340366/how-to-make-ssh-receive-the-password-from-stdin and here: http://askubuntu.com/questions/52212/what-is-the-least-insecure-way-to-store-a-password-that-is-used-by-a-script – pgr Feb 09 '15 at 16:30
  • 1
    Even if you use SSH authentication keys instead of passwords, that's n assurance of security - anyone that can steal your password database could just steal your private key. You can encrypt your private key just like you could encrypt your password database, but since your script needs to unlock the key (or password database), it's still vulnerable to an attacker. Using passwords instead of keys increases your vulnerability a bit since it opens up more avenues to steal the password, but even using keys instead of passwords is not perfect security. – Johnny Feb 09 '15 at 18:38
  • 1
    "sometimes telnet" seems to imply tha the password will sometimes even be transferred in clear over the wire ... ? – Hagen von Eitzen Feb 10 '15 at 10:04

3 Answers3

25

If your script can connect to any of those servers, anyone with access to the script (or privileged access to the machine the script runs on) can connect to any of those servers.

If the script needs to run autonomously, all bets are off. The answer here is no, there isn't a absolutely safe way to store passwords in such a environment. There's no absolutely safe and practical way of doing anything.

Instead of trying to avoid the unavoidable, you should focus on defense in depth.

Fristly, of course, you should protect the passwords adequately. This usually means keeping them in a file separate from your script and configuring restrictive filesystem permissions. That's about all you can do in this front, from a security perspective.

Other measures can most certainly add obscurity to the process. Encrypting the passwords will make the attacker need to search for the decryption key. Using some sort of operating system protected storage generally protects against other users accessing your key (so it offers no advantage over filesystem permissions, other than being complex to attack - and use). These measures will delay an attack, but most certainly not prevent it against a determined attacker.


Now, let's treat the passwords as public for a moment. What can you do to mitigate damage?

A old and tested solution is to restrict what those credentials can do. On a UNIX system, a good way to do this is to setup a separate user for your script and limit the capabilities of that user, both on the accessing and the accessed servers. You can limit user capabilities on the SSH level, on the shell level or possibly using a Mandatory Access Control mechanism like SELinux.

Something you may also want to consider is to move script logic into the servers. That way, you get a smaller interface that's easier to control, and especially to...

Monitor. Always monitor access to the servers. Preferably, log authentication and commands executed to a append only log. Don't forget to monitor the script file changes using auditd, for example.


Of course, many of these mechanisms aren't useful if you have no control over the servers, as your question seems to imply. If that is the case, I'd advise you to get into contact with the people administering the servers and let them know about your script and the potential security pitfalls.

loopbackbee
  • 1,305
  • 1
  • 10
  • 20
14

The short answer is: No.

The long answer is: No, there's no completely safe way. (This includes environment variables, which can be accessed by others on the server.) The closest you can get is to store them in some encrypted format - keepass, a GPG-encrypted file, or something else along those lines. But at some point you need to decrypt the password so that your script can use it, and at that point you will be vulnerable.

In other words, you need to take a long hard look at in-depth security, both on the server from which the script is run, on the network and on the target servers.

Jenny D
  • 27,358
  • 21
  • 74
  • 110
  • 1
    I'm not so sure this is a definitive NO. His session is secure; the file system could be secure, with appropriate permissions set; so if he can get things from the file system (a stored password) and pipe them through stdin to the ssh command, he should be ok, shouldn't he? Please see the links I gave on another comment above. What do you think? – pgr Feb 09 '15 at 17:48
  • If he does pipe them through stdin, then there's a vulnerability. WIth your suggestions it will be more secure, but it won't be completely so. Especially given that some of the sessions are over telnet. – Jenny D Feb 10 '15 at 05:08
0

You could encrypt the passwords in your db with a second password and store this password on a separate (3rd) machine and have a system in place where the script that needs to passwords out of the db first connects this 3rd machine to get the decryption password, decrypts the password in the db with the password it got from the 3rd machine and does it's work.

Of course this doesn't really add any extra security, an attacker with sufficient privileges could also just request the password from the 3rd machine.

But the point is that a 3rd party could control the 3rd machine, e.g. your boss or security officer, or the 3rd party in control of the servers you don't control.

This way you can tell them, if they ever have an issue, if you quit your job and they don't trust the guy replacing you, or they just want your scripts to stop accessing their machines, they can pull the plug on the 3rd machine, and your scripts will no longer have access to the passwords.

Jens Timmerman
  • 866
  • 4
  • 10