Nginx常用配置及优化安全

Posted henrylinux

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx常用配置及优化安全相关的知识,希望对你有一定的参考价值。

一个站点配置多个域名

server 
    listen       80;
    server_name  demo.ct99.cn demo1.ct99.cn;

server_name 后跟多个域名即可,多个域名之间用空格分隔

一个服务配置多个站点

server 
    listen       80;
    server_name  demo.ct99.cn;

    location / 
        root /home/project/pa;
        index index.html;
    


server 
    listen       80;
    server_name  demo1.ct99.cn;

    location / 
        root /home/project/pb;
        index index.html;
    


server 
    listen       80;
    server_name  demo2.ct99.cn;

    location / 
        root /home/project/pc;
        index index.html;
    

基于nginx虚拟主机配置实现,Nginx有三种类型的虚拟主机
基于IP的虚拟主机: 需要你的服务器上有多个地址,每个站点对应不同的地址,这种方式使用的比较少
基于端口的虚拟主机: 每个站点对应不同的端口,访问的时候使用ip:port的方式访问,可以修改listen的端口来使用
基于域名的虚拟主机: 使用最广的方式,上边例子中就是用了基于域名的虚拟主机,前提条件是你有多个域名分别对应每个站点,server_name填写不同的域名即可

nginx添加账号密码验证

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

有很多服务通过nginx访问,但本身没有提供账号认证的功能,就可以通过nginx提供的authbase账号密码认证来实现,可以用以下脚本来生成账号的密码

nginx开启列目录

当你想让nginx作为文件下载服务器存在时,需要开启nginx列目录

server 
    location download 
        autoindex on;

        autoindex_exact_size off;
        autoindex_localtime on;
    

autoindex_exact_size: 为on(默认)时显示文件的确切大小,单位是byte;改为off显示文件大概大小,单位KB或MB或GB
autoindex_localtime: 为off(默认)时显示的文件时间为GMT时间;改为on后,显示的文件时间为服务器时间
默认当访问列出的txt等文件时会在浏览器上显示文件的内容,如果你想让浏览器直接下载,加上下边的配置

if ($request_filename ~* ^.*?\.(txt|pdf|jpg|png)$) 
    add_header Content-Disposition ‘attachment‘;

配置默认站点

server 
    listen 80 default;

当一个nginx服务上创建了多个虚拟主机时默认会从上到下查找,如果匹配不到虚拟主机则会返回第一个虚拟主机的内容,如果你想指定一个默认站点时,可以将这个站点的虚拟主机放在配置文件中第一个虚拟主机的位置,或者在这个站点的虚拟主机上配置listen default

不允许通过IP访问

server 
    listen       80 default;
    server_name  _;

    return      404;

可能有一些未备案的域名或者你不希望的域名将服务器地址指向了你的服务器,这时候就会对你的站点造成一定的影响,需要禁止IP或未配置的域名访问,我们利用上边所说的default规则,将默认流量都转到404去
上边这个方法比较粗暴,当然你也可以配置下所有未配置的地址访问时直接301重定向到你的网站去,也能为你的网站带来一定的流量

server 
    rewrite ^/(.*)$ https://blog.linuxbaodian.com/$1    permanent;

直接返回验证文件

location = /XDFyle6tNA.txt 
    default_type text/plain;
    return 200 ‘d6296a84657eb275c05c31b10924f6ea‘;

很多时候微信等程序都需要我们放一个txt的文件到项目里以验证项目归属,我们可以直接通过上边这种方式修改nginx即可,无需真正的把文件给放到服务器上

nginx配置upstream反向代理

http 
    ...
    upstream tomcats 
        server 192.168.106.176 weight=1;
        server 192.168.106.177 weight=1;
    

    server 
        location /blog/  
            proxy_pass http://tomcats; 

            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        
    

稍不注意可能会落入一个proxy_pass加杠不加杠的陷阱,这里详细说下proxy_pass http://tomcatsproxy_pass http://tomcats/的区别:

