您现在的位置是:首页 > 技术笔记 网站首页技术笔记

No.55 Django:部署成功项目升级为HTTPS

Django  
简介Django部署一条龙之HTTPS实现。

一、Let’s Encrypt免费证书

1.预先工作

在创建证书之前,在项目根目录下(manage.py文件所在目录)创建文件夹:/.well-know,在改文件夹下创建文件:acme-challenge。

2.配置Nginx

安装完Certbot 之后,需要简单配置Nginx以便Let's Encrypt能起作用。

编辑配置文件

sudo vim /etc/nginx/conf.d/addcoder.conf

示例

# 网站配置
server {
    # 设置监听端口
    listen 80;
    # 设置对外访问入口,可以是域名可以是公网IP
    server_name addcoder.com www.addcoder.com;
    # 设置虚拟主机的基本信息
    location / {
        include uwsgi_params;
        uwsgi_pass 127.0.0.1:8855;
        uwsgi_read_timeout 5;
    }
    # 静态文件设置
    location /static {
        expires 30d;
        alias /srv/addcoder/static/;
    }
    # 创建Let’s Encrypt免费SSL证书临时文件
    location /.well-known/acme-challenge {
        alias /srv/addcoder/.well-known/acme-challenge;
    }
    # 允许网段
    allow all;
    # 设置访问的语言编码
    charset UTF-8;
    # nginx的超时参数设置为60秒
    send_timeout 60;
    # 实IP在X-Forwarded-For请求头中
    real_ip_header X-Real-IP;
    # X-Forwarded-For请求头中的最后一个IP当成真实IP
    real_ip_recursive off;
    # 设置fastcgi缓冲区为8块128k大小的空间
    fastcgi_buffers 8 128k;
    # 上传文件大小限制,默认1m
    client_max_body_size 0;
    # 访问日志记录
    access_log /var/log/nginx/addcoder_access.log;
    # 错误日志记录
    error_log /var/log/nginx/addcoder_error.log;
    # 开启gzip
    gzip on;
    # 是否在http header中添加Vary:Accept-Encoding
    gzip_vary on;
    # 设置压缩所需要的缓冲区大小
    gzip_buffers 32 4K;
    # gzip 压缩级别,1-9,数字越大压缩的越好,也越占用CPU时间
    gzip_comp_level 5;
    # 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
    gzip_min_length 100;
    # 配置禁用gzip条件,支持正则
    gzip_disable "MSIE [1-6]\.";
    # 进行压缩的文件类型
    gzip_types application/javascript text/css text/xml;
    # HTTP严格传输安全的 max-age 需要大于15768000秒
    add_header Strict-Transport-Security "max-age=31536000";
    # 配置nginx404错误配置
    error_page 404  /404.html;
    location = /404.html {
        root /usr/share/nginx/html;
    }
    # 配置nginx502错误配置
    error_page 502  /502.html;
    location = /502.html {
        root /usr/share/nginx/html;
    }
}

3.重启nginx,以便生效

# centos7
systemctl restart nginx

# Ubuntu16.04
/etc/init.d/nginx restart

4.安装certbot

# centos7
yum install -y certbot

# Ubuntu16.04
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot

5.签发 SSL 证书

两种生成证书的方式

  • andalone

certbot 会启动自带的 nginx(如果服务器上已经有nginx或apache运行,需要停止已有的nginx或apache)生成证书。

certbot certonly --standalone -d addcoder.com -d www.addcoder.com
  • webroot(推荐)
certbot certonly --webroot -w /srv/addcoder -d addcoder.com -d www.addcoder.com

-w:指定项目绝对路径。

-d:指定生成证书域名,不可以直接写IP。

这条命令的输出类似于这样(有Congratulations)为成功。

证书位置 /etc/letsencrypt/live/addcoder.com/fullchain.pem

私钥位置 /etc/letsencrypt/live/addcoder.com/privkey.pem

6.如果遇到 ImportError: No module named 'requests.packages.urllib3' 报错

  • 原因

requests库版本问题

  • 解决方法
pip install --upgrade --force-reinstall 'requests==2.6.0'

7.生成前向安全性密钥

cd /etc/letsencrypt/live
openssl dhparam 2048 -out dhparam.pem

8.其他证书

腾讯云免费ssl证书

阿里云免费ssl证书

将下载的证书复制到Nginx安装目录下的cert目录(需要新建),然后参照上述步骤。

二、将https配置进Nginx

1.配置

# 将IP重定向到域名
server {
    listen 80;
    listen 443;
    server_name 47.241.190.116;
    return 301 https://www.addcoder.com;
}

