Nginx ngx_http_limit_conn ngx_http_limit_conn模块(请求限制和连接数限制)使用指南

限制单IP地址请求频率:
http://nginx.org/en/docs/http/ngx_http_limit_req_module.html

限制每个IP地址发起的请求数:
http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html

http 字段加入以下内容:

# traffic control
# The module is used to limit the request processing rate per a defined key, in particular,
# the processing rate of requests coming from a single IP address.
# The limitation is done using the “leaky bucket” method.
limit_req_zone $binary_remote_addr zone=perip:10m rate=60r/s;

# The module is used to limit the number of connections per the defined key;
limit_conn_zone $binary_remote_addr zone=perconn:10m;

server {
listen 80;
server_name www.zhangluya.com;
charset utf-8;

location / {

# 队列模式 burst=1500 相当于超过限制速率的IP地址将会进入队列状态,如果api_ip zone处理完毕
# 将会放行队列中的请求,如果队列中的请求=1500满了,请求直接退回 客户端会收到一个服务器繁忙的请求;
# 排队不会一直继续 nginx的超时设置会限制排队在一定时间内的请求 直接退回 返回服务器繁忙请求.
limit_req zone=perip burst=1500;

# 非队列模式
# limit_req zone=one burst=8 nodelay; #不用队列burst=0

# allow only sixty connection per an IP address at a time
limit_conn perconn 100;

proxy_pass http://127.0.0.1:81;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

}

升级nginx启用http2并设置HSTS强制使用https

nginx 升级1.12 开启HTTP2

最近把网站升级到了HTTPS, 之后还将把当前一些应用的WebSocket 连接升级为 WSS连接,以安全地传输消息。最开始我本是为了测试 HTTP2 不限制请求并发数在切片请求中的优势。 但为了实现这一点,就顺手给网站在 Godaddy 上申请了域名和解析,并且通过Let’s Encrypt (这篇博文很清楚http://www.jianshu.com/p/edecc78719cb) 申请了SSL 证书。

ssllabs 安全评测 https://www.ssllabs.com/ssltest

未分类

关于OpenSSL 和 Nginx 新版本的本地编译安装就不多说了,我基本都是在linux 云服务器上搞,注意make 之前给Nginx configure 一下, 使得编译时导出这俩与HTTP2相关的module

.configure --prefix=/etc/nginx --with-http_ssl_module --with-http_v2_module

make 结束后,便会在objs 文件夹中生成按照刚才配置编译的 nginx,软连接一下即可,杀掉原来的nginx 服务实例。启动这个带有http2 module 的nginx,在网站配置中加入对端口的监听,并采用HTTP2 协议即可:

# ssl configuration
listen 443 ssl http2 default_server;
ssl on;
# ... 指定 证书和密钥地址

未分类

开启HSTS

这回主要记一下关于STS 的事儿。HTTP Strict Transport Security (通常简称为HSTS) 是一个安全功能,它通过服务器response header的形式告诉浏览器只能通过HTTPS访问当前资源, 禁止HTTP方式.

摘自:https://developer.mozilla.org
一个网站接受一个HTTP的请求,然后跳转到HTTPS,用户可能在开始跳转前,通过没有加密的方式和服务器对话,比如,用户输入http://foo.com或者直接foo.com。

这样存在中间人攻击潜在威胁,跳转过程可能被恶意网站利用来直接接触用户信息,而不是原来的加密信息。

网站通过HTTP Strict Transport Security通知浏览器,这个网站禁止使用HTTP方式加载,浏览器应该自动把所有尝试使用HTTP的请求自动替换为HTTPS请求

现实案例

你连接到一个免费WiFi接入点,然后开始浏览网站,访问你的网上银行,查看你的支出,并且支付一些订单。很不幸,你接入的WiFi实际上是黑客的笔记本热点,他们拦截了你最初的HTTP请求,然后跳转到一个你银行网站一模一样的钓鱼网站。 现在,你的隐私数据暴露给黑客了。

Strict Transport Security解决了这个问题;只要你通过HTTPS请求访问银行网站,并且银行网站配置好Strict Transport Security,你的浏览器知道自动使用HTTPS请求,这可以阻止黑客的中间人攻击的把戏。

Nginx 设置HSTS

编辑你的Nginx具体网站配置文件,在SSL Configuration 中添加SSL key和cert 签名证书,并且配置add header,让每一个http response 都具有STS 字段。

// nginx 网站部分配置内容
# ssl configuration
listen 443 ssl http2 default_server;
ssl on;
ssl_certificate [cert 路径]
ssl_certificate_key [private key 路径]
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; "
  • max-age 表示STS 策略的过期时间,也就是浏览器在收到带有 Strict Transport Security – response header 多久后过期,就可以转为http 请求。
  • includeSubdomains 表明 STS 策略也应用到 当前域名的子域名。

如此这般,就已经开启了STS,这使得服务器每次response都告诉浏览器所有请求都强制使用https,就算用户手动输入http 地址也会在浏览器内部替换为https 请求,在根源上杜绝浏览器与服务器建立非安全连接。

未分类

写在最后

为什么我一定要对网站启用https,主要是为了测试 https 对数据传输的加密,网站性能。特别是涉及到用户个人聊天记录、支付信息等隐私数据,必须采用 SSL加密传输,才能防止数据传输过程被中间人劫持、篡改。
如今网络安全形式愈演愈烈,不论是阿里巴巴还是百度,都在几年前率先全站升级为HTTPS,GeoQ Ana这样的在线制图平台也采用HTTPS 来实现用户隐私数据(往往是商业数据)的上传,保证平台的数据安全性。

配置nginx uwsgi部署Django项目

概念

  • Nginx:
    是一款面向性能设计的HTTP服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势

  • uwsgi:
    是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。

  • 运行过程:
    nginx作为服务器的最前端,它将接受WEB的所有请求,统一管理请求。nginx把所有静态请求自己来处理(这是nginx的强项,静态文件像我们django博客项目中的static文件夹下面的图片,css,js)。然后nginx将所有的非静态请求(像显示文章的详细信息,通常这类信息都保存在数据库,因此需要调用数据库获取数据)通过uwsgi传递给Django,由django来处理,从而完成一次WEB请求。uwsgi的作用就类似一个桥接器,起到桥梁的作用。

部署环境

阿里云服务器ubuntu14.04 (域名买了还没备案,所以博客暂时是通过ip访问的)

  • python3.5.2
  • nginx 1.4.6
  • uwsgi 2.0.15
  • django 1.11.3
  • markdown 1.0.1

一:安装nginx

打开putty远程控制云服务器输入账号和密码:

sudo apt-get install update 更新ubuntu库资源
sudo apt-get install nginx  安装nginx:
service nginx restart  启动nginx(重启)这个命令在后面要常用到

访问:http://59.110.155.51(这是我的云服务器的ip)

未分类

出现上图,则说明nginx启动成功

二:安装uwsgi

sudo apt-get install python3-pip
pip3 install uwsgi

测试uwsgi,创建test.py文件(注意:Linux创建目录的命令是:mkdir,创建test.py用 “vi test.py”命令)

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"]

函数名字application,这是默认的函数,uwsgi的Python加载器将会搜索这个名字
把它部署到htto端口8000(现在运行uwsgi来启动一个会把请求传递给你的wsgi应用的http服务器):

uwsgi --http :8000 --wsgi-file test.py

未分类

出现上图,则说明测试成功。

三:从github上获取django项目

sudo apt-get install git 安装git
git clone https://github.com/xuna123/Django_study1.git

四:安装django和markdwon:

pip3 install django
pip3 install markdown

五:将nginx+uwsgi部署到django博客项目

我们实现的目录:

未分类

在我们从Git拉下来Django_study1项目的时候,在子目录下回自动帮我们生成wsgi.py文件,所以我们只需要创建

myweb_uwsgi.ini配置文件。

vim myweb_uwsgi.ini

文件内容:

# Django-related settings

socket = :8000

# the base directory (full path)
chdir           = /root/Django_study1


# Django s wsgi file
module          = easyblog.wsgi

# process-related settings
# master
master          = true

# maximum number of worker processes
processes       = 4

# ... with appropriate permissions - may be needed
# chmod-socket    = 664
# clear environment on exit
vacuum          = true

文件意思:

    • socket :指定项目执行的端口号
    • chadir :指定项目的目录
    • module :可以这么来理解,对于- myweb_uwsgi.ini文件来说,与它的平级的有一个easyblog目录,这个目录下有一个wsgi.py文件
    • master :允许主线程存在(true)
    • processes:开启的进程数量(这里是开启4个进程)
    • vacuum :当服务器退出的时候自动清理环境,删除unix socket文件和pid文件

配置nginx:

接下来要做的就是修改nginx的配置文件,打开/etc/nginx/sites-available/default文件,删除所有内容,写入下面内容:

server {
    listen         8099;
    server_name    59.110.155.51
    charset UTF-8;
    access_log      /var/log/nginx/myweb_access.log;
    error_log       /var/log/nginx/myweb_error.log;

    client_max_body_size 75M;

    location / {
        include uwsgi_params;
        uwsgi_pass 59.110.155.51:8000;
        uwsgi_read_timeout 2;
    }
    location /static {
        expires 30d;
        autoindex on;
        add_header Cache-Control private;
        alias /Django_study1/blog/static;
     }
 }
  • listen 指定的是nginx代理uwsgi对外的端口号(这个要自己阿里云服务器的安全组中添加)

  • server_name : 服务器的名字,(因为暂时没有域名,就写的ip地址)

  • access_log :用来指定日志文件的存放路径

  • error_log :用来指定错误日志文件的存放路径

  • include uwsgi_params “一般来说,你只需包含uwsgi_params文件 (包含在nginx发行版本中),使用uwsgi_pass指令来设置uWSGI socket的地址。

  • uwsgi_pass 设置uwsgi服务器的协议和地址,协议可是uwsgi或suwsgi(uwsgi over ssl); 地址可以是ip地址,域名,和可选的端口。

  • uwsgi_read_timeout:指令的含义是如果视图函数处理的时间超时,uwsgi便会关闭连接,这个关闭只是针对Nginx这边的关闭,视图函数还会继续执行,处理完成后,视图函数那边会报IO写入。

  • expires 30d:意味着静态和媒体文件夹中的所有内容将在30天内由浏览器缓存,但不会删除任何内容,您将无需重新生成服务器中的任何内容。

  • autoindex on;启用目录流量, 默认为off,显示的文件时间为GMT时间。改为on后,显示的文件时间为文件的服务器时间。

  • add_header Cache-Control private: HTTP协议的Cache -Control指定请求和响应遵循的缓存机制。private(默认): 只能在浏览器中缓存, 只有在第一次请求的时候才访问服务器, 若有max-age, 则缓存期间不访问服务器。

  • alias /Django_study1/blog/static; 静态文件的位置(暂时这么理解)

接下里还有 一部修改settings.py里面的8ALLOWED_HOSTS增加我们访问的ip,如下:

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['localhost','59.110.155.51']

现在我们重启nginx 和uwsgi:

service nginx restart
uwsgi --ini myweb_uwsgi.ini

未分类

Linux Nginx性能调优

Nginx以高性能负载均衡、缓存和web服务器出名,支撑着世界上繁忙网站中的40%。大多数使用场景下,Nginx和Linux系统的默认配置表现较好,但是仍有必要做一些调优以期达到最佳性能。这篇文章讨论当调优系统时需要考虑的一些Nginx和Linux配置。这些配置有很多,但是在本文里我们只涉及适合大多数用户的配置。那些没有涉及到的配置,只有那些对Nginx和Linux有深入理解的人,或者Nginx专家服务团队推荐,才会考虑到。Nginx专家服务,已经和世界上一些繁忙网站合作来调优Nginx以达到最大限度的性能,并且可以对任何需要充分发挥系统能力的客户提供支持。

简介

这里假定读者对Nginx架构和配置概念有个基本了解。本文不会重复Nginx文档的内容,而是概述各种配置选项并提供相关文档链接。

调优时,有一条较好的准则是,一次只改一个配置项,如果改后没有性能上的提升,就退回为原先的值。

我们先讨论Linux调优,因为有些值会影响在Nginx配置中可以用的值。

Linux配置

现代Linux内核(2.6+)能够很好的调节各种配置,有些配置您可能想更改。如果操作系统配置太低,那么会在内核日志中看到错误信息,因此需要调节这些配置。Linux配置项很多,本文只提及那些在普通工作负载下最可能需要调优的配置项。如果需要这些配置的详细信息,请参考Linux文档。

Backlog队列

以下设置与连接及其如何排队直接相关。如果传入的连接率很高而性能水平参差不齐,比如一些连接似乎被暂停了,那么更改这些配置可能会有用。

  • net.core.somaxconn 该项设置等待被Nginx接受的连接的排队大小。由于Nginx接受连接速度非常快,这个值通常不需要非常大,但是默认值是非常低的,所以如果你有一个高流量网站,增加这个值是个好主意。如果设置过低,那么你能在内核日志中看到错误信息,这时你应该增加这个值直到没有错误信息。注意:如果你将其设置为大于512的值,你应该同时用listen指令的backlog参数匹配这个值来更改Nginx的配置。

  • net.core.netdev_max_backlog 该项设置在交由CPU处理之前网卡缓冲数据包的速率。对于拥有高带宽的机器,这个值可能需要增加。查看网卡文档寻求相关建议,或者检查内核日志相关错误信息。

文件描述符

文件描述符是一种操作系统资源,用来处理诸如连接和打开文件的事情。对每一个连接,Nginx可以用上多达两个文件描述符。例如,如果Nginx用作代理,则其中一个用于客户端连接,另一个用于连接到被代理的服务器。如果使用了HTTP keepalive,则连接描述符的使用会少得多。对于有大量连接的系统,如下设置可能需要进行调整:

  • sys.fs.file_max 这是系统范围内的文件描述符限制。
  • nofile 这是用户级别的文件描述符限制,在/etc/security/limits.conf文件中配置

临时端口

当Nginx被当作代理使用时,每一个到upstream服务器的连接都使用一个临时端口。

  • net.ipv4.ip_local_port_range 这个用来指定可以使用的起止端口号。如果你看到端口耗尽,你可以增加这个范围。常见的设置为1024到65000。

  • net.ipv4.tcp_fin_timeout 这个用于指定一个不再被使用的端口多久之后可以被另一连接再次使用。通常,这个值默认为60秒,但是可以安全地减少到30甚至15秒。

Nginx配置

下面是一些可能影响性能的Nginx指令。如前所述,我们仅讨论那些推荐大多数用户调整的指令。这里未提及到的任何指令,如果没有Nginx团队的指导,不推荐更改。

工作进程

Nginx可以运行多个工作进程,每个都能处理大量连接。你可以用如下指令控制工作进程个数以及连接如何被处理:

  • worker_processes 这个控制Nginx运行的工作进程个数。大多数情况下,一个CPU核心跑一个工作进程能够工作得很好。可以将该指令设为auto来达到与CPU核心数匹配的工作进程数。有时候,可以增加这个值,比如工作进程需要处理大量磁盘IO操作的时候。这个值默认为1。

  • worker_connections 这个表示每个工作进程同时能够处理的最大连接数。默认值是512,但是大多数系统能处理更大的值。这个值该设为多少取决于服务器硬件配置以及流量的特性,可以通过测试来发现。

Keepalives

持久连接可以减少打开和关闭连接所需要的CPU和网络开销,因而对性能有重大影响。Nginx终止所有客户端连接,并具有到upstream服务器的单独连接。Nginx支持客户端和upstream服务器的持久连接。如下指令涉及客户端持久连接:

  • keepalive_requests 这表示客户端能在单个持久连接上发送多少请求。默认值是100,可以设置成更高的值,这在负载生成器从单个客户端发送大量请求的测试场景中非常有用。

  • keepalive_timeout 表示一个空闲持久连接保持打开状态多长时间。

如下指令涉及upstream持久连接:

  • keepalive 这个指定每个工作进程连接到upstream服务器的空闲持久连接数量。这个指令没有默认值。

为了启用到upstream的持久连接,需要增加如下指令:

  • proxy_http_version 1.1;

  • proxy_set_header Connection “”;

Access日志

记录每个请求需要花费CPU和IO周期,减少这种影响的一种方法是启用access日志缓冲。这将导致Nginx缓冲一系列日志条目,然后一次性写入文件而不是单个单个写入。通过指定access_log指令的”buffer=size”选项可以打开access日志缓冲,该设置指定要使用的缓冲区的大小。你还可以使用”flush=time”选项告诉Nginx多长时间后把缓冲区中的条目写入文件。定义了这两个选项后,当缓冲区放不下下一条日志,或者缓冲区中的条目超过了flush参数指定的时间,Nginx会将缓冲区中的条目写入日志文件。当工作进程重新打开日志文件或者关闭时,缓冲区中的条目也会被写入文件。也可以完全禁用access日志记录。

Sendfile

Sendfile是一个操作系统特性,可以在Nginx上启用。它通过在内核中从一个文件描述符向另一个文件描述符复制数据,往往能达到零拷贝,因而可以提供更快的TCP数据传输。Nginx可以使用该机制将缓存或者磁盘上的内容写到socket,无需从内核空间到用户空间的上下文切换,因而非常快并且使用较少的CPU开销。由于数据永远不会触及用户空间,所以不可能把需要访问数据的过滤器插入到处理链中,不能使用任何需要改变内容的Nginx过滤器,比如gzip过滤器。Nginx默认没有启用该机制。

限制

Nginx和Nginx Plus允许设置各种限制,用来控制客户端资源消耗,以防影响系统性能以及用户体验和安全。以下是一些相关指令:

  • limit_conn / limit_conn_zone 这些指令可以用来限制Nginx允许的连接数,比如来自单个客户端IP地址的连接数。这可以防止单个客户端打开太多连接而消耗太多资源。

  • limit_rate 这个用来限制客户端在单个连接上允许使用的带宽。这可以防止某些客户端导致系统超载,因而有利于为所有客户端提供QoS保证。

  • limit_req / limit_req_zone 这些指令可以用来限制Nginx的请求处理速率。与limit_rate一起,可以防止某些客户端导致系统超载,因而有利于为所有客户端提供QoS保证。这些指令也可以用来增强安全性,尤其是对登录页面,通过限制请求速率,使得其对人类用户是合适的,而会减慢试图访问你的应用的程序。

  • max_conns 这个用来限制同时连接到upstream组中单个服务器的最大连接数。这可以防止upstream服务器超载。默认值是0,表示没有限制。

  • queue 如果设置了max_conns,那么queue指令用来决定当一个请求由于upstream组中没有可用服务器或者这些服务器达到max_conns限制而不能得到处理时会发生什么。这个指令用来设定有多少请求将会排队以及排多久。如果没有设置这个指令,就不会有排队行为。

其它考虑

Nginx还有一些特性可以用来提高web应用的性能。这些特性不常出现在调优讨论中,但是有必要一提,因为它们的影响也可能比较可观。我们将讨论这些特性中的两个。

缓存

对于一个为一组web服务器或者应用服务器作负载均衡的Nginx实例来说,启用缓存可以显著地降低响应时间,同时能显著减轻后端服务器的负载。缓存本身就是一个主题,这里不会讨论。Nginx缓存配置的更多信息请参考:Nginx管理指南 – 缓存。

压缩

压缩响应可以大大减小响应的大小,减少带宽占用。不过,这需要CPU资源来处理压缩,所以最好在值得减少带宽占用的情况下使用。需要注意的是,不能对已经压缩的东西(比如jpeg图片)再次启用压缩。Nginx压缩配置的更多信息请参考:Nginx管理指南 – 压缩和解压缩。

ubuntu16.04更新web服务器apache为Nginx php-fpm

网站一直跑的是apache,觉得卡卡的。换nginx玩玩喽。nginx还是很强大的,感觉速度有些提升,奥力给!!!

已经安装了Apache2的话,要先删除再安装nginx!

删除Apache2

service apache2 stop
update-rc.d -f apache2 remove
apt-get remove apache2

安装nginx

apt-get -y install nginx

service nginx start

输入ip或域名就能看到 Welcome to Nginx!

安装 PHP 7

我们可以通过使nginx的PHP工作PHP-FPM(PHP-FPM(FastCGI进程管理器)是为任何规模的网站,尤其是繁忙的网站有用的一些附加功能的替代PHP的FastCGI实现),我们安装如下:

apt-get -y install php7.0-fpm

配置 nginx

虚拟主机服务器{}容器定义。默认的虚拟主机是在文件中定义的/etc/nginx/sites-available/default

将index index.html index.htm index.nginx-debian.html;

改成index index.html index.htm index.php;

server_name _;这里改成你的主机名,一般是域名。例如:server_name zerlong.com;

找到下边这一段,把注释去掉

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ .php$ {
                include snippets/fastcgi-php.conf;

                # With php7.0-cgi alone:
                #fastcgi_pass 127.0.0.1:9000;
                # With php7.0-fpm:
                fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        }

注意上边fastcgi_pass只能用一个,不然会出错类似”fastcgi_pass”

directive is duplicate in /etc/nginx/sites-enabled/default

保存完重新加载nginx:

service nginx reload

编辑/etc/php/7.0/fpm/php.ini 设置 cgi.fix_pathinfo=0

service php7.0-fpm reload

建立个探针文件访问一下能出信息了,

未分类

MySQL 获得 PHP 7支持

使用下面的命令安装:

apt-get -y install php7.0-mysql php7.0-curl php7.0-gd php7.0-intl php-pear php-imagick php7.0-imap php7.0-mcrypt php-memcache  php7.0-pspell php7.0-recode php7.0-sqlite3 php7.0-tidy php7.0-xmlrpc php7.0-xsl php7.0-mbstring php-gettext

APCu是随PHP7 PHP Opcache模块的扩展,它增加了一些兼容性功能的支持APC缓存(例如WordPress的插件缓存)软件。

APCu可以安装如下:

apt-get -y install php-apcu

重新加载 PHP-FPM:

service php7.0-fpm reload

好了,跑起来吧网站!

附送nginx+https SSL配置

同时启用HTTP和HTTPS

server {
    listen              80;
    listen              443 ssl;
    server_name         zerlong.com;    #最好写绝对路径,你懂的
    ssl_certificate     zerlong.com.crt;
    ssl_certificate_key zerlong.com.key;
    ...

自动跳转https

server {
        listen   80;
        server_name zerlong.com;
        rewrite ^ https://$http_host$request_uri? permanent;    # force redirect http to https
        #return 301 https://$http_host$request_uri;
    }

server {
        listen 443 ssl;

        ssl_certificate /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key /etc/nginx/ssl/nginx.key;

        server_name zerlong.com;
        #禁止在header中出现服务器版本,防止黑客利用版本漏洞攻击
        server_tokens off;
        #如果是全站 HTTPS 并且不考虑 HTTP 的话,可以加入 HSTS 告诉你的浏览器本网站全站加密,并且强制用HTTPS 访问
        #add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
        # ......
        fastcgi_param   HTTPS              on;
        fastcgi_param   HTTP_SCHEME      https;

    }

wordpress的nginx伪静态规则

在站点配置文件的server { } 大括号里面添加下面的代码,然后重启nginx

location / {
if (-f $request_filename/index.html){
                rewrite (.*) $1/index.html break;
        }
if (-f $request_filename/index.php){
                rewrite (.*) $1/index.php;
        }
if (!-f $request_filename){
                rewrite (.*) /index.php;
        }
}

Ubuntu 16.04 apt安装Nginx PHP5.6 MySQL5.6

在Ubuntu 16.04中使用源安装Nginx+PHP5.6+MySQL5.6的方法。

安装Nginx

1、首先添加nginx_signing.key(必须,否则出错)

$ wget http://nginx.org/keys/nginx_signing.key

$ sudo apt-key add nginx_signing.key

2、添加]Nginx](http://nginx.org/)官方提供的源

$ echo "deb http://nginx.org/packages/ubuntu/ trusty nginx" >> /etc/apt/sources.list

$ echo "deb-src http://nginx.org/packages/ubuntu/ trusty nginx" >> /etc/apt/sources.list

3、更新源并安装Nginx

$ sudo apt-get update

$ sudo apt-get install nginx

4、安装Nginx完成后可查看版本号,输入

$ /usr/sbin/nginx -v

安装PHP5.6

1、添加PPA

$ sudo apt-get install python-software-properties software-properties-common

$ sudo add-apt-repository ppa:ondrej/php

$ sudo apt-get update

2、安装PHP5.6以及所需的一些扩展

$ sudo apt-get install php5.6-fpm php5.6-mysql php5.6-common php5.6-curl php5.6-cli php5.6-mcrypt php5.6-mbstring php5.6-dom

3、配置PHP5.6

打开php.ini配置文件:

$ sudo vim /etc/php/5.6/fpm/php.ini

找到cgi.fix_pathinfo选项,去掉注释;,然后将值设置为0:

cgi.fix_pathinfo = 0;
display_errors  =  On

location ~ .php$ {
          # include snippets/fastcgi-php.conf;
        #
          # # With php7.0-cgi alone:
        # fastcgi_pass 127.0.0.1:9000;
        # # With php7.0-fpm:
                fastcgi_param SCRIPT_FILENAME     documentroot fastcgi_script_name;
                  fastcgi_pass unix:/run/php/php5.6-fpm.sock;
                  fastcgi_index index.php;
                  include fastcgi_params;
}

安装MySQL

$ sudo apt-get install mysql-server-5.6 mysql-client-5.6

途中会提示设置MySQL的密码,安装好后:

$ mysql -uroot -p

然后输入刚刚设置的密码,能成功进入即成功安装。

使用fpm工具制作nginx的rpm包

fpm定制化RPM包之nginx rpm包的制作

1. 安装ruby模块

# yum -y install ruby rubygems ruby-devel

2. 添加阿里云的Rubygems仓库,国外资源会影响下载速度

gem sources -a http://mirrors.aliyun.com/rubygems/ 
http://mirrors.aliyun.com/rubygems/ added to sources

移除原生的ruby仓库

gem sources --remove http://rubygems.org/

3. 安装fpm

centos6:
gem install json -v 1.8.3
gem install fpm -v 1.3.3

centos7直接使用如下命令:

[root@slave02 ~]# gem install fpm

Fetching: cabin-0.9.0.gem (100%)
Successfully installed cabin-0.9.0
Fetching: backports-3.8.0.gem (100%)
Successfully installed backports-3.8.0
Fetching: arr-pm-0.0.10.gem (100%)
Successfully installed arr-pm-0.0.10
Fetching: clamp-1.0.1.gem (100%)
Successfully installed clamp-1.0.1
Fetching: ffi-1.9.18.gem (100%)
Building native extensions. This could take a while...
Successfully installed ffi-1.9.18
Fetching: childprocess-0.7.0.gem (100%)
Successfully installed childprocess-0.7.0
Fetching: archive-tar-minitar-0.5.2.gem (100%)
Successfully installed archive-tar-minitar-0.5.2
Fetching: io-like-0.3.0.gem (100%)
Successfully installed io-like-0.3.0
Fetching: ruby-xz-0.2.3.gem (100%)
Successfully installed ruby-xz-0.2.3
Fetching: stud-0.0.22.gem (100%)
Successfully installed stud-0.0.22
Fetching: mustache-0.99.8.gem (100%)
Successfully installed mustache-0.99.8
Fetching: insist-1.0.0.gem (100%)
Successfully installed insist-1.0.0
Fetching: dotenv-2.2.1.gem (100%)
Successfully installed dotenv-2.2.1
Fetching: pleaserun-0.0.29.gem (100%)
Successfully installed pleaserun-0.0.29
Fetching: fpm-1.8.1.gem (100%)
Successfully installed fpm-1.8.1
Parsing documentation for cabin-0.9.0
Installing ri documentation for cabin-0.9.0
Parsing documentation for backports-3.8.0
Installing ri documentation for backports-3.8.0
Parsing documentation for arr-pm-0.0.10
Installing ri documentation for arr-pm-0.0.10
Parsing documentation for clamp-1.0.1
Installing ri documentation for clamp-1.0.1
Parsing documentation for ffi-1.9.18
Installing ri documentation for ffi-1.9.18
Parsing documentation for childprocess-0.7.0
Installing ri documentation for childprocess-0.7.0
Parsing documentation for archive-tar-minitar-0.5.2
Installing ri documentation for archive-tar-minitar-0.5.2
Parsing documentation for io-like-0.3.0
Installing ri documentation for io-like-0.3.0
Parsing documentation for ruby-xz-0.2.3
Installing ri documentation for ruby-xz-0.2.3
Parsing documentation for stud-0.0.22
Installing ri documentation for stud-0.0.22
Parsing documentation for mustache-0.99.8
Installing ri documentation for mustache-0.99.8
Parsing documentation for insist-1.0.0
Installing ri documentation for insist-1.0.0
Parsing documentation for dotenv-2.2.1
Installing ri documentation for dotenv-2.2.1
Parsing documentation for pleaserun-0.0.29
Installing ri documentation for pleaserun-0.0.29
Parsing documentation for fpm-1.8.1
Installing ri documentation for fpm-1.8.1
15 gems installed

4.在打包机器上先安装一次nginx

yum install -y gcc gcc-c++ glibc make autoconf openssl openssl-devel pcre pcre-devel glib glib-devel
useradd nginx -M -s /sbin/nologin
tar xf nginx-1.12.0.tar.gz

cd nginx-1.12.0

./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --with-file-aio --with-http_dav_module --with-pcre

make && make install

5. 编写脚本

软件包卸载前、卸载后的脚本,可以根据情况是否编写,不编写问题也不大。但是rpm安装后的脚本是必须的。

mkdir /data/scripts/ -p
cd /data/scripts/

编写一个rpm安装后需要执行的脚本
vim nginx_post_install.sh

#!/bin/bash

useradd nginx -M -s /sbin/nologin
chmod +x /etc/init.d/nginx
chkconfig --add nginx
echo 'PATH=/user/local/nginx/sbin:$PATH'>> /etc/profile.d/nginx.sh

卸载nginx后需要执行的脚本

# cat after_remove.sh 
#!/bin/bash
rm -rf /usr/local/nginx
rm -f /etc/rc.d/init.d/nginx

准备个启动脚本,如下:

vim /etc/init.d/nginx

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15 
# description:  Nginx is an HTTP(S) server, HTTP(S) reverse 
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /usr/local/nginx/conf/nginx.conf
# pidfile:     /usr/local/nginx/logs/nginx.pid

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)

NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"

lockfile=/var/lock/subsys/nginx

make_dirs() {
   # make required directories
   user=`$nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=([^ ]*).*/1/g' -`
   if [ -z "`grep $user /etc/passwd`" ]; then
       useradd -M -s /bin/nologin $user
   fi
   options=`$nginx -V 2>&1 | grep 'configure arguments:'`
   for opt in $options; do
       if [ `echo $opt | grep '.*-temp-path'` ]; then
           value=`echo $opt | cut -d "=" -f 2`
           if [ ! -d "$value" ]; then
               # echo "creating" $value
               mkdir -p $value && chown -R $user $value
           fi
       fi
   done
}

start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    make_dirs
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    configtest || return $?
    stop
    sleep 1
    start
}

reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    $nginx -s reload
    RETVAL=$?
    echo
}

force_reload() {
    restart
}

configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}

rh_status() {
    status $prog
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac

6. 打包(打包的过程其实就是将我们编译安装好的文件、目录打包,/data/scripts/是本次的打包工作目录)

将nginx启动脚本和注意的配置及启动文件拷贝到打包目录

mkdir -p /data/scripts/etc/rc.d/init.d
cp /etc/init.d/nginx /data/scripts/etc/rc.d/init.d/

mkdir -p /data/scripts/usr/local/nginx/
cp -r /usr/local/nginx/ /data/scripts/usr/local/nginx/

/data/scripts目录结构

[root@master scripts]# tree

.
├── after_remove.sh
├── etc
│   └── rc.d
│   └── init.d
│   └── nginx
├── nginx-1.12.0-1.el6.x86_64.rpm
├── nginx_post_install.sh
└── usr
└── local
└── nginx
├── client_body_temp
├── conf
│   ├── fastcgi.conf
│   ├── fastcgi.conf.default
│   ├── fastcgi_params
│   ├── fastcgi_params.default
│   ├── koi-utf
│   ├── koi-win
│   ├── mime.types
│   ├── mime.types.default
│   ├── nginx.conf
│   ├── nginx.conf.default
│   ├── scgi_params
│   ├── scgi_params.default
│   ├── uwsgi_params
│   ├── uwsgi_params.default
│   └── win-utf
├── etc
│   └── rc.d
│   └── init.d
│   └── nginx
├── fastcgi_temp
├── html
│   ├── 50x.html
│   └── index.html
├── logs
│   ├── access.log
│   ├── error.log
│   └── nginx.pid
├── proxy_temp
├── sbin
│   └── nginx
├── scgi_temp
└── uwsgi_temp

打包,即将准备好的文件打包成rpm

# fpm -f -s dir -t rpm -n nginx --epoch 0 -v 1.12.0 --iteration 1.el6 -C /data/scripts/ -d 'pcre-devel,openssl-devel,autoconf,glib-devel' --post-uninstall /data/scripts/nginx_post_install.sh --post-uninstall /data/scripts/after_remove.sh --workdir /data/scripts/ etc usr
Created package {:path=>"nginx-1.12.0-1.el6.x86_64.rpm"}

报错:

Need executable 'rpmbuild' to convert dir to rpm {:level=>:error}

解决:

yum install rpm-build -y

注意:我们可以操作前修改下主机名,这样打包出来的Build Host就会跟着改变。

7. 安装rpm包

yum命令安装rpm包

yum -y localinstall nginx-1.12.0-1.x86_64.rpm

这个命令会自动先安装rpm包的依赖,然后再安装rpm包。

FPM常用参数:

  • -f :强制覆盖[覆盖同名rpm包]
  • -n :指定的rpm包名
  • -p :指定的rpm包文件放置位置
  • -v :指定的rpm包版本
  • -d :指定依赖的软件 ( [-d ‘name’] or [-d ‘name > version’] 例子: -d ‘libstdc++ >= 4.4.3’)
  • -a :指定系统架构,如果是noarch则为’-a all’ 或者 ‘-a native’ [x86_64] 当软件不区分64位或32位的时候可以 noarch
  • -s :指定INPUT的数据类型 ([“-s dir”] 省略数据类型)
  • -m :指定打包人员[Packager] ([ -m ‘user’])
  • -C :指定打包的相对路径,类似于buildroot. 譬如-C /tmp/apr/ 而打包机器的数据包路径是/tmp/apr/{opt,usr,etc} 那安装这个rpm包后,在本地的数据就是/opt/,/usr/,/etc/
  • -t :指定需要制作成什么包,可选项有(deb,rpm,solaris,etc)

支持的源类型::

"dir" "rpm" "gem" "python" "empty" "tar" "deb" "cpan" "npm" "osxpkg" "pear" "pkgin" "virtualenv" "zip"

支持的目标类型:

"rpm" "deb" "solaris" "puppet" "dir" "osxpkg" "p5p" "puppet" "sh" "solaris" "tar" "zip"
--description         :软件包描述
--conflicts         :指定冲突软件
--url                 :指定站点[惯例都是添加软件的官网 例如: --url "http://www.cnblog.com/roach57" ]
--verbose             :安装过程详细打印
--after-install     :包安装之后执行的脚本 也可写作 --post-install FILE
--before-install     :包安装之前执行的脚本 
--after-remove         :包卸载之后执行的脚本
--before-remove     :包卸载之前执行的脚本
--after-upgrade     :包更新之后执行的脚本[仅支持 deb 和 rpm 这两种包]
--before-upgrade     :包更新之前执行的脚本
--iteration         :发布序号[就是rpm包里面的release]
--epoch             :纪元  [不知道干嘛用的]
--no-rpm-sign        :不使用rpm签名   Signature
--license             :证书许可 [可选项有 'BSD(开源软件)' 'GPLv2(自由软件)' 'MIT' 'Public Domain(公共域)' 'Distributable(贡献)' 'commercial(商业)' 'Share(共享)等',一般的开发都写'BSD'或'GPL']
--vendor             :供应商名称 [ --vendor '[email protected]']
--no-depends         :代表没有任何依赖包,和-d是对立的,不能共用
--config-files         :指定配置文件,可以指定目录[递归]
--directories         :指定包目录
--category             :软件所属的类别[这是个什么软件]下面有个对应的表格:
    [参考这个文件 /usr/share/doc/rpm-x.x.x/GROUPS ]
    Amusements/Games [娱乐/游戏]
    Amusements/Graphics [娱乐/图形]
    Applications/Archiving [应用/文档]
    Applications/Communications [应用/通讯]
    Applications/Databases [应用/数据库]
    Applications/Editors [应用/编辑器]
    Applications/Emulators [应用/仿真器]
    Applications/Engineering [应用/工程]
    Applications/File [应用/文件]
    Applications/Internet [应用/因特网]
    Applications/Multimedia [应用/多媒体]
    Applications/Productivity [应用/产品]
    Applications/Publishing [应用/印刷]
    Applications/System [应用/系统]
    Applications/Text [应用/文本]
    Development/Debuggers [开发/调试器]
    Development/Languages [开发/语言]
    Development/Libraries [开发/函数库]
    Development/System [开发/系统]
    Development/Tools [开发/工具]
    Documentation [文档]
    System Environment/Base [系统环境/基础]
    System Environment/Daemons [系统环境/守护]
    System Environment/Kernel [系统环境/内核]
    System Environment/Libraries [系统环境/函数库]
    System Environment/Shells [系统环境/接口]
    User Interface/Desktops [用户界面/桌面]
    User Interface/X [用户界面/X窗口]
    User Interface/X Hardware Support [用户界面/X硬件支持]

RPM包的组成格式:

roach-1.0.1-57.el6.x86_64.rpm
  |    |     |       |     |
软件名称|     |       |     |
     版本号   |       |    |
           发布号     |      |
                   硬件平台  |
                            扩展名

例子备注:

  • roach :软件名称
  • 1.0.1 :软件版本号
  • 57.el6 :发布号主要是对软件存在的bug或漏洞进行修补,在软件功能上并没有变化,el6指的是rhel6系统中发布
  • x86_64 :指64位的PC架构,另外还有’i386′ ‘i686’ 等32位的PC架构,noarch是指不区分硬件架构
  • rpm :扩展名

zabbix通过stub_status模块实现对nginx的监控

原理

nginx的ngx_http_stub_status_module模块提供了基本的nginx状态信息,源码安装的话需要加上–with-http_stub_status_module编译参数,或者如果是epel源yum安装的话,已经默认启用该模块。在nginx.conf的server段中添加:

location /basic_status {
    stub_status;
    access_log off;
}

那么访问http://xxx.com/basic_status就可以得到7个nginx运行信息了:

Active connections: 291 
server accepts handled requests
 16630948 16630948 31070465 
Reading: 6 Writing: 179 Waiting: 106

各项含义摘抄如下:

Active connections  The current number of active client connections including Waiting connections.

accepts  The total number of accepted client connections.

handled  The total number of handled connections. Generally, the parameter value is the same as acceptsunless some resource limits have been reached (for example, the worker_connections limit).

requests  The total number of client requests.

Reading  The current number of connections where nginx is reading the request header.

Writing  The current number of connections where nginx is writing the response back to the client.

Waiting  The current number of idle client connections waiting for a request.

Active connections/Reading/Writing/Waiting 是状态量,体现了nginx当前的运行状态,需要重点关注。

accepts/handled/requests是统计量,是个历史计数器,其中requests可以反映出“吞吐量”的概念,accepts和handled的差值可以反映出“丢包量”,即nginx由于某种原因丢弃的连接。

由此可以看出,zabbix监控nginx就是通过搜集以上数据,并稍作加工,形成图表供分析。

自定义脚本

zabbix可以通过自定义参数收集自定义信息,详见:https://www.zabbix.com/documentation/3.2/manual/config/items/userparameters

首先需要一个脚本,得到所需数据,然后通过zabbix-agent传给zabbix-server。有几点思路:

1、使用shell脚本即可,简单实用,跟操作系统紧密结合。

2、因为有很多监控项,如果写多个脚本会很乱,最好写成函数形式。

3、直接取accepts和handled的值没什么实际意义,它们的差值表示连接丢弃数量才是我们关心的。但是,这个计算不能放在zabbix-server中进行(item type — Calculation),因为zabbix在取两个值的时候有时间差,而这个时间差得到的结果会导致计算误差。所以必须在shell中算好,直接返回给zabbix-server。

ngx_status.sh代码如下:

#!/bin/bash

URL="http://192.168.7.227:88/ngx_status"
FILE="/tmp/ngx_status.txt"

function active(){
/usr/bin/curl -s $URL |grep Active|awk '{print $3}'
}

function reading(){
/usr/bin/curl -s $URL |grep Reading|awk '{print $2}'
}

function writing(){
/usr/bin/curl -s $URL |grep Writing|awk '{print $4}'
}

function waiting(){
/usr/bin/curl -s $URL |grep Waiting|awk '{print $6}'
}

function requests(){
/usr/bin/curl -s $URL |awk '{if(NR==3) print $3}'
}

function dropped(){
/usr/bin/curl -s $URL > $FILE
accepts=`awk '{if(NR==3) print $1}' $FILE`
handled=`awk '{if(NR==3) print $2}' $FILE`
drop=`expr $accepts - $handled`
echo "$drop"
}

function ping(){
/usr/sbin/pidof nginx|wc -l
}

#根据脚本参数执行对应应函数
$1

zabbix-agent端添加以下配置:

# cat /etc/zabbix/zabbix_agentd.d/nginx_status.conf
UserParameter=nginx.status[*],/etc/zabbix/zabbix_agentd.d/nginx_status.sh $1

创建zabbix模版

active/reading/writing/waiting/requests都是一样的,方法如下:

未分类

吞吐量是由计算得出:

未分类

上面使用计算的方法没必要,官方已经提供了内置的delta数据类型来处理此类需求:

未分类

nginx存活状态是个布尔量,创建方法:

未分类

未分类

可以对这个item配置trigger,当nginx挂了做相应操作。

最后,我们可以创建几个图表,方便分析,因为是测试环境,基本没啥访问量^_^:

未分类

模版文件,适用于zabbix-3.2.7-1:https://github.com/dmli30/shell/blob/master/zabbix/ngx_status_templates.xml

解决Nginx php-fpm配置有误引起的502错误

在Ubuntu+Nginx+PHP环境下部署好以后,访问网站报错502,在后台nginx error_log里看到以下报错信息

2017/07/29 10:59:15 [error] 5622#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 183.14.134.39, server: xx.xx.xx.xx, request: “GET /index.php HTTP/1.1”, upstream: “fastcgi://127.0.0.1:9001”, host: “xx.xx.xx.xx”

通常这个报错是表示php-fpm这个服务未启动,由于默认是配置的9000端口,执行netstat -anp|grep 9000确实没有看到相关进程。

但执行命令查询php-fpm是running状态

# /etc/init.d/php7.0-fpm status
● php7.0-fpm.service – The PHP 7.0 FastCGI Process Manager
Loaded: loaded (/lib/systemd/system/php7.0-fpm.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2017-07-29 11:52:47 CST; 3h 43min ago
Process: 7191 ExecStartPre=/usr/lib/php/php7.0-fpm-checkconf (code=exited, status=0/SUCCESS)
Main PID: 7200 (php-fpm7.0)
Status: “Processes active: 0, idle: 2, Requests: 54, slow: 0, Traffic: 0req/sec”
CGroup: /system.slice/php7.0-fpm.service
├─7200 php-fpm: master process (/etc/php/7.0/fpm/php-fpm.conf)
├─7203 php-fpm: pool www
└─7204 php-fpm: pool www

Jul 29 11:52:47 iZwz96f0gkw4blayus6g2yZ systemd[1]: Starting The PHP 7.0 FastCGI Process Manager…
Jul 29 11:52:47 iZwz96f0gkw4blayus6g2yZ systemd[1]: Started The PHP 7.0 FastCGI Process Manager.

查看/etc/php/7.0/fpm/pool.d/www.conf和/etc/php/7.0/fpm/php-fpm.conf发现以下参数:

listen = /run/php/php7.0-fpm.sock

查阅资料后才知道,原来php-fpm支持网络端口监听和socket两种方式,但后者效率更高。

针对该问题的解决方案是,修改nginx/conf/vhosts下的conf文件,

将fastcgi_pass 127.0.0.1:9000;修改为fastcgi_pass unix:/run/php/php7.0-fpm.sock;

重启Nginx服务后,WEB访问依然报错502,继续定位分析。

在nginx error_log日志中出现了以下新的报错内容:

2017/07/29 11:24:47 [crit] 6114#0: *1 connect() to unix:/run/php/php7.0-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 183.14.134.xx, server: 112.74.89.xx, request: “GET / HTTP/1.1”, upstream: “fastcgi://unix:/run/php/php7.0-fpm.sock:”, host: “112.74.89.xx”

然后找到/etc/php/7.0/fpm/pool.d/www.conf文件,做以下处理:

注释掉

;listen.owner = www-data
;listen.group = www-data

将mode值修改为0666

listen.mode = 0666

最后,执行/etc/init.d/php7.0-fpm restart重启php-fpm服务,执行/etc/init.d/nginx restart重启Nginx服务,问题解决!!!

nginx+lua实现简单的waf网页防火墙功能

Nginx+Lua实现WAF

安装LuaJIT

http://luajit.org/download/LuaJIT-2.0.4.tar.gz

tar xf LuaJIT-2.0.4.tar.gz

cd LuaJIT-2.0.4

make && make install 即可

下载ngx_devel_kit

https://codeload.github.com/simpl/ngx_devel_kit/zip/master

unzip ngx_devel_kit-master.zip

解压后的路径为:root/ngx_devel_kit-master

下载nginx_lua_module解压

https://github.com/openresty/lua-nginx-module#readme

unzip lua-nginx-module-master.zip

cd lua-nginx-module-master

安装nginx或给nginx打补丁

nginx -v 查看nginx的版本号

# nginx -v

nginx version: nginx/1.8.0

nginx -V 查看以前的编译参数

# nginx -V

nginx version: nginx/1.8.0

built by gcc 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC) 

built with OpenSSL 1.0.1e-fips 11 Feb 2013

TLS SNI support enabled

configure arguments: --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_spdy_module --with-http_gzip_static_module --with-ipv6 --with-http_sub_module --with-google_perftools_module

我这里已经安装过nginx1.8了。

那么下面就是给nginx打补丁的事情了。如下:

进到nginx1.8的源代码目录下。执行下面的一系列命令:

# 导入环境变量,编译

# exportLUAJIT_LIB=/usr/local/lib    #这个很有可能不一样

# exportLUAJIT_INC=/usr/local/include/luajit-2.0 #这个很有可能不一样



# cd /home/tools/lnmp1.2-full/src/nginx-1.8.0

#./configure 

--user=www --group=www 

--prefix=/usr/local/nginx 

--with-http_stub_status_module 

--with-http_ssl_module 

--with-http_spdy_module 

--with-http_gzip_static_module 

--with-ipv6 

--with-http_sub_module 

--with-google_perftools_module 

--add-module=/root/ngx_devel_kit-master

--add-module=/root/lua-nginx-module-master

--with-ld-opt="-Wl,-rpath,$LUAJIT_LIB"



# make -j4 && make install

准备nginx的攻击日志目录

# mkdir -p /home/wwwlogs/attack

# chown www.www /home/wwwlogs/attack

# chmod -R 755 /home/wwwlogs/attack

安装nginx的Lua_waf模块

官方地址:https://github.com/loveshell/ngx_lua_waf

# wget https://codeload.github.com/loveshell/ngx_lua_waf/zip/master

# unzip ngx_lua_waf-master.zip

# cd ngx_lua_waf-master

# mkdir /usr/local/nginx/conf/waf

# cp -a ./ /usr/local/nginx/conf/waf

修改nginx的配置文件,在http段加入如下内容:

    lua_package_path"/usr/local/nginx/conf/waf/?.lua";

    lua_shared_dict limit 10m;  开启拦截cc攻击必须加这条规则

   init_by_lua_file /usr/local/nginx/conf/waf/init.lua;

   access_by_lua_file /usr/local/nginx/conf/waf/waf.lua;

修改/usr/local/nginx/conf/waf/config.lua中如下2部分内容即可:

RulePath ="/usr/local/nginx/conf/waf/wafconf/"

attacklog = "on"

logdir ="/home/wwwlogs/attack"

UrlDeny="on"

Redirect="on"

CookieMatch="on"

postMatch="on"

whiteModule="on"

black_fileExt={"php","jsp"}

ipWhitelist={"127.0.0.1"}

ipBlocklist={"1.0.0.1"}

CCDeny="on"

CCrate="100/60"




配置文件说明:

    RulePath = "/usr/local/nginx/conf/waf/wafconf/"    --规则存放目录

    attacklog = "off"               --是否开启攻击信息记录,需要配置logdir

    logdir ="/usr/local/nginx/logs/hack/"   --log存储目录,该目录需要用户自己新建,需要nginx用户的可写权限

    UrlDeny="on"                    --是否拦截url访问

    Redirect="on"                   --是否拦截后重定向

    CookieMatch = "on"              --是否拦截cookie攻击

    postMatch = "on"                --是否拦截post攻击

    whiteModule = "on"              --是否开启URL白名单

   black_fileExt={"php","jsp"}      --填写不允许上传文件后缀类型

    ipWhitelist={"127.0.0.1"}       --ip白名单,多个ip用逗号分隔

    ipBlocklist={"1.0.0.1"}          --ip黑名单,多个ip用逗号分隔

    CCDeny="on"           --是否开启拦截cc攻击(需要nginx.conf的http段增加lua_shared_dict limit 10m;)

    CCrate ="100/60"     --设置cc攻击频率,单位为秒. 默认1分钟同一个IP只能请求同一个地址100次

    html=[[Please go away~~]]       --警告内容,可在中括号内自定义

    备注:不要乱动双引号,区分大小写

重启nginx

# nginx -t

# /etc/init.d/nginx restart   重启nginx

恶意访问测试

# curl http://xxxx/test.php?id=../etc/passwd

# curl http://192.168.2.12/index.php?cmd=phpinfo();

或者直接在网页上请求

结果都是如下图所示,被拦截了。

未分类

此外,在/home/wwwlogs/attack目录下已经有日志文件记录下整个攻击的日志了。

未分类
未分类

一些说明:

过滤规则在wafconf下,可根据需求自行调整,每条规则需换行,或者用|分割

  • args里面的规则get参数进行过滤的

  • url是只在get请求url过滤的规则

  • post是只在post请求过滤的规则

  • whitelist是白名单,里面的url匹配到不做过滤

  • user-agent是对user-agent的过滤规则

默认开启了get和post过滤,需要开启cookie过滤的,编辑waf.lua取消部分–注释即可。

拦截到的非法请求,记录在日志文件名称格式如下:虚拟主机名_sec.log

说明:

这玩意貌似只能防止一些简单的sql注入类的语句,对于一些精心构造的恶意语句还是拦截不了的。

另外,我在公司的服务器上装了它,后台客服反应会出现form表单中图片无法上传的情况。