当前位置: 首页 > news >正文

【学习笔记】Nginx常用安全配置

一、Nginx的配置文件

在Linux系统中,Nginx配置文件在 /usr/local/nginx/conf/ 目录中

先看一下nginx.conf 文件结构:

	#user  nobody;worker_processes  1;#error_log  logs/error.log;#error_log  logs/error.log  notice;#error_log  logs/error.log  info;#pid        logs/nginx.pid;events {worker_connections  1024;}http {include       mime.types;default_type  application/octet-stream;#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '#                  '$status $body_bytes_sent "$http_referer" '#                  '"$http_user_agent" "$http_x_forwarded_for"';#access_log  logs/access.log  main;sendfile        on;#tcp_nopush     on;#keepalive_timeout  0;keepalive_timeout  65;#gzip  on;server {listen       80;server_name  localhost;#charset koi8-r;#access_log  logs/host.access.log  main;location / {root   html;index  index.html index.htm;}#error_page  404              /404.html;# redirect server error pages to the static page /50x.html#error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}}}

(1)全局块

       从配置文件开始到 events 块之间的内容,主要会设置一些影响 nginx 服务器整体运行的配置指令,主要包括配置运行 Nginx 服务器的用户(组)、允许生成的 worker process 数,进程 PID 存放路径、日志存放路径和类型以及配置文件的引入等。
比如上面第一行的配置:

worker_processes 1;

       这是 Nginx 服务器并发处理服务的关键配置,worker_processes 值越大,可以支持的并发处理量也越多,但是会受到硬件、软件等设备的制约。

(2)events 块

比如上面的配置:

events { worker_connections 1024; }

       events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,常用的设置包括是否开启对多 work process下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 word process 可以同时支持的最大连接数等。上述例子就表示每个 work process 支持的最大连接数为 1024。

        这部分的配置对 Nginx 的性能影响较大,在实际中应该灵活配置。

(3)http块

       这算是 Nginx 服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。
       需要注意的是:http 块包括 http 全局块 和 server 块。

        ①http 全局块
        http 全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。

       ②server 块
       这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。
       每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机。
       而每个 server 块也分为全局 server 块,以及可以同时包含多个 locaton 块。
       1)全局 server 块
       最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或 IP 配置。
       2)location 块
       一个 server 块可以配置多个 location 块。这块的主要作用是基于 Nginx 服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称(也可以是 IP 别名)之外的字符串(例如前面的 /uri-string)进行匹配,对特定的请求进行处理。

        地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。

