6

构建高效安全的Nginx Web服务器

 3 years ago
source link: http://www.androidchina.net/4835.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

一、为什么选择Nginx搭建Web服务器

Apache和Nginx是目前使用最火的两种Web服务器,Apache出现比Nginx早。Apache HTTP Server(简称Apache)是世界使用排名第一的Web服务器软件,音译为阿帕奇,是Apache软件基金会的一个开放源码Web服务器,可以运行几乎所有的计算机平台,其次开放的API接口,任何组织和个人都可以在它上面扩展和增加各种需要功能,达到为自己量身定制的功能。

Nginx(“engine x”)是一个高性能的HTTP和反向代理 服务器,也是一个 IMAP/POP3/SMTP代理服务器。Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。

在互联网初期,网站大小不是很大,访问量都很轻量,一个网站的访问量一天最多就几万IP,这个时候Apache完全可以满足需要,人们更多的是为它开发各种模块,像重写模块,访问控制列表,缓存模块等等。但是随着互联网的飞速发展,网站我访问量以指数增长,大型网站的除了加大硬件投入外,典型的Web服务器Apache这时候也力不从心了;但是Apache并不是完美的,并且不再适合大规模系统。

为什么?因为他的进程模式虽然简单而灵活,但并不适合大规模尤其是当要处理像PHP这种需要占用大量内存应用程序代码时。于是Nginx开始崛起,最初的设计是俄罗斯工程师为大型网站解决高并发设计的。所以注定了高并发是它永恒的优点。再次就是反向代理,现在大型网站分工详细,哪些服务器处理数据流,哪些处理静态文件,这些谁指挥,一般都是用nginx反向代理到内网服务器,这样就起到了负载均衡分流的作用。再次nginx高度模块化的设计,编写模块相对简单。

Nginx 是一个高性能的 Web 和反向代理服务器,它具有有很多非常优越的特性:

作为 Web 服务器:相比 Apache,Nginx使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 Nginx 尤其受到虚拟主机提供商的欢迎。能够支持高达 50,000个并发连接数的响应,感谢 Nginx为我们选择了epoll and kqueue 作为开发模型。

作为负载均衡服务器: Nginx既可以在内部直接支持 Rails 和 PHP,也可以支持作为 HTTP代理服务器 对外进行服务。Nginx用C编写, 不论是系统资源开销还是 CPU 使用效率都比 Perlbal 要好的多。

Nginx安装非常的简单,配置文件非常简洁(还能够支持perl语法),Bugs非常少的服务器: Nginx启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够在不间断服务的情况下进行软件版本的升级。

二、Nginx安装

1、安装说明

系统环境: CentOS-6.6

软件: nginx-1.8.0.tar.gz

安装方式: 源码编译安装

安装位置: /opt/program/nginx-1.8.0

下载地址: http://nginx.org/en/download.html

2、安装必须软件

# yum install gcc-c++

# yum -y install zlib zlib-devel openssl openssl–devel pcre pcre-devel

# find -name nginx

#./nginx

#./nginx/sbin/nginx

#./nginx-1.2.6/objs/nginx

检查系统已安装的Nginx:

卸载原有的Nginx

# yum remove nginx

3、安装和编译

将安装包文件上传到/opt/software中执行以下操作:

# cd /opt/program

# mkdir nginx

# tar -zxvf ../software/nginx-1.8.0.tar.gz

# cd nginx-1.8.0

# ./configure –prefix=/opt/program/nginx

注:处此是指定Nginx的安装目录,大多用户习惯于安装在/usr/local/nginx下面

# make 编译

# make install 安装

4、配置服务项

修改防火墙配置:

# vi + /etc/sysconfig/iptables

添加配置项

-A INPUT -m state –state NEW -m tcp -p tcp –dport 80 -j ACCEPT

重启防火墙

# service iptables restart

方法1

# /opt/program/nginx/sbin/nginx -c /opt/program/nginx/sbin/nginx/conf/nginx.conf

方法2

# /opt/program/nginx/sbin/nginx

查询nginx主进程号

# ps -ef | grep nginx

# pkill -9 nginx

# /opt/program/nginx/sbin/nginx -s reload

# netstat –na|grep 80

#浏览器中测试

http://ip:80

三、配置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,为所有客户端设置缓冲区的大小限制。

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

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

# 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能给我们带来更多惊喜。

转载请注明:Android开发中文站 » 构建高效安全的Nginx Web服务器


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK