【问题标题】:How to store private key on Heroku?如何在 Heroku 上存储私钥?
【发布时间】:2012-12-20 01:35:07
【问题描述】:

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

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

谢谢。

【问题讨论】:

    标签: python heroku flask


    【解决方案1】:

    您可以使用config vars 将配置项存储在 Heroku 上运行的应用程序中。

    您可以使用用户名/密码组合。您可以使用户名变得简单;但请务必生成一个强密码,例如使用openssl rand -base64 32 之类的密码。

    【讨论】:

      【解决方案2】:

      Heroku 让您可以利用 config variables 来管理您的应用程序。这是我的烧瓶应用程序中的 config.py 文件的示例:

      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"))
      

      现在我可以得到两组不同的结果。它来自我的Environment variables。一个当我的应用程序在我的本地计算机上并且在生产时来自 Heroku 配置变量时。例如。

       DEBUG = str(os.getenv("DEBUG")) 
      

      在我的本地计算机上为“TRUE”。但是在 Heroku 上是错误的。为了检查您的 Heroku 配置运行。

      Heroku config
      

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

      【讨论】:

      • 使用str(os.getenv('SPAM')) 是一个很大的错误,尤其是在需要设置的情况下。如果SPAM 未在环境中配置,则您将值设置为"None",这非常糟糕,因为它会以意想不到的方式失败。请改用os.environ['SPAM'],如果未在环境中配置SPAM,这显然会失败。如果您希望设置是可选的,请使用if os.getenv('SPAM') is not None: ... 或类似的东西。
      【解决方案3】:

      我一直在寻找有关如何处理私钥的指导。 @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()
      

      感谢@DrewV 和@yfeldblum 的帮助(为两者投票)。

      【讨论】:

      • 另一个提示:如果机密数据太大而无法放入配置变量中,请使用 AES 对其进行加密,将其放入存储库中的文件中,然后将 AES 密钥放入配置变量中.如果秘密数据是 OpenSSL 私钥,您可以改用其密码短语工具,但要确保密码短语是一个长的、完全随机的字符串——secrets.token_hex(16) 应该会生成合适的内容。
      猜你喜欢
      • 2017-12-23
      • 2016-05-04
      • 1970-01-01
      • 1970-01-01
      • 2023-01-27
      • 2010-11-14
      • 2020-02-01
      • 1970-01-01
      • 2020-02-14
      相关资源
      最近更新 更多