日志

通过nginx限制连接数和请求数

有时候服务器会遭到大流量的恶意访问,这种攻击最直接的影响就是导致服务器持续高压,严重影响正常访问,导致这种情况的原因有很多,对于一些低配置的服务器可能只需要一次简单的恶意压测就可以导致服务器502.对于这种情况,我们可以考虑对相同IP的并发连接数和请求频率进行限制,nginx本身自带了两个模块可以作为解决方案,即ngx_http_limit_conn_module和ngx_http_limit_req_module.

  • ngx_http_limit_conn_module

简介:ngx_http_limit_conn_module是一个可以根据指定key来限制连接数的模块,尤其用于根据单个IP限制连接数.

语法:limit_conn_zone key zone=name:size;

上下文:http(即nginx配置的http作用域)

说明:开辟一个名为name,大小为size的共享内存区域,用于存储一系列key(s)的状态,特别是包含各个key的连接数,其中key可以是变量、文本或二者的组合(nginx 1.7.6之前只可以包含一个变量),另外1MB共享内存可以存储3.2万个32-byte状态(在32位平台中存储状态占用32bytes)或1.6万个64-byte(64位平台),当共享内存空间不足时,之后的请求会导致服务器返回503(Service Temporarily Unavailable) 错误.

语法:limit_conn zone number;

上下文:http ,server,location

说明:设置共享内存区域zone,使zone指定的key的连接数不大于number个,当超过这个number值时服务器会返回503(Service Temporarily Unavailable) 错误.

例子:设定一个名为addr的10MB共享内存,以客户端ip作为键,限制每个客户端ip最大并发连接数为5

http{
    ...
    # $binary_remote_addr是客户端ip地址,它和$remote_addr的区别在于它是固定4字节长度
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    server {
    ...
        location ~ \.php$ {
            limit_conn addr 5;
        }
    ...
    }
    ...
}
  • ngx_http_limit_req_module

阅读全文

日志

Nginx通过ngx_log_if模块实现日志过滤

有时候我们需要对服务器的access日志进行自定义过滤,例如不想记录任何404的访问日志等.在Apache下我们可以通过CustomLog [env=XXX]来实现,但Nginx自身并不提供类似的功能,不过从官方的第三方模块中我们可以找到 ngx_log_if 这个非常好用的扩展模块来实现同样的功能.

  • 重编译Nginx安装第三方模块

首先你需要知道你的Nginx版本
$ nginx -v

nginx version: nginx/1.6.3

Nginx历史版本下载 点击这里

从GIT下载 ngx_log_if 模块

$  git clone https://github.com/cfsego/ngx_log_if.git
Nginx编译
<h1>假设你的nginx安装在/etc/nginx , ngx_log_if 在/usr/lib/ngx_log_if 目录</h1>

<h1>解压nginx后开始重编译</h1>

$ ./configure --prefix=/etc/nginx --add-module=/usr/lib/ngx_log_if + ...你的原编译配置

$ make

注意:在configure参数中务必把原来的编译配置补全,通过下面的命令可以知道你原来的配置

$ nginx -V

编译结束后会生成一个新的nginx,先关闭旧的nginx,然后替换新编译的nginx(假设位于/usr/sbin/nginx),重启nginx即可

$ sudo nginx -s stop

<h1>nginx路径按需要修改</h1>

$ sudo cp objs/nginx  /usr/sbin/nginx

$ sudo nginx

至此ngx_log_if模块安装完毕

  • 通过ngx_log_if进行Access日志过滤

server {
    # 不记录400响应状态的access日志
    access_log_bypass_if ($status = 400);

<pre><code># 不记录200响应状态且uri为 status.nginx 的访问日志
access_log_bypass_if ($uri = 'status.nginx') and;
access_log_bypass_if ($status = 200);
</code></pre>

}

子配置会默认覆盖父配置

server {
    # 父配置 , 无效
    access_log_bypass_if ($status = 400);

<pre><code>location / {
    # 子配置 , 有效
    access_log_bypass_if ($host ~* 'nolog.com');
}
</code></pre>

}
转载请注明出处:

© http://hejunhao.me

日志

Nginx 禁止通过IP直接访问网站

网站备案时需要禁止IP直接访问,否则会存在风险

  • Nginx配置

nginx配置非常简单,只需要添加一个空白的server即可

server{

<pre><code>server_name _;

return 444;
</code></pre>

}

你也可以跳转到你的域名

server {
    server_name _;
    rewrite ^(.*) http://www.yourdomain.com;
}
  • 关于 444 响应状态码

444状态码用于Nginx表示服务器没有任何返回信息,并且会关闭连接.

转载请注明出处:

© http://hejunhao.me

日志

Ubuntu14.04 搭建 LNMP 环境

  • 环境

系统:Ubuntu 14.04.1 LTS

下面所有的安装都通过apt-get的方式,为了防止安装过程报错建议先执行一次更新

sudo apt-get update
  • MySQL安装

sudo apt-get install mysql-server mysql-client

安装期间会出现类似如下的Y/N选择,直接Y 回车即可(下同)

