使用Nginx在Ghost博客上进行SSLredirect和身份validation

我在DigitalOcean上有一个关于Ghost的博客。 Nginx也提供相同的configuration文件:

server { listen 443 ssl; server_name www.example.com; return 301 $scheme://example.com$request_uri; } server { listen 443 ssl; server_name example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; include snippets/ssl-params.conf; location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://127.0.0.1:2825; } } 

这些证书是通过让我们encryption生成的,无论是有没有www的域。 在Ghost config.js文件中,URL是使用规则编写的: https : //example.com/问题是,当我进入我的博客,没有wwww的我的域,正确地login并使用SSL,但是当我尝试使用https://www.example.comlogin时,出现SSL证书authentication错误。 我真的不明白这里可能会出现什么问题。 我需要,当进入我的域名与www我redirect到域,但没有www。 我之前做过的这个操作与其他应用程序节点没有问题,具有上面相同的configuration代码。

周末我正在研究这个不便的解决方案,并设法找到解决方案。 Let's Encrypt中没有错误,Nginx中也没有错误,都指的是我的错误配置; 然而,我不能停下来认为这是一个奇怪的事情,我的解决方案可以改善,即使不说更多,这是我的Nginx配置文件:

 server { listen 80; server_name example.com www.example.com; return 301 https://example.com$request_uri; } server { listen 443 ssl http2; server_name example.com www.example.com; ssl on; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; include snippets/ssl-params.conf; if ($http_host = www.example.com) { return 301 https://example.com$request_uri; } location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-NginX-Proxy true; proxy_pass http://localhost:8080/; proxy_ssl_session_reuse off; proxy_set_header Host $http_host; proxy_cache_bypass $http_upgrade; proxy_redirect off; } } 

为了避免拖拽错误,请彻底删除我的虚拟机并从头开始创建,同时为Debian安装最新版本的Nginx,它是1.10.3,这使我可以使用http2,这也是一个改进。

您的第一个服务器块没有证书定义。 所以你可能想复制该server块中的ssl_certificatessl_certificate_key语句。

如果这些是唯一的SSL server块,并且由于您拥有两个域的公用证书文件,则可以将ssl_certificatessl_certificate_key语句移到http级别,并允许它们由两个server块继承。

 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; server { listen 443 ssl; server_name www.example.com; return 301 $scheme://example.com$request_uri; } server { listen 443 ssl; server_name example.com; ... } 

请参阅此文档了解更多

(OP请求从另一个答案中查看我的nodejs代理代码。)

在我们跳转到nodejs代理之前,我们应该检查几件事情:

证书

您的证书是否对使用和不使用www有效?

如果你的证书只有在没有www的情况下有效(或者反过来),那么没有代理(nginx或者我的或者其他)的设置可以帮助你。 因为SSL / TLS握手发生在重定向之前。 在发生重定向之前,浏览器会立即投诉。 最终用户在浏览器中看到证书错误。

我的两个都有效,你可以看看我的博客https://johnsiu.com和https://www.johnsiu.com 。 重定向发生在没有任何证书的抱怨。

DNS

您的DNS设置是否正确无论有没有www? 他们应该指向相同的IP地址。

我想知道这是否与ERR_SOCKET_NOT_CONNECTED错误有关。

Nodejs代理

它在ghithub托管: https : //github.com/J-Siu/ghost-https-nodejs-proxy

我刚刚完成微调我的nodejs代理,以下是最新版本:

 // HTTPS const fs = require('fs'); const url = require('url'); const http = require('http'); const https = require('spdy'); // http2 support const proxy = require('http-proxy').createProxyserver(); const compression = require('compression'); const ex = require('express')(); const fqdn = '<your domain name here>'; // Fill in your certificate files const serverKey = '<KEY file>'; const serverCrt = '<CRT file>'; //const serverCa='<CA file>'; const httpsOptions = { key: fs.readFileSync(serverKey), cert: fs.readFileSync(serverCrt), // ca: fs.readFileSync(serverCa), ciphers: [ "ECDHE-RSA-AES256-SHA384", "DHE-RSA-AES256-SHA384", "ECDHE-RSA-AES256-SHA256", "DHE-RSA-AES256-SHA256", "ECDHE-RSA-AES128-SHA256", "DHE-RSA-AES128-SHA256", "HIGH", "!aNULL", "!eNULL", "!EXPORT", "!DES", "!RC4", "!MD5", "!PSK", "!SRP", "!CAMELLIA" ].join(':'), }; // Ghost Proxy configuration proxy.on('proxyReq', function (proxyReq, req, res, options) { // Ngix: proxy_set_header Host $http_host; proxyReq.setHeader('Host', req.headers.host); // Ngix: proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxyReq.setHeader('X-Forwarded-For', req.connection.remoteAddress); // Ngix: proxy_set_header X-Forwarded-Proto $scheme; proxyReq.setHeader('X-Forwarded-Proto', 'https'); }); ex .use(compression()) .use((req, res) => { if (req.header.host == fqdn) { proxy.web(req, res, { target: 'http://localhost:2368' }); } else { res.writeHead(301, { 'location': 'https://' + fqdn + req.url }); res.end(); } }) // HTTPS server https.createserver(httpsOptions, ex).listen(443, '0.0.0.0'); // HTTP Redirect to HTTPS http.createserver(function (req, res) { res.writeHead(301, { 'location': 'https://' + fqdn + req.url }); res.end(); }).listen(80, '0.0.0.0'); 

这是我的Nginx配置文件,我正在用Ghost提供一个博客。 证书是使用Let's Encrypt生成的,并且对于这两个域都能正常工作。 执行301重定向时,给出的缺点是,因为它不能正常工作,因为与www的域告诉我,证书是无效的,但是如果我尝试使重定向到相反,从不www到www,它显示我相同的消息,但对于没有www的域名:

 server { listen 80; server_name www.example.com; return 301 https://example.com$request_uri; } server { listen 80; server_name example.com; return 301 https://www.example.com$request_uri; } server { listen 443; server_name example.com; return 301 https://www.example.com$request_uri; } server { listen 443; server_name www.example.com; ssl on; ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem; include snippets/ssl-params.conf; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_pass http://localhost:9002/; proxy_redirect off; } } 

目前,我正在使用数字海洋,我配置了3个字段A,一个字段A,值为*,指向虚拟机的IP,一个字段@也用于服务器的IP地址,以及最后一个值为www的字段A转到我的服务器的IP地址。