views:

125

answers:

5

Obviously, we don't want to hardcode the plaintext password in each script. This would make cycling the password difficult since a ton of scripts would need to be changed in addition to the password being in plaintext in the first place.

If the scripts takes the password as a parameter, then we need to worry about modifying the 'ps' output to not show the password argument's value. We would also have to worry about the command being recorded in shell history. This can be potentially handled via HISTIGNORE/HISTCONTROL on bash, but there are other shells in use with differing and less flexible history control (e.g.: zsh). We could also use a commandline-specific environment variable (FOO=bar ./script), and while the 'FOO=bar' won't show up in 'ps', it's still, by default, recorded to the shell history. Besides, some systems expose other user's process environments (via 'ps') anyway.

A password (configuration) file could be used that simply stores the plaintext password. This file could be owned/permissioned such to tighten up its access. But, at the end of the day, you still have a password in plaintext.

Prompting is also an option, but this tends to be less convienient (still possible via expect, for example, though) and complicates non-interactivity if the script requires such.

Encryption of some flavor could be used but then we still have a similar issue to deal with with the decryption key.

Should I just go with one of the above anyway? Are the other options that might be superior? How do people handle this situation is a secure manner?

The general goal here is that an attacker should not be able to comprise the database server if the attacker somehow gets onto a system that makes use of the database server. For example, an attack shouldn't be able to just find the password lying around somewhere, shouldn't be able to observe the system ('ps') to discover it, and shouldn't be able to "look back in time" (shell history) to find it.

I'm perfecting aware that there are a millions of scenarios (kmem, swapped pages, etc.. etc..) and that most bets are off if the attacker gets root or physical access and that nothing is going to be 100% secure. I'm just really looking for the best approach within reason. :-)

+3  A: 

If the scripts don't use prompting, and somehow know the db password then the attacker can execute any of your scripts and do those same things.

If you ask for a password, you will have to give it to some people, who will put it in their scripts, or make a password for each user, which provides multiple passwords to guess (and they'll still put it in their scripts).

Perhaps one thing to consider is to have a no password user that can do only SELECT on appropriate tables and can only login from particular hosts, and to require passwords and other users for more sensitive functions?

If you want to hide the password, you could always have a 2 part system. Although you can do very complicated things, XOR (bitwise exclusive or, which is in perl and most other languages) can also be your friend. It is simple for the admin and for the attacker no one piece is useful. An automated attacker might move on to more fertile ground. You can even keep one of the parts on another host and fetch it with wget or nfs or whatever. That way it could be shut off as part of a tripwire system.

Meanwhile, maybe you need some tripwires or honeypots of sorts, so that if the bad guys come calling you can give them disinformation or even shut things off quicker. I like fail2ban for active firewalling. It can scan log files and block ip addresses that are sending you crud you dont want based on anything that is showing up in your logs. It uses regexp's and any log file to define an incident and has some flexibility in the rules engine.

Paul
+2  A: 

I am not a unix admin, but... How about having the scripts run under a no-login account, and set the permissions on the script (and password file) to be 500. That would limit access to root and the script user.

Andrew B
+1  A: 

You might like to explore TPM (http://en.wikipedia.org/wiki/Trusted_Platform_Module)

Many security products use TPM for storing critical security related keys. Other idea could be encrypt the password using certificate stored in a smart card.

Cheers, GK

Gaurav Kumar
+4  A: 

You can put a .my.cnf file in the home dir(s) of users that can access the script, with their info and mysql can read it from there instead of the command line. You'll also have to set an environment variable to point at ~/.my.cnf, but... I'm not sure if it's MYSQL_HOME or SYSCONFDIR or something else*. It'd still be a plain text file, but if you restrict that file to owner-only, it should be fine? It'll at least keep passwords out of ps.

MySQL: Option Files and MySQL: Password Security doc pages both hint at this a little.

(*disclaimer: I'm no admin by any definition, just enough to get in trouble)

tadamson
Yes, do that. +1.
MarkR
+2  A: 

Depending on how critical the data is, you could implement various measures.

Store the password in a file readable only by root. The script reading the keys should start as root, read the password, establish the database connection using database account with minimum privilege required, wipe password from memory, and then drop down (http://stackoverflow.com/questions/910241/how-can-i-drop-privileges-in-perl may help) to a non-privileged system account.

Have simple scripts/trigger to monitor database sessions (session start and end time, user, ip address, commands executed) on the database server, monitor use of sudo on the system, etc.

mar