如何在Heroku上存储私钥?

Jas*_*son 8 python heroku flask

我有一个托管在Heroku上的烧瓶应用程序需要使用boto.cmdshell在AWS EC2实例(Amazon Linux AMI)上运行命令.几个问题:

  1. 使用密钥对访问EC2实例的最佳做法是什么?或者更好地使用用户名/密码?
  2. 如果使用密钥对是首选方法,那么在Heroku上管理/存储私钥的最佳做法是什么?显然,将私钥放在git中是不可取的.

谢谢.

Dre*_*lee 6

Heroku允许您利用配置变量来管理您的应用程序.这是我的conf.py文件的一个例子,它位于我的flask应用程序中:

import os

# flask
PORT = int(os.getenv("PORT", 5000))
basedir = str(os.path.abspath(os.path.dirname(__file__)))
SECRET_KEY = str(os.getenv("APP_SECRET_KEY"))
DEBUG = str(os.getenv("DEBUG"))
ALLOWED_EXTENSIONS = str(os.getenv("ALLOWED_EXTENSIONS"))
TESTING = os.getenv("TESTING", False)

# s3
AWS_ACCESS_KEY_ID = str(os.getenv("AWS_ACCESS_KEY_ID"))
AWS_SECRET_ACCESS_KEY = str(os.getenv("AWS_SECRET_ACCESS_KEY"))
S3_BUCKET = str(os.getenv("S3_BUCKET"))
S3_UPLOAD_DIRECTORY = str(os.getenv("S3_UPLOAD_DIRECTORY"))
Run Code Online (Sandbox Code Playgroud)

现在我可以有两组不同的结果.它来自我的环境变量.一个是我的应用程序在我的本地计算机上,而是在生产时从Heroku配置变量.例如.

 DEBUG = str(os.getenv("DEBUG")) 
Run Code Online (Sandbox Code Playgroud)

在我的本地计算机上"是".但是Heroku上的假.为了检查你的Heroku配置运行.

Heroku config
Run Code Online (Sandbox Code Playgroud)

另外请记住,如果你想在本地保留一些文件的一部分,而不是在heroku或github上,你可以使用git ignore.当然,那些文件将不会存在于您的生产应用程序中.

  • 使用`str(os.getenv('SPAM'))`是一个很大的错误,特别是如果需要设置的话.如果未在环境中配置`SPAM`,则将值设置为"无",这非常糟糕,因为它会以意外的方式失败.使用`os.environ ['SPAM']`,如果在环境中没有配置`SPAM`,它会以明显的方式失败.如果您希望设置是可选的,请使用`if os.getenv('SPAM')不是None:...`,或者其他类似的效果. (3认同)

Jas*_*son 5

我正在寻找的是有关如何处理私钥的指导。@DrewV 和 @yfeldblum 都为我指明了正确的方向。我最终将我的私钥转换为字符串并将其存储在 Heroku 配置变量中。

如果有人想做类似的事情,这里有一个使用 paramiko 的示例代码片段:

import paramiko, base64
import StringIO
import os

key = paramiko.RSAKey.from_private_key(StringIO.StringIO(str(os.environ.get("AWS_PRIVATE_KEY"))))
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(str(os.environ.get("EC2_PUBLIC_DNS")), username='ec2-user', pkey=key)
stdin, stdout, stderr = ssh.exec_command('ps')

for line in stdout:
    print '... ' + line.strip('\n')
ssh.close()
Run Code Online (Sandbox Code Playgroud)

感谢@DrewV 和@yfeldblum 的帮助(对两者都投赞成票)。

  • 另一个提示:如果机密数据太大而无法放入配置变量,请使用 AES 对其进行加密,将其放入存储库中的文件中,然后将 AES 密钥放入配置变量中。如果秘密数据是 OpenSSL 私钥,您可以改用它的密码短语工具,但要确保密码短语是一个长的、完全随机的字符串——`secrets.token_hex(16)` 应该生成一些合适的东西。 (3认同)