如何将 Rails 控制台提升为弱势 www-data 用户?

How to raise Rails console as underprivileged www-data user?

我的 Rails 应用程序 运行s 与 nginx 的 www-data 用户和所有磁盘写入功能都归 www-data 所有,因此所有应用程序相关的磁盘存储资产都归 www-data 所有.有时我需要启动 Rails 控制台并执行接触或创建存储资产的操作,我不希望这些 touched/created 资产由 root 或其他管理员用户拥有,我希望它们继续由www 数据用户。这在 ruby 1.9.3 -> 2.6.x:

下运行良好
sudo -u www-data RAILS_MASTER_KEY=xxx RAILS_ENV=production bin/rails console

当我在 ruby 2.7.x 或 3.0.0 上尝试此操作时,出现以下错误:

Loading production environment (Rails 6.1.3)
/usr/lib/ruby/3.0.0/irb/ext/save-history.rb:98:in `stat': Permission denied @ rb_file_s_stat - /root/.irb_history (Errno::EACCES)
    from /usr/lib/ruby/3.0.0/irb/ext/save-history.rb:98:in `save_history'
    from /usr/lib/ruby/3.0.0/irb/ext/save-history.rb:60:in `block in extended'
    from /usr/lib/ruby/3.0.0/irb.rb:475:in `block in run'
    from /usr/lib/ruby/3.0.0/irb.rb:475:in `each'
    from /usr/lib/ruby/3.0.0/irb.rb:475:in `ensure in run'
    from /usr/lib/ruby/3.0.0/irb.rb:475:in `run'
    from /usr/lib/ruby/3.0.0/irb.rb:400:in `start'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands/console/console_command.rb:70:in `start'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands/console/console_command.rb:19:in `start'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands/console/console_command.rb:102:in `perform'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/thor-1.1.0/lib/thor/command.rb:27:in `run'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/thor-1.1.0/lib/thor/invocation.rb:127:in `invoke_command'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/thor-1.1.0/lib/thor.rb:392:in `dispatch'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/command/base.rb:69:in `perform'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/command.rb:50:in `invoke'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands.rb:18:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'
/usr/lib/ruby/3.0.0/reline/config.rb:124:in `readlines': Permission denied @ rb_sysopen - /root/.inputrc (Errno::EACCES)
    from /usr/lib/ruby/3.0.0/reline/config.rb:124:in `read'
    from /usr/lib/ruby/3.0.0/reline.rb:232:in `inner_readline'
    from /usr/lib/ruby/3.0.0/reline.rb:175:in `readmultiline'
    from /usr/lib/ruby/3.0.0/forwardable.rb:238:in `readmultiline'
    from /usr/lib/ruby/3.0.0/forwardable.rb:238:in `readmultiline'
    from /usr/lib/ruby/3.0.0/irb/input-method.rb:302:in `gets'
    from /usr/lib/ruby/3.0.0/irb.rb:519:in `block (2 levels) in eval_input'
    from /usr/lib/ruby/3.0.0/irb.rb:721:in `signal_status'
    from /usr/lib/ruby/3.0.0/irb.rb:518:in `block in eval_input'
    from /usr/lib/ruby/3.0.0/irb/ruby-lex.rb:202:in `lex'
    from /usr/lib/ruby/3.0.0/irb/ruby-lex.rb:174:in `block (2 levels) in each_top_level_statement'
    from /usr/lib/ruby/3.0.0/irb/ruby-lex.rb:171:in `loop'
    from /usr/lib/ruby/3.0.0/irb/ruby-lex.rb:171:in `block in each_top_level_statement'
    from /usr/lib/ruby/3.0.0/irb/ruby-lex.rb:170:in `catch'
    from /usr/lib/ruby/3.0.0/irb/ruby-lex.rb:170:in `each_top_level_statement'
    from /usr/lib/ruby/3.0.0/irb.rb:537:in `eval_input'
    from /usr/lib/ruby/3.0.0/irb.rb:472:in `block in run'
    from /usr/lib/ruby/3.0.0/irb.rb:471:in `catch'
    from /usr/lib/ruby/3.0.0/irb.rb:471:in `run'
    from /usr/lib/ruby/3.0.0/irb.rb:400:in `start'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands/console/console_command.rb:70:in `start'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands/console/console_command.rb:19:in `start'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands/console/console_command.rb:102:in `perform'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/thor-1.1.0/lib/thor/command.rb:27:in `run'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/thor-1.1.0/lib/thor/invocation.rb:127:in `invoke_command'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/thor-1.1.0/lib/thor.rb:392:in `dispatch'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/command/base.rb:69:in `perform'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/command.rb:50:in `invoke'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands.rb:18:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

我试过在 /root/ 创建一个文件。irb_history 并赋予它世界写入权限,但我仍然遇到同样的错误。

我正在从 Ubuntu 18.04 和 20.04 上的源代码编译 ruby,仅使用 '--prefix=/usr' 标志。

如果我 sudo su 到一个管理员用户帐户,它是一个具有主目录的完整用户等,不像受限的 www-data 用户,或者 运行 作为 root 我可以提高 Rails控制台没有错误(当然磁盘资产的所有权是个问题)。

如果我 运行 作为完全管理员用户执行 sudo -u www-data bin/rails console 命令,我可以启动控制台,并且只有在退出控制台后才会看到错误,如下所示:

irb(main):033:0> exit
/usr/lib/ruby/3.0.0/irb/ext/save-history.rb:108:in `initialize': Permission denied @ rb_sysopen - /home/[username]/.irb_history (Errno::EACCES)
    from /usr/lib/ruby/3.0.0/irb/ext/save-history.rb:108:in `open'
    from /usr/lib/ruby/3.0.0/irb/ext/save-history.rb:108:in `save_history'
    from /usr/lib/ruby/3.0.0/irb/ext/save-history.rb:60:in `block in extended'
    from /usr/lib/ruby/3.0.0/irb.rb:475:in `block in run'
    from /usr/lib/ruby/3.0.0/irb.rb:475:in `each'
    from /usr/lib/ruby/3.0.0/irb.rb:475:in `run'
    from /usr/lib/ruby/3.0.0/irb.rb:400:in `start'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands/console/console_command.rb:70:in `start'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands/console/console_command.rb:19:in `start'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands/console/console_command.rb:102:in `perform'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/thor-1.1.0/lib/thor/command.rb:27:in `run'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/thor-1.1.0/lib/thor/invocation.rb:127:in `invoke_command'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/thor-1.1.0/lib/thor.rb:392:in `dispatch'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/command/base.rb:69:in `perform'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/command.rb:50:in `invoke'
    from /apps/connect/shared/vendor_bundle/ruby/3.0.0/gems/railties-6.1.3/lib/rails/commands.rb:18:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

如果我 运行 它作为 root 我得到上面的错误。

我相信您所要做的就是为您的命令配置 HOME 变量,如下所示:

sudo -u www-data HOME=/tmp RAILS_MASTER_KEY=xxx RAILS_ENV=production bin/rails console