我有一个小Bash脚本,我用它来访问twitter,并在某些情况下弹出咆哮通知。用脚本存储密码的最佳方法是什么?

I would like to commit this script to the git repo and make it available on GitHub, but I'm wondering what the best way to keep my login/password private while doing this is. Currently, the password is stored in the script itself. I can't remove it right before I push because all the old commits will contain the password. Developing without a password isn't an option. I imagine that I should be storing the password in an external config file, but I thought I'd check to see if there was an established way to handle this before I tried and put something together.


当前回答

实现这一点的典型方法是从配置文件中读取密码信息。如果你的配置文件叫做foobar。Config,然后向存储库提交一个名为foobar.config.example的文件,其中包含示例数据。要运行程序,需要创建一个名为foobar的本地(不跟踪)文件。配置您的真实密码数据。

要从以前的提交中过滤出您现有的密码,请参阅GitHub删除敏感数据的帮助页面。

其他回答

根据您的具体问题,可以以不同的方式处理存储库中的密码。

1. 不要这样做。

避免这样做的方法包括在一些回复- .gitignore, config。例子中,等

.gitignore:存储在服务器等,而不是Git(弱解决方案) 环境变量:https://stackoverflow.com/a/30664318/3070485 配置。例如:https://stackoverflow.com/a/2397905/3070485 命令行参数:程序启动时手动输入密码

或2。使存储库仅对授权的人访问

即允许知道密码的人。Chmod和用户组会出现在脑海中;还有一些问题,比如如果你在外部托管存储库或服务器,Github或AWS员工是否应该被允许查看内容?

或3。加密敏感数据(回复的目的)

如果您想将包含敏感信息(如密码)的配置文件存储在公共位置,则需要对其进行加密。这些文件可以在从存储库中恢复时解密,甚至可以直接从其加密形式中使用。

下面是使用加密配置数据的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就可以恢复加密的配置文件。

注意,放置一个文件配置。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),而远离加密INFO(3)解决方案。

实现这一点的典型方法是从配置文件中读取密码信息。如果你的配置文件叫做foobar。Config,然后向存储库提交一个名为foobar.config.example的文件,其中包含示例数据。要运行程序,需要创建一个名为foobar的本地(不跟踪)文件。配置您的真实密码数据。

要从以前的提交中过滤出您现有的密码,请参阅GitHub删除敏感数据的帮助页面。

信任,但要核实。

在.gitignore中,这将从repo中排除一个“安全”目录:

secure/

但我和迈克尔·波特一样偏执。因此,为了验证.gitignore,这里有一个Python单元测试,如果这个“安全”目录被签入,它将发出一个喇叭。为了检查检查,也要测试一个合法的目录:

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)

Is there any possibility to tell github to track the file under a different name? Example: Locally, I have a file passwords.config with real passwords, and sample-passwords.config with stubs. However, in public repo, I'd like to have only passwords.config with content from sample-passwords.config and real passwords.config ignored. I know .gitignore, which can hide my passwords.config, but I don't know is there any solution to rename sample-passwords.config while commiting to remote public repo. Of course, I'd like to avoid situation, when my local repo tracks renamed file as if something changed in git status.

可以使用HashiCorp Vault来保护、存储和控制对令牌、密码、证书、API密钥等的访问。

Ansible特别有一个“Vault”功能(与HashiCorp产品无关),用于加密静止的秘密。