#定义Nginx运行的用户和用户组
user www www;
#
#nginx进程数,建议设置为等于CPU总核心数.
worker_processes 8;
#
#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx/error.log info;
#
#进程文件
pid /var/run/nginx.pid;
#
#一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(系统的值ulimit -n)与nginx进程数相除,但是nginx分配请求并不均匀,所以建议与ulimit -n的值保持一致.
worker_rlimit_nofile 65535;
#
#工作模式与连接数上限
events
{#参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型.use epoll;#单个进程最大连接数(最大连接数=连接数*进程数)worker_connections 1024;    #最大连接数,默认为512
}
#
#设定http服务器
http
{include mime.types; #文件扩展名与文件类型映射表default_type application/octet-stream; #默认文件类型#charset utf-8; #默认编码server_names_hash_bucket_size 128; #服务器名字的hash表大小client_header_buffer_size 32k; #上传文件大小限制large_client_header_buffers 4 64k; #设定请求缓client_max_body_size 8m; #设定请求缓keepalive_timeout 65;  #连接超时时间,默认为75s,可以在http,server,location块。# 开启目录列表访问,合适下载服务器,默认关闭.autoindex on; # 显示目录autoindex_exact_size on; # 显示文件大小 默认为on,显示出文件的确切大小,单位是bytes 改为off后,显示出文件的大概大小,单位是kB或者MB或者GBautoindex_localtime on; # 显示文件时间 默认为off,显示的文件时间为GMT时间 改为on后,显示的文件时间为文件的服务器时间sendfile on; # 开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载.注意:如果图片显示不正常把这个改成off.tcp_nopush on; # 防止网络阻塞tcp_nodelay on; # 防止网络阻塞# FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度.下面参数看字面意思都能理解.fastcgi_connect_timeout 300; ## 链接fastcgi_send_timeout 300;  ##读取 是指nginx进程向fastcgi进程发送request的整个过程的超时时间fastcgi_read_timeout 300;  ##发请求 是指fastcgi进程向nginx进程发送response的整个过程的超时时间fastcgi_buffer_size 64k;fastcgi_buffers 4 64k;fastcgi_busy_buffers_size 128k;fastcgi_temp_file_write_size 128k;# gzip模块设置gzip on; #开启gzip压缩输出gzip_min_length 1k; #允许压缩的页面的最小字节数,页面字节数从header偷得content-length中获取.默认是0,不管页面多大都进行压缩.建议设置成大于1k的字节数,小于1k可能会越压越大gzip_buffers 4 16k; #表示申请4个单位为16k的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果gzip_http_version 1.1; #压缩版本(默认1.1,目前大部分浏览器已经支持gzip解压.前端如果是squid2.5请使用1.0)gzip_comp_level 2; #压缩等级.1压缩比最小,处理速度快.9压缩比最大,比较消耗cpu资源,处理速度最慢,但是因为压缩比最大,所以包最小,传输速度快gzip_types text/plain application/x-javascript text/css application/xml;#压缩类型,默认就已经包含text/html,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn.gzip_vary on;#选项可以让前端的缓存服务器缓存经过gzip压缩的页面.例如:用squid缓存经过nginx压缩的数据#开启限制IP连接数的时候需要使用#limit_zone crawler $binary_remote_addr 10m;##upstream的负载均衡,四种调度算法(下例主讲)###虚拟主机的配置server{# 监听端口listen 80;# 域名可以有多个,用空格隔开server_name 127.0.0.1;# HTTP 自动跳转 HTTPSrewrite ^(.*) https://www.baidu.com;deny 127.0.0.1;  #拒绝的ipallow 172.18.5.54; #允许的ip }upstream myserver {   server 127.0.0.1:8080;server 192.168.24.189:8080 backup;  #热备}server{# 监听端口 HTTPSlisten 443 ssl;server_name https://www.baidu.com;root /data/www/;# 配置域名证书ssl_certificate      C:\WebServer\Certs\certificate.crt;ssl_certificate_key  C:\WebServer\Certs\private.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_protocols SSLv2 SSLv3 TLSv1;ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;ssl_prefer_server_ciphers  on;index index.html index.htm index.php;location ~ .*\.(php|php5)?${fastcgi_pass 127.0.0.1:9000;fastcgi_index index.php;include fastcgi.conf;}# 配置地址拦截转发,解决跨域验证问题location /oauth/{proxy_pass https://localhost:13580/oauth/;proxy_set_header HOST $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}# 图片缓存时间设置location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {expires 10d;}# JS和CSS缓存时间设置location ~ .*\.(js|css)?$ {expires 1h;}# 日志格式设定log_format access '$server_name $remote_addr -$remote_user [$time_local] "$request"''$status $uptream_status $body_bytes_sent "$http_referer"''"$http_user_agent" "$http_x_forwarded_for" ''$ssl_protocol $ssl_cipher $upstream_addr $request_time $upstream_response_time';# 定义本虚拟主机的访问日志access_log /var/log/nginx/access.log access;# 设定查看Nginx状态的地址.StubStatus模块能够获取Nginx自上次启动以来的工作状态,此模块非核心模块,需要在Nginx编译安装时手工指定才能使用location /NginxStatus {stub_status on;access_log on;auth_basic "NginxStatus";auth_basic_user_file conf/htpasswd;#htpasswd文件的内容可以用apache提供的htpasswd工具来产生.}}
}

二、Nginx的安全配置

2.1 隐藏版本号

http {# 关闭在响应头中显示Nginx版本号# 默认响应头: Server: nginx/1.18.0# 关闭后响应头: Server: nginxserver_tokens off;
}

        经常会有针对某个版本的nginx安全漏洞出现,隐藏nginx版本号就成了主要的安全优化手段之一,当然最重要的是及时升级修复漏洞。

2.2 开启HTTPS

默认情况下,nginx监听在80端口(HTTP)和443端口(HTTPS)。

server {listen 443;server_name ops-coffee.cn;ssl on;ssl_certificate /etc/nginx/server.crt;ssl_certificate_key /etc/nginx/server.key;ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;ssl_ciphers         HIGH:!aNULL:!MD5;
}

可以使用openssl命令生成SSL证书:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout nginx.key -out nginx.crt
ssl_certificate /path/to/nginx.crt;
ssl_certificate_key /path/to/nginx.key;

