使用 Puma 的 SSL、HTTP 解析错误、格式错误的请求
SSL with Puma, HTTP parse error, malformed request
正在尝试为 rails 应用程序配置 HTTPS,该应用程序在远程服务器上的专用网络中提供服务。 Puma Docs 让它看起来像是可能的,他们提供了这个命令:
puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert'
采取的步骤(用于测试目的):
生成私钥和自签名证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/puma_test.key -out /etc/zzz_puma_test.crt
启动 Puma
rvmsudo rails s -p 443 -b 'ssl://127.0.0.1?key=/etc/puma_test.key&cert=/etc/zzz_puma_test.crt'
当我启动服务器时,我在日志中看到我认为很奇怪的内容:Listening on tcp://0.0.0.0:443
Puma 似乎仍在以 http 而非 https 启动。这是启动 puma 时的完整终端日志:
=> Booting Puma
=> Rails 4.2.8 application starting in development on http://ssl://127.0.0.1?key=/etc/puma_test.key&cert=/etc/zzz_puma_test.crt:443
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
Puma starting in single mode...
* Version 3.12.0 (ruby 2.3.3-p222), codename: Llamas in Pajamas
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://0.0.0.0:443
当我尝试访问该站点时,我在终端中收到此错误:
HTTP parse error, malformed request (): #Puma::HttpParserError: Invalid HTTP format, parsing fails.
在 firefox 浏览器中,它提供了这样的反馈:
SSL received a record that exceeded the maximum permissible length. Error code: SSL_ERROR_RX_RECORD_TOO_LONG
奇怪的是,我在我的计算机上本地执行了上面的确切步骤,对于在我的计算机上本地提供的应用程序,它一切正常。
- 我创建了一个新应用程序
- 运行上面一行生成秘钥和自签名证书
- 运行以上一行启动服务器
- 在服务器启动时在终端中,它显示它正在正常监听(换句话说:从不提及 http):
Listening on ssl://127.0.0.1:443?key...cert...
- 连接到
https://localhost/blogs
工作正常。
也许这与我使用 linux machine 而不是 mac 的事实有关?或者,也许是我的测试应用程序位于我网络中的远程服务器上?我查看了产生此错误的方法。是parse_error, line 95 of events.rb。
已查看的资源:
- SO Post
- GithubGist
- Open Issue, closed issue,
我尝试通过一些不同的小改动来调整上面的 rails s
命令:
- 已将 IP 从
127.0.0.1
更改为 0.0.0.0
- 不指定
-p 443
选项
- 指定实际的内部 IP 地址而不是
127.0.0.1
(这是在内部网络上提供的)
我也试过删除我的浏览历史,并尝试从多个浏览器访问该网站。
感谢任何帮助,谢谢!
我用 Ubuntu 16.04.5 LTS 服务器(HWE 内核)构建了一个新的 VM,安装了 RVM,Ruby 2.3.3 和 Rails 4.2.8,跟随你的重现说明,并且...效果很好。我使用 0.0.0.0 作为监听地址,并从主机访问来宾的地址。
客人:
mwp@ubuntu:~/Code/blag$ export rvmsudo_secure_path=1
mwp@ubuntu:~/Code/blag$ rvmsudo rails s -p 443 -b 'ssl://0.0.0.0?key=/etc/puma_test.key&cert=/etc/zzz_puma_test.crt'
=> Booting Puma
=> Rails 4.2.8 application starting in development on http://ssl://0.0.0.0?key=/etc/puma_test.key&cert=/etc/zzz_puma_test.crt:443
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
Puma starting in single mode...
* Version 3.12.0 (ruby 2.3.3-p222), codename: Llamas in Pajamas
* Min threads: 0, max threads: 16
* Environment: development
* Listening on ssl://0.0.0.0:443?key=/etc/puma_test.key&cert=/etc/zzz_puma_test.crt
Use Ctrl-C to stop
主持人:
mwp@macos:~$ curl -Ik https://192.168.10.137
HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
ETag: W/"b56dd5f9363ed0f7bd4d11c36d9471dd"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 555223a6-3f70-49cf-8b30-92d3047ff8a6
X-Runtime: 0.009792
客人:
Started HEAD "/" for 192.168.10.112 at 2019-02-28 15:39:19 -0600
Cannot render console from 192.168.10.112! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by Rails::WelcomeController#index as */*
Rendered /home/mwp/.rvm/gems/ruby-2.3.3/gems/railties-4.2.8/lib/rails/templates/rails/welcome/index.html.erb (0.6ms)
Completed 200 OK in 5ms (Views: 4.4ms | ActiveRecord: 0.0ms)
很明显这里还缺少一些其他的东西:你的服务器上的一些配置,你的 Gem 文件中的一些 Gem,或者你的 Rails 项目中的一些配置。
这是最终对我有用的解决方案:
首先,我必须使用 ssl_bind
指令创建一个 puma 配置文件:
# /<path_to_app>/puma/development.rb
ssl_bind '127.0.0.1', '9292', {
cert: ‘/etc/puma_test.key',
key: ‘/etc/zzz_puma_test.crt'
}
然后我不得不使用 puma
启动服务器而不是 rails s
。无论出于何种原因,我就是无法让 rails s
工作。在启动 puma 的命令中,我必须确保指定 -C
和 puma 配置文件的路径:
rvmsudo puma -b 'ssl://0.0.0.0:443?key=/etc/puma_test.key&cert=/etc/zzz_puma_test.crt' -C /<path_to_app>/puma/development.rb
正在尝试为 rails 应用程序配置 HTTPS,该应用程序在远程服务器上的专用网络中提供服务。 Puma Docs 让它看起来像是可能的,他们提供了这个命令:
puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert'
采取的步骤(用于测试目的):
生成私钥和自签名证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/puma_test.key -out /etc/zzz_puma_test.crt
启动 Puma
rvmsudo rails s -p 443 -b 'ssl://127.0.0.1?key=/etc/puma_test.key&cert=/etc/zzz_puma_test.crt'
当我启动服务器时,我在日志中看到我认为很奇怪的内容:Listening on tcp://0.0.0.0:443
Puma 似乎仍在以 http 而非 https 启动。这是启动 puma 时的完整终端日志:
=> Booting Puma
=> Rails 4.2.8 application starting in development on http://ssl://127.0.0.1?key=/etc/puma_test.key&cert=/etc/zzz_puma_test.crt:443
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
Puma starting in single mode...
* Version 3.12.0 (ruby 2.3.3-p222), codename: Llamas in Pajamas
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://0.0.0.0:443
当我尝试访问该站点时,我在终端中收到此错误:
HTTP parse error, malformed request (): #Puma::HttpParserError: Invalid HTTP format, parsing fails.
在 firefox 浏览器中,它提供了这样的反馈:
SSL received a record that exceeded the maximum permissible length. Error code: SSL_ERROR_RX_RECORD_TOO_LONG
奇怪的是,我在我的计算机上本地执行了上面的确切步骤,对于在我的计算机上本地提供的应用程序,它一切正常。
- 我创建了一个新应用程序
- 运行上面一行生成秘钥和自签名证书
- 运行以上一行启动服务器
- 在服务器启动时在终端中,它显示它正在正常监听(换句话说:从不提及 http):
Listening on ssl://127.0.0.1:443?key...cert...
- 连接到
https://localhost/blogs
工作正常。
也许这与我使用 linux machine 而不是 mac 的事实有关?或者,也许是我的测试应用程序位于我网络中的远程服务器上?我查看了产生此错误的方法。是parse_error, line 95 of events.rb。
已查看的资源:
- SO Post
- GithubGist
- Open Issue, closed issue,
我尝试通过一些不同的小改动来调整上面的 rails s
命令:
- 已将 IP 从
127.0.0.1
更改为0.0.0.0
- 不指定
-p 443
选项 - 指定实际的内部 IP 地址而不是
127.0.0.1
(这是在内部网络上提供的)
我也试过删除我的浏览历史,并尝试从多个浏览器访问该网站。
感谢任何帮助,谢谢!
我用 Ubuntu 16.04.5 LTS 服务器(HWE 内核)构建了一个新的 VM,安装了 RVM,Ruby 2.3.3 和 Rails 4.2.8,跟随你的重现说明,并且...效果很好。我使用 0.0.0.0 作为监听地址,并从主机访问来宾的地址。
客人:mwp@ubuntu:~/Code/blag$ export rvmsudo_secure_path=1
mwp@ubuntu:~/Code/blag$ rvmsudo rails s -p 443 -b 'ssl://0.0.0.0?key=/etc/puma_test.key&cert=/etc/zzz_puma_test.crt'
=> Booting Puma
=> Rails 4.2.8 application starting in development on http://ssl://0.0.0.0?key=/etc/puma_test.key&cert=/etc/zzz_puma_test.crt:443
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
Puma starting in single mode...
* Version 3.12.0 (ruby 2.3.3-p222), codename: Llamas in Pajamas
* Min threads: 0, max threads: 16
* Environment: development
* Listening on ssl://0.0.0.0:443?key=/etc/puma_test.key&cert=/etc/zzz_puma_test.crt
Use Ctrl-C to stop
主持人:
mwp@macos:~$ curl -Ik https://192.168.10.137
HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
ETag: W/"b56dd5f9363ed0f7bd4d11c36d9471dd"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 555223a6-3f70-49cf-8b30-92d3047ff8a6
X-Runtime: 0.009792
客人:
Started HEAD "/" for 192.168.10.112 at 2019-02-28 15:39:19 -0600
Cannot render console from 192.168.10.112! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by Rails::WelcomeController#index as */*
Rendered /home/mwp/.rvm/gems/ruby-2.3.3/gems/railties-4.2.8/lib/rails/templates/rails/welcome/index.html.erb (0.6ms)
Completed 200 OK in 5ms (Views: 4.4ms | ActiveRecord: 0.0ms)
很明显这里还缺少一些其他的东西:你的服务器上的一些配置,你的 Gem 文件中的一些 Gem,或者你的 Rails 项目中的一些配置。
这是最终对我有用的解决方案:
首先,我必须使用 ssl_bind
指令创建一个 puma 配置文件:
# /<path_to_app>/puma/development.rb
ssl_bind '127.0.0.1', '9292', {
cert: ‘/etc/puma_test.key',
key: ‘/etc/zzz_puma_test.crt'
}
然后我不得不使用 puma
启动服务器而不是 rails s
。无论出于何种原因,我就是无法让 rails s
工作。在启动 puma 的命令中,我必须确保指定 -C
和 puma 配置文件的路径:
rvmsudo puma -b 'ssl://0.0.0.0:443?key=/etc/puma_test.key&cert=/etc/zzz_puma_test.crt' -C /<path_to_app>/puma/development.rb