openresty 编译和WAF 组件安装配置

时间:2022-10-31 17:03:02

1.简介

Openresty 是在Nginx 的基础上集成开发了 Lua 语言实现高性能的扩展功能,在不降低原来Nginx 性能的情况下通过Lua 语言的功能增加诸如更细致的访问控制、集成数据库和缓存访问、web 应用安全访问等多种功能。

kong 微服务网关插件机制及常用指令  ​​https://blog.51cto.com/waringid/5800540​

kong 微服务网关配置指南  ​​https://blog.51cto.com/waringid/5793828​

使用Kong和Konga管理微服务和API  ​https://blog.51cto.com/waringid/5790671​

nginx配置指南之一  ​​https://blog.51cto.com/waringid/1438852​

nginx操作指南之二  ​https://blog.51cto.com/waringid/1441632​

nginx增加modsecurity模块  ​​https://blog.51cto.com/waringid/1629905​

也谈nginx的安全限制   ​​https://blog.51cto.com/waringid/1608666​

​利用Kong 的 request-transformer 插件重写 URL ​​​​https://blog.51cto.com/waringid/5803062​

Linux 系统生产环境配置指南 ​​https://blog.51cto.com/waringid/5782872​

2.Openresty 编译

2.1 编译Nginx

# pcre 正则库
$ wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.41.tar.gz
$ tar -zxf pcre-*.tar.gz
$ cd pcre-*
$ ./configure
$ make && sudo make install
# zlib gzip 库
$ wget http://zlib.net/zlib-1.2.11.tar.gz
$ tar -zxf zlib-1.2.11.tar.gz
$ cd zlib-1.2.11
$ ./configure
$ make && sudo make install
# openssl https库 注意官网代码是mac编译,建议如果失败,搜索一下openssl 编译
$ wget https://www.openssl.org/source/openssl-1.0.2l.tar.gz
$ tar -zxf openssl-*.tar.gz
$ cd openssl-*
$ ./config --prefix=/usr/local/openssl/
$ make && sudo make install
#主线和稳定二选一
# 主线版本

$ wget http://nginx.org/download/nginx-1.13.3.tar.gz
#稳定版本
$ wget http://nginx.org/download/nginx-1.12.1.tar.gz
$ tar zxf nginx-*.tar.gz
$ cd nginx-*
$ ./configure --prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_addition_module \
--with-http_auth_request_module \
--with-http_realip_module \
--with-http_slice_module \
--with-http_stub_status_module \
--with-http_sub_module \
--with-compat \
--with-file-aio \
--with-threads \
--with-stream \
--with-stream_realip_module \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-http_v2_module \
--with-http_ssl_module \
--with-pcre=../pcre-8.41 \
--with-zlib=../zlib-1.2.11 \
--without-http_autoindex_module \
--without-http_fastcgi_module \
--without-http_uwsgi_module \
--without-http_scgi_module \
--without-http_memcached_module \
--without-http_empty_gif_module
$ make && sudo make install
# 从官方标准参数中去除不用的模块,并新增了pcre和zlib模块
# 临时文件相关
#--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
#--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
#--http-scgi-temp-path=/var/cache/nginx/scgi_temp \
#--http-client-body-temp-path=/var/cache/nginx/client_temp \
#--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
# dav,媒体相关
#--with-http_dav_module \
#--with-http_flv_module \
#--with-http_mp4_module \
#随机首页,安全连接相关
#--with-http_random_index_module \
#--with-http_secure_link_module \
#email相关
#--with-mail \
#--with-mail_ssl_module \
#gcc相关
#--with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' \
#--with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'
#组,用户相关
#--user=nginx
#--group=nginx
#如果指定user和group 则通过此命令创建用户
#$ sudo adduser --system --no-create-home --shell /bin/false --group --disabled-login nginx
#如果用不到https,可以把ssl和http2模块也禁掉
#禁用未用模块,减少安全风险
#--without-http_autoindex_module \
#--without-http_fastcgi_module \
#--without-http_uwsgi_module \
#--without-http_scgi_module \
#--without-http_memcached_module \
#--without-http_empty_gif_module

$ nginx -t && nginx

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok

nginx: configuration file /etc/nginx/nginx.conf test is successful

2.2编译openresty