或者

server {# 监听443端口,启用SSLlisten 443 ssl;# 指定SSL证书路径ssl_certificate /path/to/cert.pem;ssl_certificate_key /path/to/key.pem;# 将所有HTTP请求重定向到HTTPSif ($scheme != "https") {return 301 https://$server_name$request_uri;}# 启用HSTS,强制浏览器在指定时间内使用HTTPS访问add_header Strict-Transport-Security "max-age=31536000" always;
}

ssl on: 开启https

ssl_certificate: 配置nginx ssl证书的路径

ssl_certificate_key: 配置nginx ssl证书key的路径

使用更安全的SSL配置参数:# 只允许TLS 1.2和1.3版本,禁用不安全的SSL和早期TLS版本
ssl_protocols TLSv1.2 TLSv1.3;# 配置加密套件,按推荐顺序排列
# ECDHE: 使用椭圆曲线密钥交换
# AES-GCM: 使用AES-GCM加密模式
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;# 优先使用服务器的加密套件
ssl_prefer_server_ciphers on;# 配置SSL会话缓存,提高性能
# shared:SSL:10m: 所有工作进程共享的缓存,大小为10MB
ssl_session_cache shared:SSL:10m;# SSL会话超时时间
ssl_session_timeout 10m;# 启用OCSP Stapling,提供证书状态信息
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

ssl_protocols: 指定客户端建立连接时使用的ssl协议版本,如果不需要兼容TSLv1,直接去掉即可

ssl_ciphers: 指定客户端连接时所使用的加密算法,你可以在这里配置更高安全的算法

2.3 添加黑白名单

白名单配置

location /admin/ {# 允许内网IP段访问# 192.168.1.0/24: 允许192.168.1.x网段的所有IPallow 192.168.1.0/24;# 允许另一个内网IP段访问allow 10.0.0.0/8;# 拒绝其他所有IP访问deny all;# 开启基础认证auth_basic "Restricted Access";auth_basic_user_file /etc/nginx/.htpasswd;
}

       上边表示只允许192.168.1.0/24网段的主机访问,拒绝其他所有

        也可以写成黑名单的方式禁止某些地址访问,允许其他所有,例如

location /ops-coffee/ {deny   192.168.1.0/24;allow    all;
}

       更多的时候客户端请求会经过层层代理,我们需要通过$http_x_forwarded_for来进行限制,可以这样写

set $allow false;
if ($http_x_forwarded_for = "211.144.204.2") { set $allow true; }
if ($http_x_forwarded_for ~ "108.2.66.[89]") { set $allow true; }
if ($allow = false) { return 404; }

2.4 添加账号认证

server {location / {auth_basic "please input user&passwd";auth_basic_user_file key/auth.key;}
}

关于账号认证《Nginx的几个常用配置和技巧》文章中已有详细介绍,这里不赘述

2.5 限制请求方法

if ($request_method !~ ^(GET|POST)$ ) {return 405;
}

$request_method能够获取到请求nginx的method

配置只允许GET\POST方法访问,其他的method返回405

2.6 拒绝User-Agent

if ($http_user_agent ~* LWP::Simple|BBBike|wget|curl) {return 444;
}

       可能有一些不法者会利用wget/curl等工具扫描我们的网站,我们可以通过禁止相应的user-agent来简单的防范。Nginx的444状态比较特殊,如果返回444那么客户端将不会收到服务端返回的信息,就像是网站无法连接一样

2.7 图片防盗链

location /images/ {valid_referers none blocked www.ops-coffee.cn ops-coffee.cn;if ($invalid_referer) {return  403;}
}

valid_referers: 验证referer,其中none允许referer为空,blocked允许不带协议的请求,除了以上两类外仅允许referer为www.ops-coffee.cn或ops-coffee.cn时访问images下的图片资源,否则返回403

当然你也可以给不符合referer规则的请求重定向到一个默认的图片,比如下边这样

location /images/ {valid_referers blocked www.ops-coffee.cn ops-coffee.cnif ($invalid_referer) {rewrite ^/images/.*\.(gif|jpg|jpeg|png)$ /static/qrcode.jpg last;}
}

2.8 控制并发连接数

可以通过ngx_http_limit_conn_module模块限制一个IP的并发连接数

