Nginx 访问日志记录 RespBody 响应内容

Nginx 本身可以通过 $request_body 变量记录请求内容,但响应内容需要通过 Lua 模块来记录:

步骤如下:

安装 LuaJIT:

wget http://luajit.org/download/LuaJIT-2.0.4.tar.gz
tar zxvf LuaJIT-2.0.4.tar.gz
cd LuaJIT-2.0.4
make
make install

安装 Lua:

yum install readline-devel
wget http://www.lua.org/ftp/lua-5.3.3.tar.gz
tar zxvf lua-5.3.3.tar.gz
cd lua-5.3.3
make linux
make install

安装 Nginx 开发包:

cd /usr/local
git clone https://github.com/simpl/ngx_devel_kit.git

安装 LuaNginx 模块:

cd /usr/local
git clone https://github.com/chaoslawful/lua-nginx-module.git

刷新动态库路径缓存:

# 使 ld.so.conf 立即生效
ldconfig --verbose

重新编译 Nginx,加入以下两个参数:

./configure \
    ...
    --add-module=/usr/local/ngx_devel_kit \
    --add-module=/usr/local/lua-nginx-module
make

# 平滑升级
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
\cp objs/nginx /usr/local/nginx/sbin/nginx
make upgrade

顺便说一下,如果用的是 lnmp1.3-full 一键包,则修改 /root/soft/lnmp1.3-full/lnmp.conf

Nginx_Modules_Options='--add-module=/usr/local/ngx_devel_kit --add-module=/usr/local/lua-nginx-module'

然后执行 cd /root/soft/lnmp1.3-full && ./upgrade.sh nginx,输入 1.10.2 一路回车就行。

编译完 Nginx 后,修改 /usr/local/nginx/conf/nginx.conf,在日志格式中增加 $resp_body 变量:

# 以 staylife 正在用的 `big_api` 格式示例(实际只加了最后一行):
log_format  big_api  '$remote_addr - $remote_user [$time_local] "$request" '
     '$status $body_bytes_sent "$request_body" "$http_referer" '
     '"$http_user_agent" $http_x_forwarded_for "appid=$http_appid,appver=$http_appver,vuser=$http_vuser" '
     '"phpsessid=$cookie_phpsessid,vuser_cookie=$cookie___vuser" '
     '"$resp_body"'
;

新增 /usr/local/nginx/conf/resp_body.conf 文件:

lua_need_request_body on;

set $resp_body "";
body_filter_by_lua '
    local resp_body = string.sub(ngx.arg[1], 1, 1000)
    ngx.ctx.buffered = (ngx.ctx.buffered or "") .. resp_body
    if ngx.arg[2] then
        ngx.var.resp_body = ngx.ctx.buffered
    end
';

修改对应的虚拟主机配置文件 /usr/local/nginx/conf/vhost/staylife.conf

在 PHP 这一段增加引入 resp_body.conf 文件,例如(加了最后一行):

location ~ [^/]\.php(/|$)
{
    fastcgi_pass  unix:/tmp/php-cgi.sock;
    fastcgi_index index.php;
    include fastcgi.conf;
    include pathinfo.conf;
    include resp_body.conf;
}

附:禁止记录 favicon.ico 的请求日志:

location = /favicon.ico {
    log_not_found off;
    access_log off;
}

如何升级 CentOS 的 OpenSSL 库

Nginx 开启 HTTP/2 要求 OpenSSL 库版本必须 1.0.2 以上(因为 1.0.1a~f 有安全威胁,虽然 1.0.1g 已修复)。除了在安装 Nginx 时临时指定 OpenSSL 源码路径外,我们也可以动手将 CentOS 系统自带的 OpenSSL 库升级,一劳永逸。

OpenSSL 官网:https://www.openssl.org

查看当前 OpenSSL 版本:

openssl version -a

先更新 zlib(提供压缩传输支持):

yum install -y zlib

然后开始下载安装 OpenSSL:

# 下载解压
wget https://www.openssl.org/source/openssl-1.0.2j.tar.gz
tar -zxvf openssl-1.0.2j.tar.gz
cd openssl-1.0.2j

# 编译安装
./config shared zlib-dynamic
make && make install

# 备份旧的版本
mv /usr/bin/openssl /usr/bin/openssl.old
mv /usr/include/openssl /usr/include/openssl.old

# 为新的版本建立软链
ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/ssl/include/openssl /usr/include/openssl

然后修改系统自带的 OpenSSL 库文件:

# 找到系统库位置(各种 Linux 版本都不同)
# CentOS 6.6 是在以下位置:`/usr/lib64/libssl.so`
find / -name 'libssl.so'

# 建立软链(因为 /usr/local/lib64/ 读取优先级高于 /usr/lib64/)
ln -s /usr/local/ssl/lib/libssl.so /usr/local/lib64/libssl.so

