Is there a safe way to store passwords used for ssh by a script?
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?
Solution 1:
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.
Solution 2:
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.