【问题标题】:ERR_EMPTY_RESPONSE with Ghost 0.7.5, Nginx 1.9, HTTPS and HTTP/2带有 Ghost 0.7.5、Nginx 1.9、HTTPS 和 HTTP/2 的 ERR_EMPTY_RESPONSE
【发布时间】:2016-04-30 12:57:06
【问题描述】:

问题

当我点击kevinsuttle.com 时,我得到了

"No data received ERR_EMPTY_RESPONSE".

当我点击https://kevinsuttle.com 时,我得到了该网站。

幽灵 0.7.5
nginx 1.4 => 1.9.9
让我们加密 0.2.0

数字海洋:Ubuntu 14.04 Ghost 1-click droplet

Networking > Domains 下,我有 kevinsuttle.comwww.kevinsuttle.com 作为指向服务器 IP 地址 (@) 的 A 记录。

DNSimple 记录

|类型 |姓名 | TTL |内容 | |-------- |---------- |--------------- |---- -------------------- | |网址 | www.kevinsuttle.com | 3600 (1 小时) | http://kevinsuttle.com |

Ghost 的 config.js 中唯一修改的部分是我的域。

url: 'http://kevinsuttle.com',

Nginx 1.9

nginx 1.9 默认不创建以下目录:
/etc/nginx/sites-available
/etc/nginx/sites-enabled

并且通常的default conf 不会在这两个目录中创建。

取而代之的是etc/nginx/conf.d/default.conf 和重要的etc/nginx/conf.d/nginx.conf。您会看到很多教程告诉您删除 default.conf,这似乎很好,但无论您做什么,不要删除 nginx.conf

此外,您应该将ghost.conf 移动/创建到/etc/nginx/conf.d/ 目录中。这就是解决我的一个问题的原因,因为etc/nginx/conf.d/nginx.conf 中的最后一行在/conf.d/ 目录中查找并包含那里的所有文件:include /etc/nginx/conf.d/*.conf;

这是我的/etc/nginx/conf.d/ghost.conf 文件:

  server {
  root /usr/share/nginx/html;
  index index.html index.htm;

  listen 443 ssl http2;

  server_name kevinsuttle.com www.kevinsuttle.com;
    ssl_certificate /etc/letsencrypt/live/kevinsuttle.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/kevinsuttle.com/privkey.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

  location ~ /.well-known {
      allow all;
      root /var/www/;
  } 

  location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header HOST $http_host;
        proxy_set_header X-NginX-Proxy true;

        proxy_pass http://127.0.0.1:2368;
        proxy_redirect off;
        root /var/www/;
    }
      location /.well-known/ {
        root /var/www/;
    }
}

server {
    listen 80 ssl http2;
    server_name kevinsuttle.com;
    return 301 https://$host$request_uri;
}

现在,我一切正常,并尝试将 nginx 升级到 1.9+,以便通过 http/2 服务。 DigitalOcean 的 1-click Ghost droplet 默认使用 nginx 1.4。

长话短说,我一直收到这个错误:

dpkg: error processing archive /var/cache/apt/archives/nginx_1.9.9-1~trusty_amd64.deb (--unpack):

我找到的唯一解决方案是

apt-get purge nginx nginx-common

然后我可以安装 nginx 1.9,方法是将以下几行添加到我的 /etc/apt/source.list 文件中。

deb http://nginx.org/packages/mainline/ubuntu/ trusty nginx
deb-src http://nginx.org/packages/mainline/ubuntu/ trusty nginx

现在我只是添加了listen 80 ssl http2;listen 443 ssl http2;,http/2 就可以正常工作了。但仅当显式输入 https:// URL 时。

我发现some evidence 表明express 不支持http/2,但我并不是100% 支持这一点。

任何想法将不胜感激。

【问题讨论】:

    标签: nginx https http2 ghost lets-encrypt


    【解决方案1】:

    我认为这不是 Ghost 的问题,也不是 DNS 的问题。

    您可以排除 DNS,因为 www 和 not-www 都解析到配置的 IP。

    ➜  ~  dig kevinsuttle.com +short
    162.243.4.120
    ➜  ~  dig www.kevinsuttle.com +short
    162.243.4.120
    

    DNS 协议在比 HTTP 更低的级别上工作,它不关心 HTTP 版本或您使用的是 HTTP 还是 HTTPS。因此我们可以排除 DNS 并转而检查更高级别的协议。

    我也排除了 Ghost/Express 的问题,因为当我使用 HTTPS 时,我可以向您的博客发送 HTTP/2 请求。

    ➜  ~  curl --http2 -I https://kevinsuttle.com/
    HTTP/2.0 200
    server:nginx/1.9.9
    date:Sun, 24 Jan 2016 19:34:30 GMT
    content-type:text/html; charset=utf-8
    content-length:13594
    x-powered-by:Express
    cache-control:public, max-age=0
    etag:W/"351a-fflrj9kHHJyvRRSahEc8JQ"
    vary:Accept-Encoding
    

    只要我使用网站的 HTTP 版本,我也可以回退到 HTTP 1.1。

    ➜  ~  curl -I https://kevinsuttle.com/
    HTTP/1.1 200 OK
    Server: nginx/1.9.9
    Date: Sun, 24 Jan 2016 19:35:36 GMT
    Content-Type: text/html; charset=utf-8
    Content-Length: 13594
    Connection: keep-alive
    X-Powered-By: Express
    Cache-Control: public, max-age=0
    ETag: W/"351a-fflrj9kHHJyvRRSahEc8JQ"
    Vary: Accept-Encoding
    

    因此,问题在于 Nginx 配置。具体来说,问题在于 HTTP-only 块的 Nginx 配置。

    我现在不能尝试,但我个人认为问题出在这一行:

    listen 80 ssl http2;
    

    应该是

    listen 80;
    

    ssl 指令用于强制侦听套接字理解ssl。但是,在您的情况下,让套接字侦听 80 以使用 HTTPS 是没有意义的。此外,使用ssl 的套接字必须声明关联的 SSL 配置(也就是至少一个有效的证书和密钥)。

    通常,您使用ssl 来配置一个同时处理 HTTP 和 HTTPS 请求的服务器:

    server {
        listen              80;
        listen              443 ssl;
        server_name         www.example.com;
        ssl_certificate     www.example.com.crt;
        ssl_certificate_key www.example.com.key;
        ...
    }
    

    还要注意explained in the Nginx documentation

    因此不鼓励在现代版本中使用 ssl 指令。

    http2 与非 https 套接字结合使用也可能导致问题。

    引用this article:

    虽然该规范并未强制任何人通过 TLS 实现 HTTP/2,但允许您通过明文 TCP 来实现,但 Firefox 和 Chrome 开发团队的代表都表达了他们的意图,即仅通过 TLS 实现 HTTP/2 TLS。这意味着 HTTPS:// URL 是为这些浏览器启用 HTTP/2 的唯一 URL。

    因此,假设有可能,通过 HTTP/2 为非 https 站点提供服务可能没有用。实际上,鉴于issue described in this ticket 似乎与您的问题相符,我怀疑它甚至可能在今天。

    总而言之,简单地改变

    server {
        listen 80 ssl http2;
        server_name kevinsuttle.com;
        return 301 https://$host$request_uri;
    }
    

    server {
        listen 80;
        server_name kevinsuttle.com;
        return 301 https://$host$request_uri;
    }
    

    【讨论】:

    • 一个简单的改变就解决了它。非常感谢!
    猜你喜欢
    • 2016-05-23
    • 2017-10-30
    • 2021-07-16
    • 2016-07-06
    • 1970-01-01
    • 2019-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多