root@li568-33:/# sudo apt-get install mysql-server mysql-client
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
libaio1 libdbd-mysql-perl libdbi-perl libmysqlclient18 libterm-readkey-perl
mysql-client-5.5 mysql-client-core-5.5 mysql-common mysql-server-5.5
mysql-server-core-5.5
Suggested packages:
libclone-perl libmldbm-perl libnet-daemon-perl libplrpc-perl
libsql-statement-perl tinyca mailx
The following NEW packages will be installed:
libaio1 libdbd-mysql-perl libdbi-perl libmysqlclient18 libterm-readkey-perl
mysql-client mysql-client-5.5 mysql-client-core-5.5 mysql-common
mysql-server mysql-server-5.5 mysql-server-core-5.5
0 upgraded, 12 newly installed, 0 to remove and 123 not upgraded.
Need to get 0 B/9,260 kB of archives.
After this operation, 96.5 MB of additional disk space will be used.
Do you want to continue? [Y/n]y

中途会出现新的界面设置MySQL的root用户密码

首先设置root密码:yourpassword
然后重复输入root密码:yourpassword

等安装结束后输入以下命令查看是否成功

mysql --version

正常会显示类似以下的版本信息,则安装完成

mysql  Ver 14.14 Distrib 5.5.43, for debian-linux-gnu (x86_64) using readline 6.3

mysql的配置文件在:/etc/mysql/my.cnf
例如:若要允许远程访问请注释my.cnf 的 bind_address 127.0.0.1

  • Nginx安装

阅读全文

日志

Ubuntu下通过Crontab设置计划任务

  • 简介

cron 是一个在指定时间执行指定任务的系统守护进程.

crontab是一个简单的文本文件,它包含一行行的指令,以及指定每行指令何时执行的时间参数.它通过特定的方式进行编辑,crontab中的每一行命令会在设定的时间由cron在后台执行.每个用户均有其独立的crontab文件,不管用户是否已经登录系统,crontab中的命令都会在规定的时间被执行.如果你的任务需要用到管理员权限(administrative privileges),你可以通过root的crontab创建你的计划任务.

  • 创建计划任务

为当前用户创建一个计划任务

crontab -e

如果你希望任务以管理员权限运行,将其加入到root的crontab下即可

sudo crontab -e

首次创建会要求你先选择默认的文本编辑器,自行决定. 如需更换编辑器可执行以下指令

select-editor

crontab文件类似这样,你可以根据指定的格式编辑添加你的crontab计划任务

# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
*/10 * * * * cd /var/www/test && python task.py >> ~/test.log

其中 */10 * * * * cd /var/www/test && python task.py >> ~/test.log 就是一个计划任务的全部配置

一条crontab的配置分为六段,其中前五段属于时间段,用于指定执行的时间,第六段属于命令段,用于指定要执行的命令.除了命令段以外,其他各段不能包含空格,段与段之间允许空格.

每段的意思如下:

分钟 (0-59), 小时 (0-23, 0 = 凌晨), 日 (1-31), 月 (1-12), 星期 (0-6, 0 = 星期日), 命令

多个时间值用逗号隔开,区间用横杠表示(例如 1-5),时间步长控制以斜杠标识,例如上面 */10 的写法是指每隔10分钟的意思,其等价于 0,10,20,30,40,50  (* 和 */1 等价).上面的crontab的意思是指每隔10分钟执行一次命令

“cd /var/www/test && python task.py >> ~/test.log”

终极例子

阅读全文

日志

Nginx与Apache的区别

可以举一个简单的例子来说明Apache的工作流程,我们平时去餐厅吃饭.餐厅的工作模式是一个服务员全程服务客户,流程是这样,服务员在门口等候客人(listen),客人到了就接待安排的餐桌上(accept),等着客户点菜(request uri),去厨房叫师傅下单做菜(磁盘I/O),等待厨房做好(read),然后给客人上菜(send),整个下来服务员(进程)很多地方是阻塞的.这样客人一多(HTTP请求一多),餐厅只能通过叫更多的服务员来服务(fork进程),但是由于餐厅资源是有限的(CPU),一旦服务员太多管理成本很高(CPU上下文切换),这样就进入一个瓶颈.

再来看看Nginx得怎么处理?餐厅门口挂个门铃(注册epoll模型的listen),一旦有客人(HTTP请求)到达,派一个服务员去接待(accept),之后服务员就去忙其他事情了(比如再去接待客人),等这位客人点好餐就叫服务员(数据到了read()),服务员过来拿走菜单到厨房(磁盘I/O),服务员又做其他事情去了,等厨房做好了菜也喊服务员(磁盘I/O结束),服务员再给客人上菜(send()),厨房做好一个菜就给客人上一个,中间服务员可以去干其他事情.整个过程被切分成很多个阶段,每个阶段都有相应的服务模块.我们想想,这样一旦客人多了,餐厅也能招待更多的人.

Git中的fetch和pull

Git中从远程的分支获取最新的版本到本地有这样2个命令:git fetch、git pull

1. git fetch:相当于是从远程获取最新版本到本地,不会自动merge

git fetch origin master
git log -p master..origin/master
git merge origin/master

以上命令的含义:
首先从远程的origin的master主分支下载最新的版本到origin/master分支上
然后比较本地的master分支和origin/master分支的差别
最后进行合并

上述过程其实可以用以下更清晰的方式来进行:

git fetch origin master:tmp
git diff tmp
git merge tmp

从远程获取最新的版本到本地的test分支上
之后再进行比较合并

2. git pull:相当于是从远程获取最新版本并merge到本地

git pull origin master

上述命令其实相当于git fetch 和 git merge
在实际使用中,git fetch更安全一些
因为在merge前,我们可以查看更新情况,然后再决定是否合并