虽然只是一个/的区别但结果确千差万别。分为以下两种情况:
1. 目标地址中不带uri(proxy_pass http://tomcats)。此时新的目标url中,匹配的uri部分不做修改,原来是什么就是什么。

location /blog/ 
    proxy_pass  http://192.168.106.135:8181;

http://domain/blog/ –> http://192.168.106.135:8181/blog/
http://domain/blog/action/abc –> http://192.168.106.135:8181/blog/action/abc

  1. 目标地址中带uri(proxy_pass http://tomcats//也是uri),此时新的目标url中,匹配的uri部分将会被修改为该参数中的uri。
location /blog/ 
    proxy_pass  http://192.168.106.135:8181/;

http://domain/blog/ –> http://192.168.106.135:8181
http://domain/blog/action/abc –> http://192.168.106.135:8181/action/abc

nginx upstream开启keepalive

upstream tomcat 
    server blog.linuxbaodian.com:8080;
    keepalive 1024;


server 
    location / 
        proxy_http_version 1.1;
        proxy_set_header Connection "";

        proxy_pass http://tomcat;
    

nginx在项目中大多数情况下会作为反向代理使用,例如nginx后接tomcat,nginx后接php等,这时我们开启nginx和后端服务之间的keepalive能够减少频繁创建TCP连接造成的资源消耗,配置如上

keepalive: 指定每个nginx worker可以保持的最大连接数量为1024,默认不设置,即nginx作为client时keepalive未生效
proxy_http_version 1.1: 开启keepalive要求HTTP协议版本为HTTP 1.1
proxy_set_header Connection "": 为了兼容老的协议以及防止http头中有Connection close导致的keepalive失效,这里需要及时清掉HTTP头部的Connection

404自动跳转到首页

server 
    location / 
       error_page 404 =  @404page;
    

    location @404page 
       rewrite  .*  / permanent;
    

网站出现404页面不是特别友好,我们可以通过上边的配置在出现404之后给自动跳转到首页去

配置Nginx支持高并发

1、Nginx常规优化
编辑nginx.conf,修改相关参数进行优化。

worker_processes 8;

Nginx 进程数,建议按照CPU数目来指定,一般为它的倍数 (如,2个四核的CPU计为8)。

worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
worker_rlimit_nofile 65535;

这个指令是指当一个Nginx 进程打开的最多文件描述符数目,理论值应该是最多打开文
件数(ulimit -n)与nginx 进程数相除,但是Nginx 分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。现在在linux 2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应应该填写65535。

worker_connections 65535;

每个进程允许的最多连接数, 理论上每台nginx 服务器的最大连接数为worker_processes*worker_connections

keepalive_timeout 60;

keepalive 超时时间。

client_header_buffer_size 4k;

客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。

open_file_cache max=65535 inactive=60s;

这个将为打开文件指定缓存,默认是没有启用的,max 指定缓存数量,建议和打开文件数一致,inactive 是指经过多长时间文件没被请求后删除缓存。

open_file_cache_valid 80s;

这个是指多长时间检查一次缓存的有效信息。

open_file_cache_min_uses 1;

open_file_cache 指令中的inactive
参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive 时间内一次没被使用,它将被移除。

2、内核参数的优化
编辑sysctl.conf优化linux内核。

net.ipv4.tcp_max_tw_buckets = 6000

timewait 的数量,默认是180000。

net.ipv4.ip_local_port_range = 1024 65000

允许系统打开的端口范围。

net.ipv4.tcp_tw_recycle = 1

启用timewait 快速回收。

net.ipv4.tcp_tw_reuse = 1

开启重用。允许将TIME-WAIT sockets 重新用于新的TCP 连接。

net.ipv4.tcp_syncookies = 1

开启SYN Cookies,当出现SYN 等待队列溢出时,启用cookies 来处理。

net.core.somaxconn = 262144

web 应用中listen 函数的backlog 默认会给我们内核参数的net.core.somaxconn 限制到128,而nginx 定义的NGX_LISTEN_BACKLOG 默认为511,所以有必要调整这个值。

net.core.netdev_max_backlog = 262144

每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。

net.ipv4.tcp_max_orphans = 262144

系统中最多有多少个TCP 套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS 攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。

net.ipv4.tcp_max_syn_backlog = 262144

记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M 内存的系统而言,缺省值是1024,小内存的系统则是128。

net.ipv4.tcp_timestamps = 0

时间戳可以避免序列号的卷绕。一个1Gbps 的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉。

net.ipv4.tcp_synack_retries = 1

为了打开对端的连接,内核需要发送一个SYN 并附带一个回应前面一个SYN 的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK 包的数量。

net.ipv4.tcp_syn_retries = 1

在内核放弃建立连接之前发送SYN 包的数量。

net.ipv4.tcp_fin_timeout = 1

如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2 状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60 秒。2.2 内核的通常值是180 秒,3你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB 服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2 的危险性比FIN-WAIT-1 要小,因为它最多只能吃掉1.5K 内存,但是它们的生存期长些。

net.ipv4.tcp_keepalive_time = 30

当keepalive 起用的时候,TCP 发送keepalive 消息的频度。缺省是2小时。
经过以上优化后,Nginx可支持超过5万的并发量。

Nginx安全配置

网络上有太多关于Nginx安全配置的方法,本文根据自己的实际环境,选择适合自己的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、控制缓冲区溢出攻击

编辑nginx.conf,为所有客户端设置缓冲区的大小限制。

vim /usr/local/nginx/conf/nginx.conf

编辑和设置所有客户端缓冲区的大小限制如下:

## 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 ##

4、控制并发连接

使用NginxHttpLimitZone模块来限制指定的会话或者一个IP地址的特殊情况下的并发连接。编辑nginx.conf:

limit_zone slimits $binary_remote_addr 5m;
limit_conn slimits 5;

上面表示限制每个远程IP地址的客户端同时打开连接不能超过5个。

5、限制可用的请求方法

GET和POST是互联网上最常用的方法。Web服务器的方法被定义在RFC 2616。如果Web服务器不要求启用所有可用的方法,它们应该被禁用。下面的指令将过滤只允许GET,HEAD和POST方法:

## Only allow these request methods ##
if ($request_method !~ ^(GET|HEAD|POST)$ ) 
return 444;

## Do not accept DELETE, SEARCH and other methods ##

6、拒绝一些User-Agents

你可以很容易地阻止User-Agents,如扫描器,机器人以及滥用你服务器的垃圾邮件发送者。

## Block download agents ##
if ($http_user_agent ~* LWP::Simple|BBBike|wget) 
return 403;

##

阻止Soso和有道的机器人:

## Block some robots ##
if ($http_user_agent ~* Sosospider|YodaoBot) 
return 403;

7、防止图片盗链

图片或HTML盗链的意思是有人直接用你网站的图片地址来显示在他的网站上。最终的结果,你需要支付额外的宽带费用。需要封锁,并阻止盗链行为。

# Stop deep linking or hot linking
location /images/ 
valid_referers none blocked www.example.com example.com;
if ($invalid_referer) 
return 403;

8、在防火墙级限制每个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链接。

9:配置操作系统保护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-rr 1 root root 925 Jan 3 00:50 error4xx.html
-rw-rr 1 root root 52 Jan 3 10:00 error5xx.html
-rw-rr 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选项来删除这些文件,慎用,很危险,查找到就删除。

10、限制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

五、小结
本文只是根据自己的需要来构建适合自己的Web服务器,希望对各位有所帮助。Nginx是一个好工具好转件,Nginx的功能绝不止限于构建Web服务器,它的更过功能还有待大家继续去开发,我期待Nginx能给我们带来更多惊喜,你也可以在评论区分享你的好方法。

以上是关于Nginx常用配置及优化安全的主要内容,如果未能解决你的问题,请参考以下文章

Nginx常用功能配置及优化

09-nginx常用配置详解

Nginx +Tomcat 动静分离及Tomcat配置文件优化

nginx.conf 配置及基本优化

CentOS7 系统服务器初始化配置安全加固内核升级优化常用软件安装的Shell脚本分享

nginx实战操作(常用命令及配置)