django HTTPS访问

最近开发的一个django项目要求必须通过安全检测,必须采用https访问,因此,进行https相关的学习

1. ssl证书获取

由于商业证书要付费获取,这里采用openssl进行自签证书的获取。
在linux上安装openssl

yum install openssl -y

采用openssl获取证书,证书默认生成位置:/root

openssl
# 首先生成虚构的CA认证机构
genrsa -des3 -out ca.key 1024
rsa -in ca.key -out ca.key
req -new -x509 -key ca.key -out ca.crt -days 365
# 接着使用虚拟的CA认真机构生成证书
genrsa -des3 -out server.key 1024
req -new -key server.key -out server.csr
x509 -req -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt -days 365

2. 将证书添加到chrome浏览器

【设置】-【隐私设置和安全性】-【安全】-【管理证书】,将server.crt导入

django HTTPS访问_第1张图片

3. 开启django HTTPS服务

把server.crt、server.key证书复制到manage.py同级目录下
在settings.py中配置

SECURE_SSL_REDIRECT = True
INSTALLED_APPS = [
	...,
	'werkzeug_debugger_runserver',
    'django_extensions',
]

安装相关依赖

pip3 install --upgrade pip -i https://mirrors.aliyun.com/pypi/simple
pip3 install django-extensions -i https://mirrors.aliyun.com/pypi/simple
pip3 install django-werkzeug-debugger-runserver -i https://mirrors.aliyun.com/pypi/simple
pip3 install pyOpenSSL -i https://mirrors.aliyun.com/pypi/simple

启动django

python3 manage.py runserver_plus --cert server.crt 0.0.0.0:8001

然而,在浏览器打开网页的时候,报错静态文件找不到,404。在这里插入图片描述
尝试采用另一个插件django-ssl

pip3 install django-sslserver==0.22

在settings.py中配置

SECURE_SSL_REDIRECT = True
INSTALLED_APPS = [
	...,
	'sslserver',
]

启动django,仍然报同样的静态文件404错误

python3 /opt/web/manage.py runsslserver 0.0.0.0:8001

考虑到生产环境部署时应当采用nginx来处理静态文件,尝试nginx+uwsgi部署

4. nginx+uwsgi开启django HTTPS服务

下载nginx镜像,在宿主机上建如图4个目录,

docker pull nginx

在宿主机上创建如下4个目录

在这里插入图片描述
创建容器,将容器中的conf、html目录复制到宿主机上

docker run -d -p 80:80 --name nginx nginx
docker cp nginx:/etc/nginx/nginx.conf /opt/nginx/conf
docker cp nginx:/etc/nginx/conf.d /opt/nginx/conf
docker cp nginx:/usr/share/nginx/html /opt/nginx

关闭并删除已创建的nginx容器,将django中的静态文件dist放到html目录下,配置conf.d中的default.conf文件

# https版
server {
    listen       80;
    listen  [::]:80;
    # 这里有域名写域名,没有域名我写了ip地址
    server_name  <ip>;
	# 开启https服务时,需要进行http的重定向
	rewrite ^(.*) https://$server_name$1 permanent;
	
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

# 不开启https服务时,可以直接注释这个server
server {
    listen       443 ssl;
    # 这里有域名写域名,没有域名我写了ip地址
    server_name  <ip>;
 	# 这里指定ssl文件中的证书和key的位置
    ssl_certificate      /etc/nginx/ssl/development.crt;
    ssl_certificate_key  /etc/nginx/ssl/development.key;
 
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
 
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;
 
    location / {
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   Host              $http_host;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        # 静态文件地址
        root   /usr/share/nginx/html/dist;
        index  index.html index.htm;
        # uwsgi地址,ip根据实际情况填写
		uwsgi_pass  <ip>:8001;
		include     uwsgi_params;
    }
 
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
# http版
# 实现负载均衡
upstream web {
    server <ip1>:8000;
    # 多ip
    # 若某一节点故障,从探查到故障的时刻开始,0-fail_timeout内,该节点会被排除
    # server :8001 max_fails=1 fail_timeout=604800s;
    # server :8002 max_fails=1 fail_timeout=604800s;
    # 一定时间内同一个客户端的请求,由同一个节点处理
    # ip_hash
}
server {
    listen       80;
    listen  [::]:80;
    server_name  10.30.239.195;
    	
    location / {        
        root   /usr/share/nginx/html/dist;
	    index  index.html index.htm;
        include     uwsgi_params;
        uwsgi_pass  web;
    }
    # 指定静态文件路径
    # 否则会出现"GET /static/css/chunk-f660d60c.71ab5669.css HTTP/1.1" 404这样的静态资源访问错误
    location /static {
        # 指定静态文件存放的目录
        alias /usr/share/nginx/html/dist;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

采用如下命令重新创建nginx容器,注意此处80(http)、和443(HTTPS)端口都要开启。

docker run -p 443:443 -p 80:80 --name nginx -v /opt/web/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /opt/web/nginx/conf/conf.d:/etc/nginx/conf.d -v /opt/web/nginx/log:/var/log/nginx -v /opt/web/nginx/html:/usr/share/nginx/html -v /opt/web/nginx/ssl:/etc/nginx/ssl/ -d nginx:latest

在生产环境中是这样的逻辑关系,个人理解:wsgi 是后端 http 服务器,nginx 是前端 http 服务器,django项目是客户所真正要访问到的提供数据方。因此还需要采用uwsgi来启动django
client–>NGINX–>uwsgi–>django

创建web容器

docker run -ti -p 8000:8000 -v /opt/145_graph/web:/opt/web --name 145_web_1 --privileged=true -t web:0 /bin/bash

在django项目的manage.py同级目录下创建uwsgi.ini文件,配置如下,启动命令

# 启动
uwsgi /opt/web/uwsgi.ini
# 停止
uwsgi --stop /opt/web/logs/uwsgi.pid
# 也可以通过kill进程方式停止
pkill -f uwsgi -9
[uwsgi]
; 监听的端口
; http = 0.0.0.0:8001

; 指定和nginx进行套接字通信的方式:端口或文件
socket = :8001

; 项目所在目录,和manage.py同级
chdir = /opt/web

; 主应用中的wsgi文件
wsgi-file = src/wsgi.py

; 代理静态资源:路径映射
static-map = /static=/opt/web/static

; 启动一个master进程,来管理其余的子进程
master=True
processes = 4
threads = 2
buffer-size = 65536

; 保存主进程的pid,用来控制uwsgi服务
pidfile=/opt/web/logs/uwsgi.pid

; 设置后台运行,保存日志
daemonize=/opt/web/logs/uwsgi.log

; 设置每个工作进程处理请求的上限,达到上限时,将回收(重启)该进程。可以预防内存泄漏
max-requests=5000

; 服务停止时自动移除unix Socket和pid文件
vacuum=true

如果uwsgi没有正确启动,打开网页的时候,nginx的error.log会报错
在这里插入图片描述
nginx和uwsgi启动完毕后,打开网页,https://,访问正常

你可能感兴趣的:(https,网络协议,http)