yum install openresty openresty-resty openresty-doc \
> openresty-opm openresty-debug openresty-pcre-devel openresty-openssl-devel \
> openresty-zlib-devel openresty-debug gcc gcc-c++ tree git elfutils-devel
wget https://openresty.org/download/openresty-1.15.8.1.tar.gz
git clone https://github.com/fdintino/nginx-upload-module
cd LuaJIT-2.1-20190507/
make clean
make&&make install
export LUAJIT_INC=/usr/local/include/luajit-2.1
export LUAJIT_LIB=/usr/local/lib
cd openresty-1.15.8.1/nginx-1.15.8.1
./configure --prefix=/usr/local/openresty/nginx \
--with-cc-opt='-O2 -DNGX_LUA_ABORT_AT_PANIC -I/usr/local/openresty/zlib/include -I/usr/local/openresty/pcre/include -I/usr/local/openresty/openssl/include' \
--add-module=../nginx-upload-module --add-module=../ngx_devel_kit-0.3.1rc1 --add-module=../echo-nginx-module-0.61 \
--add-module=../xss-nginx-module-0.06 --add-module=../ngx_coolkit-0.2 --add-module=../set-misc-nginx-module-0.32 \
--add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.08 --add-module=../srcache-nginx-module-0.31 \
--add-module=../ngx_lua-0.10.15 --add-module=../ngx_lua_upstream-0.07 --add-module=../headers-more-nginx-module-0.33 \
--add-module=../array-var-nginx-module-0.05 --add-module=../memc-nginx-module-0.19 --add-module=../redis2-nginx-module-0.15 \
--add-module=../redis-nginx-module-0.3.7 --add-module=../ngx_stream_lua-0.0.7 \
--with-ld-opt='-Wl,-rpath,/usr/local/openresty/luajit/lib -L/usr/local/openresty/zlib/lib -L/usr/local/openresty/pcre/lib -L/usr/local/openresty/openssl/lib -Wl,-rpath,/usr/local/openresty/zlib/lib:/usr/local/openresty/pcre/lib:/usr/local/openresty/openssl/lib' \
--with-pcre-jit --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_v2_module --without-mail_pop3_module \
--without-mail_imap_module --without-mail_smtp_module --with-http_stub_status_module --with-http_realip_module --with-http_addition_module \
--with-http_auth_request_module --with-http_secure_link_module --with-http_random_index_module --with-http_gzip_static_module \
--with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-threads \
--with-stream --with-stream_ssl_preread_module --with-http_ssl_module
make
vim nginx.conf

2.3配置nginx文件

worker_processes auto;
worker_rlimit_nofile 8192;
error_log logs/error.log error;
events {
use epoll;
worker_connections 8000;
}

