写在前

说来你们可能不信,昨天一个乙方系统的同学发了这么个需求来找我帮忙配……What?!😱😱😱

对于上述需求不予评价,但就这个事来说我觉得我有必要整理下Nginx相关配置的东西了……一是防止自己闹出这种笑话;二也是因为岁数大了记性差了,还是写点东西备查吧。

从一堆timeout说起

proxy_connect_timeout

Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location
官方文档:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_connect_timeout

这个参数定义的是Nginx与后端服务器(“proxied server”,被代理的服务器)建立连接的超时时间,一般不应大于75s。

proxy_read_timeout

Syntax: proxy_read_timeout time;
Default: proxy_read_timeout 60s;
Context: http, server, location
官方文档:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout

这个参数定义的是Nginx读后端服务器(“proxied server”,被代理的服务器)响应包的超时时间(需要注意的是这个时间指的是两次成功读取造作的间隔时间而不是读取完整响应包的总时间)。超过这个时间没有收到后端服务器传送数据的话连接就会超时断开。

PS:该值过小可能会导致504的情况出现,如不想遇到可以将此值改为略大于后端服务器响应超时的时间。

proxy_send_timeout

Syntax: proxy_send_timeout time;
Default: proxy_send_timeout 60s;
Context: http, server, location
官方文档:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_send_timeout

这个参数定义的是Nginx给后端服务器(“proxied server”,被代理的服务器)发送请求包的超时时间(需要注意的是这个时间指的是两次成功写取造作的间隔时间而不是发送完整请求包的总时间)。超过这个时间没有发送数据给后端服务器的话连接就会超时断开。

(未完待续)

 

点击数:600

最近在做的两个功能都需要对request body进行读取处理,好在OpenResty提供了相关函数,这里简单记一下。

获取request body

ngx.req.get_body_data

官方文档:https://github.com/openresty/lua-nginx-module#ngxreqget_body_data

简单说这个函数是获取内存中request body。获取成功时它会返回string类型的request body(如果需要table形式的请求参数可以使用ngx.req.get_post_args()函数);获取失败时返回nil,返回nil可能是以下原因造成的:

  1. request body没有被读入;
  2. request body已被写入临时文件(temporary file);
  3. 没有request body(request body大小为0)。

因为Nginx默认不会读取request body,所以为保证可以如期的获取到,我们最好先请求ngx.req.read_body()函数(或者打开lua_need_request_body开关强制读取request body。PS:不建议这样做),再去请求ngx.req.get_body_data();当request body已被写入临时文件时,我们需要通过ngx.req.get_body_file()函数来获取request body。

ngx.req.get_body_file

官方文档:https://github.com/openresty/lua-nginx-module#ngxreqget_body_file

这个函数和上面ngx.req.get_body_data相似,但是是用来获取临时文件中request body的。当还没有读取request body或request body在内存中时会返回nil。

这里需要注意的一件事是这时读出来的数据是只读的,不可以再在Lua代码中进行手工的modified、rename、remote。

Nginx的几个重要配置

讲到这里,感觉前面好像错过了什么重要的细节……对,就是request body到底在哪里?什么时候在内存,什么时候在临时文件?说到这个就需要去翻一下Nginx的文档啦~

client_max_body_size

首先先来看下client_max_body_size,这个参数设置了被允许的最大的request body大小,当一个request超过这个值的时候将会返回413错误(Request Entity Too Large)。如果不需要检查request body的大小将此值置为0即可。

client_body_buffer_size

再来看下client_body_buffer_size,这个参数设置了读取request body的buffer大小(默认值是两个内存页的大小,8k|16k)。当request body大于这个值时就会写在临时文件中。

好了,前面的疑惑解决了,但是还有两个问题:如何让request body只在内存或者临时文件中呢?

强制使用内存存request body

前面讲了client_max_body_size和client_body_buffer_size两个参数,其实将client_body_buffer_size设为client_max_body_size的大小就可以强制把request body放在内存中了。

强制使用临时文件存request body

Nginx配置中有个client_body_in_file_only参数(详见这里),开启后就强制把request body放在临时文件中了。

最后

好了,文章戛然而止,没有“最后”……

 

点击数:1211

我怎么知道我一个RD为什么要来研究这个,可能是因为身边的同学们都想把我当全栈培养吧……🤦‍♂️

背景

某台Nginx反代服务器(假定IP为10.10.1.2)在公司的某个新办公区网段(假定为172.16.0.0/16)怎么也访问不到,主机本身iptables没有限制,从该主机(10.10.1.2)ping不到172.16段的网关,traceroute时会跳到外网。经排查,172.16段到10.10.1.2的内网网关(假定为10.10.1.1)是通的,最终锁定到问题是因为10.10.1.2是双网卡的服务器,默认走的是外网网卡(假定为bind1,内网网卡是bind0)的网关(假定外网网关为123.123.123.1),到172.16.0.0/12段没有配置相应路由,所有需要在主机上单独配下。

查看路由表

修改路由之前还是先来看下当前我们的路由表是什么样子的吧

其中,第一列Destination是目的地址或目的网络;
第二列Gateway是网关地址,如果没有设置,这里是“*”;
第三列Genmask是目的网路的掩码,如果目的地址是主机时这里是“255.255.255.255”,默认路由这里是“0.0.0.0”;
第四列Flags路由标志:“U”表示该路由是启用状态,“G”表示使用网关……
第八列Iface是这条路由的数据包将发给的网卡。

