ERR_EMPTY_RESPONSE与Ghost 0.7.5,Nginx 1.9,HTTPS和HTTP/2

Kev*_*tle 2 https nginx http2 ghost lets-encrypt

问题

当我击中时kevinsuttle.com,我明白了

"No data received ERR_EMPTY_RESPONSE".
Run Code Online (Sandbox Code Playgroud)

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

ghost 0.7.5
nginx 1.4 => 1.9.9
letsencrypt 0.2.0

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

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

DNSimple记录

| Type  | Name                  | TTL               | Content                   |
|------ |---------------------  |---------------    |------------------------   |
| URL   | www.kevinsuttle.com   | 3600 (1 hour)     | http://kevinsuttle.com    |  

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

url: 'http://kevinsuttle.com',
Run Code Online (Sandbox Code Playgroud)

Nginx 1.9

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

并且通常的defaultconf不会在这两个目录中创建.

相反,有一个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;
}
Run Code Online (Sandbox Code Playgroud)

现在,我把这一切都搞好了,并尝试将nginx升级到1.9+,以便通过http/2服务.DigitalOcean的一键Ghost Droplet默认使用nginx 1.4.

长话短说,我不断收到这个错误:

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

我发现的唯一解决方案是

apt-get purge nginx nginx-common
Run Code Online (Sandbox Code Playgroud)

然后我可以通过在我的/etc/apt/source.list文件中添加以下行来安装nginx 1.9 .

deb http://nginx.org/packages/mainline/ubuntu/ trusty nginx
deb-src http://nginx.org/packages/mainline/ubuntu/ trusty nginx
Run Code Online (Sandbox Code Playgroud)

下面我简单加listen 80 ssl http2;listen 443 ssl http2;,和HTTP/2工作正常.但只有在https://明确输入URL 时.

我找到了一些证据表明express不支持的事实http/2,但我不是百分之百.

任何想法将不胜感激.

Sim*_*tti 6

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

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

?  ~  dig kevinsuttle.com +short
162.243.4.120
?  ~  dig www.kevinsuttle.com +short
162.243.4.120
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

?  ~  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
Run Code Online (Sandbox Code Playgroud)

因此,问题是Nginx配置.具体来说,问题是仅HTTP块的Nginx配置.

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

listen 80 ssl http2;
Run Code Online (Sandbox Code Playgroud)

它应该是

listen 80;
Run Code Online (Sandbox Code Playgroud)

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;
    ...
}
Run Code Online (Sandbox Code Playgroud)

另请注意,如Nginx文档中所述

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

采用http2结合非HTTPS插座也可以是一个麻烦的原因.

引用这篇文章:

虽然规范并没有强制任何人通过TLS实现HTTP/2,但允许您通过明文TCP进行,但Firefox和Chrome开发团队的代表已经表达了他们只想通过TLS实现HTTP/2的意图.这意味着HTTPS:// URL是唯一能够为这些浏览器启用HTTP/2的URL.

因此,假设有可能,通过HTTP/2服务非https站点可能没有用.实际上,我怀疑今天甚至可能,因为这张票描述问题似乎与您的问题相符.

总而言之,只需改变

server {
    listen 80 ssl http2;
    server_name kevinsuttle.com;
    return 301 https://$host$request_uri;
}
Run Code Online (Sandbox Code Playgroud)

server {
    listen 80;
    server_name kevinsuttle.com;
    return 301 https://$host$request_uri;
}
Run Code Online (Sandbox Code Playgroud)