• 证书提供商: Let’s Encrypt
  • 系统: ubuntu 14.04
  • 证书类型: DV域名验证证书
  • Web Server: nginx

为什么要用HTTPS

  • 每个人都有隐私权,不管是现实还是网络中,如果没有https,网络将没有任何隐私可言,无论我们的WIFI、网络提供商、运营商、公司或是政府机构。
  • HTTPS的性能损失已经不存在了,事实上,HTTPS在现代设备上的性能还优于HTTP
  • 使用HTTPS意味着没人可以篡改我们Web浏览器中的内容,这在几年前还没受到大家的关注,但现在越来越多的网络或网络设备提供商会利用他们的渠道来『处理』数据。比如: 网络运营商会在宽带帐号快到期前,会将欠费提醒插入你正在浏览的网页中,甚至地方运营商会直接做DNS劫持,往正在浏览的网页中插入广告,甚至在浏览京东、淘宝等网站时动手脚做返利链接跳转等等。

据统计,去年新上线网站默认采用HTTPS的数量已经增加了一倍

2017年1月起,使用Google Chrome浏览器进行登录或填写信用卡表单时,如果网站处于未加密状态时,地址栏也会出现不安全的提示。

此外Google搜索引擎也会降低未加密网站的排名权重,显然这已经引起搜索巨头相当大的重视。

加密需要用到的证书是由证书颁发机构颁发的,以前由于证书都是收费的,个人网站很少申请,但现在有了免费的选择: 一个由Linux基金会支持的非营利组织推出的 Let’s Encrypt。

HTTPS证书有三种类型:

  • DV域名验证证书
  • OV组织机构验证证书
  • 增强的组织机构验证证书

每种类型的证书在审核和验证方面要求严格程度不同,浏览器也会在地址栏给予不同证书不一样的展现。 个人用户一般使用DV域名验证证书就足够了(浏览器地址栏会显示绿色的锁)。

Let’s Encrypt属于DV域名验证证书,它虽然免费,但每三个月要续期一次,这里记录下 Let’s Encrypt证书的申请、使用以及自动续期。

下载Let’s Encrypt

git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt

配置证书

# 停止nginx
service nginx stop
# 确认80端口没被别的程序占用
netstat -na | grep ':80.*LISTEN'
# 防火墙放行80和443端口(如果有必要的话)
ufw allow 80
ufw allow 443
# 获取证书并在弹出的提示中填写所需的信息,一般情况下只需要填写一个email
cd /opt/letsencrypt
./letsencrypt-auto certonly --standalone -d junnan.org -d www.junnan.org
# 获取成功后,证书的符号链接会被保存到如下路径
ls /etc/letsencrypt/live/junnan.org/
# fullchain.pem 用来配置服务器,privkey.pem 作为证书的 key 文件

# 生成 dhparam.pem
mkdir /etc/nginx/ssl
openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

升级nginx

由于 Ubuntu14.04 上的nginx的版本是1.4.6,不支持http2,所以要使用nginx官方的源来安装新版

# 卸载旧版nginx
apt-get autoremove --purge nginx nginx-common
# 添加源
vim /etc/apt/sources.list.d/nginx.list
deb http://nginx.org/packages/mainline/ubuntu/ trusty nginx
deb-src http://nginx.org/packages/mainline/ubuntu/ trusty nginx
# 添加nginx signing key
wget -q -O- http://nginx.org/keys/nginx_signing.key | sudo apt-key add -
# 更新源
apt-get update
# 安装nginx
apt-get install nginx
# 修改配置
vim /etc/nginx/nginx.conf
user www-data;
worker_processes 4;
# http节点修改
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 2048;
server_tokens off;
gzip  on;
gzip_disable "msie6";
include /etc/nginx/sites-enabled/*;
# 移除默认配置
rm -rf /etc/nginx/conf.d/default.conf
# 添加fastcgi_params配置
vim /etc/nginx/fastcgi_params
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# 建立目录
mkdir /etc/nginx/sites-available /etc/nginx/sites-enabled

配置nginx

server {
    listen 80;
    server_name junnan.org www.junnan.org;
    return 301 https://junnan.org$request_uri;
}

server {
  listen 443 ssl http2;
  server_name junnan.org www.junnan.org;
  root /var/www/junnan.org;
  index index.html index.htm;
  charset utf-8;

  ssl_certificate /etc/letsencrypt/live/junnan.org/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/junnan.org/privkey.pem;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
  ssl_prefer_server_ciphers on;
  ssl_dhparam /etc/nginx/ssl/dhparam.pem;

  location / {
    try_files $uri $uri/ =404;
  }

  error_page 404 /404.html;
}

其他选项:

# Improve the performance
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

# Enable HSTS
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";

启动nginx

service nginx start

证书自动续期

Let’s encrypt 的有效期是 90 天,可以使用脚本达到自动续期的目的。

创建脚本

cd /var/scripts
touch renewal.sh
chmod u+x renewal.sh

脚本内容(如需测试脚本是否可用,只需为脚本里的 letsencrypt-auto 命令加上 --force-renewal 测试即可):

#!/bin/sh
service nginx stop
/opt/letsencrypt/letsencrypt-auto renew -nvv --standalone > /var/log/letsencrypt/renew.log 2>&1
LE_STATUS=$?
service nginx start
if [ "$LE_STATUS" != 0 ]; then
     echo Automated renewal failed:
     cat /var/log/letsencrypt/renew.log
     exit 1
fi

加入cron,每两个月的15号凌晨12点30分执行

crontab -e
# 加入如下内容
30 0 15 */2 * sh /var/scripts/renewal.sh

相关问题

  • redirected you too many times

如果是rails项目,在启用ssl后,需要将 proxy_set_header X-Forwarded-Proto http; 改为 proxy_set_header X-Forwarded-Proto $scheme;

相关参考

相关工具和测试网站