为什么 Rails 不能使用 nginx 和自签名 SSL 证书?
Why isn't Rails with nginx and a self-signed SSL certificate working?
在将站点从 Heroku 迁移到(Digital Ocean)VPS 之前,我正在尝试测试我的 SSL 设置,所以我根据 these instructions 使用自签名证书.
我使用以下命令创建了证书,它们位于相应的目录中:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
以下是我 nginx.conf 上 server
块中的相关行:
server {
listen 80 default_server;
listen 443 ssl;
server_name migration.my_domain.com;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
此外,在 production.rb
中,我使用了以下行:
config.force_ssl = true
my_domain
(不是实际域名)及其子域 migration
都在我的 DNS 中设置并且正确指向我服务器的 IP 地址。目前,当我通过 http://migration.my_domain.com
访问页面时,页面就会被提供。但是当我通过 https://migration.my_domain.com
访问时,我在 Chrome 中遇到错误:
This site can’t be reached
migration.my_domain.com refused to connect.
Try:
Reloading the page
Checking the connection
Checking the proxy and the firewall
ERR_CONNECTION_REFUSED
知道我在这里遗漏了什么吗?
想通了。首先,我通过 Capistrano 进行部署,我错误地认为它是在部署后重新启动 nginx。事实证明它没有。所以我需要手动完成。所以在我的 server
块的开头部署了这个:
server {
listen 443 ssl default_server deferred;
server_name migration.my_domain.com;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
已部署,但在重新启动 nginx 后,首先收到来自 Chrome 的关于自签名证书的警告,并且该站点不可信任(这很好并且符合预期)。移动过去后收到有关重定向过多的消息。结果是我的 production.rb
文件中上面的行:
config.force_ssl = true
导致了问题。看到 this 据我所知,这意味着 nginx 发送给 puma 的内容不包含它是否是 ssl,因此 puma 重定向 所有内容 ,甚至 https 请求,因为它只是不知道它得到了什么。所以,现在我有两个几乎重复的 server
块。第一个处理 http
请求的有以下相关语句:
server {
listen 80;
server_name migration.my_domain.com;
# ...bunch of non-relevant config...
location @puma {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://puma;
}
}
由于 production.rb
中的 config.force_ssl = true
,这处理了 puma 将全部重定向到 ssl(我相信)的所有 80 个请求。然后 Nginx 将收到一个 https 请求相同的 URL 将由这个块处理:
server {
listen 443 ssl;
server_name migration.my_domain.com;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
# ...bunch of non-relevant config...
location @puma {
proxy_set_header X-Forwarded-Proto https; # IMPORTANT!! I believe this tells puma that everything sent through via this block is https. Thus, puma no longer redirects.
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://puma;
}
}
这似乎工作正常,尽管在收到自签名证书时应该在浏览器中收到所有适当的警告。我相信一旦我切换到我的实际证书,我现在将拥有一个正常运行的 ssl 设置。
再次感谢@doon!
在将站点从 Heroku 迁移到(Digital Ocean)VPS 之前,我正在尝试测试我的 SSL 设置,所以我根据 these instructions 使用自签名证书.
我使用以下命令创建了证书,它们位于相应的目录中:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
以下是我 nginx.conf 上 server
块中的相关行:
server {
listen 80 default_server;
listen 443 ssl;
server_name migration.my_domain.com;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
此外,在 production.rb
中,我使用了以下行:
config.force_ssl = true
my_domain
(不是实际域名)及其子域 migration
都在我的 DNS 中设置并且正确指向我服务器的 IP 地址。目前,当我通过 http://migration.my_domain.com
访问页面时,页面就会被提供。但是当我通过 https://migration.my_domain.com
访问时,我在 Chrome 中遇到错误:
This site can’t be reached
migration.my_domain.com refused to connect.
Try:
Reloading the page
Checking the connection
Checking the proxy and the firewall
ERR_CONNECTION_REFUSED
知道我在这里遗漏了什么吗?
想通了。首先,我通过 Capistrano 进行部署,我错误地认为它是在部署后重新启动 nginx。事实证明它没有。所以我需要手动完成。所以在我的 server
块的开头部署了这个:
server {
listen 443 ssl default_server deferred;
server_name migration.my_domain.com;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
已部署,但在重新启动 nginx 后,首先收到来自 Chrome 的关于自签名证书的警告,并且该站点不可信任(这很好并且符合预期)。移动过去后收到有关重定向过多的消息。结果是我的 production.rb
文件中上面的行:
config.force_ssl = true
导致了问题。看到 this 据我所知,这意味着 nginx 发送给 puma 的内容不包含它是否是 ssl,因此 puma 重定向 所有内容 ,甚至 https 请求,因为它只是不知道它得到了什么。所以,现在我有两个几乎重复的 server
块。第一个处理 http
请求的有以下相关语句:
server {
listen 80;
server_name migration.my_domain.com;
# ...bunch of non-relevant config...
location @puma {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://puma;
}
}
由于 production.rb
中的 config.force_ssl = true
,这处理了 puma 将全部重定向到 ssl(我相信)的所有 80 个请求。然后 Nginx 将收到一个 https 请求相同的 URL 将由这个块处理:
server {
listen 443 ssl;
server_name migration.my_domain.com;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
# ...bunch of non-relevant config...
location @puma {
proxy_set_header X-Forwarded-Proto https; # IMPORTANT!! I believe this tells puma that everything sent through via this block is https. Thus, puma no longer redirects.
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://puma;
}
}
这似乎工作正常,尽管在收到自签名证书时应该在浏览器中收到所有适当的警告。我相信一旦我切换到我的实际证书,我现在将拥有一个正常运行的 ssl 设置。
再次感谢@doon!