部署 快速实现 HTTPS 和 HTTP 同时都可以访问 Ruby on Rails 应用

doosolar · February 08, 2018 · Last by YanhaoMo replied at February 25, 2018 · 5346 hits

前言

最近试了一下腾讯云的 SSL 服务,很好地解决了 https://www.test.comhttp://www.test.com 同时都可以访问的问题。

首先,解决 HTTPS

要实现 HTTPS 访问,关键要有 SSL 证书,目前有些云服务商,都提供这个服务。

申请 SSL 证书

比如:在腾讯云中,有【SSL 证书管理】的服务,在【域名和网站】里面。具体操作如下:

  1. 点击:购买证书
  2. 选择:域名型免费版(DV)

然后按照页面的提示,一步一步往下走:直到:【域名身份认证】;

这里有两个选择:「手动 DNS 验证」或者「文件验证」:

  1. 我们选择简单的:「手动 DNS 验证」,
  2. 确认申请

一会儿之后,出现:【证书详情】。点击后,页面出现了具体在 DNS 域名解析中需要添加的 TXT 记录的内容。

  1. 请按照这个内容,修改您的 DNS 域名解析。

过一会之后,在【SSL 证书管理】的列表中,会出现一条,右边有【下载】按钮。点击后,您就把 SSL 证书得到了。

安装 SSL 证书

在【下载】按钮的旁边是【详情】按钮,点击后,在【证书详情】页面,

点击:【指引文档】,将会出现一个新的帮助页面:证书安装指引 https://cloud.tencent.com/document/product/400/4143

里面有 apache, nginx, tomcat 等的配置说明。我按照 nginx 的配置操作,基本都可以用。

同时 容许:HTTPS,HTTP 访问

比如,您的 nginx 配置中,缺省的访问应用是:test_app, 其相关的配置文件是:/etc/nginx/conf.d/test_app.conf

那么,最基本的样子,如下就可以。(让 HTTPS 和 HTTP 同时访问的的步骤:注释掉:# ssl_on; )这一步就够了。

upstream test_app {                                                                                                                                                                                                                                  
   server unix:/tmp/unicorn.test_app.sock fail_timeout=0;                                                                                                                                                                                            
} 

server {                                                                                                                                                                                                                                                  
    listen 80 default_server;                                                                                                                                                                                                                             
    listen 443  default_server ssl;                                                                                                                                                                                                                       

    server_name test.com www.test.com;                                                                                                                                                                                           

    # ssl on;                                                                                                                                                                                                                                             
    ssl_certificate /etc/nginx/conf.d/ssl/1_www.test.com_bundle.crt;                                                                                                                                                                                    
    ssl_certificate_key /etc/nginx/conf.d/ssl/2_www.test.com.key;                                                                                                                                                                                       
    ssl_session_timeout 5m;                                                                                                                                                                                                                               
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置                                                                                                                                                                                                
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置                                                                                                                                                                  
    ssl_prefer_server_ciphers on;                                                                                                                                                                                                                         

    root      /home/your_name/test_app/public;                                                                                                                                                                                           
    try_files $uri/index.html $uri @test_app;                                                                                                                                                                                                        

    location @test_app {                                                                                                                                                                                                                             
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;                                                                                                                                                                                        
      proxy_set_header Host $http_host;                                                                                                                                                                                                                   
      proxy_redirect off;                                                                                                                                                                                                                                 
      proxy_pass http://test_app;                                                                                                                                                                                                                    
    }                                                                                                                                                                                                                                                     

    error_page 500 502 503 504 /500.html;                                                                                                                                                                                                                 
    client_max_body_size 4G;                                                                                                                                                                                                                              

    keepalive_timeout 10;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
}  

其他注意问题:

  1. 请别忘了设置安全组(防火墙):允许 TCP:443 的访问,😄
  2. unicorn 等配置,是不需要更改的。除非您想强制让应用只接受 HTTPS 的访问。

验证:

https://www.test.com

https://test.com

http://www.test.com

http://test.com

包括下面的各个页面,均可以正常访问了。

请问同时使用两种方式有什么优势,会带来什么问题?

重定向到 https

让本来是 HTTP 访问的应用,以极小的修改,极省事的操作,快速实现 HTTPS 的访问,同时不影响本来 HTTP 的访问。

Reply to doosolar

为什么不 301 重定向呢?

Reply to Peter

目前,不需要任何重定向,就满足 HTTPS 和 HTTP 两者的访问,将来依据业务发展需求,再逐渐加其他配置。

6 Floor has deleted
Reply to doosolar

我想知道的是,为什么要两种方式同时访问,我觉得没有必要还保留 http,只留 https 就可以了啊。 有用户一定要用 http 来访问吗?

SEO 怎么做?

Reply to Peter

无所谓啦,看具体需求而定。比如,在本来 HTTP 的应用中,加个对微信小程序的支持,就可以这样快速实现一下,而不影响本来的业务。

Reply to doosolar

谢谢回复,理解了,还真有这种场景。

话说腾讯云这种分发证书(打包下载)的方式是不是有点奇怪,而且理论上它拥有你的私钥..

Reply to ecnelises

不奇怪。而且不是理论上,是实际上。

腾讯云的服务,用下来,体验还不错:安静稳定、不烦人。其实,所有公司的云服务,理论上……

ps) client_max_body_size 4G 这个配置可以改小一点,比如 100M

免费证书的话,为什么不用 Let‘s encrypt

Reply to YanhaoMo

可以用的啊,只是用微信提供的服务,操作更简单一些,点击几下就好啦。

You need to Sign in before reply, if you don't have an account, please Sign up first.