nginx深度优化
隐藏nginx软件名和版本号
1、调整参数隐藏Nginx版本号信息
一般来说,软件的漏洞都和版本有关,因此我们应尽量隐藏或清除Web服务队访问的用户显示各类敏感信息(例如:Web软件名称及版本号等信息),这样恶意的用户就很难猜到他攻击的服务器所用的是否是特定漏洞的软件,或者是否有对应的漏洞存在。
vim /application/nginx/conf/nginx.conf
http{
server_tokens off;
}
#我们在http标签端开启即可
server_tokens 可以放在http、server、location的标签中
2、更改Nginx源码修改软件名
隐藏了Nginx版本号后,更进一步,可以通过一些手段把web服务软件的名称也给因此,或者更改为其他Web服务软件名迷惑黑客。Nginx模块不支持更改软件名,所以我们需要更改Nginx源代码重新编译nginx才能解决。需要修改三个源码文件,如下:
修改的第一个文件为nginx-1.6.3/src/core/nginx.h
cd /home/goser/tools/nginx-1.6.3/src/core/ vim nginx.h #define NGINX_VERSION "1.2.1" #修改为想要的版本号 #define NGINX_VER "GOSER/" NGINX_VERSION #将nginx修改想要修改的软件名称 #define NGINX_VAR "GOSER" #将nginx修改为想要修改的软件名称。
修改第二个文件nginx-1.6.3/src/http/ngx_http_header_filter_module.c的第49行
vim src/http/ngx_http_header_filter_module.c staticchar ngx_http_server_string[]="Server: GOSER" CRLF; #修改本行,此处的文件是我们Curl 出来显示的名称
修改第三个文件nginx-1.6.3/src/http/ngx_http_special_response.c,对外页面报错时,它会控制是否展示敏感信息。修改28~30行
vim src/http/ngx_http_special_response.c 21static u_char ngx_http_error_full_tail[]= 22"<hr><center>"GOSER"</center>" CRLF 23"</body>" CRLF 24"</html>" CRLF 25; 26 27 28static u_char ngx_http_error_tail[]= 29"<hr><center>GOSER</center>" CRLF
修改完成之后需要重新编译nginx
/application/nginx/sbin/nginx -V nginx version: nginx/1.6.3 built by gcc 4.4.720120313(RedHat4.4.7-16)(GCC) TLS SNI support enabled configure arguments:--prefix=/application/nginx-1.6.3/ --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module 重新编译./configure --prefix=/application/nginx-1.6.3/ --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module 提示:需要停止原来的nginx,从新进行编译。如果不想在覆盖原来的编译参数可以选择指定新的目录。
最后对修改好的软件名和版本号做测试,可以对server_tokens开启或关闭做测试看看设置是否生效
温馨提示:
|
1.提示网站安全,要从最简单、最短板、最低点入手解决问题,门大开着,窗户安装再结实的护栏也没有意义。
2.向有经验的人及优秀的网站公司学习。
3.学习看官方文档,根据一手资料去分析
4.命令输出结果中含有需要过滤或者要保留的内容时,命令自身可能有参数直接实现。
|
更改Nginx服务的默认用户
grep "#user"/application/nginx/conf/nginx.conf.default #user nobody;
更改nginx的默认用户可以直接在编译前在配置文件中指定用户名,或者在编译的时候直接指定一个用户名来作为nginx的默认用户,我们常用的是在编译的时候指定用户名。
第一种 如果是在编译前对配置文件做修改,来指定用户名方式为:
创建一个nginx用户,同时直接更改配置文件参数,将默认的#user nobody修改直接更改配置文件参数,将默认的#user nobody修改如下内容为user nginx nginx
第二种 为直接在编译nginx软件时指定编译的用户和组
./configure --prefix=/application/nginx-1.6.3/ --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_modul
优化Nginx服务的worker进程个数
在高并发、访问量大的Web服务场景,需要事先启动好更多的nginx进程,以保证快速响应并处理大量并发用户的请求.
查看Linux服务一个CPU总核数的方法
grep "processor"/proc/cpuinfo |wc -l #或者使用下面命令查看 grep -c processor /proc/cpuinfo
查看cpu总数是多少
grep "pysical id"/proc/cpuinfo |sort|uniq|wc -l
对查看CPU的总数还可以通过top命令并按1显示

