bash 在 shell/Perl 脚本中保存密码的最佳实践?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/80612/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best practices for holding passwords in shell / Perl scripts?
提问by GodEater
I've recently had to dust off my Perl and shell script skills to help out some colleagues. The colleagues in question have been tasked with providing some reports from an internal application with a large Oracle database backend, and they simply don't have the skills to do this. While some might question whether I have those skills either (grin), apparently enough people think I do to mean I can't weasel out of it.
我最近不得不磨练我的 Perl 和 shell 脚本技能来帮助一些同事。有问题的同事的任务是从具有大型 Oracle 数据库后端的内部应用程序提供一些报告,而他们根本不具备执行此操作的技能。虽然有些人可能会质疑我是否有这些技能(咧嘴笑),但显然有足够多的人认为我这样做意味着我无法摆脱它。
So to my question - in order to extract the reports from the database, my script is obviously having to connect and run queries. I haven't thus far managed to come up with a good solution for where to store the username and password for the database so it is currently being stored as plaintext in the script.
所以对于我的问题 - 为了从数据库中提取报告,我的脚本显然必须连接并运行查询。到目前为止,我还没有想出一个很好的解决方案来存储数据库的用户名和密码,因此它目前以纯文本形式存储在脚本中。
Is there a good solution for this that someone else has already written, perhaps as a CPAN module? Or is there something else that's better to do - like keep the user / password combo in a completely separate file that's hidden away somewhere else on the filesystem? Or should I be keeping them trivially encrypted to just avoid them being pulled out of my scripts with a system-wide grep?
是否有其他人已经编写的好的解决方案,也许作为 CPAN 模块?或者还有其他更好的方法 - 比如将用户/密码组合保存在一个完全独立的文件中,该文件隐藏在文件系统的其他地方?或者我应该对它们进行简单的加密以避免它们被系统范围的 grep 从我的脚本中拉出?
Edit:
The Oracle database sits on an HP-UX server.
The Application server (running the shell scripts) is Solaris.
Setting the scripts to be owned by just me is a no-go, they have to be owned by a service account that multiple support personnel have access to.
The scripts are intended to be run as cron jobs.
I'd love to go with public-key authentication, but am unaware of methods to make that work with Oracle - if there is such a method - enlighten me!
编辑:Oracle 数据库位于 HP-UX 服务器上。
应用程序服务器(运行 shell 脚本)是 Solaris。
将脚本设置为仅由我拥有是不行的,它们必须由多个支持人员可以访问的服务帐户拥有。
这些脚本旨在作为 cron 作业运行。
我很想使用公钥身份验证,但我不知道使该方法与 Oracle 一起使用的方法 - 如果有这样的方法 - 请赐教!
采纳答案by Redbeard
Best practice, IMHO, would be to NOT hold any passwords in a shell / Perl script. That is what public key authentication is for.
恕我直言,最佳实践是不要在 shell / Perl 脚本中保存任何密码。这就是公钥认证的用途。
回答by Matthew Watson
If the script is running remotely from the server.
如果脚本从服务器远程运行。
- Make your reports views
- Give the user you are logging into ONLY access to select on the report views
- Just store the password.
- 使您的报告视图
- 仅授予您登录的用户选择报告视图的权限
- 只需存储密码。
That way, all that the user can do, is select the data for its report. Even if someone happened to get the password, they would be limited as to what they could do with it.
这样,用户所能做的就是为其报告选择数据。即使有人碰巧得到了密码,他们也能用它做什么。
回答by Barbie
Personally I hold passwords in configuration files which are then distributed independently of the application, and can be changed to the specific machine/environment. In shell scripts you can source these within the main script.
我个人将密码保存在配置文件中,然后独立于应用程序分发,并且可以更改为特定的机器/环境。在 shell 脚本中,您可以在主脚本中获取这些内容。
However, in Perl there are a variety of approaches. You may wish to investigate Getopt::Longfor command line options (and additionally Getopt::ArgvFileto store those in a simple configuration file), or look at something like Config::IniFilesfor something with a little more power behind it. These are the two types I generally use, but there are other configuration file modules available.
但是,在 Perl 中有多种方法。您可能希望研究Getopt::Long以获取命令行选项(另外还有Getopt::ArgvFile将这些选项存储在一个简单的配置文件中),或者查看诸如Config::IniFiles 之类的东西以了解其背后的功能。这是我通常使用的两种类型,但还有其他可用的配置文件模块。
回答by Chris Madden
For storing passwords you could do a two step encryption routine, first with a hardcoded key in your script itself, and optionally a 2nd time with a key stored in a file (which is set using file permissons to have restricted access).
为了存储密码,您可以执行两步加密例程,首先在脚本本身中使用硬编码密钥,第二次使用存储在文件中的密钥(使用文件权限设置以限制访问)。
In a given situation you can then either use a key file (+ key from script), or if the situation requirements aren't that great he can just use the encyrption using the key is hardcoded in the script. In both cases the password would be encrypted in the config file.
在给定的情况下,您可以使用密钥文件(+ 脚本中的密钥),或者如果情况要求不是那么好,他可以使用加密,使用脚本中的硬编码密钥。在这两种情况下,密码都将在配置文件中加密。
There is no perfect solution because somehow you have to be able to decrypt and obtain the cleartext password...and if you can do it someone else can too if they have the right info.
没有完美的解决方案,因为以某种方式您必须能够解密并获得明文密码……如果您可以做到,其他人也可以,如果他们拥有正确的信息。
Especially in the situation where we give them a perl script (vs. an exe) they can easily see how you do the encryption (and the hardcoded key)...which is why you should allow the option to use a keyfile (that can be protected by filesystem permissions) as well.
特别是在我们给他们一个 perl 脚本(与一个 exe)的情况下,他们可以很容易地看到你如何进行加密(和硬编码的密钥)......这就是为什么你应该允许选择使用密钥文件(可以也受文件系统权限保护)。
Some practical examples for how to implement is here
如何实施的一些实际例子是here
回答by Mark Nold
I'm not sure what version of Oracle you are running. On older version of Oracle (pre 9i Advanced Security) some DBA's would CREATE USER OPS$SCOTT IDENTIFIED BY EXTERNALLYand set REMOTE_OS_AUTHENTto true.
我不确定您正在运行什么版本的 Oracle。在旧版本的 Oracle(9i 之前的高级安全)上,一些 DBA 会CREATE USER OPS$SCOTT IDENTIFIED BY EXTERNALLY设置REMOTE_OS_AUTHENT为 true。
This would mean that your remote sun machine could authenticate you as SCOTT and then your Oracle DB would accept that authentication.
这意味着您的远程 sun 机器可以将您验证为 SCOTT,然后您的 Oracle DB 将接受该验证。
This is a bad idea.
这是一个坏主意。
As you could image any Windows XP with a local user of SCOTT could then log into your DB without a password.
正如您可以使用 SCOTT 的本地用户对任何 Windows XP 进行映像,然后无需密码即可登录您的数据库。
Unfortunately it's the only option that i know of Oracle 9i DBs to not store username/passwords in your script or somewhere else accessible by the client machine.
不幸的是,这是我所知道的 Oracle 9i DB 的唯一选项,即不在您的脚本或客户端机器可访问的其他地方存储用户名/密码。
What ever your solution it's worthwhile having a look through Oracle's Project Lockdownbefore committing.
无论您的解决方案是什么,在提交之前都值得查看 Oracle 的Project Lockdown。
回答by moritz
There is no good solution. You can obfuscate the passwords a bit, but you can't secure them.
没有好的解决办法。您可以稍微混淆密码,但无法保护它们。
If you have control over your DB setup, you could try to connect by a named pipe (at least mysql supports that) without a password and let the OS handle the permissions.
如果您可以控制您的数据库设置,您可以尝试通过没有密码的命名管道(至少 mysql 支持)进行连接,并让操作系统处理权限。
You could also store the credentials in a file with restrictive permissions.
您还可以将凭据存储在具有限制性权限的文件中。
回答by Paul Hargreaves
Since you've tagged ksh & bash I'm going to assume Linux.
由于您已经标记了 ksh 和 bash,我将假设使用 Linux。
Most of the problem is that if the user can read the script and locate the method you used to hide / encrypt the file then they will also be able to do the same thing manually.
大多数问题是,如果用户可以阅读脚本并找到您用来隐藏/加密文件的方法,那么他们也可以手动执行相同的操作。
A better way may be do the following:
更好的方法可能是执行以下操作:
- Make your script so it can only be seen/read/opened by you. chmod 700 it. Hardcode passwords away.
- Have a "launcher" script that is executable by the user and does a sudo .
- 制作您的脚本,使其只能由您看到/阅读/打开。chmod 700吧。硬编码密码。
- 拥有一个可由用户执行并执行 sudo 的“启动器”脚本。
This way the user can see your launcher script, examine it to see it only has the single command line. They can run it and it works, but they don't have permissions to read the source for the script that is sudo'd.
这样用户就可以看到您的启动程序脚本,检查它以查看它只有一个命令行。他们可以运行它并且它可以工作,但是他们无权读取 sudo 脚本的源代码。
回答by paxdiablo
In UNIX, I always make these scripts setuid and store the user and password info in a file that's heavily protected (the entire directory tree is non-readable/searchable by regular users and the file itself is readable only by the owner of the script).
在 UNIX 中,我总是将这些脚本设置为 setuid 并将用户和密码信息存储在一个受到严密保护的文件中(整个目录树对于普通用户是不可读/不可搜索的,并且文件本身只能由脚本所有者读取) .
回答by paxdiablo
Keep them in a separate file, trivially encrypted, and make a separate user in the database with read only access to necessary tables. If you think the file has been read, then you can shut off access to just that user.
将它们保存在单独的文件中,简单加密,并在数据库中创建一个单独的用户,对必要的表具有只读访问权限。如果您认为该文件已被读取,那么您可以仅关闭对该用户的访问。
If you want to get fancy, a SUID program could check the /proc//exe and cmdline (in Linux), and only then release the username.
如果你想花哨,SUID 程序可以检查 /proc//exe 和 cmdline(在 Linux 中),然后才释放用户名。
回答by Jonathan Bourke
I have / had a similar issue with developers deploying SQL code to MSSQL (in fact to any database on that MSSQL server, so role had to be SysAdmin) using ANT from a Solaris server. Again I did not want to store the username and password in the ANT build.xml files so my solution, which I know is not ideal, is as follows:
我遇到过类似的问题,开发人员使用 Solaris 服务器上的 ANT 将 SQL 代码部署到 MSSQL(实际上部署到该 MSSQL 服务器上的任何数据库,因此角色必须是 SysAdmin)。再次,我不想将用户名和密码存储在 ANT build.xml 文件中,所以我知道我的解决方案并不理想,如下所示:
- Store name / value pairs for username and password in a plain text file
- Encrypt file (on Solaris) and use a pass phrase only known to certain admins
- Leave only the encrypted file on the Solaris system
- ANT build.xml runs a sudo decrypt and prompts for pass phrase, which is entered by admin
- ANT sources decrypted file loading username and password as variables for the SQL string
- ANT immediately deleted the plaintext file
- ANT deploys code and exits
- 将用户名和密码的名称/值对存储在纯文本文件中
- 加密文件(在 Solaris 上)并使用只有某些管理员知道的密码
- 在 Solaris 系统上只保留加密文件
- ANT build.xml 运行 sudo 解密并提示输入密码,由管理员输入
- ANT 源解密文件加载用户名和密码作为 SQL 字符串的变量
- ANT立即删除明文文件
- ANT部署代码退出
This all happens in a matter of seconds, and the sql username and password is never visibly accessible on the server. As the code is deployed by allowed admins in production, the developers never need to include it in their code.
这一切都在几秒钟内发生,并且 sql 用户名和密码永远不会在服务器上可见。由于代码是由允许的管理员在生产中部署的,因此开发人员永远不需要将其包含在他们的代码中。
I am sure it could be better, but...
我相信它可以更好,但是......
JB
JB

