处理生产配置中的密码以进行自动化部署
我在这里看到了相关问题,但它们似乎并没有完全回答我所需要的。
我们使用 Powershell 脚本来部署我们的应用程序,大多数环境(UAT 等)的配置文件中的密码等信息都是纯文本形式。这不是一个大问题,但是当涉及到 PREPROD 和 PROD 时,这是一个大问题。因此,我们在配置中有一些标记,例如“{{prompt-password}}”,它将提供一个登录对话框(Get-Credential
),并且执行部署的人员可以输入凭据,部署将继续。
但这对于自动化部署并没有真正的帮助(意味着通过 TeamCity 等工具进行一键部署)
我是否应该采用非对称加密( http://msdn.microsoft.com/en-us/library/as0w18af.aspx ),其中密码使用公钥加密,输入在配置中,并存储私钥(如此处所述 http://msdn .microsoft.com/en-us/library/tswxhw92.aspx )在运行自动化部署,它可以解密密码吗?对密码学之类的东西不是很了解,但这听起来像是正确的方法吗?还有其他建议吗?人们如何处理这种自动化部署?
更新:
好的,我已经实施了。我用 C# 编写了一个控制台应用程序,它使用密码学库。该应用程序生成密钥:
RSACryptoServiceProvider rsa = GetRsa(containerName);
File.WriteAllText("keys.kez",rsa.ToXmlString(true));
我还获取了公钥:
File.WriteAllText("public.pke", rsa.ToXmlString(false));
将公钥提供给必须加密密码的任何人,并要求他们在配置中输入密码。将keys.kez 文件放入任何必须运行部署的代理中。
I have seen related questions here, but they don't seem to be answering exactly what I need.
We use Powershell scripts to deploy our applications and the info like passwords in configuration files for most of the environments ( UATs etc. ) are in plain text. It is not a big issue, but when it comes to PREPROD and PROD, it is a big issue. So we had some markers in the config like "{{prompt-password}}" which will give a login dialog (Get-Credential
) and the person doing the deployment can enter the credential and the deployment continues.
But this doesn't really help for automated deployment ( meaning one-click deploy through tools like TeamCity )
Should I go for Asymmetric encryption ( http://msdn.microsoft.com/en-us/library/as0w18af.aspx ) where the password is encrypted using a public key, entered in the config, and private key is stored (as described here http://msdn.microsoft.com/en-us/library/tswxhw92.aspx ) in the "agent" ( as in a VM from where TeamCity will trigger the deployment and which has restricted access ) running the automated deployment and it can decrypt the password? Not really strong on Cryptography and stuff, but does this sound like the way to go? Any other suggestions? How do people handle such automated deployment?
Update:
Ok, I have gone ahead and implemented it. I have written a Console Application in C# which uses the Crypography libraries. The app generates the keys:
RSACryptoServiceProvider rsa = GetRsa(containerName);
File.WriteAllText("keys.kez",rsa.ToXmlString(true));
I also get out the public key:
File.WriteAllText("public.pke", rsa.ToXmlString(false));
Give the public key to anyone who has to encrypt the password and ask them to enter the password in the config. Put the keys.kez file in any agent that has to run the deployment.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
从安全性和简单性的角度来看,非对称加密绝对是赢家。我已经以这种方式非常成功地部署了生产 SaaS 应用程序。
有一些技巧。一,正如您提到的,确保公钥/私钥对安装在主机上,而不是存储在配置文件或代码中。第二,假设 MS 提供的管理和密钥生成工具很弱甚至很糟糕,并相应地进行计划(我们为操作创建了一个简单的 keygen exe,以便在部署期间运行。)
Asymmetric encryption is definitely the winner here from a security and simplicity standpoint. I have deployed production SaaS apps in this manner very successfully.
There are a few tricks. One, as you mentioned, make sure the public/private key pair is installed on the host, not stored in config files or in the code. Two, assume the management and key generation tools provided by MS are weak to terrible and plan accordingly (we created a simple keygen exe for Operations to run during deploy.)
并不是真正的答案,而是建议或其他问题。
为什么不将密码存储在配置文件中的加密字符串中
据我了解文档,使用相同凭据运行的进程可以取回密码
您可以将
$credential.Password
替换为 <代码>读取主机-assecurestringNot really an answer, but a suggestion or an other question.
Why don't tou store the password in a crypted string in a config file
As far as I understand the documentation a process running with the same credential can get it back
You can replace
$credential.Password
byread-host -assecurestring
正如您在问题中所说,您的密码以纯文本形式保存在配置文件的 PROD 中。再多的加密也无济于事。此外,这是一种恶性循环 - 您将如何保护加密密钥?
这里的关键是考虑什么是实用的,以及您的组织在部署时遵循哪种业务工作流程。
让我用一个例子来解释这一点。我们假设到 PROD 的部署是由基础设施团队执行的。该团队有权访问您的配置中所需的密码。出于安全原因,他们绝不会向您(部署开发人员)透露此密码。您希望避免他们在每次安装期间输入密码。想想看,这是你能做的最好的事情了。他们必须至少输入一次密码。
加密解决方案在这里不起作用,因为您的部署包无论如何都需要一种解密密码的方法,并且如果它可以在没有用户输入的情况下解密密码,那么您(开发人员)也可以,这是不可接受的。
由于密码无论如何都以纯文本形式存储在 PROD 配置文件中,因此仅在不知道密码时才让部署包提示输入密码。基础设施团队成员提供密码后,将其保存在本地文件中。更好的是,将其保存在机器范围内的密钥容器中。为此您不需要密码。围绕密钥的下一次安装将是已知的,并且您的安装不需要再次提示输入密钥。当然,如果需要,您也需要提供一种更改存储密钥的方法。
您所描述的标记化方法是有效的。我已经这样做了一段时间,非常成功。 (即通过了外部安全审查)由于您在PROD中确实有纯文本密码,因此PROD必须被视为安全(safe)环境。由于它是安全的,因此在其中缓存(存储其副本)此安全密码没有任何问题。
As you said in your question, your password are kept in PROD in config file in plain text. No amount of encryption can help with that. Also, this is kind of a vicious cycle - how are you going to protect encryption key?
The key think here is to look at what is practical, and what kind of business workflows your organization follows when it comes to deployments.
Let me explain this on an example. Let's assume that the deployment to PROD is executed by an infrastructure team. This team has access to the password that is required in your configs. They will never disclose this password to you (deployment developer) for security reasons. You want to avoid them entering the password during each installation. To think of it this is the best you can do. They will have to enter the password at least once.
Cryptography solution won't really work here because your deployment package will need a way to decrypt the password anyway and if it can do it without user input, so can you (the developer), and this is not acceptable.
Since the password is store in PROD config files in plain text anyway, make the deployment package prompt for the password only if it's not know. Once a infrastructure team member supplies the password, save it in a file locally. Better yet, save it in machine-wide key container. You do not need a password for this. Next installation around the key will already be known, and your installation won't need to prompt for a key again. Of course you need to provide a way to change the stored key too if needed.
The tokenizing approach, that you described, works. I've been doing this for quite some time quite successfully. (I.e. passed external security reviews) Since you do have a plain text password in PROD, PROD must be considered secure (safe) environment. And since it safe, there is nothing wrong about caching (storing a copy of) this secure password within it.
无论您使用非对称加密还是对称加密,您都需要将解密密钥保留在代码中,以便将安全风险从配置文件转移到可执行文件(代理)。它在混淆方面要好得多,但可以想象,可执行文件可以由有足够决心提取解密密钥的人进行逆向工程。
Whether you use asymetric or symetric encryption you'll need to keep the deciphering key in your code so you are shifting the security risk from your configuration file to your executable (agent). It is much better in terms of obfuscation but the executable could conceivably be reverse engineered by someone sufficiently determined to extract the deciphering key.
创建计划作业来运行部署脚本怎么样?设置任务使用特定的用户帐户运行,并授予该帐户相关权限。
How about creating a scheduled job to run the deployment scripts? Set the task to be run with specific an user account and grant the account relevant permissions.
一个有趣的问题,我也在多个环境中工作,并且面临着针对不同环境的不同设置的挑战。不过,我们并没有真正将密码放入配置中(机器受到攻击或工程师的错误等......)。如果我们这样做是为了非常不安全的东西,因此我们将它们保留为纯文本。
考虑到这一点,构建机器是否可能没有每个环境的密码列表?
如果你不想将它们保留为纯文本,你也许可以使用 PowerShell 做一些事情 - 我确信 Jaykul 曾以这种方式发表过一篇文章,但我的(快速)谷歌搜索只返回了 Halr 的一些内容(两者都是 PowerShell) MVP,所以这应该很有趣)。
http://halr9000.com/article/531
An interesting question, I work with multiple environments as well and have the challenge of different settings for different environments. We don't really put passwords in the config though (a compromised machine or a mistake by an engineer etc...). If we do it's for pretty insecure stuff, as such we keep them plain text.
With that in mind could the build machine just not have a list of password for each environment?
If you don't want to you keep them plain text you may be able to do something with PowerShell - I'm sure Jaykul did a post on this way back when but my (quick) googling only returned something from Halr (both are PowerShell MVPs so it should be interesting) .
http://halr9000.com/article/531