http {# 定义一个共享内存区域,用于存储IP连接数信息# $binary_remote_addr: 使用二进制格式存储客户端IP,节省空间# zone=addr:10m: 指定共享内存区域名称为addr,大小为10MBlimit_conn_zone $binary_remote_addr zone=addr:10m;# 限制每个IP同时最多100个连接limit_conn addr 100;# 定义请求频率限制,每个IP每秒最多10个请求# rate=10r/s: 每秒10个请求limit_req_zone $binary_remote_addr zone=req_zone:10m rate=10r/s;# 应用请求频率限制,burst=20表示最多允许20个请求排队limit_req zone=req_zone burst=20 nodelay;
}

      limit_conn_zone: 设定保存各个键(例如$binary_remote_addr)状态的共享内存空间的参数,zone=空间名字:大小

大小的计算与变量有关,例如$binary_remote_addr变量的大小对于记录IPV4地址是固定的4 bytes,而记录IPV6地址时固定的16 bytes,存储状态在32位平台中占用32或者64 bytes,在64位平台中占用64 bytes。1m的共享内存空间可以保存大约3.2万个32位的状态,1.6万个64位的状态

       limit_conn: 指定一块已经设定的共享内存空间(例如name为ops的空间),以及每个给定键值的最大连接数

上边的例子表示同一IP同一时间只允许10个连接

当有多个limit_conn指令被配置时,所有的连接数限制都会生效

http {limit_conn_zone $binary_remote_addr zone=ops:10m;limit_conn_zone $server_name zone=coffee:10m;server {listen       80;server_name  ops-coffee.cn;root /home/project/webapp;index index.html;location / {limit_conn ops 10;limit_conn coffee 2000;}}
}

      上边的配置不仅会限制单一IP来源的连接数为10,同时也会限制单一虚拟服务器的总连接数为2000。

2.9 缓冲区溢出攻击

缓冲区溢出攻击 是通过将数据写入缓冲区并超出缓冲区边界和重写内存片段来实现的,限制缓冲区大小可有效防止


## Start: Size Limits & Buffer Overflows ##
client_body_buffer_size 1K;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
## END: Size Limits & Buffer Overflows ##

client_body_buffer_size: 默认8k或16k,表示客户端请求body占用缓冲区大小。如果连接请求超过缓存区指定的值,那么这些请求实体的整体或部分将尝试写入一个临时文件。

client_header_buffer_size: 表示客户端请求头部的缓冲区大小。绝大多数情况下一个请求头不会大于1k,不过如果有来自于wap客户端的较大的cookie它可能会大于 1k,Nginx将分配给它一个更大的缓冲区,这个值可以在large_client_header_buffers里面设置

client_max_body_size: 表示客户端请求的最大可接受body大小,它出现在请求头部的Content-Length字段, 如果请求大于指定的值,客户端将收到一个"Request Entity Too Large" (413)错误,通常在上传文件到服务器时会受到限制

large_client_header_buffers 表示一些比较大的请求头使用的缓冲区数量和大小,默认一个缓冲区大小为操作系统中分页文件大小,通常是4k或8k,请求字段不能大于一个缓冲区大小,如果客户端发送一个比较大的头,nginx将返回"Request URI too large" (414),请求的头部最长字段不能大于一个缓冲区,否则服务器将返回"Bad request" (400)

同时需要修改几个超时时间的配置,防止慢速攻击

# 客户端请求体超时时间,单位秒
client_body_timeout 10;# 客户端请求头超时时间
client_header_timeout 10;# 客户端保持连接超时时间
# 第一个参数是客户端超时时间
# 第二个参数是在响应头中的Keep-Alive超时时间
keepalive_timeout 5 5;# 向客户端发送响应的超时时间
send_timeout 10;# 读取代理服务器响应的超时时间
proxy_read_timeout 10;# 连接代理服务器的超时时间
proxy_connect_timeout 10;

client_body_timeout: 表示读取请求body的超时时间,如果连接超过这个时间而客户端没有任何响应,Nginx将返回"Request time out" (408)错误

client_header_timeout: 表示读取客户端请求头的超时时间,如果连接超过这个时间而客户端没有任何响应,Nginx将返回"Request time out" (408)错误

keepalive_timeout: 参数的第一个值表示客户端与服务器长连接的超时时间,超过这个时间,服务器将关闭连接,可选的第二个参数参数表示Response头中Keep-Alive: timeout=time的time值,这个值可以使一些浏览器知道什么时候关闭连接,以便服务器不用重复关闭,如果不指定这个参数,nginx不会在应Response头中发送Keep-Alive信息

