Nginx安全优化与性能调优

Nginx基本安全优化

隐藏Nginx软件版本号信息

通常来讲,软件的漏洞都和版本有关,这个很像汽车的缺陷,同一批次的要有问题就都有问题,别的批次可能就都是好的。所以,咱们应尽可能隐藏或者消除Web服务对访问用户显示各种敏感信息(例如Web软件名称以及版本号等信息),增长恶意用户攻击服务器的难度,从而增强Web服务器的安全性。javascript

我如今在个人CentOS7上编译安装了Nginx,当咱们请求服务器的时候咱们能够经过chrome的调试工具看到咱们请求的服务器Nginx的版本,以下图所示css

假如Nginx1.18.0这个版本有漏洞,那么恶意用户就能够根据这个信息经过漏洞来攻击咱们的服务器html

如今咱们来在Nginx的配置文件nginx.conf中增长一项参数来隐藏Nginx的版本,这样用户就不知道咱们用的是哪一个版本的Nginx了。前端

在nginx.conf中的http标签段内加入server_tokens off;参数,以下图所示java

如今咱们重启服务器再次访问能够看到Nginx版本号已经看不到了node

更改源码隐藏Nginx软件名及版本号

隐藏了Nginx版本号后,更进一步,能够经过一些手段把Web服务软件的名称也隐藏起来,或者改成其余Web服务软件名以迷惑恶意用户。Nginx并不提供修改Nginx软件名称的参数和入口,须要修改源码才行,这里只是提供一个思路,修改源码需慎重,防止修改源码致使服务器不能正常运行。其它服务器软件同理。修改方法自行百度。nginx

修改Nginx服务的默认用户

为了让Web服务更安全,要尽量地改掉软件默认的配置,好比端口、用户等。web

下面就来更改Ninx服务的默认用户。算法

首先,查看Ninx服务对应的默认用户。通常状况下,Ninx服务启动后,默认使用的用户是nobody,查看默认的配置文件命令以下:chrome

grep '#user' nginx.conf.default

为了防止黑客猜到这个Web服务的用户,咱们须要更改成特殊的用户名,例如www、nginx或者特殊点的itbsl,可是这个用户必须是系统里事先存在的,下面以nginx用户为例进行说明

(1)为Nginx服务建立新用户

为Nginx服务创建新用户的操做过程以下:

useradd nginx -s /sbin/nologin -M # 不须要有系统登陆权限,应当禁止其登陆能力

(2)配置Nginx服务,让其使用刚创建的Nginx用户

更改Nginx服务默认使用的用户,方法有两种

第一种是直接修改配置文件参数,将默认的#user nobody;修改成以下内容:

user nginx nginx;

若是注释或不设置上述参数,默认为nobody用户,不推荐使用nobody用户名,最好采用一个普通用户。

第二种方法为直接在编译Nginx软件的时候指定编译的用户名和组,命令以下(推荐使用该种方式):

./configure \
--user=nginx \
--group=nginx \
--prefix=/usr/local/nginx-1.18.0 \
--with-http_v2_module \
--with-http_ssl_module \
--with-http_stub_status_module

提示:在编译Nginx服务时,直接指定用户和组,这样不管配置文件中是否加参数,默认都是nginx用户。

修改参数优化Nginx服务性能

优化Nginx服务的worker进程数

在高并发、高访问量的Web服务场景,须要事先启动好更多的Nginx进程,以保证快速响应并处理大量并发用户的请求。

1.优化NGINX进程对应的配置

优化Nginx进程对应的Nginx服务的配置参数以下:

worker_processes  1; # 指定了Nginx要开启的进程数,结尾的数字就是进程的个数

上述参数调整的是Nginx服务的worker进程数,Nginx有Master进程和worker进程之分,Master为管理进程,真正处理请求的是worker进程。

2.优化Nginx进程个数的策略

worker_processes参数大小的设置最好和网站的用户数量相关联,可若是是新配置,不知道网站的用户数量该怎么办?

