使用 docker 构建本地 lnmp 开发环境(Mac)

最近给个人的 mac 重装了系统,所有的配置全部没有了。对 Mac 下的 PHP 不同语言的环境切换还是很头疼的。这篇文章将介绍我使用 docker 部署本地 lnmp 开发环境的整个过程,可以结合我的 github 提交历史了解。业务涉及的知识点有 openresty、php 7.1、laravel、composer、postgresql、redis 等。

本项目也已经开源在 github 上,可以简单使用 docker-compose up -d 命令直接运行起来。

架构

这套环境由前端 openresty 接收请求,通过 linux sock 的方式传给 php-fpm,php-fpm 解析 php 代码,并连接数据库 postgresql 和 redis。

openresty 模块要做好配置文件,与 php-fpm 进行对接。

php-fpm 模块,需要事前编译 postgresql 扩展包。也要做好配置文件,与 openresty 对接。同时代码运行也需要提前使用 composer 进行依赖包的安装,并做好与 postgresql 的配置对接。

postgresql 模块需要准备好 dump 文件,用于首次运行的数据库准备工作。如有需要还要编辑postgresql的配置文件,比如打开慢日志、外部连接等配置。

相关的日志文件保存到 log 文件夹下。

对应的 docker-compose.yml 文件如下:

version:  '3.0'
services:
  nginx:
    image: openresty/openresty:alpine
    volumes:
      - $MYWORKSPACE:/var/www/html
      - ./openresty:/etc/nginx/conf.d
      - ./sock:/sock
      - ./log:/log
    links:
      - "php:php"
    ports:
      - "8000:80"

  php:
    build: ./php
    volumes:
      - $MYWORKSPACE:/var/www/html
      - ./php/php-fpm.d:/usr/local/etc/php-fpm.d
      - ./php/conf/php-fpm.conf:/usr/local/etc/php-fpm.conf
      - ./sock:/sock
      - ./log:/log
    links:
      - "pgsql:pgsql"

  pgsql:
    image: postgres:9.4-alpine
    volumes:
      - ./psql/data:/var/lib/postgresql/data
      - ./psql/dump:/var/lib/postgresql/dump
    ports:
      - "5432:5432"

openresty

基于 laravel 的写法,主要注意点在于 fastcgi 使用 sock 的方式,对提高 php 性能很有帮助。

server {
    listen       80;

    access_log off;
    error_log off;

    root         /var/www/html/public;

    location = / {
        fastcgi_pass                               unix:/sock/www.sock;
        fastcgi_index                              index.php;
        include                                    fastcgi.conf;
    }

    location = /_status {
        fastcgi_pass                               unix:/sock/www.sock;
        include                                    fastcgi.conf;
        fastcgi_param           SCRIPT_NAME        /_status;
    }

    location / {
        # URLs to attempt, including pretty ones.
        try_files   $uri $uri/ /index.php?$query_string;
    }

    # Remove trailing slash to please routing system.
    if (!-d $request_filename) {
        rewrite     ^/(.+)/$ /$1 permanent;
    }

    location ~* ^(.+\.php)(.*)$ {
        # limit_req zone=req_perip burst=8;
        fastcgi_pass                               unix:/sock/www.sock;
        fastcgi_split_path_info                    ^(.+\.php)(.*)$;
        include                                    fastcgi.conf;
    }

    location /nginx_status {
       stub_status on;
       access_log off;
    }
}

php-fpm

我使用的是 postgresql 数据库,官方默认没有带有 postgresql 的扩展,需要自行编译。官方专门为容器提供了三个的命令,用来简化扩展的安装: docker-php-ext-configuredocker-php-ext-install, 和 docker-php-ext-enable 。具体使用可以查看 Dockerfile:

FROM php:7.1-fpm

RUN apt-get update

RUN apt-get install -y libpq-dev \
    && docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \
    && docker-php-ext-install pdo_pgsql pgsql

还有需要注意的是laravel 项目的依赖安装的工作。在这里我也是使用了容器进行处理。可以参考 test.sh 文件中的命令:

#!/bin/bash

MYWORKSPACE="/Users/kelu/workspace/wechat.kelu.org"

docker run -it --rm \
  -v $MYWORKSPACE:/app \
  composer:1.4.2 install --ignore-platform-reqs --no-scripts

postgresql

完成了前面两步,接下来开始安装 postgresql。

我目前还在使用 postgresql 9.4的版本,所以安装时指定了版本号。

