Answers:
典型的方法是从配置文件中读取密码信息。如果您的配置文件名为foobar.config
,那么您将向foobar.config.example
存储库提交一个包含示例数据的文件。要运行程序,您将创建一个foobar.config
使用真实密码数据调用的本地(未跟踪)文件。
要从以前的提交中过滤掉您现有的密码,请参阅删除敏感数据上的GitHub帮助页面。
.gitignore
文件不适用于存储库中已跟踪的文件。例如,git add -u
即使已存在,也会添加一个已更改的文件.gitignore
。
一种方法是使用环境变量设置密码(或API密钥)。因此,此密码不受版本控制。
使用Bash,您可以使用以下命令设置环境变量
export your_env_variable='your_password'
这种方法可以与Travis之类的持续集成服务一起使用,您存储在GitHub存储库中的代码(无密码)可以由Travis执行(使用环境变量设置密码)。
使用Bash,您可以使用以下方法获取环境变量的值:
echo "$your_env_variable"
使用Python,您可以使用以下方法获取环境变量的值:
import os
print(os.environ['your_env_variable'])
PS:请注意,这可能有点冒险(但这是很常见的做法)https://www.bleepingcomputer.com/news/security/javascript-packages-caught-stealing-environment-variables/
PS2:dev.to
这篇标题为“如何安全存储API密钥”的文章可能很有趣。
根据您的确切问题,将以不同的方式处理存储库中的密码。
并在某些答复中介绍了避免这样做的方法-.gitignore,config.example等
即允许人们知道密码的人。chmod
和用户群浮现在脑海;如果您在外部托管存储库或服务器,还应该允许Github或AWS员工看到问题吗?
如果要将包含敏感信息(例如密码)的配置文件存储在公共位置,则需要对其进行加密。从存储库中恢复文件时,可以对其进行解密,甚至可以直接使用其加密形式来使用。
下面显示了使用加密的配置数据的示例javascript解决方案。
const fs = require('fs');
const NodeRSA = require('node-rsa');
let privatekey = new NodeRSA();
privatekey.importKey(fs.readFileSync('private.key', 'utf8'));
const config = privatekey.decrypt(fs.readFileSync('config.RSA', 'utf8'), 'json');
console.log('decrypted: ', config);
因此,您可以恢复仅编写几行Javascript的加密配置文件。
请注意,将文件config.RSA
放入git存储库将有效地使其成为二进制文件,因此它将失去诸如Git之类的许多好处,例如,能够自动选择更改。
解决方案可能是加密键值对或仅加密值。您可以加密所有值,例如,如果您具有敏感信息的单独文件,或者如果一个文件中具有所有值,则仅加密敏感值。(见下文)
上面的示例对于想要对其进行测试的任何人都是无用的,或者作为一个示例,因为它假设存在一些RSA密钥和一个加密的配置文件,因此从此开始config.RSA
。
因此,这里添加了一些额外的代码行来创建RSA密钥和一个配置文件。
const fs = require('fs');
const NodeRSA = require('node-rsa');
/////////////////////////////
// Generate some keys for testing
/////////////////////////////
const examplekey = new NodeRSA({b: 2048});
fs.writeFileSync('private.key', examplekey.exportKey('pkcs8-private'));
fs.writeFileSync('public.key', examplekey.exportKey('pkcs8-public'));
/////////////////////////////
// Do this on the Machine creating the config file
/////////////////////////////
const configToStore = {Goodbye: 'Cruel world'};
let publickey = new NodeRSA();
publickey.importKey(fs.readFileSync('public.key', 'utf8'));
fs.writeFileSync('config.RSA', publickey.encrypt(configToStore, 'base64'), 'utf8');
/////////////////////////////
// Do this on the Machine consuming the config file
/////////////////////////////
let privatekey = new NodeRSA();
privatekey.importKey(fs.readFileSync('private.key', 'utf8'));
const config = privatekey.decrypt(fs.readFileSync('config.RSA', 'utf8'), 'json');
console.log('decrypted: ', config);
fs.writeFileSync('config.RSA', JSON.stringify(config,null,2), 'utf8');
您可以使用类似的方法解密带有加密值的配置文件。
const savedconfig = JSON.parse(fs.readFileSync('config.RSA', 'utf8'));
let config = {...savedconfig};
Object.keys(savedconfig).forEach(key => {
config[key] = privatekey.decrypt(savedconfig[key], 'utf8');
});
通过将每个配置项放在单独的行上(例如Hello
,Goodbye
以上),Git将更好地识别文件中发生的事情,并将对信息项的更改存储为差异而不是完整文件。Git也将能够更好地管理合并和樱桃采摘等。
但是,您越想对敏感信息进行版本控制更改,就越倾向于SAFE REPOSITORY解决方案(2)而远离ENCRYPTED INFO(3)解决方案。
这是我使用的一种技术:
我在主文件夹中创建一个文件夹:
.config
在该文件夹中,我放置了配置文件,以容纳要外部化密码和密钥的任何数量的内容。
我通常使用反向域名语法,例如:
com.example.databaseconfig
然后在bash脚本中执行以下操作:
#!/bin/bash
source $HOME/.config/com.example.databaseconfig ||exit 1
|| exit 1
如果脚本无法加载配置文件,则会导致脚本退出。
我将这种技术用于bash,python和ant脚本。
我非常偏执,并且认为.gitignore文件没有足够强壮的功能来防止意外签入。另外,没有任何东西可以监视它,因此,如果签入确实发生了,那么没人会找到解决方案。
如果一个特定的应用程序需要多个文件,我将创建子文件夹而不是单个文件。
如果您在轨道上使用红宝石,那么Figaro宝石非常好,简单且可靠。它对生产环境的影响也很小。
信任但要验证。
在.gitignore
这种情况下,将从存储库中排除“安全”目录:
secure/
但我分享@ 迈克尔·波特的偏执狂。因此,要验证.gitignore,以下是一个Python 单元测试,如果该“安全”目录被检入,它将引发klaxon。此外,还要检查合法目录,以检查该检查:
def test_github_not_getting_credentials(self):
safety_url = 'https://github.com/BobStein/fliki/tree/master/static'
danger_url = 'https://github.com/BobStein/fliki/tree/master/secure'
self.assertEqual(200, urllib.request.urlopen(safety_url).status)
with self.assertRaises(urllib.error.HTTPError):
urllib.request.urlopen(danger_url)