(2)配置 php-fpm 监听端口apt-get install php5 php5-cli php5-cgi php5-dev mysql-server php5-mysql php5-gd php5-mcrypt php5-curl php5-fpm
查看vim /etc/php5/fpm/php-fpm.conf
pid = /var/run/php5-fpm.pid
include=/etc/php5/fpm/pool.d/tanjiti.conf
error_log = /var/log/php5-fpm.log
cp /etc/php5/fpm/pool.d/www.conf /etc/php5/fpm/pool.d/tanjiti.conf
vim /etc/php5/fpm/pool.d/tanjiti.conf
启动[tanjiti]
;listen = 127.0.0.1:9000
listen = /var/run/php5-fpm.socklisten.owner = www-data
listen.group = www-data
listen.mode = 0660
/etc/init.d/php5-fpm start
编辑vim nginx/conf/nginx.conf
location ~ \.php$ {
root html;
#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
nginx/sbin/nginx -s reload
编辑vim nginx/conf/nginx.conf
(2)response bodylog_format main '$remote_addr [$time_local] $request_method "$request_uri" $status '
'"$query_string" "$http_user_agent" '
'"$http_referer" "$http_cookie" "$http_content_type" $content_length $body_bytes_sent '
'"$http_x_forwarded_for" '
'"$request_body" "$resp_body"';
access_log logs/access.log main;
编辑vim nginx/conf/nginx.conf
set $resp_body "";
lua_need_request_body on;
body_filter_by_lua_file ../lualib/logResponse.lua;
编写vim lualib/logResponse.lua
local chunk, eof = ngx.arg[1], ngx.arg[2]
local buffered = ngx.ctx.buffered
if not buffered then
buffered = {}
ngx.ctx.buffered = buffered
end
if chunk ~= "" then
buffered[#buffered + 1] = chunk
ngx.arg[1] = nil
end
if eof then
local whole = table.concat(buffered)
ngx.ctx.buffered = nil
ngx.arg[1] = whole
ngx.var.resp_body = ngx.arg[1]
end
http localhost:8085
xxx.xxx.xxx.xxx [22/Dec/2015:15:37:52 +0800] GET "/" 200 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36" "-" "_pk_id.7.ca22=490c960efd9ccf66.1434705267.0.1435055206.." "-" - 177 "-" "-" "<html><body><h1>It works!</h1>\x0A<p>This is the default web page for this server.</p>\x0A<p>The web server software is running but no content has been added, yet.</p>\x0A</body></html>\x0A"
第一步:配置nginx为代理模式
(1) 日志格式设置
vim nginx/conf/nginx.conf
编辑
log_format main '$remote_addr [$time_local] $request_method "$request_uri" '
'"$query_string" "$http_user_agent" '
'"$http_referer" "$http_cookie" "$http_content_type" $content_length ''$status "$sent_http_content_type" $body_bytes_sent '
'"$proxy_add_x_forwarded_for" "$http_via" '
'"$upstream_http_server<||>$upstream_http_x_powered_by" '
'"$upstream_http_location" "$upstream_addr" "$upstream_status" "$upstream_response_time" '
'"$request_body" $attack_type($rule_id) $ban_type($waf_duration) "$resp_body"';
其中以下变量,是用于标记请求行为来进行有条件的记录response body
$attack_type: e.g. SQLI
$rule_id e.g. 0001
$ban_type e.g. BAN
$waf_duration 检测模块花费时间,用于计算访问控制模块性能的时间花费
(2)配置代理模式
p.s. 当然这是waf简化版本,去掉了最关键的cache设置(加速)与访问控制(安全)
vim nginx/conf/nginx.conf
编辑
#访问控制,标签请求行为
set $attack_type "NONE";
set $rule_id "";
set $ban_type "NONE";
set $waf_duration "0";
access_by_lua '
local waf = require "waf-runner"
waf.execute()
';
#记录response body
set $resp_body "";
lua_need_request_body on;
body_filter_by_lua_file ../lualib/logResponse.lua;
location / {
proxy_http_version 1.1; # enable chunked
proxy_set_header Host $host:$server_port;
proxy_set_header Accept-Encoding ""; #否则Accept-Encoding为gzip时返回是gzip编码的数据
proxy_set_header Connection "";# keep alive
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://127.0.0.1:8080; #upstream的地址,云waf一般会使用redis动态配置来维持地址表
proxy_buffering on;
proxy_buffer_size 16k;
proxy_buffers 64 16k;
proxy_busy_buffers_size 32k;
proxy_max_temp_file_size 10240m;
proxy_temp_file_write_size 16k;
proxy_temp_path /var/log/nginx/proxy_temp;
proxy_intercept_errors on;
proxy_ignore_client_abort on;
proxy_connect_timeout 10;
proxy_read_timeout 600; # default is 60s
proxy_send_timeout 600; # default is 60s
proxy_redirect off;
proxy_ssl_session_reuse off;
}
(3) 设置有条件的记录response body
vim lualib/logResponse.lua
编辑
local MAX_LOGED_LENGTH = 10485760 -- 10M
local attack_type = ngx.var.attack_type
local sent_http_content_type = ngx.var.sent_http_content_type
local chunk, eof = ngx.arg[1], ngx.arg[2]
local buffered = ngx.ctx.buffered
if string.find(sent_http_content_type, "text",1,true) and attack_type == "填写需要记录的类型" then
if not buffered then
buffered = {}
ngx.ctx.buffered = buffered
end
if chunk ~= "" then
buffered[#buffered + 1] = chunk
ngx.arg[1] = nil
end
if eof then
local whole = table.concat(buffered)
ngx.ctx.buffered = nil
ngx.arg[1] = whole
if #ngx.arg[1] > MAX_LOGED_LENGTH then
ngx.var.resp_body = string.sub(ngx.arg[1], 1, MAX_LOGED_LENGTH)
else
ngx.var.resp_body = ngx.arg[1]
end
end
end
第二步:测试
例如记录phpmyadmin的访问细节
http localhost:8085/phpmyadmin -v
127.0.0.1 [23/Dec/2015:13:20:53 +0800] GET "/phpmyadmin" 301 "-" "HTTPie/0.9.0-dev" "-" "-" "-" - 318 "127.0.0.1" "-" "Apache/2.2.22 (Ubuntu)<||>-" "http://localhost:8085/phpmyadmin/" "127.0.0.1:8080" "301" "0.002" "-" logbody(221) LOG(48) "<!DOCTYPE HTML PUBLIC \x22-//IETF//DTD HTML 2.0//EN\x22>\x0A<html><head>\x0A<title>301 Moved Permanently</title>\x0A</head><body>\x0A<h1>Moved Permanently</h1>\x0A<p>The document has moved <a href=\x22http://localhost:8085/phpmyadmin/\x22>here</a>.</p>\x0A<hr>\x0A<address>Apache/2.2.22 (Ubuntu) Server at localhost Port 8085</address>\x0A</body></html>\x0A"
修改nginx配置文件connect() to unix:/var/run/php5-fpm.sock failed (13: Permission denied) while connecting to u
pstream
编辑user指令vim nginx/conf/nginx.conf
user www-data www-data;
修改nginx配置文件FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream
编辑fastcgi_param指令vim nginx/conf/nginx.conf
参考 http://lovelace.blog.51cto.com/1028430/1314565fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
当开启nginx proxy模式的时候,如果发送请求中采用gzip编码,则采用以上方法记录的response body不可读
127.0.0.1 [22/Dec/2015:17:18:29 +0800] GET "/index.php" 404 "-" "HTTPie/0.9.0-dev" "-" "-" "-" - 236 "-" "-" "\x1F\x8B\x08\x00\x00\x00\x00\x00\x00\x03M\x8FOK\xC40\x10\xC5\xEF\xFD\x14\xE3\x9E\xF4`&-\x0B\xEE!\x04t\xDB\xC5\x85\xBA\x16M\x0F\x1E\xB3f$\x855\xA9I\xEA\x9Foo\xDAE\x90\x07\x033\xF3~\xC3\x1BqQ?n\xD5K\xD7\xC0\xBDzh\xA1\xEB\xEF\xDA\xFD\x16V\xD7\x88\xFBF\xED\x10kU\x9F7\x15\xE3\x88\xCDa%\x0Ba\xD3\xFBI\x0AK\xDA\xE4&\x0D\xE9Dr\xCD\xD7p\xF0\x09v~rF\xE0yX\x08\x5CL\xE2\xE8\xCD\xCF\xCC\x95\xF2\x9F'w\x85\x18\xA5\xB2\x04\x81>&\x8A\x89\x0C\xF4O-\xE0\xE0\x0C}\xB3\xD1\x8E\xF0\xA5#\xB8\x8C\xBC\xCD\x08x\x07\xC9\x0E\x11\x22\x85O\x0AL\xE08\x1F\x0D\xB9hc\x02\xC5(oG\xFDj\x09+\x96U\xC1e\x7F\x9C\x5C\x9A\xAE\xE0y\x01@'(\xAB\x1B\xC6\xB3J\xE8|H\xB0\xE1\x1B.\xF0\x8F\xCEy\x97\xA49\xDB\xFCa\xF1\x0B\xC8\xD5\xF63\x1C\x01\x00\x00"
vim /etc/modsecurity/modsecurity.conf
第三步:编辑记录规则SecResponseBodyAccess On
SecAuditEngine RelevantOnly
SecAuditLogParts ABCDEFGHIJKZ #全记录
SecAuditLogType Serial
SecAuditLog /var/log/apache2/modsec_audit.log
vim /etc/modsecurity/my.conf
SecRule "REQUEST_FILENAME" "@contains phpmyadmin" "phase:1,auditlog,pass,t:lowercase,log,tag:'just for test',msg:'just for test',id:0000001"
http localhost:8085/phpmyadmin
--a3bef27a-B--
GET /phpmyadmin/ HTTP/1.1
Host: xxx.xxx.xx:8080
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
Cookie: pma_lang=zh_CN; pma_collation_connection=utf8_general_ci; phpMyAdmin
=kegrv6adlm9oae5tgvoeg61sjcjo62mk; pma_navi_width=200; _pk_id.7.ca22=490c960efd9ccf66.1434705267.0.1435055206..
If-Modified-Since: Sat, 18 Feb 2012 12:26:45 GMT
--a3bef27a-F--
HTTP/1.1 200 OK
X-Powered-By: PHP/5.3.10-1ubuntu3.21
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Last-Modified: Sat, 18 Feb 2012 12:26:45 GMT
Set-Cookie: pmaPass-1=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/phpmyadmin/
Pragma: no-cache
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 2492
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
--a3bef27a-E--
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh" lang="zh" dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="icon" href="./favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" />
<title>phpMyAdmin </title>
<link rel="stylesheet" type="text/css" href="phpmyadmin.css.php?server=1&token=4cc02ab2aad2355a5213b7f80f752bbb&js_frame
=right&nocache=3988383895" />省略
--a3bef27a-H--
Message: Warning. String match "phpmyadmin" at REQUEST_FILENAME. [file "/etc/modsecurity/my.conf"] [line "1"] [id "0000001"] [msg "j
ust for test"] [tag "just for test"]
Apache-Handler: application/x-httpd-php
Stopwatch: 1450855051967581 66146 (- - -)
Stopwatch2: 1450855051967581 66146; combined=201, p1=165, p2=27, p3=1, p4=1, p5=7, sr=0, sw=0, l=0, gc=0
Response-Body-Transformed: Dechunked
Producer: ModSecurity for Apache/2.6.3 (http://www.modsecurity.org/).
Server: Apache/2.2.22 (Ubuntu)
--a3bef27a-K--
SecRule "REQUEST_FILENAME" "@contains phpmyadmin" "phase:1,auditlog,pass,t:lowercase,log,tag:'just for test',msg:'just for test',id:0000001"
--a3bef27a-Z--