搭建服务器时,worker进程数最开始的设置能够等于CPU的核数,且worker进程数要多一些,这样起始提供服务时就不会出现由于访问量快速增长而临时启动新进程提供服务的问题,缩短了系统的瞬时开销和提供服务的时间,提高了服务用户的速度。高流量高并发场合也能够考虑将进程数提升至CPU核数*2,具体状况要根据实际的业务来选择,由于这个参数除了要和CPU核数匹配外,也和硬盘存储的数据及系统的负载有关,设置为CPU的核数是一个好的起始配置,这也是官方的建议。

3.查看Web服务器CPU硬件资源信息

经过/proc/cpuinfo可查看CPU个数及总核数。查看PCU总核数的示例以下:

# 方法一
grep processor /proc/cpuinfo | wc -l
# 方法二
grep -c processor /proc/cpuinfo

经过top命令,而后按数字1,便可显示全部的CPU核数,以下:

4.修改服务器Nginx配置

个人服务器时1核2G,假设服务器的CPU颗数为1颗,核数为4核,咱们将参数值改成4

worker_processes  4;

修改并保存后,优雅重启Nginx,使修改生效,以下:

nginx -s reload

如今检查修改后的worker进程数量,以下:

# 假如Nginx监听的是8端口
lsof -i:80
# 或者经过以下命令查看
ps -ef | grep nginx | grep -v grep

worker_process可知,worker的进程数为4个。Nginx Master主进程不包含在这个参数里,Nginx Master的主进程为管理进程,负责调度和管理worker进程。

绑定不一样的Nginx进程到不一样的CPU上

默认状况下,Nginx的多个进程有可能跑在某一个CPU或CPU的某一核上,致使Nginx进程使用硬件的资源不均,因此咱们须要配置Nginx与CPU的亲和力参数,尽量地分配不一样的Nginx进程给不一样的CPU处理,打到充分有效利用硬件的多CPU多核资源的目的。

在优化不一样的Nginx进程对应不一样的CPU配置时,四核CPU服务器的参数配置参考以下:

worker_processes  4;
# worker_cpu_affinity就是配置Nginx进程与CPU亲和力的参数,即把不一样的进程分给不一样的CPU处理。这里0001 0010 0100 1000
# 是掩码,分别表明第一、二、三、4核CPU,因为worker_processes进程数为4,所以,该配置会吧每一个进程分配一核CPU处理,默认状况
# 下进程不会绑定任何CPU,参数位置为main段
worker_cpu_affinity 0001 0010 0100 1000;

八核CPU服务器的参数配置参考以下:

worker_processes  8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;

Nginx事件处理模型优化

Nginx的链接链接处理机制在不一样的操做系统会采用不一样的I/O模型,在Linux下,Nginx使用epoll的I/O多路复用模型,在Freebsd中使用kqueue的I/O多路复用模型,在Solaris中使用/dev/poll方式的I/O多路复用模型,在Windows中使用的是icop,等等。

要根据系统类型选择不一样的事件处理模型,可供使用的选择有use [kqueue|rtsig|epoll|/dev/poll|select|poll]。我使用的是CentOS7,所以将Nginx的时间处理模型调整为epoll模型。

具体的配置参数以下:

# events指令是设定Nginx的工做模式及链接数上限
events {
    use epoll;
    worker_connections  10240;
}
# use是一个事件模块指令,用来指定Nginx的工做模式。Nginx支持的工做模式有select、poll、kqueue、epoll、rtsig和/dev/poll
# 其中select和poll都是标准的工做模式,kqueue和epoll是高效的工做模式,不一样的是epoll用在Linux平台上,kqueue用在BSD系统中。对于Linux系统Linux2.6+的内核,推荐选择epoll工做模式,这是高性能高并发的设置

调整Nginx单进程容许的客户端最大链接数

接下来,调整Nginx单个进程容许的客户端最大链接数,这个控制链接数的参数为worker_connections