postgresql 比较重要的两个配置文件我提取了出来,以方便修改:

  • ./psql/data/postgresql.conf
  • ./psql/data/pg_hba.conf

因为本地环境的原因我便偷懒了一会,首次运行后需要手动进入镜像还原数据库。按照标准的做法是做一个只运行一次用于还原数据库的镜像。

如何使用可以参考 psql 目录下的 readme 文件,主要步骤是:

  • 设定数据库管理员密码
  • 生成用户 abc 和 其管理的数据库 abc
  • 还原 dump 文件
  • 检验是否还原成功
su postgres
psql

\password postgres
CREATE USER abc WITH PASSWORD 'abc';
CREATE DATABASE abc OWNER abc;
GRANT ALL PRIVILEGES ON DATABASE abc to abc;

sudo -u postgres pg_restore -d abc abc.dump;

\l
\c abc
\d
\d account
\q

待办

redis 的内容待完成。

参考资料


恶意代码分析必备知识 - 简书

反病毒软件原理

  • 反病毒软件一般由扫描器、病毒库和虚拟机组成,并由主程序将它们整合为一体
  • 一般情况下,扫描器用于查杀病毒,是反病毒软件的核心。一个反病毒软件的效果好坏直接取决于扫描器的技术与算法是否先进
  • 病毒库中存储着病毒所具有的独一无二的特征字符,我们称之为“特征码”,而病毒库存储特征码的存储形式则取决于扫描器采用哪种扫描技术
  • 特征码可能存在于任何文件中,例如exe文件、dll文件、apk文件、php文件、甚至是TXT文件中,所以它们都有可能被查杀。
  • 虚拟机,可以使病毒在一个反病毒软件构建的虚拟机环境中执行,这样就与现实的cpu、硬盘等物理设备完全隔离,从而可以更加深入的检测文件的安全性

常见的防病毒技术(基于文件扫描)

基于文件扫描的反病毒技术可以分为: “第一代扫描技术” “第二代扫描技术” “算法扫描” 对于恶意代码分析师来说,非常有必要对每一种扫描技术有所了解

第一代扫描技术可以用“在文件中检索病毒特征序列”这句话高度概括,这一扫描技术直到现在也仍然被各大反病毒软件厂商使用着,其主要分为“字符串扫描技术”与“通配符扫描技术”两种。

第二代扫描技术的代表有

  • 智能扫描法
  • 近似精确识别法
  • 骨架扫描法
  • 精确识别法

智能扫描法

这种方法是在大量变异病毒出现后提出的。智能扫描法会忽略检测文件中像nop这种无意义的指令。而对于文本格式的脚本病毒或者宏病毒,则可以替换掉多余的格式字符,例如空格,换行符,制表符等。由于这一切替换动作往往是在扫描缓冲区中执行的,从而大大提高了扫描器的检测能力

近似精确识别法

多套特征码

该方法采用两个或者更多的字符集来检测每一个病毒,如果扫描器检测到其中一个特征符合,那么就会警告发现变种,但不会执行下一步操作。如果多个特征码全部符合,则报警发现病毒,并执行下一步操作


库与检测算法 AC/BM 原理

ACBM算法:

ACBM算法是在AC自动机的基础之上,引入了BM算法的多模扩展,实现的高效的多模匹配。和AC自动机不同的是,ACBM算法不需要扫描目标文本串中的每一个字符,可以利用本次匹配不成功的信息,跳过尽可能多的字符,实现高效匹配。

比如:{P} = {her,where,redo},匹配过程如下:

img

img

img

img

img

可以看到在匹配步骤如下:

1、  选定一个匹配起始位置。

2、  使用AC树进行匹配,如果匹配失效,跳转步骤1;如果匹配成功,可根据应用需要跳转至步骤1或者退出。

ACBM算法的核心思想就是让每次匹配的起始位置跨度尽可能的大,以提高效率。

上例中,采用的是整体上正向匹配+反向的AC自动机;可以采用整体上反向的匹配+正向的AC自动机。

ACBM算法中的AC算法部分比AC自动机算法的实现要简单,不需要考虑失效函数的问题,也就是说ACBM算法中实现的AC算法部分是一棵树,而在AC自动机的实现是一个图。

ACBM算法中的BM算法的实现要比BM算法本身的实现要复杂一些,因为这是对BM算法的多模式一种扩展。

ACBM算法中的核心数据结构:

