【问题标题】:Supplying an argument at Rails runtime在 Rails 运行时提供参数
【发布时间】:2010-09-20 04:53:20
【问题描述】:

我正在寻找一种在运行时为 ruby​​ on rails 项目提供参数的方法。本质上,我们的项目使用公钥加密来加密一些敏感的客户端数据,我们希望能够在运行时向私钥文件提供密码。

【问题讨论】:

  • 请告诉我,您的进程监视器将如何重新启动死掉的进程? ;-) 一旦您决定自动重启,您就必须放弃这种保密性。最后,您只需确保正确访问您的服务器(或重新启动其进程的机器)即可。

标签: ruby-on-rails ruby cryptography arguments


【解决方案1】:

任何 Ruby 脚本都可以通过 ENV 哈希访问本地环境变量。

puts ENV['PATH']

因此,对于任何 posix 系统(Linux、Unix、Mac OS),您都可以在调用脚本时简单地设置它,如下所示:

MY_ARG=supersecret ruby script.rb

这同样适用于rails。如果您将puts ENV['MY_ARG'] 放入您的 environment.rb 并启动您的服务器:

$ MY_ARG=supersecret mongrel_rails start
** Starting Mongrel listening at 0.0.0.0:3000
** Starting Rails with development environment...
supersecret
** Rails loaded.
** Loading any Rails specific GemPlugins
** Signals ready.  TERM => stop.  USR2 => restart.  INT => stop (no restart).
** Rails signals registered.  HUP => reload (without restart).  It might not work well.
** Mongrel 1.1.5 available at 0.0.0.0:3000
** Use CTRL-C to stop.

在我看来,环境变量是迄今为止最简单的解决方案。

【讨论】:

  • 绝对比我的解决方案更容易。有人可能会担心,在 Linux 环境中,root 可以简单地枚举进程的环境(例如通过读取 /proc/[pid]/environ),但需要更多的知识和工作才能从 Ruby 的内存中获取密码字符串。
  • 我想知道在 Windows 中从 'cmd.exe' 调用可执行文件时是否可以内联设置环境变量(如您的示例中)。
  • 嗯,关于 /proc/[pid]/environ 的好点子。然而,与在纯文本文件中实际编写密钥相比,它仍然需要更多的工作(并且不太直观)。
【解决方案2】:

一个简单的方法是创建一个 Rails 插件,在它的 'init.rb' 中使用 'gets' 来接受参数。请允许我编写一个快速代码示例:

创建一个目录:'$railsRoot/vendor/plugins/startup_args/lib'

创建一个对象以将参数数据存储在 '$railsRoot/vendor/plugins/startup_args/lib/startup_args.rb' 中:

module StartupArgs
 @@argHash = {}

 def self.setArg(key, value)
  @@argHash[key.to_sym] = value
 end

 def self.getArg(key)
  return @@argHash[key.to_sym]
 end
end

将 StartupArgs 模块加载到 Rails 项目的命名空间中,并使用 '$railsRoot/vendor/plugins/startup_args/init.rb' 中的参数填充它:

require "startup_args"

promptString = "Enter arg name (type nothing to continue):"

puts promptString
while (newArg = gets.chomp) != ""
 puts "Enter value for '#{newArg}':"
 newVal = gets.chomp
 StartupArgs.setArg(newArg, newVal)

 puts promptString
end

现在,在 Rails 项目的启动过程中,它会尝试从控制台获取键值对。这些对将存储在全局命名空间对象 StartupArgs 中以供以后访问(通过 'StartupArgs.getArg()')。

如果您预计您的 Rails 项目可能部署在守护程序在启动时无法访问控制台的情况下,您可以从命名管道而不是控制台的标准输入中读取。

更进一步,您可以删除“init.rb”的所有部分,“require”语句除外,并将执行此设置的操作添加到控制器,该控制器将相关参数作为网络上的帖子。确保配置 Rails 以防止将潜在的敏感参数(例如密码)输入到记录访问或错误的日志文件中(特别是如果它可能用作 HTTP GET,在 URL 中带有参数)。

(如果您将其他 Rails 操作配置为忽略请求,直到设置操作将适当的参数存储到全局对象,您将获得与上述系统相同的效果。)

给 Micah 的注意事项:我没有直接对您的帖子发表评论的声誉,因此我将在此处包含我的评论。考虑一个从不需要密码在文件系统中表示的系统可能有几个原因。例如,开发人员可能正在计划一个 Rails 项目,该项目可以部署在不同的操作系统和不同的环境中。如果开发人员确定在某些情况下管理用户或 root 用户可能会受到威胁、无法信任或无法被要求签署保密和安全协议,则开发人员可能会决定添加额外的混淆,将密码放入内存中仅(为了需要稍微不那么安全的系统或更聪明的攻击来窃取密码)。或许这可以被认为是一个相对成本的问题:以低成本,密码可以以一种需要更昂贵的知识才能检索的方式隐藏。

【讨论】:

    【解决方案3】:

    将密码放入经过 chmod 修改为只有 Web 服务器用户可读的文件有什么问题?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-09
      • 1970-01-01
      • 2014-11-06
      • 1970-01-01
      相关资源
      最近更新 更多