Я ищу способ предоставить аргумент Ruby для проекта rails во время выполнения. По сути, в нашем проекте используется криптография с открытым ключом для шифрования некоторых конфиденциальных данных клиента, и мы хотим, чтобы во время выполнения мы могли предоставить пароль в файл закрытого ключа.Поставка аргумента во время выполнения Rails
ответ
Простым способом сделать это будет создание плагина Rails, который принимает аргументы, используя 'gets' в своем 'init.rb'. Позвольте мне приготовить вверх быстрый пример кода:
Создайте директорию: «$ railsRoot/поставщик/плагины/startup_args/Библиотека»
Создание объекта для хранения данных аргументов в «$ railsRoot/поставщика/плагинов /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/поставщик/плагины/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 игнорировать запросы, пока действие настройки не сохраняются соответствующие параметры глобального объекта.)
Замечание Для Мика: У меня нет репутации, чтобы комментировать прямо на ваш пост, поэтому я включу свой комментарий здесь. Может быть несколько причин считать систему, которая никогда не требует, чтобы пароль был представлен в файловой системе. Например, разработчик может планировать проект Rails, который может быть развернут в разных операционных системах и в разных средах. Если разработчик определяет, что могут быть сценарии, в которых администратор или пользователь root могут быть скомпрометированы, нельзя доверять или не может потребовать подписывать соглашения о конфиденциальности и безопасности, разработчик может решить добавить дополнительную обфускацию размещения пароля в памяти только (в интересах требовать немного менее безопасной системы или немного более умной атаки, чтобы украсть пароль). Возможно, это можно рассматривать как относительные затраты: при низкой стоимости пароль может быть скрыт таким образом, чтобы требовать более дорогих знаний для извлечения.
Что не так с помещением пароля в файл, который является chmod'ed, только для чтения пользователем веб-сервера?
Любой скрипт Ruby имеет доступ к локальным переменным окружения через хэш ENV.
puts ENV['PATH']
Так с любой системой Posix (Linux, Unix, Mac OS), вы можете просто установить его при вызове сценария, например:
MY_ARG=supersecret ruby script.rb
То же самое справедливо и для рельсов. Если поставить 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. – Jsnydr
Интересно, есть ли способ установить переменные среды inline (как в вашем примере) при вызове исполняемых файлов из cmd.exe в Windows. – Jsnydr
Хмм, хорошая точка о/proc/[pid]/environ. Однако это еще немного больше (и менее интуитивно понятно), чем на самом деле писать ключ в текстовом файле. – webmat
Скажите мне, как ваш процесс контролирует перезапуск процессов, которые умирают? ;-) Как только вы решите автоматизировать перезапуск, вы должны отказаться от такой секретности. В итоге вам просто нужно обеспечить безопасный доступ к вашему серверу (или машине, которая перезагружает свои процессы). – webmat