Nginx配置
生产上检查Nginx日志,发现有python爬虫程序
对日志进行分析,如何简单配置进行防御
1.配置文件
参考文档
https://www.cnblogs.com/knowledgesea/p/5175711.html
配置举例:http://blog.csdn.net/hzsunshine/article/details/63687054
... #全局块
events { #events块
...
}
http #http块
{
... #http全局块
server #server块
{
... #server全局块
location [PATTERN] #location块
{
...
}
location [PATTERN]
{
...
}
}
server
{
...
}
... #http全局块
}
1、全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。
- 关于worker_processes Nginx支持自动配置,一般情况下不要超过cpu核数
2、events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
- 关于worker_connections 的正确理解,一个重点,这个是总连接数,包括和客户端,以及作为反向代理时,与服务端等的所有连接。
这里注意,连接是一个连接,一个连接上的请求可以是双向的,Nginx用作静态资源服务器和反向代理的实现是不一样的
参考文档:nginx 并发数问题思考:worker_connections,worker_processes与 max clients
http://blog.51cto.com/liuqunying/1420556
直接看结论
当Nginx作为静态资源服务器: max_clients = worker_processes * worker_connections;
此处如果Http1.1请求默认发起2个连接的话,要除以2
用作反向代理时: max_clients = worker_processes * worker_connections/4
3、http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
4、server块:配置虚拟主机的相关参数,一个http中可以有多个server。
5、location块:配置请求的路由,以及各种页面的处理情况。
2.日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent $request_time "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
字段说明
字段 | 说明 |
---|---|
$remote_addr | 客户端地址 |
$remote_user | 客户端用户名称 |
$time_local | 访问时间和时区 |
$request | 请求的URI和HTTP协议 |
$http_host | 请求地址,即浏览器中你输入的地址(IP或域名) |
$status | HTTP请求状态 |
$upstream_status | upstream状态 |
$body_bytes_sent | 发送给客户端文件内容大小 |
$http_referer | url跳转来源 |
$http_user_agent | 用户终端浏览器等信息 |
$ssl_protocol | SSL协议版本 |
$ssl_cipher | 交换数据中的算法 |
$upstream_addr | 后台upstream的地址,即真正提供服务的主机地址 |
$request_time | 整个请求的总时间 |
$upstream_response_time | 请求过程中,upstream响应时间 |
备注
request_time的正确理解
举个例子,Nginx上显示某个接口时间经常超过5s,但是upStream服务器上时间却没有超过1S,为何
这里要对$request_time进行理解
$request_time
request processing time in seconds with a milliseconds resolution;
time elapsed between the first bytes were read from the client and
the log write after the last bytes were sent to the client
即这是Nginx从收到第一个字节计算到最后一个字节发出的时间
$upstream_response_time
keeps servers response times in seconds with a milliseconds
resolution. Several responses are also separated by commas and colons.
|upstream_response_time 会比||$request_time时间短。|
对于HTTP POST的请求,两者相差特别大。因为Nginx会把HTTP request body缓存
住,接受完毕后才会把数据一起发给后端。
’REMOTE_ADDR’ 不容易篡改
这个值是服务端根据客户端的ip确定的,而不是客户端主动提供的
是远端IP,默认来自tcp 连接是,客户端的Ip。可以说,它最准确,确定是,只会得到直接连服务器客户端IP。如果对方通过代理服务器上网,就发现。获取到的是代理服务器IP了。
如:a->b(proxy)->c ,如果c 通过’REMOTE_ADDR’ ,只能获取到b的IP,获取不到a的IP了。
’HTTP_X_FORWARDED_FOR’,’HTTP_CLIENT_IP’ 容易篡改
为了能在大型网络中,获取到最原始用户IP,或者代理IP地址。对HTTp协议进行扩展。定义了实体头。
HTTP_X_FORWARDED_FOR = clientip,proxy1,proxy2 所有IP用”,”分割。 HTTP_CLIENT_IP 在高级匿名代理中,这个代表了代理服务器IP。既然是http协议扩展一个实体头,并且这个值对于传入端是信任的,信任传入方按照规则格式输入的。以下以x_forword_for例子加以说明,正常情况下,这个值变化过程。
无标题.jpg
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
加上上一句后,X-Forwarded-For中存放的将是:IP0, IP1, IP2
若不加,则 X-Forwarded-For中存放的是remore_address,即最近的一个代理ip(若没有代理,则是用户的真实的IP)
3. location的优先级
参考文档http://www.nginx.cn/115.html
location匹配命令
~ #波浪线表示执行一个正则匹配,区分大小写
~* #表示执行一个正则匹配,不区分大小写
^~ #^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录
= #进行普通字符精确匹配
@ #"@" 定义一个命名的 location,使用在内部定向时,例如 error_page, try_files
location 匹配的优先级(与location在配置文件中的顺序无关)
= 精确匹配会第一个被处理。如果发现精确匹配,nginx停止搜索其他匹配。
普通字符匹配,正则表达式规则和长的块规则将被优先和查询匹配,也就是说如果该项匹配还需去看有没有正则表达式匹配和更长的匹配。
^~ 则只匹配该规则,nginx停止搜索其他匹配,否则nginx会继续处理其他location指令。
最后匹配理带有""和"*"的指令,如果找到相应的匹配,则nginx停止搜索其他匹配;当没有正则表达式或者没有正则表达式被匹配的情况下,那么匹配程度最高的逐字匹配指令会被使用。
4.阻挡特定user-Agent 的爬虫
在server中配置
if ($http_user_agent ~* "Scrapy|Sogou web spider|Baiduspider") {
return 403;
}
备注:linux中脚本对于空格要求特别严,注意if后面等地方是有空格的,否则无法启动
测试工具
linux下自带,curl, I请求头信息,A为user-agent
curl -I -A "BaiduSpider" www.test.com (模拟浏览器头信息)
HTTP/1.1 200 OK
Server: nginx
Date: Mon, 09 Feb 2015 03:37:20 GMT
Content-Type: text/html; charset=UTF-8 Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.5.19 Vary: Accept-Encoding, Cookie
Cache-Control: max-age=3, must-revalidate
WP-Super-Cache: Served supercache file from PHP
5.rewrite功能
背景
生产上是因为app有了国外版本。我们想用一套代码,通过分开部署,达到两者互不影响的目的
方案
1.前端给我们发请求的时候,会通过定位,给我们发带有国家前缀的url
如原来为 content/pre/shop/coupon接口,现在在美国发送的请求为content/usa/pre/shop/coupon
2.请求通过F5进行分流,保证请求到单独部署的Nginx服务器
3.Nginx使用rewrite功能,重写为不带前缀的请求,交由web容器处理
rewrite单独一个location,进行重写,重写后,交由下一个location进行处理
如
location ~ ^/content/f/(.*)${
rewrite /content/f(.*)$ /content/$1 last;
}
location /{
proxy_pass http:content;
}
反思
http请求头添加参数原来是方案之一,但由于对F5不熟,没有测试,再项目需要快速落地的情况下, 使用了不同前缀的方案