所以这里可以看到默认是指到了外网网关123.123.123.1上,到10及192.168段的也有单独配指到内网网关10.10.1.1的路由,但是到172.16.0.0/12段的没有单独的路由,所以当traceroute 172.16.0.0/12段IP时会从外网网关进外网也就可以理解了。

添加路由

那么现在我们把去172.16.0.0/12段的下一跳指到内网的网关(10.10.1.1)上应该就可以了。

其中,“-net 172.16.0.0 netmask 255.240.0.0”表示目的网段;
“gw 10.10.1.1”指定了将使用10.10.1.1这个网关;
“dev bond0”指定了bond0这个网卡。

配完以后再检查一下路由表,已经有了刚才的配置,traceroute 172.16段的网关下一跳也到了内网网关,网路也通了。

删除路由

一个小插曲,刚才在添加路由时手滑把172.16.0.0/12的掩码写成了255.255.240.0所以导致加出了一跳错误的配置,这时可以通过route del 来删除路由:

最后

好了,问题解决了,其他上面没涉及细节以后遇到再来补吧~

最后再次感谢身边同学们对我的栽培……🤦‍♂️

 

点击数:287

来到甲方做安全后也算是亲眼见识了现在流量劫持到底有多厉害,周末闲着没事突发奇想还是把自己的博客也升到HTTPS吧,虽然其实真没有什么需要保护的东西……😂

这里简记一下过程,希望对需要的同学能有帮助~

证书购买

上HTTPS首先需要一个SSL证书啦,SSL证书分为3类:

DV:最低级别认证,可以确认申请人拥有这个域名。对于这种证书,浏览器会在地址栏显示一把锁。
OV:确认域名所有人是哪一家公司,证书里面会包含公司信息。
EV:最高级别的认证,浏览器地址栏会显示公司名。

对于个人博客一个DV证书就够用了,所以我在阿里云上买了一个Symantec的免费DV证书(PS:如果需要买更高级的付费证书的话欢迎先来这里领张优惠券来~)。买完之后去“控制台-安全(云盾)-证书服务”里完善一下相应信息,稍等一下审核完毕就可以用啦~

配置Nginx

有了证书下面就要在Nginx里配上了啦~

首先下载证书及私钥文件放到Nginx目录的cert目录(没有的话建一个)中,然后修改Nginx配置:

reload Nginx即可通过https访问了~测试没问题后就可以将http的配置下掉了,这里可以将http的请求301重定向到https:

reload Nginx即可。

更新WordPress设置

下面还需要更新下WordPress的设置,将后台“设置-常规”中的“WordPress地址(URL)”和“站点地址(URL)”改为HTTPS的地址。

解决残留的http链接

由于博客已有的文章中可能包含原来的http链接(如图片等)这可能会导致浏览器认为网站的部分页面不可信,所以我们需要将所有文章中的http链接改成https。如果文章太多了可以直接去数据库中批量替换,虽然直接动数据库不是个好习惯(记得提前备份哦):

好了,一切搞定,静静地欣赏https上的那把绿色小锁头吧~

点击数:4070

写在前

如何黑掉一个验证码?很多人第一反应是验证码识别,什么预处理,提取有效信息,分割字符,识别字符,吧啦啦一长串流程……其实有时根本没那么复杂,今天就来讨论些除了验证码识别还可以怎么黑掉一个验证码。

论如何黑掉验证码

使用cookie/session记录登录失败信息
很多时候为了用户体验验证码只有在登录失败一定次数后才会弹出验证码,但是当登录失败次数被记录在cookie或session时,如果攻击者不使用cookie或每次使用新的session验证码弹出机制将被绕过。

验证码使用后不过期
通常验证码与session存在对应关系,当一个验证码验证成功后未做过期处理,攻击者则可反复使用这组验证码和session;当一个验证码验证失败后未做过期处理,则可能会被暴力破解。

验证码使用后过期处理不及时/过期机制可被绕过
如果验证码更新不及时或更新机制可以被绕过将导致攻击者仍旧可以使用用过的验证码。

将验证码的值返回客户端
将验证码的值通过response、cookie等方式返回给客户端将会使验证码失去存在的意义,即使使用md5等方式返回也同样存在这种风险。

验证码可预测
如可根据验证码生产算法预测出验证码的值。

验证码的值域太小
如果验证码的值只有10个,那么攻击者随便尝试一个就有10%的正确率。

无超时/超时时间过长
验证码无超时或超时时间过长可能会给人工打码提供机会,如先收集验证码及对应的session,然后进行人工识别,在需要时再取出人工识别过的验证码和对应的session使用。

绕过验证码
这个属于系统整体设计的问题,如一个功能在PC端有验证码而移动端没有的话,攻击者完全可以利用移动端的接口去实现攻击而没必要再去黑掉验证码。

验证码易识别
想想最后还是不得不讲回验证码识别,一个过于简单的验证码确实还是无法达到防御的目的地。

最后

有些话等过两天再来讲吧……

点击数:628

安装Supervisor

生成默认配置文件

生成默认配置文件的方法如下:


配置文件常用配置如下:


启动Supervisor

通过如下命令使用上述配置文件启动Supervisor:

管理Supervisor中的进程

通过supervisorctl可以对Supervisor启动的进程进行管理,首先使用下面的命令打开Supervisor的控制台:

相关命令如下:

注:programxxx[program:theprogramname]里配置的值。

另外,通过Web端也可以进行管理,地址及认证信息详见[inet_http_server]中的配置。

点击数:1202