有关worker_process参数的官方说明如下:
syntax: worker_processes number:#此行为参数语法,number为数量 default: worker_processes 1 #此行意思是不配置该参数,软件默认情况为1 context: main #此行为worker_processes参数可以放置的位置 worker_processes为定义worker进程数的数量,建议设置为CPU的核数或者cpu核数*2的进程数,具体情况要根据实际业务来进行选择。除了要和CPU核数的匹配外,和硬盘存储的数据以及系统的负载也会有关,设置为CPU的个数或核数是一个好的起始配置 |
优化绑定不同的Nginx进程到不同CPU上
绑定不同的NGINX进程到不同CPU上,也就是做CPU的亲和力,即对worker_cpu_affinity的配置
默认情况Nginx的多个进程有可能跑在某一个或某一核的CPU上,导致Nginx进程使用硬件的资源不均。可以分配不同的Nginx进程给不同的CPU处理,达到充分有效利用硬件的多CPU多核资源的目的。
worker_processes 4; worker_cpu_affinity 0001001001001000; #worker_cpu_affinity就是配置nginx进程CPU亲和力的参数,即把不同的进程分给不同的CPU处理。这里0001 0010 0100 1000是掩码,分别代表1、2、3、4核cpu核心,由于worker_processes进程数为4,因此上述配置会把每个进程分配一核CPU处理,默认情况下进程不会绑定任何CPU,参数位置为main段