events {
    # worker_connections也是个事件模块指令,用于定义Nginx每一个进程的最大链接数,默认是1024。最大客户端链接数由
    # worker_processes和worker_connections决定,即Max_client=worker_processes*worker_connections。进程
    # 的最大链接数受Linux系统进程的最大打开文件数限制,在执行操做系统命令`ulimit -HSn 65535`或配置相关文件后,
    # worker_connections的设置才能生效
    worker_connections  10240;
}

说明:worker_connections用来设置一个worker process支持的最大并发链接数,这个链接数包括了全部链接,例如:代理服务器的链接、客户端的链接等,实际的并发链接数除了受worker_connections参数控制外,还和最大打开文件数 worker_rlimit_nofile有关,Nginx总并发链接=worker数量 * worker_connections。

配置Nginx worker进程最大打开文件数

接下来,调整配置Nginx worker进程的最大打开文件数,这个控制链接数的参数为worker_rlimit_nofile。该参数的实际配置以下:

# 最大打开文件数,可设置为系统优化后的ulimit -HSn的结果,调整系统文件描述和这个问题有相同之处
worker_rlimit_nofile 65535;

开启高效文件传输模式

1.设置参数: sendfile on;

sendfile参数用于开启文件的高效传输模式。同时将tcp_nopush和tcp_nodelay两个指令设置为on,可防止网络及磁盘I/O阻塞,提高Nginx工做效率。

sendfile    on;

2.设置参数:tcp_nopush on;

参数做用:激活或禁用

限制文件上传大小

下面介绍如何调整上传文件的大小(http Request body size)限制。

在nginx.conf的http段增长以下配置参数:

client_max_body_size 10m; # 最大容许上传的文件大小根据业务需求来设置

若是上传的文件大小超过该设置,那么就会报413 Request Entity Too Large的错误。

配置gzip压缩实现性能优化

Nginx gzip压缩功能介绍

Nginx gzip压缩模块提供了压缩文件内容的功能,用户请求的内容在发送到用户客户端以前,Nginx服务器会根据一些具体的策略实施压缩策略,以节约网站出口带宽,同时加快数据传输效率,来提高用户访问体验。

Nginx gzip压缩的优势

  • 提高网站用户体验:发送给用户的内容小了,用户访问单位大小的页面就加快了,用户体验提高了,网站口碑就行了
  • 节约网站带宽成本:数据是压缩传输的,所以节省了网站的带宽流量成本,不过压缩时会稍微消耗一些CPU资源,这个通常能够忽略不计

须要和不须要压缩的对象

  • 纯文本内容压缩比很高,所以,纯文本的内容最好进行压缩,例如:html、css、js、xml、shtml等格式的文件
  • 被压缩的纯文本文件必须大于1KB,因为压缩算法的特殊缘由,极小的文件压缩后可能反而变大
  • 图片、视频(流媒体)等文件尽可能不要压缩,由于这些文件大多都是通过压缩的,若是再压缩极可能不会减少或减少不多,或者可能增大,同事压缩时还会消耗大量的CPU、内存资源

参数介绍及配置使用

此压缩功能与早期的Apache服务的mod_deflate压缩功能很类似,Nginx的gzip压缩功能依赖于ngx_http_gzip_module模块,默认已安装。

对应的压缩参数说明以下:

#压缩配置
# 开启gzip压缩功能
gzip on;  
# 设置容许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取。默认值是0,表示无论页面多大都进行压缩。
# 建议设置成大于1K,若是小于1K可能会越压越大
gzip_min_length 1k; 
# 压缩缓存区大小。表示申请4个单位的位16K的内存做为压缩结果流缓存,
# 默认值是申请与原始数据大小相同的内存空间来存储gizp压缩结构
gzip_buffers 4 16k;
# 压缩版本(默认1.1),用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器都支持GZIP解压,使用默认便可
gzip_http_version 1.1;
# 压缩比率。用来指定gzip压缩比,1压缩比最小,处理速度最快;9压缩比最大,传输速度快,但处理最慢,也比较消耗CPU资源
gzip_comp_level 2;
# 用来指定压缩的类型
gzip_types text/plain text/css text/xml application/javascript;
# vary header支持。该选项可让前端的缓存服务器缓存通过gzip压缩的页面,例如用Squid缓存通过Nginx压缩的数据
gzip_vary on;

