2008-10-31 5 views
4

Я ищу способ предоставить аргумент Ruby для проекта rails во время выполнения. По сути, в нашем проекте используется криптография с открытым ключом для шифрования некоторых конфиденциальных данных клиента, и мы хотим, чтобы во время выполнения мы могли предоставить пароль в файл закрытого ключа.Поставка аргумента во время выполнения Rails

+0

Скажите мне, как ваш процесс контролирует перезапуск процессов, которые умирают? ;-) Как только вы решите автоматизировать перезапуск, вы должны отказаться от такой секретности. В итоге вам просто нужно обеспечить безопасный доступ к вашему серверу (или машине, которая перезагружает свои процессы). – webmat

ответ

1

Простым способом сделать это будет создание плагина 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 могут быть скомпрометированы, нельзя доверять или не может потребовать подписывать соглашения о конфиденциальности и безопасности, разработчик может решить добавить дополнительную обфускацию размещения пароля в памяти только (в интересах требовать немного менее безопасной системы или немного более умной атаки, чтобы украсть пароль). Возможно, это можно рассматривать как относительные затраты: при низкой стоимости пароль может быть скрыт таким образом, чтобы требовать более дорогих знаний для извлечения.

+0

Это именно то, что я искал, спасибо! – latortuga

+0

Я рад, что смог помочь! – Jsnydr

1

Что не так с помещением пароля в файл, который является chmod'ed, только для чтения пользователем веб-сервера?

3

Любой скрипт 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. 

Среда, безусловно, является простым решением, на мой взгляд.

+0

Определенно легче, чем мое решение. Можно было бы подумать, что в средах Linux root может тривиально перечислить среду процесса (например, путем чтения/proc/[pid]/environ), но возьмет больше знаний и будет работать, чтобы получить строку паролей из памяти Ruby. – Jsnydr

+0

Интересно, есть ли способ установить переменные среды inline (как в вашем примере) при вызове исполняемых файлов из cmd.exe в Windows. – Jsnydr

+0

Хмм, хорошая точка о/proc/[pid]/environ. Однако это еще немного больше (и менее интуитивно понятно), чем на самом деле писать ключ в текстовом файле. – webmat