昨天给网站加了个 HTTPS,并且已经全站做了跳转。今天记录一下整个过程。主要包括 Apache 下对于 SSL 的配置,以及整站 301 跳转。
安装 LAMP
这个不是重点,顺便说一下。我用的是 lamp.sh 提供的一键包。安装方法(以 Ubuntu 16.04 LTS 为例,更多的请前往参考文献查看):
apt-get -y install wget screen git
git clone https://github.com/teddysun/lamp.git
cd lamp
chmod +x *.sh
screen -S lamp
./lamp.sh
安装完成即可。
配置 SSL 证书
LAMP 一键包目前提供两种配置 SSL 证书的方法,使用第三方购买的证书,或者使用 Let’s Encrypt 提供的免费证书。这个在最新版的 LAMP 添加网站的时候就会有提示。不过今天说的不是这个自动配置的,说一下手动配置的流程。毕竟不少人是之前已经配置过网站,现在想手动加 SSL 证书的。(主要也是记录一下方便自己日后查看)
1. 生成 CSR 文件
输入下面命令(在你希望存放的目录下,比如 /data/ssl),生成 CSR 文件:
openssl req -new -newkey rsa:2048 -nodes -keyout example.key -out example.csr
上面的 example.key 和 example.csr 请替换成自己想要的名字,比如 oldtang_com.key,oldtang_com.csr。
需要填写的内容如下:
You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:CN // 国家代码 State or Province Name (full name) []:Shanghai // 省 Locality Name (eg, city) [Default City]:Shanghai // 城市 Organization Name (eg, company) [Default Company Ltd]:OldTang // 组织或公司名 Organizational Unit Name (eg, section) []: // 不填 Common Name (eg, your name or your server's hostname) []:oldtang.com // 需要加 SSL 的域名 Email Address []:[email protected] // 邮箱地址 Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: // 不填 An optional company name []: // 不填
2. 获取证书
这一步一般就是去你购买的 SSL 证书的服务提供商那里,提交 CSR 文件,然后获取你的证书。可以通过
cat example.csr
查看刚刚生成的 CSR 文件的内容,然后整个复制即可。提交到你的 SSL 证书提供商。比如我是在 ssls.com 买的,3 年 15 美元。
获取到的证书一般有两个,一个是 example.crt,一个是 example.ca-bundle,都下载下来,放到刚刚的目录下(比如现在在 /data/ssl/example.crt 和 /data/ssl/example.ca-bundle)。
3. 配置 Apache
首先我们需要打开 Apache 的 https 配置。修改文件 /usr/local/apache/conf/httpd.conf,找到 #Include conf/extra/httpd-ssl.conf
,把前面的 # 去掉,保存。
然后配置一下 /usr/local/apache/conf/extra/httpd-ssl.conf
,模板如下:
Listen 443 SSLPassPhraseDialog builtin SSLSessionCache "shmcb:/usr/local/apache/logs/ssl_scache(512000)" SSLSessionCacheTimeout 300 <VirtualHost *:443> DocumentRoot /data/www/example.com/ ServerName example.com ServerAlias www.example.com ErrorLog "/usr/local/apache/logs/lamp_error_log" TransferLog "/usr/local/apache/logs/lamp_access_log" SSLEngine on SSLProtocol All -SSLv2 -SSLv3 SSLHonorCipherOrder on SSLCipherSuite ALL:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA SSLCertificateFile /data/ssl/example.crt SSLCertificateKeyFile /data/ssl/example.key SSLCertificateChainFile /data/ssl/example.ca-bundle CustomLog "/usr/local/apache/logs/lamp_ssl_request_log" \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b \"%{Referer}i\" \"%{User-Agent}i\"" BrowserMatch "MSIE [2-5]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 <Directory /data/www/example.com/> Options -Indexes +FollowSymLinks AllowOverride All Require all granted </Directory> </VirtualHost>
把上面所有带有 example 字样的,都修改成你自己的信息。
如果有多个不同的域名需要加 SSL 的,也很简单,<VirtualHost *:443> </VirtualHost>
前面的东西不变,连带里面的东西再复制一份即可。就像这样:
Listen 443 SSLPassPhraseDialog builtin SSLSessionCache "shmcb:/usr/local/apache/logs/ssl_scache(512000)" SSLSessionCacheTimeout 300 <VirtualHost *:443> .... </VirtualHost> <VirtualHost *:443> .... </VirtualHost>
然后重启一下 Apache 即可:
/etc/init.d/httpd restart
如果开了防火墙,记得检查一下防火墙状态,要放行 443 端口。
自动跳转到 HTTPS
配置完成后,会发现通过 HTTP 和 HTTPS 都能访问。如果我们想要保持统一,可以对 HTTP 的链接做强制跳转,都跳转到 HTTPS。
1. HTTP 自动跳转到 HTTPS
方法很简单,在网站目录下,新建或者编辑 .htaccess
文件,在最前面加入以下内容:
RewriteEngine On RewriteCond %{HTTPS} !on [NC] RewriteRule (.*) https://oldtang.com%{REQUEST_URI} [R=301,NC,L]
这段代码的意思是说:当检测到 HTTPS 未开启(!on
嘛)的时候,把请求重定向到 https:// 的对应 URI。
如果想要针对不同的搜索引擎,配置是否跳转或者不跳转,也简单。稍作修改如下:
RewriteEngine On RewriteCond %{HTTPS} !on [NC] RewriteCond %{HTTP_USER_AGENT} !(baiduspider|soso|bing|sogou|yahoo|sohu-search|yodao|robozilla|msnbot|msie|feedburner) [NC] RewriteRule (.*) https://oldtang.com%{REQUEST_URI} [R=301,NC,L]
这段代码比刚刚那段多加了一个判断条件,即判断访客的 User Agent 是否是搜索引擎或者 IE 用户,如果不是,那才跳转到 https:// 版的页面。注意,这里面是不包含 Google Bot(Google 的爬虫)的,因为 Google 本身就是能抓取 https:// 站点的,没必要重定向。而 IE 用户则是像其他的非 Google 的搜索引擎一般看待了,保持不跳转。
2. 带 WWW 的自动跳转到不带 WWW 的域名
仅仅是跳转到 HTTPS,还不够,为了保持更统一,我们要把带 WWW 的域名和不带 WWW 的域名也统一起来。比如我这里都是跳转到不带 WWW 的,方法如下。
在刚刚的 .htaccess 文件里,紧跟着加入:
RewriteEngine On RewriteCond %{HTTP_HOST} ^www.oldtang.com [NC] RewriteRule ^(.*)$ https://oldtang.com/$1 [L,R=301]
那么最后的文件就大概变成这样子了,可以实现 HTTP 跳转到 HTTPS,并且带 WWW 的域名跳转到不带 WWW 的域名:
RewriteEngine On RewriteCond %{HTTP_HOST} ^www.oldtang.com [NC] RewriteRule ^(.*)$ https://oldtang.com/$1 [L,R=301] RewriteCond %{HTTPS} !on [NC] RewriteRule (.*) https://oldtang.com%{REQUEST_URI} [R=301,NC,L]
最终的效果就是我的网站现在的样子。
参考文献
- https://lamp.sh/
- https://helpdesk.ssls.com/hc/en-us/articles/203427502-How-to-generate-a-CSR-code-on-Apache-Nginx-using-OpenSSL
- https://teddysun.com/395.html
- https://helpdesk.ssls.com/hc/en-us/articles/203482651-How-to-install-a-SSL-certificate-on-Apache