不一样Nginx版本中,gzip_types的配置可能会有不一样,对应的文件类型,请查看安装目录的mime.types文件

增长http accept-ranges头来提升性能

网页的图片,js ,css ,视频 都加 http accept-ranges头,以支持多线程加载,断点续传,提升性能!目前各大网站都在使用此方式!

server {
  listen 80;
  server_name p2hp.com;
  location ~ ^/(img/|js/|css/|upload/|font/|fonts/|res/|video) {
    add_header Access-Control-Allow-Origin *;
    add_header Accept-Ranges bytes;
    root /var/www/...;
    access_log off;
    expires 30d;
  }
}

Nginx日志相关优化与安全

Nginx access日志切割

为何要作日志切割?

由于随时系统访问量的增加,访问日志里会出现愈来愈多的数据,若是不去按照时间去作合理的日志切割,访问日志里的数据多到没法打开的地步,因此须要作日志切割。

建立一个runlog.sh文件,按天切割

LOGPATH=/usr/local/nginx/logs/access.log
BASEPATH=/usr/local/nginx/logs/access/$(date -d yesterday +%Y%m)

mkdir -p $BASEPATH

BACKUP=$BASEPATH/$(date -d yesterday +%Y%m%d).access.log

mv $LOGPATH $BACKUP
touch $LOGPATH
/usr/local/nginx/sbin/nginx -s reopen

而后配合定时任务,天天零点切割一次

0 0 * * * sh /usr/local/nginx/logs/runlog.sh

Nginx图片及目录防盗链解决方案

若是咱们本身网站内的图片资源被其它网站所盗用,这会增长本身网站的带宽资源,增长不少额外的消耗,并且会对咱们系统的稳定性有影响,为了防止本身网站上的图片资源被其它网站所盗用,咱们须要给本身的服务器配置防盗链。

在Nginx的配置文件nginx.conf的 server段匹配图片资源容许的域名,,不匹配的直接重定向到其它链接或者直接返回403错误。

# 图片防盗链
location ~* \.(png|jpg|jpeg|gif|swf|flv)$ {
    valid_referers none blocked www.test.com *.test.com;
    if ($invalid_referer) {
        # 若是有盗链的状况就使用url重写到错误页面(示例重定向到了百度首页logo图片)
        rewrite ^/ https://www.baidu.com/img/bd_logo1.png?qua=high;
        # 或者直接返回403错误码
        #return 403;
    }
}

Nginx防爬虫优化

robots.txt机器人协议介绍

Robots协议(也称为爬虫协议、机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站经过Robots协议告诉搜索引擎那些页面能够抓取,那些页面不能抓取。

Nginx防爬虫优化配置

咱们能够根据客户端的user-agent信息,轻松地阻止指定的爬虫爬取咱们的网站。下面来看几个案例。

范例1:阻止下载协议代理,命令以下:

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

说明:若是用户匹配了if后面的客户端(例如wget),就返回403

范例2:测试禁止不一样的浏览器软件访问

示例代码以下:

if ($http_user_agent ~* "Firefox|MSIE") {
    rewrite ^(.*) http://www.baidu.com/$1 permanent;
}

若是浏览器为FireFox或IE,就会跳转到http://www.baidu.com。

整理自:
跟老男孩学Linux运维:Web集群实战,机械工业出版社
网页的图片,js ,css ,视频 都加 http accept-ranges头,以提升性能

若是该文章对您有帮助,请点击推荐,感谢。

相关文章
相关标签/搜索