http {
include mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 256;
client_header_buffer_size 256k;
large_client_header_buffers 4 256k;
client_max_body_size 200M;
client_body_buffer_size 256k;
sendfile on;
tcp_nopush on;
server_tokens off;
keepalive_timeout 65;
fastcgi_connect_timeout 600;
fastcgi_send_timeout 600;
fastcgi_read_timeout 600;
fastcgi_buffer_size 64k;
fastcgi_buffers 16 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript image/jpeg image/gif image/png;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
log_format mpos '{ "@timestamp": "$time_local", '
'"@fields": { '
'remote_addr: "$remote_addr", '
'body_bytes_sent: "$body_bytes_sent", '
'request_time: "$request_time", '
'status: "$status", '
'request: "$request", '
'request_method: "$request_method", '
'body_bytes_sent:"$body_bytes_sent", '
' upstream_addr: "$upstream_addr",'
' upstream_status: "$upstream_status",'
' upstream_response_time: "$upstream_response_time",'
'http_user_agent: "$http_user_agent" } }';
log_format json '$time_local - $remote_addr - $upstream_addr - $upstream_status';
lua_code_cache on;
lua_shared_dict limit_conn_store 100M;
lua_package_path "/usr/local/openresty/lualib/?.lua;;";
lua_package_cpath "/usr/local/openresty/lualib/?.so;;";
include vhost/*.conf;
}

2.4示例

upstream yunpan.myj.com.cn {
server 192.168.5.100:8000;
keepalive 6000;
}

server {
listen 80;
server_name yunpan.myj.com.cn;
rewrite ^(.*) https://$server_name$request_uri permanent;
}

server {
listen 443 ssl;
access_log logs/yunpan_access.log json;
server_name yunpan.myj.com.cn;
ssl_certificate /root/myj/214828708690016.pem;
ssl_certificate_key /root/myj/214828708690016.key;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

location / {
root html;
index index.html index.htm;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://yunpan.myj.com.cn;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Proto https;
proxy_read_timeout 1200s;
access_by_lua_file conf/vhost/access.lua;
}

location /seafhttp {
rewrite ^/seafhttp(.*)$ $1 break;
proxy_pass http://192.168.5.100:8082;
client_max_body_size 0;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 36000s;
proxy_read_timeout 36000s;
proxy_send_timeout 36000s;
send_timeout 36000s;
access_by_lua_file conf/vhost/access.lua;
}
error_page 404 /50x.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
vim access.lua
local limit_conn = require "resty.limit.conn"
local lim, err = limit_conn.new("limit_conn_store", 1000, 1, 0.01)
local lan_ip_addr = ngx.var.remote_addr
if ( not string.find(lan_ip_addr,"192.168.13.44" or "127.0")) then
ngx.var.limit_rate = "300K"
end
if not lim then
ngx.log(ngx.ERR,"failed to instantiate a resty.limit.conn object: ", err)
return ngx.exit(500)
end
local key = ngx.var.binary_remote_addr
local delay, err = lim:incoming(key, true)
if not delay then
if err == "rejected" then
return ngx.exit(503)
end
ngx.log(ngx.ERR, "failed to limit req: ", err)
return ngx.exit(500)
end
if lim:is_committed() then
local ctx = ngx.ctx
ctx.limit_conn = lim
ctx.limit_conn_key = key
ctx.limit_conn_delay = delay
end
local conn = err
if delay >= 0.001 then
ngx.sleep(delay)
end

2.5 WAF 组件 ModSecurity 配置

$ git clone -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity.git --depth=1
$ cd ModSecurity/
$ git checkout -b v3/master origin/v3/master
$ sh build.sh
$ git submodule init
$ git submodule update #[for bindings/python, others/libinjection, test/test-cases/secrules-language-tests]
$ ./configure
$ make
$ sudo make install
#使用 ModSecurity-nginx 而不是网上流传的独立版 详见 https://github.com/SpiderLabs/ModSecurity-nginx
$ export MODSECURITY_INC="/home/anjia/openresty/ModSecurity/headers"
$ export MODSECURITY_LIB="/home/anjia/openresty/ModSecurity/src/.libs"
$ git clone https://github.com/SpiderLabs/ModSecurity-nginx --depth=1
$ git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git --depth=1
$ sudo cp -R owasp-modsecurity-crs/rules /opt/openresty/nginx/nginx/conf
$ cp owasp-modsecurity-crs/crs-setup.conf.example /opt/openresty/nginx/nginx/conf/crs-setup.conf
$ sudo wget -P /opt/openresty/nginx/nginx/conf https://raw.githubusercontent.com/SpiderLabs/ModSecurity/master/modsecurity.conf-recommended h
ttps://raw.githubusercontent.com/SpiderLabs/ModSecurity/master/unicode.mapping
$ sudo mv /opt/openresty/nginx/nginx/conf/modsecurity.conf-recommended /opt/openresty/nginx/nginx/conf/modsecurity.conf
$ sudo mkdir /opt/openresty/nginx/nginx/conf/sites-enabled
#使用www-data用户
$ sudo sed -i '1s/^/user www-data;\n/' /opt/openresty/nginx/nginx/conf/nginx.conf
$ sudo vim /opt/openresty/nginx/nginx/conf/nginx.conf
#删除36-116行,即server{}段,可以在英文输入法状态按 :36,166d 然后 :wq
#如果确认行数没问题,也可以用sudo sed '35,116d' -i /opt/openresty/nginx/nginx/conf/nginx.conf
$ sudo sed '$i include /opt/openresty/nginx/nginx/conf/sites-enabled/*; ' -i /opt/openresty/nginx/nginx/conf/nginx.conf
#嫌费事,也可以直接用下面的配置文件

user www-data;
worker_processes 1;

events {
worker_connections 1024;
}

http {

include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
include /opt/openresty/nginx/nginx/conf/sites-enabled/*;

}

 

$ vi /opt/openresty/nginx/nginx/conf/modsecurity.conf

#Load OWASP Config

Include crs-setup.conf

#Load all other Rules

Include rules/*.conf

#Disable rule by ID from error message

#SecRuleRemoveById 920350

$ sudo sed s/"SecRuleEngine DetectionOnly"/"SecRuleEngine On"/g -i /opt/openresty/nginx/nginx/conf/modsecurity.conf
$ sudo /opt/openresty/nginx/nginx/sbin/nginx -t && sudo /opt/openresty/nginx/nginx/sbin/nginx -s reload
$ curl "http://localhost/wp-admin/admin.php?where1=%3Cscript%3Ealert(String.fromCharCode(88,+83,+83))%3C/script%3E&searchsubmit=Buscar&page=nsp_search"

# 返回403 Forbidden