【问题标题】:How to hide the password in fabric when the command is printed out?打印命令时如何在fabric中隐藏密码?
【发布时间】:2011-04-08 22:44:19
【问题描述】:

假设我有一个看起来像这样的fabfile.py

def setup():                                
    pwd = getpass('mysql password: ')
    run('mysql -umoo -p%s something' % pwd)

这个的输出是:

[host] run: mysql -umoo -pTheActualPassword

有没有办法让输出看起来像这样?

[host] run: mysql -umoo -p*******

注意:这不是mysql问题!

【问题讨论】:

    标签: python passwords fabric


    【解决方案1】:

    最好将密码放在用户的 ~/.my.cnf 的 [client] 部分下。这样您就不必将密码放入 python 文件中。

    [client]
    password=TheActualPassword
    

    【讨论】:

    • 我澄清了这个问题。我只是以mysql为例,因为我使用的命令没有命令行的替代选项。
    【解决方案2】:

    当您使用 Fabric 命令run 时,Fabric 不知道您正在运行的命令是否包含纯文本密码。如果不修改/覆盖 Fabric 源代码,我认为您无法在显示正在运行的命令但密码被星号替换的位置获得所需的输出。

    但是,您可以更改整个 Fabric 脚本或一部分的 Fabric 输出级别,以便不显示正在运行的命令。虽然这会隐藏密码,但缺点是您根本看不到该命令。

    查看 Managing Output 上的 Fabric 文档。

    【讨论】:

      【解决方案3】:

      您可以用过滤器替换标准输出(或任何 iostream),而不是修改/覆盖 Fabric。

      这是一个覆盖 stdout 以审查特定密码的示例。它从 Fabric 的 env.password 变量 set by the -I argument 获取密码。请注意,您可以使用正则表达式执行相同的操作,这样您就不必在过滤器中指定密码。

      我还应该提到,这不是世界上最高效的代码,但如果您使用的是 Fabric,您可能会将一些东西粘合在一起,并且更关心可管理性而不是速度。

      #!/usr/bin/python
      
      import sys
      import string
      from fabric.api import *
      from fabric.tasks import *
      from fabric.contrib import *
      
      class StreamFilter(object):
      
          def __init__(self, filter, stream):
              self.stream = stream
              self.filter = filter
      
          def write(self,data):
              data = data.replace(self.filter, '[[TOP SECRET]]')
              self.stream.write(data)
              self.stream.flush()
      
          def flush(self):
              self.stream.flush()
      
      @task
      def can_you_see_the_password():
          sys.stdout = StreamFilter(env.password, sys.stdout)
          print 'Hello there'
          print 'My password is %s' % env.password 
      

      运行时:

      fab -I can_you_see_the_password
      Initial value for env.password:
      

      这将产生:

      Hello there
      My password is [[TOP SECRET]]
      

      【讨论】:

      • 我想如果 OP 不希望他的密码出现在他的终端日志中,那么他可能不希望他的密码存在于 .py 文件中。
      • 他也可以在密码提示符上使用正则表达式到行尾。你有更好的主意还是喜欢吹毛求疵? :)
      • 在 Fabric 中,您可以使用 env.password 获取密码,因此您不需要在 .py 文件中使用它,但它似乎只在任务中设置,而不是在全局环境中设置。我还发现我还必须在 StreamFilter 中实现 flush
      • 为了能够使用fabric shell输入提示(例如,当没有指定主机名时),我必须在类中添加一个方法def __getattr__(self, attr_name): return getattr(self.stream, attr_name)以便在fabric查询时不会出错其他一些流属性。
      【解决方案4】:

      编写一个 shell 脚本,使用适当的密码调用相关命令,但不回显该密码。您可以让 shell 脚本从比 .py 文件更安全的位置查找密码。

      然后让 fabric 调用 shell 脚本。

      这解决了 Fabric 不显示密码的问题,并确保您的源代码中没有凭据。

      【讨论】:

        【解决方案5】:
        from fabric.api import run, settings
        with settings(prompts={'Enter password: ': mysql_password}):
            run("mysql -u {} -p -e {}".format(mysql_user,mysql_query))
        

        或者如果没有可用提示:

        from fabric.api import run, hide
        with hide('output','running','warnings'):
           run("mycommand --password {}".format(my_password))
        

        【讨论】:

          猜你喜欢
          • 2021-08-13
          • 2014-07-22
          • 2019-09-10
          • 1970-01-01
          • 2019-12-01
          • 1970-01-01
          • 2018-12-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多