send_timeout: 表示发送给客户端应答后的超时时间,Timeout是指没有进入完整established状态,只完成了两次握手,如果超过这个时间客户端没有任何响应,nginx将关闭连接

通过以下设置可有效防止XSS攻击

# 防止网站被嵌入恶意网页中,避免点击劫持
add_header X-Frame-Options "SAMEORIGIN";# 启用浏览器XSS防护功能,并在检测到攻击时,停止渲染页面
add_header X-XSS-Protection "1; mode=block";# 禁止浏览器猜测(嗅探)资源的MIME类型,防止资源类型混淆攻击
add_header X-Content-Type-Options "nosniff";# 控制引用地址信息的传递,增强隐私保护
add_header Referrer-Policy "strict-origin-origin-when-cross-origin";# 内容安全策略,控制资源加载来源,防止XSS等攻击
# default-src 'self': 只允许加载同源资源
# http: https:: 允许通过HTTP和HTTPS加载资源
# data:: 允许data:URI的资源(如base64编码的图片)
# blob:: 允许blob:URI的资源(如视频流)
# 'unsafe-inline': 允许内联脚本和样式(根据需要配置)
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'";

X-Frame-Options: 响应头表示是否允许浏览器加载frame等属性,有三个配置DENY禁止任何网页被嵌入,SAMEORIGIN只允许本网站的嵌套,ALLOW-FROM允许指定地址的嵌套

X-XSS-Protection: 表示启用XSS过滤(禁用过滤为X-XSS-Protection: 0),mode=block表示若检查到XSS攻击则停止渲染页面

X-Content-Type-Options: 响应头用来指定浏览器对未指定或错误指定Content-Type资源真正类型的猜测行为,nosniff 表示不允许任何猜测

在通常的请求响应中,浏览器会根据Content-Type来分辨响应的类型,但当响应类型未指定或错误指定时,浏览会尝试启用MIME-sniffing来猜测资源的响应类型,这是非常危险的

例如一个.jpg的图片文件被恶意嵌入了可执行的js代码,在开启资源类型猜测的情况下,浏览器将执行嵌入的js代码,可能会有意想不到的后果

另外还有几个关于请求头的安全配置需要注意

Content-Security-Policy: 定义页面可以加载哪些资源,

add_header Content-Security-Policy "default-src 'self'";

上边的配置会限制所有的外部资源,都只能从当前域名加载,其中default-src定义针对所有类型资源的默认加载策略,self允许来自相同来源的内容

Strict-Transport-Security: 会告诉浏览器用HTTPS协议代替HTTP来访问目标站点

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

上边的配置表示当用户第一次访问后,会返回一个包含了Strict-Transport-Security响应头的字段,这个字段会告诉浏览器,在接下来的31536000秒内,当前网站的所有请求都使用https协议访问,参数includeSubDomains是可选的,表示所有子域名也将采用同样的规则

2.11 文件上传安全

1. 限制上传文件大小
防止通过上传大文件耗尽服务器资源:

# 限制请求体大小,即上传文件的最大大小为10MB
client_max_body_size 10m;# 设置请求体缓冲区大小为128KB
# 超过此大小的请求体会被写入临时文件
client_body_buffer_size 128k;# 配置临时文件存储路径
client_body_temp_path /var/nginx/client_body_temp;


2. 配置上传目录权限
确保上传目录的权限配置正确:

location /uploads/ {# 指定上传根目录root /var/www/uploads;# 指定临时文件目录client_body_temp_path /var/www/tmp;# 允许的WebDAV方法dav_methods PUT DELETE MKCOL COPY MOVE;# 自动创建上传目录create_full_put_path on;# 设置目录访问权限# user:rw - 文件所有者可读写# group:rw - 组用户可读写# all:r - 其他用户只读dav_access user:rw group:rw all:r;# 限制上传文件类型if ($request_filename ~* ^.*?\.(php|php5|sh|pl|py)$) {return 403;}

2.12 防止常见攻击

1)防止SQL注入

配置特殊字符过滤。

location / {# 检查URL中是否包含特殊字符# 如果包含分号、单引号、尖括号等字符,返回444状态码# 444是Nginx特殊状态码,表示关闭连接而不发送响应头if ($request_uri ~* [;'<>] ) {return 444;}# 检查查询字符串中的特殊字符if ($args ~* [;'<>] ) {return 444;}# 保护敏感URIlocation ~* /(admin|backup|config|db|src)/ {deny all;}
}

