LAMP 环境下安装配置 SSL 证书并自动跳转到 HTTPS

已关闭留言

昨天给网站加了个 HTTPS,并且已经全站做了跳转。今天记录一下整个过程。主要包括 Apache 下对于 SSL 的配置,以及整站 301 跳转。

文章目录
隐藏
安装 LAMP
配置 SSL 证书
自动跳转到 HTTPS
参考文献

安装 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 []:contact@example.com  // 邮箱地址

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]

最终的效果就是我的网站现在的样子。

参考文献

  1. https://lamp.sh/
  2. https://helpdesk.ssls.com/hc/en-us/articles/203427502-How-to-generate-a-CSR-code-on-Apache-Nginx-using-OpenSSL
  3. https://teddysun.com/395.html
  4. https://helpdesk.ssls.com/hc/en-us/articles/203482651-How-to-install-a-SSL-certificate-on-Apache