# 网站配置
server {
    # 设置监听端口
    listen 80;
    # 设置监听端口,开启https、http2,默认端口
    listen 443 ssl http2 default;
    # 设置对外访问入口,可以是域名可以是公网IP
    server_name addcoder.com www.addcoder.com;
    # HTTP请求301永久跳转到HTTPS
    if ($server_port = 80) {
        return 301 https://$server_name$request_uri;
    }
    # 设置虚拟主机的基本信息
    location / {
        include uwsgi_params;
        uwsgi_pass 127.0.0.1:8855;
        uwsgi_read_timeout 5;
    }
    # 静态文件设置
    location /static {
        expires 30d;
        alias /srv/addcoder/static/;
    }
    # 创建Let’s Encrypt免费SSL证书临时文件
    location /.well-known/acme-challenge {
        alias /srv/addcoder/.well-known/acme-challenge;
    }
    # session会话的缓存类型和大小
    ssl_session_cache shared:SSL:10m;
    # ession会话的超时时间
    ssl_session_timeout 10m;
    # 依赖SSLv3和TLSv1协议的服务器密码将优先于客户端密码
    ssl_prefer_server_ciphers on;
    # 证书位置
    ssl_certificate /etc/letsencrypt/live/addcoder.com/fullchain.pem;
    # 私钥位置
    ssl_certificate_key /etc/letsencrypt/live/addcoder.com/privkey.pem;
    # 前向安全性,DH-Key交换密钥文件位置
    ssl_dhparam /etc/letsencrypt/live/dhparam.pem;
    # PCI DSS支付卡行业安全标准,禁用不安全的SSLv1 2 3,只使用TLS,PCI安全标准委员会规定开启TLS1.0将导致PCI DSS不合规
    ssl_protocols TLSv1.1 TLSv1.2;
    # 需要配置符合PFS规范的加密套件
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;
    # 允许网段
    allow all;
    # 设置访问的语言编码
    charset UTF-8;
    # nginx的超时参数设置为60秒
    send_timeout 60;
    # 实IP在X-Forwarded-For请求头中
    real_ip_header X-Real-IP;
    # X-Forwarded-For请求头中的最后一个IP当成真实IP
    real_ip_recursive off;
    # 设置fastcgi缓冲区为8块128k大小的空间
    fastcgi_buffers 8 128k;
    # 上传文件大小限制,默认1m
    client_max_body_size 0;
    # 访问日志记录
    access_log /var/log/nginx/addcoder_access.log;
    # 错误日志记录
    error_log /var/log/nginx/addcoder_error.log;
    # 开启gzip
    gzip on;
    # 是否在http header中添加Vary:Accept-Encoding
    gzip_vary on;
    # 设置压缩所需要的缓冲区大小
    gzip_buffers 32 4K;
    # gzip 压缩级别,1-9,数字越大压缩的越好,也越占用CPU时间
    gzip_comp_level 5;
    # 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
    gzip_min_length 100;
    # 配置禁用gzip条件,支持正则
    gzip_disable "MSIE [1-6]\.";
    # 进行压缩的文件类型
    gzip_types application/javascript text/css text/xml;
    # HTTP严格传输安全的 max-age 需要大于15768000秒
    add_header Strict-Transport-Security "max-age=31536000";
    # 配置nginx404错误配置
    error_page 404  /404.html;
    location = /404.html {
        root /usr/share/nginx/html;
    }
    # 配置nginx502错误配置
    error_page 502  /502.html;
    location = /502.html {
        root /usr/share/nginx/html;
    }
}

2.重启nginx,以便生效

# centos7
systemctl restart nginx

# Ubuntu16.04
/etc/init.d/nginx restart

三、Let’s Encrypt 续期

certbot renew

四、Let’s Encrypt 自动续期

Let’s Encrypt 的证书90天就过期了,所以,我们还需要设置自动化更新脚本。

# 编辑当前用户的定时作业
crontab -e

# 改变通知邮件目的地
MAILTO=820685755@qq.com

# 加入作业
00 10 * * 1 certbot renew --deploy-hook "systemctl restart nginx" >> /srv/log/certbot.log 2>&1
  1. 这里是每周一的10点00分尝试更新证书,如果证书在30天内到期,则会更新证书,否则不会更新

  2. --deploy-hook选项表示在更新成功以后才运行重载 nginx 的命令。

  3. crontab 六个字段含义:

    • minute: 表示分钟,(整数 0 -59)。

    • hour:表示小时,可以是从0到23之间的任何整数。

    • day:表示日期,可以是从1到31之间的任何整数。

    • month:表示月份,可以是从1到12之间的任何整数。

    • week:表示星期几,可以是从0到7之间的任何整数,这里的0或7代表星期日。

    • command:要执行的命令,可以是系统命令,也可以是自己编写的脚本文件。

    • 如果字段使用 * 号,则为满足其他字段约束的每月都执行该命令。