nginx可以通过使用正则表达式过滤请求来防御此类攻击。

location / {if ($args ~ "(?i)[\s'"]+(union|select|insert|update|delete)[\s'"]+) {return 403;}
}

2)防御跨站脚本攻击(XSS)

跨站脚本攻击(XSS)是通过将恶意脚本注入到Web应用程序中来攻击用户浏览器。nginx可以通过使用正则表达式过滤请求来防御此类攻击。

location / {if ($args ~ "(?i)<script(.*?)>(.*?)</script>") {return 403;}
}

3)防御文件包含攻击

文件包含攻击是通过将恶意文件包含到Web应用程序中来攻击服务器。nginx可以通过使用正则表达式过滤请求来防御此类攻击。

location / {if ($args ~ "(?i)[\s'"]+(include|require)[\s'"]+) {return 403;}
}

4)防止目录遍历

禁止访问隐藏文件和目录:

# 禁止访问所有以点开头的隐藏文件和目录
location ~ /\. {# 拒绝所有请求deny all;# 禁止记录访问日志access_log off;# 禁止记录404错误日志log_not_found off;
}# 禁止访问特定目录
location ~* ^/(uploads|images)/.*\.(php|php5|sh|pl|py|asp|aspx|jsp)$ {deny all;
}# 防止目录列表
location / {autoindex off;
}

2.13 日志安全

1)配置访问日志

详细记录访问信息,便于安全分析:

# 定义详细的日志格式
log_format detailed '$remote_addr - $remote_user [$time_local] '  # 记录客户端IP和访问时间'"$request" $status $body_bytes_sent '        # 记录请求信息、状态码和发送字节数'"$http_referer" "$http_user_agent" '        # 记录来源页面和用户代理'$request_time $upstream_response_time';      # 记录请求处理时间和上游响应时间# 配置访问日志
# buffer=32k: 使用32KB缓冲区
# flush=5s: 每5秒刷新一次日志
access_log /var/log/nginx/access.log detailed buffer=32k flush=5s;# 对于静态资源,可以关闭访问日志以提高性能
location /static/ {access_log off;
}

访问日志记录了每个请求的详细信息,包括请求时间、请求方法、请求URL、请求头、响应状态代码和响应大小。这些日志对于故障排除、安全分析和性能优化至关重要。

2)配置错误日志

设置适当的错误日志级别:

# 设置错误日志级别为warn
# 可选级别: debug, info, notice, warn, error, crit, alert, emerg
error_log /var/log/nginx/error.log warn;# 对于开发环境,可以使用debug级别获取更多信息
# error_log /var/log/nginx/error.log debug;

2.14 禁止执行脚本

在静态资源目录中禁止执行脚本:

location /static/ {# 禁止执行PHP文件location ~ \.(php|php5)$ {deny all;}# 只允许特定文件类型location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {expires 30d;  # 设置缓存时间add_header Cache-Control "public, no-transform";}
}

三、Nginx部署及环境优化

1 删除所有不需要的Nginx模块

直接通过编译Nginx源代码使模块数量最少化。通过限制只允许Web服务器访问模块把风险降到最低。例如,禁用SSL和autoindex模块你可以执行以下命令:

./configure –without-http_autoindex_module –without-http_ssi_module
make
make install

通过以下命令来查看当编译Nginx服务器时哪个模块能开户或关闭:

./configure –help | less

然后禁用用不到的Nginx模块。

2 安装SELinux策略以强化Nginx Web服务器
默认的SELinux不会保护Nginx Web服务器,我这里安装和编译保护软件。
安装编译SELinux所需环境支持

yum -y install selinux-policy-targeted selinux-policy-devel

下载SELinux策略以强化Nginx Web服务器。

cd /opt
wget ‘http://downloads.sourceforge.net/project/selinuxnginx/se-ngix_1_0_10.tar.gz?use_mirror=nchc’

解压、编译文件

tar -zxvf se-ngix_1_0_10.tar.gz

编译文件

cd se-ngix_1_0_10/nginx
make

将会输出如下:

Compiling targeted nginx module
/usr/bin/checkmodule: loading policy configuration from tmp/nginx.tmp
/usr/bin/checkmodule: policy configuration loaded
/usr/bin/checkmodule: writing binary representation (version 6) to tmp/nginx.mod
Creating targeted nginx.pp policy package
rm tmp/nginx.mod.fc tmp/nginx.mod