Nginx事件处理模型优化
events {
#events指令是设定Nginx的工作模式及连接数上限
use epoll
}
#use是个事件模块指定,用来指定Nginx的工作模式,Nginx支持的工作模式有select、poll、kqueue、epoll、rtsig和/dev/poll。其中select和poll都是标准的工作迷失,kqueue和epoll是高效工作模式,不同的是epoll用在Linux平台,而kqueue用在BSD系统中。对于Linux 2.6内核推荐使用epoll工作模式
根据Nginx的官方文档建议,也可以不指定事件处理模型,Nginx会自动选择最佳的事件处理模型服务。
调整Nginx单个进程允许的客户端最大连接数
worker_connections的值要根据具体服务器性能和程序的内存使用量来指定(一个进程启动使用的内存根据程序确定)
events {
worker_connections 20480;
}
#worker_connections 也是个事件模块指令,用于定义Nginx每个进程的最大连接数,默认是1024.最大客户端连接数由worker_processes和worker_connections决定.
并发=worker_process * worker_connections
参考资料:http:nginx.org/en/docs/ngx_core_module.html
配置Nginx worker进程最大打开文件数
例如设置worker_rlimit_nofile大小为65535
worker_rlimit_nofile 65535
开启高效文件传输模式
sendfile参数用于开启文件的高效传输模式,同时将tcp_nopush和tcp_nodelay两个指定设为on,可防止网络及磁盘I/O阻塞,提升Nginx工作效率
sendfile官方说明:
syntax: sendfile on|off #参数语法 default: sendfile off #参数默认大小 context: http,server,location,ifin location #可放置的标签段
Syntax: tcp_nopush on | off; #参数语法 Default: tcp_nopush off; #参数默认大小 Context: http, server, location #可以放置标签段
Syntax: tcp_nodelay on | off; Default: tcp_nodelay on; Context: http, server, location
优化Nginx连接参数调整连接超时时间
Syntax: keepalive_timeout timeout [header_timeout];#参数语法 Default: keepalive_timeout 75s;#参数默认大小 Context: http, server, location #可以放置的标签段
参数作用:keep-alive可以使客户端到服务端已经建立的连接一直工作不退出,当服务器有持续请求时,keep-alive会使用正在建立的连接提供服务,从而避免服务器重新建立新连接处理请求。
设置参数:client_header_timeout 15
用于设置读取客户端请求头数据的超时时间,此处的数值15单位是秒。
Syntax: client_header_timeout time; Default: client_header_timeout 60s; Context: http, server
参数作用:设置读取客户端请求头数据的超时时间。如果超过这个时间,客户端还没有发送完整的header数据,服务端将数据返回“Request time out (408)”错误
设置参数:client_body_timeout 15
用于设置读取客户端请求主体的超时时间,默认值是60 Syntax: client_body_timeout time; Default: client_body_timeout 60s; Context: http, server, location
Syntax: send_timeout time; Default: send_timeout 60s; Context: http, server, location
一般放在http标签即可
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
server_names_hash_bucket_size 128;
server_names_hash_max_size 512;
keepalive_timeout 65;
client_header_timeout 15s;
client_body_timeout 15s;
send_timeout 60s;
}
优化服务器域名的bash表大小
举个例子,如果Nginx.org和www.nginx.org来访问服务器最频繁,那么明确的定义出来更为有效
server {
listen 80;
server_name nginx.org www.nginx.org *.nginx.org
location /{
root html/www;
index index.php index.html index.htm;
}
server_names_hash_bucket_size size的值,具体信息如下
server_names_hash_bucket_size size 512;
#默认是512KB 一般要看系统给出确切的值。这里一般是cpu L1的4-5倍
官方说明:
Syntax: server_names_hash_bucket_size size; Default: server_names_hash_bucket_size 32|64|128; Context: http
参数作用:设置存放域名(server names)的最大哈希表大小。
上传文件大小(http Request body size)的限制(动态应用)
设置上传文件大小需要在nginx的主配置文件加入如下参数
client_max_body_size 8m;
具体大小根据公司的业务调整,如果不清楚设置为8m即可
Syntax: client_max_body_size size; Default: client_max_body_size 1m; #默认值是1m Context: http, server, location
参数作用:设置最大的允许客户端请求主体大小,在请求头域有“Content-Length”,如果超过了此配置值,客户端会收到413错误,意思是请求的条目过大,有可能浏览器不能正确的显示这个错误,设置为0表示禁止检查客户端请求主体大小,此参数对服务端的安全有一定的作用。
http://nginx.org/en/docs/http/ngx_http_core_module.html
fastcgi相关参数调优(配合PHP引擎动态服务)
fastcgi_connect_timeout 240; fastcgi_send_timeout 240; fastcgi_read_timeout 240; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; #fastcgi_temp_path /data/ngx_fcgi_tmp; 需要有路径 fastcgi_cache_path /data/ngx_fcgi_cache levels=2:2 keys_zone=ngx_fcgi_cache:512m inactive=1d max_size=40g;
PHP缓存 可以配置在server标签和http标签
fastcgi_cache ngx_fcgi_cache; fastcgi_cache_valid 200 302 1h; fastcgi_cache_valid 301 1d; fastcgi_cache_valid any 1m; fastcgi_cache_min_uses 1; fastcgi_cache_use_stale error timeout invalid_header http_500; fastcgi_cache_key http://$host$request_uri;

nginx做反向代理优化
nginx作为反向代理的话,有些参数是需要优化的,优化配置如下:
server
{
listen 80;
server_name bbs.linuxtone.conf;
index index.html index.htm;
root /date/www;
location / {
root /date/wwwroot/linuxtone/;
proxy_redirect off ;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 50m;
client_body_buffer_size 256k;
proxy_connect_timeout 30;
proxy_send_timeout 30;
proxy_read_timeout 60;
proxy_buffer_size 256k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
proxy_max_temp_file_size 128m;
proxy_pass http://bbs.linuxtone.com;
}
}
配置Nginx gzip 压缩实现性能优化
1.Nginx gzip压缩功能介绍
2.Nginx gzip 压缩的优点
3.需要和不需要压缩的对象
gzip on; gzip_min_length 1k; gzip_buffers 4 32k; gzip_http_version 1.1; gzip-comp_level 9; gzip_types text/css text/xml application/javascript; gzip_vary on;
设置完成之后重启Nginx服务器,在火狐浏览器中安装插件Firebug和YSlow 进行查看页面压缩率
配置Nginx expires 缓存实现性能优化
location ~ .*\.(gif|jpg|png|bmp|swf)$
{
expires 3650d;
}
location ~ .*\.(js|css)$
{
expires 30d;
}
该示例表示当前用户访问网站URL结尾的文件扩展名为上述指定的各种类型的图片时,设置缓存3650天,访问的是js、css代码时本地缓存1一个月
配置可以放在server标签,也可以放在http标签下配置

location ~^/(images|javascript|js|css|flash|media|static)/{
expires 360d;
}
意思是当用户访问URI中包含上述路径(例:images、js、css,这些在服务端是程序目录)时,把访问的内容设置缓存360天,即1年。如果要想缓存30天,设置30d即可
5.Nginx expires功能缺点及解决方法
6.企业网站缓存日期曾经的案例参考
7.企业网站有可能不希望被缓存的内容
Nginx日志相关优化
1、Nginx目前没有类似Apache的通过cronlog或者rotatelog对日志分割处理的能力,但是,运维人员可以通过利用脚本开发、Nginx的信号控制功能或reload重新加载,来实现日志自动切割,轮询。然后在定时任务中将这个切割nginx的日志脚本添加进去。
2、不记录不需要的访问日志,比如访问图片、JS、CSS文件的记录就不需要记录到日志了,因为 对于负载均衡器健康检查节点或某些特定文件(比如图片、js、css)的日志,一般不需要记录下来,因为在统计PV时是按照页面计算的。而且日志写入频繁会大量消耗磁盘I/O,降低服务的性能。
location ~.*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF)?$ {
access_log off;
}
3、访问日志的权限设置
不需要在日志目录上给nginx用户读或写的许可,因为让nginx的用户查看日志存在很大隐患。加入日志目录为/app/logs,则授权方法为:
chown -R root.root /app/logs/ chmod -R 700/app/logs
Nginx站点目录及文件URL访问控制
配置nginx限制指定目录下的指定程序被解析,放在fast_pass的location前面,这样可有效的限制指定的php等动态程序的解析。
location ~ ^/images/.*\.(php|php5|.sh|.pl|.py)$
{
deny all;
}
location ~ ^/static/.*\.(php|php5|.sh|.pl|.py)$
{
deny all;
}
location ~ ^/data/(attachment|avatar)/.*\.(php|php5)$
{
deny all;
}
对于限制目录或URL访问,有的资源只能对内部人员开放,对外部人员禁止、
location ~ ^/docker/ {
allow 202.58.209.56;
deny all;
}
企业问题案例:Nginx做反向代理的时候可以限制客户端IP吗?
解答:可以,具体方法如下。
if ( $remote_addr = 10.0.0.143 ) {
return 403;
}
if ( $remote_addr = 218.247.17.130 ) {
set $allow_access_root 'true';
}
配置Nginx禁止非法域名解析访问企业网站
nginx如何防止用户ip访问网站(恶意域名解析,也相当于是直接ip访问企业网站)
方法1:让使用ip访问的网站的,或者访问经恶意解析域名,收到501错误
但是直接报501错误,从用户体验上不是很好
#放在第一个虚拟主机前面
server{
listen 80 default_server;
server_name _;
return 501;
}
方法2:发现某域名恶意解析到公司的服务器IP,在server标签里添加一下代码即可,若有多个server要多出添加
if ($host !~ ^www/.goser/.com$){
rewrite ^(.*) http://www.goser.com$1 permanent;
}
Nginx图片及目录防盗链解决方案
1.什么是资源盗链
2.常见防盗链 根据http referer 实现防盗链
在HTTP协议中,有一个表头字段叫referer,使用URL格式来表示哪里的链接用了当前网页的资源。通过referer可以检测目标访问的来源网页,如果是资源文件,可以跟踪到显示它的网页地址,一旦检测出来不是本站,马上进行阻止或返回指定的页面。
HTTP Referer是header的一部分,当浏览器向Web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理,Apache、Nginx、Lighttpd三者都支持根据http referer实现防盗链referer是目前网站图片、附件、html最常用的盗链手段。
3、根据cookie防盗链
4.通过加密变换访问路径实现防盗链
防盗链的优化配置示例如下:
location ~* \.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)$ {
valid_referers none blocked *.goser.com goser.com;
if($invalid_referer) {
rewrite ^/ http://www.goser.com/img/nolink.jpg;
}
}
#当然放盗链也可以对某个目录设置
访问nginx web页面不存在时优雅显示
在网站的运行过程中,可能由于页面不存在或者系统过载等原因,导致网站无法正常响应用于的请求,此时Web服务默认会返回系统默认的错误码,或者很不友好的页面。影响用户体验
例如:
server {
listen 80;
server_name www.goser.com;
location /{
root html/www;
index index.php index.html index.htm;
error_page 404 /404.html
}
}
当然如果客户端访问的页面不存在 可以直接对访问的错误码 用首页来显示
比如 error_page 404 http://www.goser.com;
还可以对多个错误码用一个页面来显示:比如天猫网站设置:
error_page 500 501 502 503 504 http://err.tmall.com/error2.html; error_page 400 403 404 405 408 410 411 412 413 414 415 http://err.tmall.com/error1.html;
Nginx防爬虫优化
我们可以根据客户端的user-agents信息,轻松地阻止爬虫取我们的网站防爬虫,例如:
## Block download agents ##
if ($http_user_agent ~* LWP::Simple|BBBike|wget) {
return 403;}
添加内容防止N多爬虫代理访问网站示例
if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot") {
return 403;
}
利用Nginx限制HTTP的请求方法
HTTP最常用的方法为GET/POST,我们可以通过Nginx限制http请求的方法来达到提升服务器安全的目的,例如,让HTTP只能使用GET、HEAD和POST方法配置如下:
#Only allow these request methods
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 501;
}
设置对应的用户相关权限,这样一旦程序有漏洞,木马就有可能被上传到服务器挂载的对应存储服务器的目录里,虽然我们也做了禁止PHP、SH、PL、PY等扩展名的解析限制,但是还是会遗漏一些我们想不到的可执行文件。对于这种情况,该怎么办捏?事实上,还可以通过限制上传服务器的web服务(可以具体到文件)使用GET方法,来达到防治用户通过上传服务器访问存储内容,让访问存储渠道只能从静态或图片服务器入口进入。例如,在上传服务器上限制HTTP的GET方法的配置如下:
## Only allow GET request methods ##
if ($request_method ~* ^(GET)$ ) {
return 501;
}
对于nginx连接php要用到的变量有:
cd /application/nginx/conf/ cat fastcgi_params fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param HTTPS $https if_not_empty; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; # PHP only, required if PHP was built with --enable-force-cgi-redirect fastcgi_param REDIRECT_STATUS 200;
使用普通用户启动Nginx(监牢模式)
useradd inca
su - inca
mkdir conf logs www
cp /application/nginx/conf/mime.types ~/conf/
echo inca >www/index.html
vim conf/nginx.conf
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
worker_rlimit_nofile 65535;
error_log /home/inca/logs/error.log;
user inca inca;
pid /home/inca/logs/nginx.pid;
events {
use epoll;
worker_connections 10240;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#web.fei fa daolian..............
server {
listen 8080;
server_name www.goser.com;
root /home/inca/www;
location / {
index index.php index.html index.htm;
}
access_log /home/inca/logs/web_blog_access.log main;
}
}
用普通用户inca启动nginx的话,首先要关闭root开启的nginx,步骤如下:
/application/nginx/sbin/nginx -s stop su - inca /application/nginx/sbin/nginx -c /home/inca/conf/nginx.conf &>/dev/null lsof -i:80 [1]+ Exit1 /application/nginx/sbin/nginx -c /home/inca/conf/nginx.conf &>/dev/null
这种方式启动nginx类似于mysql多实例的配置
控制Nginx并发连接数
limit_conn_zone参数: 语法:limit_conn_zone key zone=name:size; 上下文:http 用于设置共享内存区域,key可以是字符串,nginx自有变量或前两个组合,如$binary_remote_addr、$server_name。name为内存区域的名称,size为内存区域的大小。 limit_conn参数: 语法:limit_conn zone number; 上下文:http、server、location
对nginx的配置文件配置如下:
cat /application/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
listen 80;
server_name www.goser.com;
location / {
root html;
index index.html index.htm;
limit_conn addr 1; #<==限制单IP的并发连接为1
}
}
}
还可以设置某个目录单IP并发连接数
location /download/ {
limit_conn addr 1;
}
在客户端使用Apache的ab测试工具进行测试
执行ab -c 1 -n 10 http://10.0.0.3进行测试
注意:-c并发数、-n请求总数,10.0.0.3nginx的IP地址

不仅可以限制单IP的并发连接数,还可以限制虚拟主机的总连接数,可以同时使用
nginx配置文件nginx.conf的配置如下:
http{
limit_conn_zone $server_name zone=perserver:10m;
server{
limit_conn perserver 2;#设置此虚拟主机的总连接数为2
}
}
控制客户端请求Nginx的速率
cat /application/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
#<==以请求的客户端IP作为key值,内存区域命名为one,分配10m内存空间,访问速率限制为1秒1次请求(request)
server {
listen 80;
server_name www.etiantian.org;
location / {
root html;
index index.html index.htm;
limit_req zone=one burst=5;
#<==使用前面定义的名为one的内存空间,队列值为5,即可以有5个请求排队等待。
}
}
}
浙公网安备 33010602011771号