1、  MinLen,模式串集合中最短那个模式串的长度:比较失配时最多跳跃的字符个数不能超过Minlen。

2、  ACTree,由模式串集合构建出的状态树,构建方法和AC自动机的构建方法相同,而且不需要计算失效函数,比较简单。

3、  BCshift[256]:ACTree对应一个坏字符数组,当匹配失效时,查找该数组计算坏字符偏移量。

4、  GSshift:AC树的每一个节点对应一个好后缀偏移量。

ACBM算法的核心部分是计算BCshift和GSshift,可参考BM算法的实现

参考资料


开源协议的比较——GPL BSD MIT Apache

GPL

GPL,全称 GNU General Public License。

常说的传染性:只要在一个软件中使用(“使用”指类库引用或者修改后的代码) GPL 协议的产品,则该软件产品必须也采用GPL协议,既必须也是开源和免费。

采用这个协议的开源软件有:Linux、 MySQL。

BSD

全称 Berkeley Software Distribution。

这个协议允许使用者修改和重新发布代码,也允许使用或在BSD代码基础上开发商业软件发布和销售,因此是适用于商业软件的。

使用时需要满足三个条件:

  1. 如果再发布的产品中包含源代码,则在源代码中必须带有原来代码中的BSD协议。
  2. 如果再发布的只是二进制类库/软件,则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。
  3. 不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。

适用BSD协议的开源软件有: nginx、CruiseControl、Redis。

MIT

MIT,源自麻省理工学院(Massachusetts Institute of Technology, MIT),又称X11协议。MIT与BSD类似,但是比BSD协议更加宽松,是目前最少限制的协议。

这个协议唯一的条件就是在修改后的代码或者发行包包含原作者的许可信息。

使用MIT的软件项目有:Node.js, jQuery.NET Core, 和 Rails .

Apache License 2.0

比起 BSD,Apache License 2.0 除了为用户提供版权许可之外,还有专利许可,使用者可以获得永久授权,修改时需要放置版权说明。

  1. 需要给代码的用户一份 Apache Licence。
  2. 如果你修改了代码,需要再被修改的文件中说明。
  3. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议,商标,专利声明和其他原来作者规定需要包含的说明。
  4. 如果再发布的产品中包含一个Notice文件,则在Notice文件中需要带有Apache Licence。你可以在Notice中增加自己的许可,但不可以表现为对Apache Licence构成更改。

它还有这些好处:

  1. 永久权利 一旦被授权,永久拥有。
  2. 全球范围的权利 在一个国家获得授权,适用于所有国家。假如你在美国,许可是从印度授权的,也没有问题。
  3. 授权免费 无版税, 前期、后期均无任何费用。
  4. 授权无排他性 任何人都可以获得授权
  5. 授权不可撤消 一旦获得授权,没有任何人可以取消。比如,你基于该产品代码开发了衍生产品,你不用担心会在某一天被禁止使用该代码

使用apache Licence vesion 2.0协议的开源软件有:Android、 ApacheSwift 、Hadoop 、Spring Framework、MongoDB 。

举一个例子:

GitHub 上开源项目 SeaweedFS 的作者 Chris Lu 控诉京东 TigLab 项目涉嫌抄袭代码的事情在知乎上闹得沸沸扬扬。Chris Lu 发文表示京东的项目使用了他的源码,但是没有根据 Apache-2.0 协议的许可条款添加引用说明。

jd

最后给张图:

http://choosealicense.online/:

http://choosealicense.online/

参考资料


windows 命令行下用 netsh 实现端口转发(端口映射)

命令

netsh interface portproxy add/set/show/delete v4tov4/v4tov6/v6tov6/v6tov4

例子

增加

netsh interface portproxy add v4tov4 listenport=8080 connectaddress=192.168.56.101 connectport=8080

将本地的8080端口的数据转发至192.168.56.101上的8080端口。

netsh interface portproxy add v4tov4 listenport=9090 connectaddress=192.168.56.101 connectport=9090

将本地的9090端口的数据转发至192.168.56.101上的9090端口。

显示

netsh interface portproxy show all

修改

netsh interface portproxy set v4tov4 listenport=9090 connectaddress=192.168.56.101 connectport=9080

将本地9090端口改成转发至192.168.56.101的9080端口中。

删除

netsh interface portproxy delete v4tov4 listenport=9090

删除本地端口9090的端口转发配置。

参考资料