安装生成的nginx.pp SELinux模块:

/usr/sbin/semodule -i nginx.pp

3 在防火墙级限制每个IP的连接数

网络服务器必须监视连接和每秒连接限制。PF和Iptales都能够在进入你的Nginx服务器之前阻止最终用户的访问。
Linux Iptables:限制每次Nginx连接数
下面的例子会阻止来自一个IP的60秒钟内超过15个连接端口80的连接数。

/sbin/iptables -A INPUT -p tcp –dport 80 -i eth0 -m state –state NEW -m recent –set
sbin/iptables -A INPUT -p tcp –dport 80 -i eth0 -m state –state NEW -m recent –update –seconds 60 –hitcount 15 -j DROP
service iptables save

设置同一个IP 60秒内只允许10个Nginx链接。

4 配置操作系统保护Web服务器

       Nginx程序一般以用户nginx运行。但是根目录(/nginx或者/usr /local/nginx/html)不应该设置属于用户nginx或对用户nginx可写。找出错误权限的文件可以使用如下命令:

find /nginx -user nginx
find /usr/local/nginx/html -user nginx

确保你更所有权为root或其它用户,一个典型的权限设置

/usr/local/nginx/html/
ls -l /usr/local/nginx/html/

示例输出:

-rw-r–r– 1 root root 925 Jan 3 00:50 error4xx.html
-rw-r–r– 1 root root 52 Jan 3 10:00 error5xx.html
-rw-r–r– 1 root root 134 Jan 3 00:52 index.html

删除由vim或其它文本编辑器创建的备份文件:

find /nginx -name ‘.?*’ -not -name .ht* -or -name ‘*~’ -or -name ‘*.bak*’ -or -name ‘*.old*’
find /usr/local/nginx/html/ -name ‘.?*’ -not -name .ht* -or -name ‘*~’ -or -name ‘*.bak*’ -or -name ‘*.old*’

通过find命令的-delete选项来删除这些文件,慎用,查找到就删除。

4 限制Nginx连接传出

       黑客会使用工具如wget下载服务器本地的文件。使用Iptables从nginx用户来阻止传出连接。ipt_owner模块试图匹配本地产生的数据包的创建者。

下面的例子中只允许user用户在外面使用80连接。

/sbin/iptables -A OUTPUT -o eth0 -m owner –uid-owner vivek \
-p tcp –dport 80 -m state –state NEW,ESTABLISHED -j ACCEPT

http://www.dtcms.com/a/276204.html

相关文章:

  • arcgis投影后数据显示问题记录
  • 以电商平台性能测试为例,详细描述Jmeter性能测试步骤,及如何确定用户并发数、用户启动时间、循环次数的设置
  • 算法练习6-大数乘法(高精度乘法)
  • jenkins部署vue前端项目
  • 【TA/Unity】Shader基础结构
  • TCP套接字
  • 网络配置综合实验全攻略(对之前学习的总结)
  • 医学AI前沿论坛第6期|目前主流的医学AI基础模型有哪些?我们应该如何在有限的数据下构建高性能的基础模型?
  • 某某航空 (新版)同盾 blackbox 补环境
  • 迷宫可达性统计问题详解
  • 缓存三剑客解决方案
  • 基于YOLO11的垃圾分类AI模型训练实战
  • 计算机毕业设计ssm医院耗材管理系统 基于SSM框架的医疗物资供应链管理平台 医院低值易耗品信息化监管系统
  • 解决MySql8报错:Public Key Retrieval is not allowed
  • 六年级数学知识边界总结思考-上册
  • 苍穹外卖项目日记(day05)
  • JavaScript加强篇——第六章 定时器(延时函数)与JS执行机制
  • matplotlib:散点图
  • CCF CSP第一轮认证一本通
  • 【Fargo】发送一个rtp包的过程3:为什么媒体包发送端检测到扩展,接收端检测不到
  • Rail开发日志_7
  • 9.3 快速调用与标准调用
  • 串口连接工控机
  • Gameplay - 独立游戏Celeste的Player源码
  • 失败的面试经历二(ʘ̥∧ʘ̥)
  • 【赵渝强老师】国产数据库TiDB的代理路由:TiProxy
  • K3S滚动发布Jar
  • TCP详解——各标志位
  • 字母异位词分组
  • 闲庭信步使用图像验证平台加速FPGA的开发:第十一课——图像均值滤波的FPGA实现