干货——nginx的一般安全配置

项目一般配置,例如default.conf

server {

#引入lua文件加载一些默认配置

include conf.d/lua_core.conf;

#引入一些默认localtion的配置

include conf.d/limits.conf;

#指定dcoment_root

root /var/www/html/default/public;

#加载项目相关的localtion的配置

include conf.d/rewrite/thinkphp.conf;

#测试用

location = /lua {

set $loggable 0;

default_type text/html;

content_by_lua 'ngx.say("hello world")';

#这个链接必须是在浏览器下访问,受制于此文件内的配置

include conf.d/lua/must_be_human.conf;

}

access_log /var/log/nginx/access.default.log json_log buffer=64k flush=10s if=$loggable;

error_log /var/log/nginx/error.default.log error;

}

nginx的主入口nginx.conf

user nginx;

worker_processes auto;

pid /var/run/nginx.pid;

error_log /var/log/nginx/nginx_error.log warn;

worker_rlimit_nofile 51200;

events {

use epoll;

worker_connections 51200;

multi_accept on;

}

http {

include /etc/nginx/mime.types;

default_type application/octet-stream;

server_names_hash_bucket_size 128;

client_header_buffer_size 32k;

large_client_header_buffers 4 32k;

client_max_body_size 50m;

client_body_buffer_size 5m;

client_body_temp_path /var/cache/nginx/client_body_temp 1 2;

sendfile on;

tcp_nopush on;

tcp_nodelay on;

client_body_timeout 30;

client_header_timeout 30;

keepalive_timeout 30;

send_timeout 30;

fastcgi_connect_timeout 300;

fastcgi_send_timeout 300;

fastcgi_read_timeout 300;

fastcgi_buffer_size 1m;

fastcgi_buffers 8 1m;

fastcgi_busy_buffers_size 2m;

fastcgi_temp_file_write_size 4m;

fastcgi_temp_path /var/cache/nginx/fastcgi_temp 1 2;

proxy_http_version 1.1;

proxy_buffer_size 1m;

proxy_buffers 4 1m;

proxy_busy_buffers_size 2m;

proxy_temp_file_write_size 2m;

proxy_cache_path /var/cache/nginx/nginx_proxy_cache levels=1:2 keys_zone=cache_one:500m inactive=1d max_size=10g;

gzip on;

gzip_min_length 1k;

gzip_buffers 4 16k;

gzip_http_version 1.1;

gzip_comp_level 4;

gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/json;

gzip_vary on;

gzip_proxied expired no-cache no-store private auth;

gzip_disable "MSIE [1-6]\.";

server_tokens off;

access_log off;

autoindex off;

open_file_cache max=102400 inactive=20s;

open_file_cache_valid 30s;

open_file_cache_min_uses 2;

open_file_cache_errors on;

map $http_x_forwarded_for $clientRealIp {

"" $remote_addr;

~^(?P[0-9\.]+),?.*$ $firstAddr;

}

map $sent_http_content_type $expires {

default 1d;

text/html off;

text/css 1d;

application/javascript 1d;

~image/ 1d;

}

map $host $resp_body {

default "";

}

map $host $loggable {

default 1;

}

map $host $request_body_sub {

default "";

}

#日志采用json形式,方便和jq命令查找分析

log_format json_log escape=json '{"realip":"$clientRealIp","timestamp":"$time_iso8601","host":"$http_host","request":"$request","req_body":"$request_body_sub","status":"$status","resp_body":"$resp_body","size":$body_bytes_sent,"ua":"$http_user_agent","cookie":"$http_cookie","req_time":"$request_time","uri":"$uri","referer":"$http_referer","xff":"$http_x_forwarded_for","ups_status":"$upstream_status","ups_addr":"$upstream_addr","ups_time":"$upstream_response_time"}';

lua_need_request_body on;

#不关闭这个,不能启动lua module

lua_load_resty_core off;

include /etc/nginx/conf.d/vhost/*.conf;

}

lua_core.conf中的一些内容

#将输入输出也写进log中

body_filter_by_lua_block {

if ngx.var.request_method == "POST" then

ngx.var.request_body_sub = string.sub(ngx.var.request_body or "", 1, 1000)

local resp_body = string.sub(ngx.arg[1] or "", 1, 1000)

ngx.ctx.buffered = (ngx.ctx.buffered or "") .. resp_body

if ngx.arg[2] then

ngx.var.resp_body = ngx.ctx.buffered

end

end

}

#放在顶级server中进行筛选

rewrite_by_lua_block {

local body = nil

if ngx.var.request_method == "POST" then

ngx.req.read_body()

body = ngx.unescape_uri(string.sub(ngx.var.request_body or "", 1, 1000))

elseif ngx.var.request_method == "GET" then

body = ngx.unescape_uri(string.sub(ngx.var.args or "", 1, 1000))

end

-- 检测请求数据中的不安全参数

if body and string.len(body) >= 8 then

local patterns = {

"(shell_exec|phpinfo|system|passthru|preg_\\w+|execute|echo)\\s*\\(",

}

for _, pattern in pairs(patterns) do

local match = ngx.re.match(body, pattern, "ijo")

if match then

ngx.status = 200

ngx.say("hello world")

ngx.exit(200)

end

end

end

}

limits.conf

#https的时候要用到

add_header X-Frame-Options SAMEORIGIN;

add_header X-Content-Type-Options nosniff;

add_header X-XSS-Protection "1; mode=block";

add_header strict-transport-security "max-age=31536000; includeSubDomains";

fastcgi_hide_header X-Powered-By;

#只允许特定的METHOD

if ($request_method !~ ^(GET|POST|HEAD|OPTION)$) {

return 405;

}

#禁止默认的命令行工具访问

if ($http_user_agent ~* (pytho[n]?|curl|wget)) {

return 403;

}

# 防止外部直接thinkphp漏洞攻击

if ($request_uri ~* ^/index\.php) {

return 405;

}

#letsencrypt需要访问这个地址下文件

location ^~ /.well-known {

try_files $uri $uri/ =404;

access_log off;

}

#禁止所以点开头的访问

#eg: /upload/../index.php

location ~ /\. {

deny all;

}

#upload下php无运行权限,防止上传漏洞

location ~* /upload[s]?/.*\.php$ {

return 404;

}

#静态文件就不需要记录在日志了

location ~* \.(map|gif|jpg|png|css|js|ico|swf|pdf|apk|exe|eot|otf|ttf|woff|woff2)$ {

try_files $uri =404;

access_log off;

}

location = /favicon.ico {

try_files $uri =404;

access_log off;

}

lua的一些应用

#一般爬虫无法动态cookie,用作判断是否是浏览器行为

rewrite_by_lua_block {

local random = ngx.var.cookie_random

if(random == nil) then

random = math.random(999999)

end

local token = ngx.md5("salt" .. ngx.var.remote_addr .. random)

if (ngx.var.cookie_token ~= token) then

ngx.header["Set-Cookie"] = {"token=" .. token, "random=" .. random}

return ngx.redirect(ngx.var.scheme .. "://" .. ngx.var.host .. ngx.var.request_uri)

end

}

thinkphp.conf相关的配置

location / {

try_files $uri $uri/ /index.php?s=$uri&$query_string;

}

#杜绝其他上传php文件的漏洞

location = /index.php {

try_files $uri =404;

fastcgi_pass php-fpm:9000;

fastcgi_index index.php;

fastcgi_param SCRIPT_FILENAME $document_root/index.php; # $fastcgi_script_name

include fastcgi_params;

}

你可能感兴趣的:(干货——nginx的一般安全配置)