#在Nginx配置文件nginx.conf中的http标签段内加入“server_tokens off”
http
{
...
server_tokens off;
...
}
此参数作用是控制http响应报头中,Web服务版本信息的显示,以及错误信息中Web服务版本信息的显示。
server_tokens参数的官方说明如下:
syntax: server_tokens on|off; #此行为参数语法,on为开启状态,off为关闭状态
default: server_tokens on; #此行意思是不配置该参数,软件默认情况的结果
context: http,server,location #此行为server_tokens参数可以放置的位置参数作用:激活或禁止Nginx的版本信息显示在报错信息和Server的响应首部位置中。
测试
#重载nginx后,curl -I 域名/IP 测试
vim /usr/src/nginx-1.12.1/src/core/nginx.h
#修改以下行
13 #define NGINX_VERSION "" #默认是版本号,修改为空则不显示
14 #define NGINX_VER "apache/" NGINX_VERSION #默认为nginx,修改为自定义名称
22 #define NGINX_VAR "APACHE" #默认为NGINX,改为自定义
vim /usr/src/nginx-1.12.1/src/http/ngx_http_header_filter_module.c
#修改49行中server名
49 static u_char ngx_http_server_string[] = "Server: apache" CRLF;
vim /usr/src/nginx-1.12.1/src/http/ngx_http_special_response.c
#22行是定义对外展示的内容,在""字段前加了(ERROR),报错时会显示
22 "
" NGINX_VER "(ERROR)" CRLF
#33行是报错是对外显示的服务名,默认是nginx,改为了apache
36 "
apache " CRLF
curl -I IP
或者浏览器访问一个找不到的页面,查看404错误信息
nginx默认启动用户为nobody,为了安全需要更改系统用户,以用户nginx为例
先添加用户
useradd -M -s /sbin/nologin nginx
然后有两个方法:
第一个办法:
更改nginx配置文件,在第一行添加(或者修改)
#user nobody
改为
user nginx nginx;
注释代表默认是nobody
第二个办法:
编译的时候,指定用户及用户组编译
./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
#使用ps命令可查看进程的user
ps -ef | grep nginx | grep -v grep
新网站在刚配置时,不清楚用户访问量,可以将worker_processes设置为CPU核数或者核数2倍,官方建议为CPU核数
查看cpu总核数(逻辑CPU个数)
grep processor /proc/cpuinfo | wc -l
或者
top 然后按1,显示所有cpu核数
查看物理CPU个数
grep "physical id" /proc/cpuinfo | sort | uniq | wc -l
修改worker为核数,假设为4,可以通过以下方法查看nginx的worker进程数
ps -ef | grep "nginx" | grep -v grep
早期的nginx,不会自动根据cpu数分进程,但是经过很多版本优化后,现在nginx自动会优化进程绑定到不同的cpu上,例如四核CPU,四个worker进程,nginx会默认
自动的分别在每个核上绑定一个worker进程,分担单核压力,配置文件中配置方法为
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
#worker_cpu_affinity就是配置Nginx进程与CPU亲和力的参数,即把不同的进程分给不同的CPU处理。这里0001 0010 0100 1000是掩码,分别代表第1,2,3,4核CPU
#八核掩码
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
#四核掩码
worker_cpu_affinity 0001 0010 0100 1000;
#安装webbench
tar xf webbench-1.5.tar.gz
cd webbench-1.5
mkdir /usr/local/man
make install clean
which webbench.
webbench -c 2000 -t 60 http://192.168.200.122/
#具体的配置参数如下:
events #events指令是设定Nginx的工作模式及连接数上限
{
use epoll;
}
#use是一个事件模块指令,用来指定Nginx的工作模式。Nginx支持的工作模式有select,poll,kqueue,epoll,rtsig和/dev/poll。其中select和poll都是标准的工作模式,kqueue和epoll是高效的工作模式,不同的是epoll用在Linux平台上,而kqueue用在BSD系统中。对于Linux系统Linux2.6+内核,推荐选择epoll工作模式,这是高性能高并发的设置
#6.5和7.5内核不同,选用的事件模型可能不太一样,没有深究
调整worker_connections的值,要根据服务器性能和程序的内存使用量来指定(一个work进程启动使用的内存根据程序确定)
events
{
worker_connections 20480;
#worker_connections也是个事件模块指令,用于定义Nginx每个进程的最大连接数,默认是1024.最大客户端连接数由worker_processes和worker_connections决定,即Max_client= worker_processes*worker_connections。进程的最大连接数受Linux系统进程的最大打开文件数限制,在执行操作系统命令“ulimit -HSn 65535”或配置相应文件后,worker_connections的设置才能生效
}
调整nginx worker进程的最大文件打开数,参数为
work_rlimit_nofile 65535;
#设置在events模块之前的主标签段,建议设置为系统设置的ulimit -n的值,当nginx访问量大的时候,打开多个文件,也会对系统造成一种负担,所以要根据服务器性能来测试
可以利用webbench工具来测试,查看链接数到哪个极值时,nginx服务或者系统会出现宕机的问题,然后进行链接数的限制,这样也可以防止nginx打开文件值太大造成服务器心性能故障
#抓取nginx链接数
netstat -antp | grep nginx | wc -l
sendfile参数用于开启文件的高效传输模式。同时将tcp_nopush和tcp_nodelay两个指令设置为on,可防止网络及磁盘I/O阻塞,提升Nginx工作效率。
开启sendfile后,再开启tcp_nopush参数才有效,作用是把http response
header和文件的开始部分放在一个文件里发布,其积极的作用是减少网络报文段的数量
建议同时开启两个参数
http {
...
sendfile on;
tcp_nopush on;
tcp_nodelay on;
...
}
- 将无用的连接设置为尽快超时,可以保护服务器的系统资源(CPU,内存,磁盘)。
- 恶意用户攻击网站,就会不断地和服务器建立多个连接,消耗连接数,大量消耗服务器的资源,应该及时断掉这些连接。
- PHP程序站点会希望设置成短连接,因为PHP程序建立连接消耗的资源和时间相对要少些。而对于Java程序站点来说,一般建议设置长连接,因为Java程序建立连接消耗的资源和时间更多,这是语言运行机制决定的。
keepalive_timeout参数的官方说明如下:
syntax: keepalive_timeout timeout [header_timeout] #参数语法
default: keepalive_timeout 75s; #参数默认大小
context: http,serverr,location #可以放置的标签段
#tcp_nodelay参数的官方说明如下:
syntax: tcp_nodelay on | off #参数语法
default: tcp_nodelay on; #参数默认大小
context: http,server,location #可以放置的标签段
参数作用:
默认情况下当数据发送时,内核并不会马上发送,可能会等待更多的字节组成一个数据包,这样可以提高I/O性能。但是,在每次只发送很少字节的业务场景中,使用tcp_nodelay功能,等待时间会比较长。
参数生效条件:
激活或禁用TCP_NODELAY选项,当一个连接进入keep-alive状态时生效
用于设置读取客户端请求头数据的超时时间。此处的数值15,其单位是秒,为经验参考值。
#client_header_timeout参数的官方说明如下:
syntax: client_header_timeout time; #参数语法
default: client_header_timeout 60s; #参数默认大小
context: http,server #可以放置的标签段
参数作用:
设置读取客户端请求头数据的超时时间。如果超过这个时间,客户端还没有发送完整的header数据,服务器端将返回“Request time out (408)”错误,可指定一个超时时间,防止客户端利用http协议进行攻击。
#client_body_timeout参数的官方说明如下:
syntax: client_body_timeout time; #参数语法
default: client_body_timeout 60s; #默认60
context: http,server,location #可以放置的标签段
参数作用:
设置读取客户端请求主体的超时时间。这个超时仅仅为两次成功的读取操作之间的一个超时,非请求整个主体数据的超时时间,如果在这个超时时间内,客户端没有发送任何数据,Nginx将返回“Request time out(408)”错误,默认值60
用于指定响应客户端的超时时间。这个超时仅限于两个连接活动之间的时间,如果超过这个时间,客户端没有任何活动,Nginx将会关闭连接,默认值为60秒,可以改为参考值25秒。
#send_timeout参数的官方说明如下:
syntax: send_timeout time; #参数语法
default: send_timeout 60s; #默认值60
context: http,server,location #可以放置的标签段
#首先,我们可以在Nginx主配置文件里加入如下参数:
client_max_body_size 8m;
设置最大的允许的客户端请求主体大小,在请求头域有“Content-Length”,如果超过了此配置值,客户端会受到413错误,意思是请求的条目过大,有可能浏览器不能正确显示。设置为0表示禁止检查客户端请求主体大小。此参数对提高服务器端的安全性有一定作用。
#具体大小根据公司的业务做调整,如果不清楚就先设置为8m把,一般情况下,HTTP的post方法在提交数据时才会携带请求主体信息。
#client_max_body_size参数的官方说明如下:
syntax: client_max_body_size size; #参数语法
default: client_max_body_size 1m; #默认值1m
context: http,server,location #可以放置的1\标签段
Nginx FastCGI相关参数 | 说明 |
---|---|
fastcgi_connect_timeout | Nginx服务器和后端FastCGI服务器连接的超时时间,默认60s,最好不要超过75秒 |
fastcgi_send_timeout | Nginx允许FastCGI服务器返回数据的超时时间,即在规定时间内后端服务器必须传完所有的数据,否则Nginx将断开这个连接,默认60s |
fastcgi_read_timeout | Nginx从FastCGI服务器读取响应信息的超时时间,表示连接建立成功后,Nginx等待后端服务器的响应时间 |
fastcgi_buffer_size | Nginx FastCGI 的缓冲区大小,用来读取从FastCGI服务器端收到的第一部分响应信息的缓冲区大小 |
fastcgi_buffers | 设定用来读取从FastCGI服务器端收到的响应信息的缓冲区大小和缓冲区数量 |
proxy_busy_buffers_size | 用于设置系统很忙时可以使用proxy_buffers大小,官方推荐大小为proxy_buffers*2 |
fastcgi_busy_buffers_size | 用于设置系统很忙时可以使用的 proxy_buffers 大小,官方推荐为fastcgi_buffers*2 |
fastcgi_temp_file_write_size | FastCGI 临时文件的大小,可设置为128~256KB |
fastcgi_temp_path | fastcgi缓存存放的临时目录 |
fastercgi_cache cache_nginx | 开启FastCGI缓存并为其指定以同一个名称,可以有效的降低cpu的负载,并且防止502错误的发生 |
fastcgi_cache_path | 缓存目录,示例:fastcgi_cache_path /data/ngx_fcgi_cache levels=2:2 keys_zone=ngx_fcgi_cache:512m inactive=1d max_size=40g; |
缓存目录,可以设置目录前列层级,比如2:2会成生256*256个子目录,keys_zone是这个缓存空间的名字,cache是用多少内存(提高访问速度),min active表示默认失效时间,max_size表示最大占用磁盘空间,需要注意的是,fastcgi的cache缓存是先写在fastcgi_temp_path再移到fastcgi_cache_path中,建议两个目录放在同一分区 | |
fastcgi_cache_valid 200 302 1h | 指定nginx状态码的缓存时间,这里表示将200和302缓存1小时 |
fastcgi_cache_min_uses | 设置请求几次之后响应被缓存,1表示一次即被缓存,可以提高高频率访问内容的访问速度 |
fastcgi_cache_use_stale | 定义在哪些情况下使用过期缓存 |
fastcgi_cache_key | 定义 fastcgi_cache 的 key |
http {
...
fastcgi_connect_timeout 240; #Nginx允许fcgi连接超时时间
fastcgi_send_timeout 240; #Nginx允许fcgi返回数据的超时时间
fastcgi_read_timeout 240; #Nginx读取fcgi响应信息的超时时间
fastcgi_buffer_size 64k; #Nginx读取响应信息的缓冲区大小
fastcgi_buffers 4 64k; #指定Nginx缓冲区的数量和大小
fastcgi_busy_buffers_size 128k; #当系统繁忙时buffer的大小
fastcgi_temp_file_write_size 128k; #Nginx临时文件的大小
fastcgi_temp_path /data/ngx_fcgi_tmp; #指定Nginx临时文件放置路径
fastcgi_cache_path /data/ngx_fcgi_cache levels=2:2 keys_zone=ngx_fcgi_cache:512m inactive=1d; #指定Nginx缓存放置路径
server {
...
location ~ .*\.(php|php5)?$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
fastcgi_cache ngx_fcgi_cache; #开启fcgi缓存并起名叫ngx_fcgi_cache,很重要,有效降低CPU负载,并且防止502错误发生。
fastcgi_cache_valid 200 302 1h; #指定应答代码的缓存时间,1h=1小时
fastcgi_cache_valid 301 1d; #1d=1天
fastcgi_cache_valid any 1m; #and 1m:将其他应答缓存1分钟
fastcgi_cache_min_uses 1; #待缓存内容至少要被用户请求过1次
fastcgi_cache_use_stale error timeout invalid_header http_500; #当遇到error,timeout,或者返回码500时,启用过期缓存返回用户(返回过期也比返回错误强)
# fastcgi_cache_key http://$host$request_uri;
}
}
}
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,前端为squid2.5时使用1.0),用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP解压,使用默认即可
gzip_comp_level 2;
#压缩比率。用来指定gzip压缩比,1压缩比最小,处理速度最快;9压缩比最大,传输速度快,但处理最慢,也比较消耗CPU资源
gzip_types text/plain application/x-javascript text/css application/xml;
#用来指定压缩的类型,“text/html”类型总是会被压缩,这个就是HTTP原理部分讲的媒体类型
gzip_vary on;
#vary header支持。该选项可以让前端的缓存服务器缓存经过gzip压缩的页面,例如用Squid缓存经过Nginx压缩的数据。
不同的Nginx版本中,gzip_types的配置可能会有不同,上述配置示例适合Nginx 1.6.3
- 简单说,Nginx expires的功能就是为用户访问的网站内容设定一个过期时间,当用户第一次访问这些内容时,会把这些内容存储在用户浏览器本地,这样用户第二次及以后继续访问该网站时,浏览器会检查加载已经缓存在用户浏览器本地的内容,就不会去服务器下载了,直到缓存的内容过期或被清除位置。
- 更深入的理解:expires的功能就是允许通过Nginx配置文件控制HTTP的“Expires”和“Cache-Control”响应头部内容,告诉客户端浏览器是否缓存和缓存多久以内访问的内容。这个expires模块控制Nginx服务器应答时的expires头内容和Cache-Control头的max-age指令。缓存的有效期可以设置为相对于源文件的最后修改时刻或客户端的访问时刻。
- 这些HTTP头向客户端表明了额内容的有效性和持久性。如果客户端本地有内容缓存,则内容就可以从缓存而不是从服务器中读取,然后客户端会检查缓存中的副本,看其是否过期或失效,以决定是否重新从服务器获得内容更新。
expires可以降低网站的带宽,节约成本。
加快用户访问网站的速度,提升用户访问体验。
服务器访问量降低了,服务器压力就减轻了,服务器成本也会降低,甚至可以节约人力成本。
对于几乎所有的Web服务来说,这是非常重要的功能之一,Apache服务也有此功能。
1、根据文件扩展名过滤
范例一:
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 3650d;
}
#当用户访问网站URL结尾的文件扩展名为上述指定类型的额图片时,设置缓存3650天,即10年
范例二:
location ~ .*\.(js|css)$ {
expires 30d;
}
#当用户访问网站URL结尾的文件扩展名为js,css类型的元素时,设置缓存30天,即1个月
2、根据URL过滤
范例1:
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
expires 360d;
}
当用户访问网站URL中包含上述路径(例:images,js,css,这些在服务器端是程序目录)时,把访问的内容设置缓存360天,即1年
curl -I 192.168.200.122
其中有两行是记录expires设置的
Expires: Sat, 09 Sep 2017 02:15:54 GMT #缓存的过期时间
Cache-Control: max-age=864000 #缓存的总时间,单位秒
- 第一,对于经常需要变动的图片等文件,可以缩短对象缓存时间,例如:谷歌和百度的首页图片经常根据不同的日期换成一些节日的图,所以这里可以将这个图片设置为缓存期1天。
- 第二,当网站改版或更新时,可以在服务器将缓存的对象改名(网站代码程序)。
- 对于网站的图片,附件,一般不会被用户直接修改,用户层面上的修改图片,实际上是重新传到服务器,虽然内容一样但是是一个新的图片名了。
- 网站改版升级会修改JS,CSS元素,若改版时对这些元素改了名,会使得前端的CDN及用户端需要重新缓存内容。
cat /server/scripts/cut_nginx_log.sh
#!/bin/bash
#日志切割脚本可挂定时任务,每天00点整执行
Dateformat=`date +%Y%m%d`
Basedir="/usr/local/nginx"
Nginxlogdir="$Basedir/logs"
Logname="access"
[ -d $Nginxlogdir ] && cd $Nginxlogdir || exit 1
[ -f ${Logname}.log ] || exit 1
/bin/mv ${Logname}.log ${Dateformat}_${Logname}.log
$Basedir/sbin/nginx -s reload
添加定时任务
00 00 * * * /bin/bash /server/scripts/cut_nginx_log.sh >/dev/null 2>&1
对于负载均衡器健康节点检查或某些特定文件(比如图片,JS,CSS)的日志,一般不需要记录下来,因为在统计PV时是按照页面计算的,而且日志写入太频繁会消耗大量磁盘I/O,降低服务的性能。
location ~ .*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF)$ {
access_log off;
}
#这里用location标签匹配不记录日志的元素扩展名,然后关闭日志
nginx的日志是启动进程的用户写入,不是程序用户
chown -R root.root /app/logs
chown -R 700 /app/logs
利用nginx配置禁止访问上传资源目录下的PHP,shell,perl,python等程序文件,以防执行木马程序,加强网站安全
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;
}
#对上述目录的限制必须写在Nginx处理PHP(处理动态请求)服务配置的前面
location ~* \.(txt|doc)$
{
if (-f $request_filename)
{
root /data/www/www;
#rewrite ...可以重定向到某个URL
break;
}
}
location ~* \.(txt|doc)$
{
root /data/www/www;
deny all;
}
#禁止访问单个目录:
location ~ ^/static
{
deny all;
}
#禁止访问多个目录:
location ~ ^/(static|js)
{
deny all;
}
server
{
listen 80;
server_name www.yunjisuan.com yunjisuan.com;
root /data/www/www;
index index.html index.htm;
access_log logs/www_access.log commonlog;
location /admin/
{
return 404;
}
location /tmplates/
{
return 403;
}
}
禁止某目录让外界访问,但允许某IP和某些IIP段访问该目录(通过location过滤来限制访问的资源)
location ~ ^/yunjisuan/
{
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
deny all;
}
if ($remote_addr = 10.0.0.7)
{
return 403;
}
if ($remote_addr = 218.247.17.130)
{
set $allow_access_root 'ture';
}
location / {
root html;
index index.php index.html index.htm;
allow 10.0.0.7;
deny all;
}
只允许某些IP访问,或者
location / {
root html/blog;
index index.php index.html index.htm;
deny 10.0.0.7;
allow all;
}
只拒绝某些IP访问
注意事项
24表示子网掩码:255.255.255.0
16表示子网掩码:255.255.0.0
8表示子网掩码:255.0.0.0
以deny all:结尾,表示除了上面允许的,其他的都禁止。如:
deny 192.168.1.1;
allow 127.0.0.0/24;
allow 192.168.0.0/16;
allow 10.10.0.0/16;
deny all;
Nginx防止用户IP访问网站(恶意域名解析,也相当于是直接IP访问企业网站)
server {
listen 80 default_server;
server_name _;
return 501;
}
server {
listen 80 default_server;
server_name _;
rewrite ^(.*) http://主页的URL/$1 permanent;
}
if ($host ! ~ ^www\.yunjisuan\.com$)
{
rewrite ^(.*) http://www.yunjisuan.com/$1 permanent;
}
#说明:代码含义为如果header信息的host主机名字非www.yunjisuan.com,就301跳转到www.yunjisuan.com
在HTTP协议中,有一个表头字段叫referer,使用URL格式来表示是哪里的链接用了当前网页的资源。通过referer可以检测访问的来源网页,如果是资源文件,可以跟踪到显示它的网页地址,一旦检测出来源不是本站,马上进行阻止或返回指定的页面。
对于一些特殊的业务数据,例如流媒体应用通过ActiveX显示的内容(例如Flash,Windows Media视频,流媒体的RTSP协议等),他们不向服务器提供referer header,采用上述referer防盗链手段达不到效果,但会传递Cookie,可以在显示ActiveX的页面的标签内嵌入一段JavaScript代码,设置“Cookie:Cache=av”如下:
<script>document.cookie="Cache=av;domain=domain.com;path=/";</script>
根据Cookie来防盗链的技术比较复杂,企业需要可通过网络来了解相关方法。
#下面的代码为利用referer且针对扩展名rewrite重定向,即实现防盗链的Nginx配置。
location ~* \.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)$
{
valid_referers none blocked *.yunjisuan.com yunjisuan.com; #
if ($invalid_referer)
{
rewrite ^/ http://www.yunjisuan.com/img/nolink.jpg;
}
}
#提示:要根据自己公司的实际业务(是否有外链的合作)进行域名设置。
location /images {
valid_referers none blocked *.yunjisuan.com yunjisuan.com;
if ($invalid_referer) {
return403;
}
}
当referers中的信息,不包括yunjisuan相关域名,就代表源网页不是本站,代表可能被网站盗链,不给他访问,直接返回403
- 推荐使用NginxHttpAccessKeyModule。
- 其运行方式是:如download目录下有一个file.zip文件。对应的URI是http://www.abc.com/download/file.zip,使用ngx_http_accesskey_module 模块后就成了http://www.bac.com/download/file.zipkey=09093abeac094,只有正确地给定了key值,才能下载download目录下的file.zip,而且key值是与用户的IP相关的,这样就可以避免被盗链了
给图片加水印,over
server {
listen 80;
server_name www.yunjisuan.com;
location / {
root html/www;
index index.html index.htm;
}
error_page 403 /403.html;
}
#当出现403错误时,会跳转到403.html页面
#上面的/403.html是相对于站点根目录html/www的
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /data/www/html;
}
#这里指定单独的站点目录存放到50x.html文件中
server {
listen 80;
server_name www.yunjisuan.com;
location / {
root html/www;
index index.html index.htm;
error_page 404 http://bbs.yunjisuan.com;
}
}
#当出现404错误时,会跳转到指定的URL http://bbs.yunjisuan.com页面显示给用户,这个URL一般是企业另外的可用地址
#代码中的/404.html是相对于站点根目录html/www的
location / {
error_page 404 = @fallback;
}
location @fallback {
proxy_pass http://backend;
}