rm -f /usr/lib64/libssl.so
ln -s /usr/local/ssl/lib/libssl.so /usr/lib64/libssl.so

查看 OpenSSL 依赖库版本是否为 1.0.2j 了:

strings /usr/local/lib64/libssl.so | grep OpenSSL

更新可共享的动态链接库的搜索路径:

echo "/usr/local/ssl/lib" >> /etc/ld.so.conf

# 使 ld.so.conf 立即生效
# ldconfig 命令会重建缓存文件 `/etc/ld.so.cache`
# 参数 `-v` 或 `--verbose` 可以让 ldconfig 显示正在扫描的目录及搜索到的共享库
ldconfig --verbose

升级完成。再次看看版本是不是最新的了?

openssl version

参考文章:

SASS 和 Compass 用法小记

Compass 是 Sass 的工具库,用 Ruby 语言开发,所以安装之前,必须安装Ruby。 Sass 本身只是一个编译器,Compass 在它的基础上,封装了一系列有用的模块和模板,有点像 Javascript 和 jQuery、Ruby 和 Rails 的关系。

安装

# 更新 RubyGems
sudo gem update --system

sudo gem install -n /usr/local/bin sass
sudo gem install -n /usr/local/bin compass

注意务必增加 -n /usr/local/bin,否则安装时会遇到权限问题:

ERROR:  While executing gem ... (Errno::EPERM)
Operation not permitted - /usr/bin/sass

初始化

在父目录执行:

compass create myproject
cd myproject

或者进入已有目录后执行:

compass create init

会生成了一个 config.rb 和两个目录:

|-- config.rb       --- 配置文件
|-- sass/           --- 存放 sass 源文件
|-- stylesheets/    --- 编译后的 css 文件

配置文件 config.rb 的设置详见官方文档

编译

下划线开头的文件(例如 _common.scss)表示局部文件,只能被别的 scss 引用包含。本身不会被编译成单独的 scss 文件。

手动编译:

compass compile [path/to/project]

自动检测文件变化并自动编译:

compass watch [path/to/project]

生产环境需要压缩后的 css 文件,去除注释空行等:

compass compile --output-style compressed

Compass 只编译发生变动的文件,如果你要重新编译未变动的文件,使用 --force 参数:

compass compile --force

也可以通过指定环境配置,智能判断编译模式,修改 config.rb

environment = :development
output_style = (environment == :production) ? :compressed : :expanded

然后用以下命令编译:

compass compile -e production --force

内置模块

Compass 采用模块结构,内置五个模块。官网文档最佳实践

  • reset
  • css3
  • layout
  • typography
  • utilities

如何在自己的 scss 中引用?

@import "compass/reset";

除了模块,Compass 还提供一系列函数。比如 inline-image() 可以将图片转为 data 协议的数据。

@import "compass";
.icon { background-image: inline-image("icon.png"); }

编译后得到

.icon { background-image: url('data:image/png;base64,iBROR...QmCC');}

函数与 mixin 的主要区别是,不需要使用 @include 命令,可以直接调用。

参考文章:

Linux Crontab 拾遗笔记

介绍

Crontab 是一个用于设置周期性被执行任务(即计划任务)的工具。

  • 被周期性执行的任务:Cron Job
  • 周期性执行的任务列表:Cron Table

安装

# 主程序
yum install vixie-cron -y

# 用来安装、卸装、列举用来驱动 cron 守护进程的表格的程序
yum install crontabs -y

# 启动 crond 服务
service crond start|stop|status|try-restart|reload

检测服务状态

+ 方法1:crontab -l
+ 方法2:ps -elf | grep crond | grep -v "grep"
+ 方法3:service crond status

Crond 是什么?

Crond 是一个守护进程,每分钟会从配置文件中刷新并执行定时任务。 每分钟不仅要读一次 /var/spool/cron 内的所有文件,还需要读一次 /etc/crontab。

系统级计划任务 /etc/crontab

分 时 日 月 周 `用户名` /root/do.sh

用户级的计划任务 /var/spool/cron/用户名

# 编辑指定用户的任务表
# -u 缺省不写就代表当前用户
crontab -e [-u 用户名]

# 列举指定用户的任务表
crontab -l [-u 用户名]

# 清除指定用户的任务表
crontab -r [-u 用户名]

补充几点说明:

  1. 执行 crontab -e 实际上是修改文件 vi /var/spool/cron/用户名
  2. 执行 crontab 文件名 时,是直接导入覆盖任务表到 /var/spool/cron/用户名 中。
  3. /etc/cron.d/ 目录里的文件,可以认为是对系统配置的补充文件,会在 crond 运行时自动加载

使用者权限

  • 文件 /etc/cron.deny 中所列用户不允许使用 crontab 命令
  • 文件 /etc/cron.allow 中所列用户允许使用 crontab 命令

配置格式

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed

有趣的配置示例

# 奇数分钟执行
1-59/2 * * * * /root/do.sh

