Rails + Passenger + Nginx 错误 Request Origin (domainname.com) does not match Request Base_url (IP Address)

Rails + Passenger + Nginx error Request Origin (domainname.com) does not match Request Base_url (IP Address)

设置: Rails 5.1.3,Dreamhost VPS 与 Passenger 和 Nginx。 因为它是 VPS,所以我没有 root 权限来执行任何需要 root 权限的功能。

情况:目前,我重做了一个具有 ActionCable 功能的 rails 应用程序。较早的配置是使用 Apache 而不是 Nginx 作为 http 服务器。除了 websockets 一切正常,我读了很多文章,所有确认操作电缆 + apache 都不起作用。

此时,我切换到 NginX。使用 NginX,我的第一个观察是应用程序不断尝试 'get cable/' 进程并且无法升级到 websocket。在阅读了各种讨论后,我设法解决了这个问题:

location /cable {
    proxy_pass http://127.0.0.1:8000/cable;
    proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

}

因为我没有 root 权限访问通常的 dt/etc/nginx/.../***.conf 文件,使用 dreamhost VPS 包,我可以在 /home/username/nginx/(appname.com)/(any-file-name.conf) 根据 dreamhost 文档,这将添加到 nginx "server block"。

^^所以上面的代码块单独在该目录中名为 "redis.conf" 的文件中对动作电缆问题进行了排序。它成功地开始在频道上播放一切正常。

我后来意识到,主要问题是我无法执行任何创建、更新、销毁操作 - 任何需要 POST 或 DELETE 方法的操作,因为它会导致真实性令牌错误,说“请求来源 (http://siik.io - 这是应用程序和域名) 与 request.base_url (http://127.0.0.1) 不匹配.

详细错误:

I, [2017-09-11T03:27:28.623080 #7273]  INFO -- : [50a21156-0333-413e-94b

8-07b791c209fc] Completed 200 OK in 83ms (Views: 56.0ms | ActiveRecord: 16.6ms)
I, [2017-09-11T03:27:31.950732 #7273]  INFO -- : [dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] Started POST "/conversations/1/messages" for 106.208.156.243 at 2017-09-11 03:27:31 -0700
I, [2017-09-11T03:27:31.953339 #7273]  INFO -- : [dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] Processing by MessagesController#create as JS
I, [2017-09-11T03:27:31.953511 #7273]  INFO -- : [dd8e08f7-f28b-497b-9ae9-e57a6a45c35d]   Parameters: {"utf8"=>"✓", "message"=>{"user_id"=>"1", "body"=>"sdfgh"}, "commit"=>"Send", "conversation_id"=>"1"}
W, [2017-09-11T03:27:31.954325 #7273]  WARN -- : [dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] HTTP Origin header (http://www.siik.io) didn't match request.base_url (http://127.0.0.1:8000)
I, [2017-09-11T03:27:31.954890 #7273]  INFO -- : [dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)
F, [2017-09-11T03:27:31.956888 #7273] FATAL -- : [dd8e08f7-f28b-497b-9ae9-e57a6a45c35d]   
F, [2017-09-11T03:27:31.956969 #7273] FATAL -- : [dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
F, [2017-09-11T03:27:31.957017 #7273] FATAL -- : [dd8e08f7-f28b-497b-9ae9-e57a6a45c35d]   
F, [2017-09-11T03:27:31.957126 #7273] FATAL -- : [dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_controller/metal/request_forgery_protection.rb:195:in `handle_unverified_request'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_controller/metal/request_forgery_protection.rb:227:in `handle_unverified_request'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] devise (4.3.0) lib/devise/controllers/helpers.rb:253:in `handle_unverified_request'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_controller/metal/request_forgery_protection.rb:222:in `verify_authenticity_token'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activesupport (5.1.3) lib/active_support/callbacks.rb:413:in `block in make_lambda'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activesupport (5.1.3) lib/active_support/callbacks.rb:197:in `block (2 levels) in halting'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/abstract_controller/callbacks.rb:12:in `block (2 levels) in <module:Callbacks>'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activesupport (5.1.3) lib/active_support/callbacks.rb:198:in `block in halting'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activesupport (5.1.3) lib/active_support/callbacks.rb:507:in `block in invoke_before'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activesupport (5.1.3) lib/active_support/callbacks.rb:507:in `each'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activesupport (5.1.3) lib/active_support/callbacks.rb:507:in `invoke_before'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activesupport (5.1.3) lib/active_support/callbacks.rb:130:in `run_callbacks'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/abstract_controller/callbacks.rb:19:in `process_action'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_controller/metal/rescue.rb:20:in `process_action'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activesupport (5.1.3) lib/active_support/notifications.rb:166:in `block in instrument'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activesupport (5.1.3) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activesupport (5.1.3) lib/active_support/notifications.rb:166:in `instrument'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_controller/metal/params_wrapper.rb:252:in `process_action'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activerecord (5.1.3) lib/active_record/railties/controller_runtime.rb:22:in `process_action'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/abstract_controller/base.rb:124:in `process'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionview (5.1.3) lib/action_view/rendering.rb:30:in `process'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_controller/metal.rb:189:in `dispatch'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_controller/metal.rb:253:in `dispatch'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_dispatch/routing/route_set.rb:31:in `serve'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_dispatch/journey/router.rb:46:in `block in serve'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_dispatch/journey/router.rb:33:in `each'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_dispatch/journey/router.rb:33:in `serve'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_dispatch/routing/route_set.rb:834:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] remotipart (1.3.1) lib/remotipart/middleware.rb:32:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] warden (1.2.7) lib/warden/manager.rb:36:in `block in call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] warden (1.2.7) lib/warden/manager.rb:35:in `catch'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] warden (1.2.7) lib/warden/manager.rb:35:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] rack (2.0.3) lib/rack/etag.rb:25:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] rack (2.0.3) lib/rack/conditional_get.rb:38:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] rack (2.0.3) lib/rack/head.rb:12:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] rack (2.0.3) lib/rack/session/abstract/id.rb:232:in `context'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] rack (2.0.3) lib/rack/session/abstract/id.rb:226:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_dispatch/middleware/cookies.rb:613:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_dispatch/middleware/callbacks.rb:26:in `block in call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activesupport (5.1.3) lib/active_support/callbacks.rb:97:in `run_callbacks'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_dispatch/middleware/callbacks.rb:24:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_dispatch/middleware/debug_exceptions.rb:59:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] railties (5.1.3) lib/rails/rack/logger.rb:36:in `call_app'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] railties (5.1.3) lib/rails/rack/logger.rb:24:in `block in call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activesupport (5.1.3) lib/active_support/tagged_logging.rb:69:in `block in tagged'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activesupport (5.1.3) lib/active_support/tagged_logging.rb:26:in `tagged'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activesupport (5.1.3) lib/active_support/tagged_logging.rb:69:in `tagged'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] railties (5.1.3) lib/rails/rack/logger.rb:24:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_dispatch/middleware/request_id.rb:25:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] rack (2.0.3) lib/rack/method_override.rb:22:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] rack (2.0.3) lib/rack/runtime.rb:22:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] activesupport (5.1.3) lib/active_support/cache/strategy/local_cache_middleware.rb:27:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] actionpack (5.1.3) lib/action_dispatch/middleware/executor.rb:12:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] rack (2.0.3) lib/rack/sendfile.rb:111:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] railties (5.1.3) lib/rails/engine.rb:522:in `call'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] passenger (5.1.8) src/ruby_supportlib/phusion_passenger/rack/thread_handler_extension.rb:97:in `process_request'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] passenger (5.1.8) src/ruby_supportlib/phusion_passenger/request_handler/thread_handler.rb:160:in `accept_and_process_next_request'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] passenger (5.1.8) src/ruby_supportlib/phusion_passenger/request_handler/thread_handler.rb:113:in `main_loop'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] passenger (5.1.8) src/ruby_supportlib/phusion_passenger/request_handler.rb:416:in `block (3 levels) in start_threads'
[dd8e08f7-f28b-497b-9ae9-e57a6a45c35d] passenger (5.1.8) src/ruby_supportlib/phusion_passenger/utils.rb:113:in `block in create_thread_and_abort_on_exception'

但是,当我通过 http://siik.io:8000 访问网站时,一切正常,甚至 websockets 也不需要 redis.conf 文件。

我已经完成了一周的各种修复和文档,但未能找到解决方案。我认为基本要求是将更多 headers 添加到位置/{} 块以添加到 nginx.conf 文件...(我在下面列出了一些我尝试过的示例。)

listen 80;
listen *:80;
server_name siik.io www.siik.io http://siik.io;
location / {

        proxy_redirect off;
        proxy_set_header Host $host:8000;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


        proxy_http_version 1.1;

        proxy_set_header   X-Real-IP $remote_addr:8000;
        proxy_set_header  X-Forwarded-Port $server_port;

        proxy_pass http://127.0.0.1:8000/;
}

.. 所以我基本上是在尝试对上述值进行各种组合和排列以查看有效的方法,因为很明显,我不知道这是如何工作的——我对反向代理和 http 服务器有一些概念性的了解。

是的,我知道 request.origin == request.base_url 的东西来自 rails 的 protect_from_forgery 位,我不认为关闭它是一个解决方案,尽管如此,我确实在某处读到过包含正确的 headers 将解决此问题。我已经尝试了这个 header 集的一些变体并且 none 工作了,我想知道包括正确的 headers 是否应该达到 http origin header 将从 domainname.io 更改为 IP 地址或 request.base_url 将从 IP 地址更改为域名??

哦,是的,当我在 redis.conf 旁边的新文件 proxy.conf 中添加 location / {} 块时,它完全崩溃了。通过 domainname.io 的网站拒绝连接,而 domainname.io:8000 完美运行。即使是 location / 下的空块也会破坏它 - 我正在测试是否有任何特定的 proxy_set 命令导致它破坏 - 但没有。只是位 "location / {}" 破坏了它 - 也许这是预期的?

当我通过 siik.io:8000 访问它时,为什么它可以完美地工作,并明确指定端口号?

非常感谢任何帮助!!!!

您不需要 运行 您的操作电缆服务器在另一个端口上,请尝试按照以下说明操作:https://www.phusionpassenger.com/library/config/nginx/action_cable_integration/

根据 THE RULES™ 复制于此:

运行 Action Cable 服务器在同一主机和端口上,在子 URI 下

这是 Rails 推荐的默认设置,也是最简单的设置。它的工作原理是将 ActionCable.server 挂载到 config/routes.rb 中的特定路径。这样,您的 Action Cable 服务器将 运行 与您的应用程序位于相同的主机和端口上,但位于子 URI 下。

例如,您的 routes.rb 可能包含:

# Serve websocket cable requests in-process
mount ActionCable.server => '/cable'

(尽管 routes.rb 评论说安装 ActionCable.server 是为了在进程中提供服务,但 Passenger 实际上坚持 运行 将其作为一个单独的进程。)

要在 Passenger + Nginx 中进行这项工作,您需要向 Nginx 虚拟主机添加一个片段。假设您的应用程序已经有一个虚拟主机,如下所示:

server {
    listen 80;
    server_name www.foo.com;
    root /path-to-your-app/public;
    passenger_enabled on;
}

您需要插入一个配置 Action Cable 端点的位置块,如下所示:

server {
    listen 80;
    server_name www.foo.com;
    root /path-to-your-app/public;
    passenger_enabled on;

    ### INSERT THIS!!! ###
    location /cable {
        passenger_app_group_name YOUR_APP_NAME_HERE_action_cable;
        passenger_force_max_concurrent_requests_per_process 0;
    }
}

/cable 替换为 routes.rb 中指定的实际 Action Cable 路径。

YOUR_APP_NAME_HERE 替换为 Nginx 配置文件中其他任何地方都没有出现的唯一标识符。

passenger_force_max_concurrent_requests_per_process 选项调整 Passenger 以获得最佳的 WebSocket 性能。

已修复。

我不完全确定这是如何解决的,我仍在努力弄清楚为什么一切正常。 基本上,问题似乎出在 Passenger+Nginx 配置的维护方式上。 - 我认为这是 dreamhost 的特定问题。

我的初始 VPS 配置是按照 Dave Jones 在 youtube 上的教程使用 Apache 作为 http 服务器完成的。在 Dreamhost 面板的域托管部分,有一个复选框,用于将 Passenger 与 ruby 应用程序一起使用,根据我遵循的原始教程,该复选框未选中。 阅读@Camden 的链接 - 非常有帮助 - 我决定从头开始重新配置所有内容,并检查了控制面板上的这个 Passenger Box 以及 HTTPS 安全位,添加了来自“让我们加密 SSL”的证书并重新启动了我的服务器。 一切都按要求开始完美运行。我还在 CONF 文件中为“/cable”的位置块下的 443 端口添加了 headers - 并在 production.rb 文件中添加了 http://www.domainnam.io,其中 config.force_ssl设置为真。

所以,总而言之,我知道问题出在 passenger nginx 集成配置不当。 感谢@Camden 提供的链接。