【问题标题】:Why isn't my Sinatra app working with SSL?为什么我的 Sinatra 应用程序不能使用 SSL?
【发布时间】:2016-04-28 13:27:29
【问题描述】:

好吧,我决定在构建 api 之前确保我可以让这些 ssl 的东西正常工作。我觉得那里已经完成了 95%。

所以,我有一个来自 namecheap 的证书和密钥。那里一切都应该很好。

这是我的 app.rb

require 'sinatra/base'
require 'webrick'
require 'webrick/https'
require 'openssl'

class MyServer  < Sinatra::Base
  set :bind, '0.0.0.0'

  get '/' do
    "Hello, world!\n"
  end
end

CERT_PATH = './ssl'

webrick_options = {
    :Port               => 443,
    :Logger             => WEBrick::Log::new($stderr, WEBrick::Log::DEBUG),
    :DocumentRoot       => "/ruby/htdocs",
    :SSLEnable          => true,
    :SSLVerifyClient    => OpenSSL::SSL::VERIFY_NONE,
    :SSLCertificate     => OpenSSL::X509::Certificate.new(  File.open(File.join(CERT_PATH, "server.crt")).read),
    :SSLPrivateKey      => OpenSSL::PKey::RSA.new(          File.open(File.join(CERT_PATH, "server.key")).read),
    :SSLCertName        => [ [ "CN",WEBrick::Utils::getservername ] ],
    :app                => MyServer
}
Rack::Server.start webrick_options

我运行这个程序

sudo ruby app.rb

有趣的是,在本地主机上(从我的 macbook pro 测试,运行 El Capitan)我可以访问 https://localhost,它只是说证书不受信任,并询问我是否想进入。伟大的。

但是,我现在可以通过域名访问我的 ec2 实例,当然,该域名与证书匹配。但是该站点只返回一个 ERR_CONNECTION_REFUSED(这是在 chrome 中显示的内容)

当然,这表明我是否运行 sinatra 服务器。

好的,听起来很简单。安全组,对吧?

好吧,根据 ec2,我使用的安全组在入站时启用了 tpc 端口 443。 (HTTPS)

那么,什么给了?我做错了什么?为什么它在 localhost 但在 ec2 实例上却没有达到我的预期?

任何帮助将不胜感激。


其他信息:

  • 服务器似乎正在运行。 sudo ruby​​ app.rb 给了我关于我的证书的有效信息,然后是

    [2016-01-22 03:36:52] 调试 WEBrick::HTTPServlet::FileHandler 安装在 / 上。 [2016-01-22 03:36:52] 调试 Rack::Handler::WEBrick 安装在 /. [2016-01-22 03:36:52] INFO WEBrick::HTTPServer#start: pid=2499 port=443

  • 如果我删除 webrick 并将端口更改为 80,一切正常。我可以从我网站的域访问这个应用程序,当然是在 http(不是 https)上。

  • 我收到了来自本地机器的响应。

$ wget https://localhost

--2016-01-22 04:11:48--  https://localhost/ 
Resolving localhost     (localhost)... 127.0.0.1 
Connecting to localhost (localhost)|127.0.0.1|:443... connected. 
ERROR: cannot verify localhost's certificate, issued by ‘/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA’:   
Unable to locally verify the issuer's authority. 
ERROR: no certificate subject alternative name matches  requested host name ‘localhost’. 
To connect to localhost insecurely, use `--no-check-certificate'.

这似乎是正确的!所以,这似乎与服务器设置有关。我无法连接到它。 =/ 再次。安全组允许 443 和 80。


自从我最初提出问题后添加的内容,但仍未解决问题:

  • 设置:绑定,'0.0.0.0'

【问题讨论】:

  • 您应该绑定到 0.0.0.0 或您的 DNS 指向的任何 IP 以查看 sinatrarb.com/…
  • 您能否在退出 shell 后确认服务器运行,因为您应该对进程进行守护进程,否则在您退出 ssh 会话并且进程终止后进程会发送SIGINT
  • 有太多可能出错的地方,抱歉帮不上忙
  • 你应该从网络连接开始,你应该检查你可以ping盒子,并从公众使用nmapnc来检查盒子上哪些端口是开放和可达的,你可能还想tcpdump 流量并查看是否有任何数据包到达盒子,一旦你完成了所有这些,那么你可以确定它是否是我认为不是的应用程序问题(或 ssl)跨度>
  • 澄清您是在互联网上的任何地方运行ncnmap,而不是在盒子上,并且您在盒子上运行tcpdump。例如:nmap -p 443 www.google.com(将 www.google.com 更改为您的域名)并在盒子上运行 sudo tcpdump tcp and port 443,您应该会看到使用 nmap 理解的输出,如果流量到达盒子,您应该使用 tcp 数据包tcpdump

标签: ruby amazon-web-services ssl amazon-ec2 sinatra


【解决方案1】:

通常,您不希望任何 ruby​​ 网络服务器实际处理 SSL。您让它们提供纯 HTTP(只能通过 localhost 访问)。然后安装一个反向代理来处理所有 SSL 通信。

例如

  1. 安装 nginx(反向代理)并将其配置为侦听端口 443。
  2. 设置您的 ruby 应用服务器监听端口 127.0.0.1:80 (接受本地 仅限连接)
  3. 所有请求都命中 nginx,从而剥离 SSL, 并将纯 HTTP 请求发送到您的 ruby​​ 网络服务器。

一个非常简单的 nginx 配置让你开始:

ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/your.key;
ssl on;
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";

server {
    listen 443 ssl;
    server_name you.example.com;

    location / {
        proxy_pass http://localhost:8080;  # your ruby appserver
    }
}

【讨论】:

  • 谢谢,我会试试这个 :D 稍后或明天。我会回来报告的。
  • 我在使用此配置时遇到问题。在第 2 步中,是否必须“仅接受本地连接”?
  • 是的,只设置为 localhost,因为 nginx(位于同一主机上 - 因此为“localhost”)将是唯一一个代理来自外部世界的连接
猜你喜欢
  • 2014-05-24
  • 2018-06-22
  • 1970-01-01
  • 2012-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多