# 偶数分钟执行
*/2 * * * * /root/do.sh

# 表示第 1,3,5,7,9 分钟会执行,第11分钟不会执行
# 即先要满足条件 1~10,再满足逢 2
1-10/2 * * * * /root/do.sh

执行日志

可以通过看日志来知道任务有没有运行 tail -f /var/log/cron

ls /var/log/cron*

- cron(最新的日志文件)
- cron-20161030(截止到10月30日的日志文件)
- cron-20161106
- cron-20161113
- cron-20161120

容易犯错的点

1、环境变量读取

Crontab 执行任务调度时,不会加载任何环境变量,所以请在执行脚本中自己用 source 命令引入环境变量。

另外执行脚本中涉及文件路径时必须写绝对路径。

2、第3个参数(日)和第五个参数(周)是逻辑或的关系

# 四月的第一个星期日0点59分运行
# 注意 %w 百分号要用斜杠转义,因为 % 本身在 Crontab 里是换行的意思
59 0 1-7 4 * test `date +\%w` -eq 0 && /root/do.sh

# 错误的写法:
# 四月的 1~7 号或星期日0点59分运行
59 0 1-7 4 0 /root/do.sh

# 比较(0 真,1 假)
test 1 = 1

# 输出上一条命令的结果
echo $?

3、如何执行周期小于1分钟的任务?

# 每半分钟执行一次
# 写两遍:第1遍每分钟的0秒执行,第2遍虽然也是0秒开始,但会先睡30秒再真正执行脚本
*/1 * * * * /root/do.sh
*/1 * * * * sleep 30s; /root/do.sh

注意清理系统用户的邮件日志

每条任务调度执行完毕,系统都会将任务输出信息通过 mail 形式发送给当前系统用户 /var/spool/mail/用户名,日积月累,日志会很大,因此,将每条任务进行重定向忽略输出:

0 */3 * * * /root/do.sh >/dev/null 2>&1

如何选择 HTTPS/SSL 证书?

通常考虑的因素:

  • 是否支持多域名、泛域名
  • 价格
  • 信息泄露的保额
  • 厂商是国内还是国外
  • 证书在浏览器上显示的小图标样式

SSL证书分为四大类:

  • DV 证书
  • OV 证书
  • EV 证书
  • 自签名证书

自签名证书很少被部署到正式的网站上,一般是被用在内部的测试环境中,这里就不做介绍。

DV 证书

DV 证书即 Domain Validation Certificate。

用于验证一个或多个域名的所有权,无需递交纸质文件,仅验证域名管理权(即 whois 信息中的管理员邮箱验证),无需人工验证申请单位真实身份。

OV 证书

OV 证书即 Organization Validation CErtificate。 OV 证书用于验证此域名由特定组织或单位所拥有的域名,在 DV 证书的基础上,增加了企业认证信息。

申请此类证书,通过证书颁发机构审查网站企业身份和域名所有权以证明申请单位是一个合法存在的真实实体,CA 机构将在人工核实后签发证书。

DV 证书和 OV 证书在浏览器上显示的图标为:

EV 证书

EV 证书即 Extended Validation Certificate EV 证书是目前最高信任级别的证书,通过极其严格、苛刻的审查来验证网站企业身份和域名所有权,确保网站身份的真实可靠。一般会要求提供纸质材料。

例如 GitHub 采用的是 EV 证书,所以浏览器地址栏显示了企业名,并采用了目前最推荐的安全加密算法套件:TLS1.2(协议版本)+ ECDHE_RSA(密钥协商交换)+ AES_128_GCM(对称加密)。

EV 证书在浏览器上显示的图标为:

除了认证等级和显示图标的区别,三类证书在域名的支持性、价格、赔偿费用上也是不相同的。

总结下:

  • 如果是个人网站或初期的企业网站,可以选择 DV 证书
  • 如果是综合性的企业门户网站,可以选择 OV 证书
  • 如果是金融类的企业网站,域名需求没有那么多,可以选择 EV 证书

哪个SSL证书厂商是可以被信赖的?

SSL证书的厂商非常多,也没有绝对的好与坏之分。不过我们也可以从行业内影响力、历史安全问题、市场占有率等角度来评判。

这也是目前行业中比较公认的可信任厂商,可以看到前六名分别是:

  • Comodo
  • Symantec
  • Godaddy
  • GlobalSign
  • IdenTrust
  • DigiCert

个人博客网站,可以考虑以下免费 SSL 证书:

  • 阿里云 Symantec 免费证书(云盾-HTTPS证书)
  • 腾讯云 GeoTrust 免费证书 http://www.laozuo.org/8681.html
  • StartSSL
  • Let’s Encrypt
  • Namecheap

参考文章:

Linux sed 的日常用法

sed 全名 StreamEditor(流编辑器)用程序的方式来编辑文本,基本上就是正则匹配。

http://coolshell.cn/articles/9104.html