Nginx+Lua进行访问控制

背景

前阵子帮朋友做了个服务端,用来给他APP做一些基本的注册、付费等功能。但是他APP被盗版了,话说这盗版也是厉害,有时候注册量远远高于正版注册量,昨天盗版一天注册6000人,正版才2000人。于是乎服务器扛不住了,注册接口超时,客户端自动发起重连,又超时,又重连,如此往复,最后正常用户都没法访问了。

处理方案

要保证现有客户的能正常使用,还要限制盗版,那必须得知道盗版跟正版有啥区别了,检查过后,发现盗版应用在接口中有一个参数跟正版不一致。那当然得从参数上做限制。
两个方案:

  1. PHP接收到数据后,判断然后剔除。
  2. 使用Lua在Nginx层直接剔除

不用看,当然能在Web服务剔除最好了。为啥呢?如果在应用层提出,一样会进入PHPFPM消耗资源。

具体实施

安装Lua过程不表,可以参考https://segmentfault.com/a/1190000018641801

lua_need_request_body on;
location ~ \.php {
    access_by_lua '
        local uri = ngx.var.request_uri
        if string.find(uri,"/api/register") ~= nil then
            local body = ngx.req.get_body_data()    
            if string.find(body,"20200101") or string.find(body,"20200102") or string.find(body,"9.9.9") or string.find(body,"8.8.8") then
                ngx.exit(ngx.HTTP_NOT_FOUND)
            end
        end
    ';
    # 接着往下继续执行php,正常请求
}

这里提一个点access_by_lua用来进行访问控制,之前一直用content_by_lua_block,匹配成功以后,就不会继续执行php了。一定要用access_by_lua

网上是这么说的

access_by_lua 在请求访问阶段处理,用于访问控制,适用于 http、server、location、location if

content_by_lua 是内容处理器,接受请求并输出响应,适用于 location、location if

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


2020年04月08日简单优化一下。随着盗版越来越多,盗版的关键字丢数组里

lua_need_request_body on;
location / {  
  access_by_lua '
    local uri = ngx.var.request_uri
    if string.find(uri,"/api/register") ~= nil then
        local body = ngx.req.get_body_data()
        local denyList = {"20200101","20200102","9.9.9","8.8.8"}
        for i = 1,#denyList do
            if string.find(body,denyList[i]) then
                ngx.header.content_type = "application/json";
                ngx.say(\'{"toast":"您正在使用盗版软件"}\');       
                ngx.exit(ngx.HTTP_OK);
            end
        end
    end
';
}  

细心的朋友会发现,上面的for循环中,i是从1开始的,没毛病,在很多语言中长度是从0开始,但是在lua里面,长度居然是从1开始。


2020年04月10日在优化一波,将所有处理失败的请求全部记录下来

在处理这个功能的时候,发现一个神奇的bug

在lua中,比如匹配8.8.8里面的居然会匹配成任意字符,也就是说,8d8c8也会被匹配成功,导致有一部分用户被误判。需要用%p来表示

将错误信息,写入文件中。

file = io.open("/tmp/lua.txt", "a")
io.output(file)
io.write(date)
io.write(body)
io.close(file)

以下是将lua脚本单独放在一个文件中的完整代码

lua_need_request_body on;
access_by_lua_file /usr/local/nginx/conf/lua.lua
local uri = ngx.var.request_uri
    if string.find(uri,"/api/register") ~= nil then
        local body = ngx.req.get_body_data()
        local denyList = {"20200101","20200102","9%p9%p9"}
        for i = 1,#denyList do
            if string.find(body,denyList[i]) ~= nil then
            local time = os.date("%Y-%m-%d %H:%M:%S")
                    local date = os.date("%Y-%m-%d")
                    local fileName = "/tmp/lua"..date..".txt"
            file = io.open(fileName, "a")
          io.output(file)
          io.write(time)
          io.write(body)
          io.write("\n")
          io.close(file)
                    ngx.header.content_type = "application/json";
          ngx.say(\'{"toast":"您正在使用盗版软件"}\');       
          ngx.exit(ngx.HTTP_OK);
            end
        end
    end

给自己打个气

八月了,今年一整年都不是很顺利,无论是工作还是生活,最近一直都状态也不是很好。一切都是有因果的,今天的一切都是昨天的造成的,所以我也在想这些年以来,我有没有哪一步是走错了,才导致今天这样的结果。想了一下,我觉得有两点

没有认识到工作的天花板

说白了就是年少不想事。从我大学毕业的时候,三叔就一直劝我叫我做生意,不要上班打工。而我一直喜欢写代码,一直都在老老实实写代码,从来没想过未来怎么办,那时候也觉得未来很远,还有这么长时间,够我挥霍。到现在年近三十,结婚即将生子,已经没有再挥霍的资本,才发现一切都已经晚了。
那么工作的天花板在哪里呢?其实就是收入,大部分人工作就是普普通通的一份工作而已,我们不去讨论那些大企业总裁级别的,岗位收入的天花板一直都会在那里,当你走到一定高度的时候,就是需要走出来,离开这个岗位,才可能达到另一个层次。就好像在南昌,程序员一万多的工资已经差不多到天花板了。而随着年龄的增长,需要花钱的地方也越来越多,一万的收入已经完全不足以支撑日常开支。

没有在一件事上坚持做下去

是的,没有任何一件事情,我虽然这两年尝试了很多事,但是没有任何一件事情,是花了80%的力气去做的,顶多当时做kindle推送、Youtube搬运的时候花了一点心思,那是能看到实实在在的钱嘛。而我没有在其他任何一件事情上,付出同样的力气,总是在做一些以为随便花点力气就能有不错回报的尝试,却从来不够深入。

人生总是起起伏伏,也会有不同的阶段,我一直记得当年在沃尔玛的时候,当时店总东哥说过一句话,销售不好的是就做标准。现在看这句话,就是在劝我们,脚踏实地,稳扎稳打。越是在低谷的时候,越是需要打起精神,不要让自己走错一步。人生啊,坚持做对的事情,哪怕只是一个很小的选择,坚持下去,一定会让一切走入正轨。

面试有感

最近公司一直在招小程序猿,说几个印象比较深刻的。

做了6年的92年老鸟

当时一拿到简历,第一眼一个92年的小伙子,干了这么多年了,想想应该不会太差吧,看了一下过往项目经历我就惊呆了。可以说就两家公司,第一家外包,第二家莆田系医院。一开始还抱有一点点希望,莆田系医院万一是做站群呢,万一访问比较大高并发呢。结果一聊,就是在莆田系医院做模版网站。薪资要求只要6k。于是我很奇怪,一个干了这么多年的人,项目也只有这么几个,那他也业余时间都在干啥,不关注技术成长吗?顺口一问,他很自信的说「我会做discuz的插件,我做了很多插件blabla」原来这小子业余时间都做插件卖钱去了。

一直都很建议多出去走走,就算出不去,也一定要多了解一下外面的世界,才会知道自己的不足,才会知道更广阔的天空应该是怎样,否则只会被眼前的事物蒙蔽双眼,止步不前。

做了一年半的99年小鸟

HR把小伙子带进办公室,我打量了一眼,看穿着比较跳的感觉,仔细一看简历又惊呆了,99年的!!!其实这时候心里已经打了靶,工作经验一年半,不用说很多东西都不会。抱着走过场的心态跟他随意聊了几句,聊完却感觉,如果是我的公司,且资金没问题的话,我愿意好好带带他。为毛呢?

他给我一股特别质朴的感觉,我已经很久没有在别人身上看到这样的东西。

我问了他几个问题,比如他提到Laravel的数据库迁移,问他知不知道这是怎么实现的,他羞涩又很诚实的说之前做的都是外包项目,所以自己没有关注过底层。跟他说我们可能会用到WebSocket,他有点尴尬的说我没听过。

其实这些都在我意料之中,我只是想通过问他问题的方式,告诉他答案,希望他能多了解一些东西,至于他事后会不会去学习我就管不了了。然后问他为什么会从深圳来南昌,他说「我上家公司从深圳搬到南昌来了,就一起过来了,但是上家公司现在就我一个人,也是做外包的,我就不想做了,我在南昌租了一年房子,还没到期,所以想到南昌找工作,到期了再去其他城市。」这么实诚的孩子真的很久没见到了。

最后我假装惊讶的问了一句「哎呀,你是99年的啊,你好小哦」。他又羞涩的说到「是的,我是99年的,我今年19岁周岁,我是河南省安阳市XX技术学院毕业的,所以我毕业以后到现在只有一年半工作经验,我家里条件不太好,所以我中专毕业就出来工作了blablabla」

可能我表达的不太好,但这个小伙子就是个我一股很质朴的感觉。于是跟他聊了很多技术、产品、职业发展等等以外的话题。他要走程序员这条路,一定是很坎坷的,要付出比其他人更多的努力。

三个前端小伙子

我们要做的系统是对内的OA,其实对前端来说要求不高,没有什么特效,没有什么复杂功能,都是正常的增删改查,所以一般来说只要会VUE都能胜任。
第一个小伙子很会聊,叫他A吧,看着就像那种比较跳的人,但做的东西跟我们几乎一模一样,所以就让他来了,但是来了以后果然很跳的人不太踏实,整天都在逛掘进、知乎,安排点任务也是拖拖拉拉,做做玩玩,第四天正好有另外一个小伙子B过来面试,居然跟A是一家公司的,聊了一会儿,人相对比较踏实,于是就B留下来。面完以后,正好A也看到了B,于是就跟A随口聊了一下,A说「B的技术不咋地,XXX都不会,之前老是问我XXXXX」。第二就让A走了。
接着说B,来的第一条,正好公司有一个15、16年左右的项目,前后端都在一起的,不像现在完全分离。用的都是jQuery、Smarty之类的,让B改了一个下午,大概是被这玩意儿搞怕了,第二天就不来了。
最后一个C,来公司面过两次了,4月初一次,5月底一次。4月初的时候,前一家公司离开刚一个星期,就顺口问了下为啥离职,他说家里原因,我就问他家里事情都处理完了吗?回答处理完了。然后仔细一看,上上家公司离开,也是家庭原因。于是就问他能不能提供上一家公司离职证明,回答拿不到。5月底问他为啥从4月份找工作到5月份,他说已经上了一个月的班,但是感觉那家公司老板不咋地,所以不干了。具体原因不方便透漏。然后就没有然后了。

港真我是真的很不喜欢程序员在面试的时候只谈技术,排除复杂业务和纯技术驱动类的项目,对大部分中小公司来说,技术要求都不会太高,大部分有几年工作经验程序员都能胜任,技术以外的东西,才是竞争力。
比如对产品的理解、对业务的理解、怎样与服务端或客户端更好的配合协作、自我驱动力来带动团队执行力等等,这些是不管做程序员背井离乡在外打工,还是自己创业当上CEO赢取白富美走上人生巅峰都需要的技能。

职场新人应该掌握的基本功

职场新人应该掌握的基本功

最近入职新公司,公司一大批实习生或者毕业一两年的孩子们,一转眼我也成为一只老鸟了。在上一家公司的时候,因为团队里几乎都是老手,所以没有啥感觉,最近在跟这群新人打交道的时候,再对比之前同事,总会发现老鸟和菜鸟的不同点,这几天我也在思考,我又是如何成为现在这个样子?

把手头的事做到极致

这是我第一次有意识的去改变,大概14年的时候,有几天在一亲戚暂住,那天她大概晚上10点才到家,然后开始检查学前班儿子的作业,正值中秋,学校的作业中有一项是画一幅「中秋节」相关的画,亲戚看了一眼,觉得不太好,叫我上上色,于是我拿起蜡笔,将草地、月亮、树木花草、孔明灯等涂上颜色,大概20分钟过去了,我觉得都差不多,于是大概下面这个样子。亲戚检查完其他作业,走了过来看了一眼,默默的拿起画笔,将草地每一个缝隙都涂上绿色,树干全部涂成棕色等等,用一个成语形容「绝不留白」。当时我就觉得,她能在一家全球TOP的企业做高管是真的该。她的标准跟我的标准完全不一样,我标准只是上面有颜色,表示一下意思就行了。而她做每一件事情应该都是这样,力求做到极致,一定要到自己满意为止,而我做一件事,只是把它当成一个任务。
手残党,真不会画画

往前多想一步

接着上一个话题,怎样才叫极致?怎样才算自己满意?怎样避免「自己满意,实际却糟糕透顶」?接着上一幅画,如果我能多想一步,弟弟的老师一定是希望能看到一副画得很好的画,我怎样才能把这幅画的颜色画好呢?如果我能想到这一步,一定不会留白。
再举个栗子:

你司经营一款商家库存管理的APP,由于一直没有盈利,公司在寻找盈利的可能性。于是同事A提议在库存的基础上,加上电商的模块,同事B立即附议,原因是下单之类开发很简单,我们很快就能上线。

于是开始开发,对于一个入行没多久的程序员,他可能只会想,增加一个下单,支付,结算的功能就ok了。可实际上下单以后还需要发货,发货可能需要对接快递,有发货就可能会有退货,退货就可能会有纠纷,有纠纷那么平台作为担保方就要处理,那是不是还得增加一个客服岗?

虽然说实际情况可能并不会发展这么快,也确实当有太多的纠纷需要处理的时候,那电商项目肯定也运营的不错,一项增长的业务,增加一个客服岗的人工成本也值得。但你最好能有往前多想一步的能力。

怎样培养自己多想一步的能力?我也没有一个科学、系统性的方法,我会在处理一件事情的时候,想一想接下来可能会发生什么。比如公司搬家,你要把一些办公桌椅拆开放到杂物间,既然要拆,就很可能要安装,零件怎么摆放能方便下次安装呢?搬家一定会很脏,脏了就要打扫,有没有什么办法能方便自己或其他人打扫呢?

培养好的工作态度,学习好的工作方法

这是一句比较空的话,但如果回到20岁,我一定会的自己说这句话。好的工作态度能决定你可能担起多大的胆子、负多大的责任,能让你有更多的机遇,甚至可能决定你走多远。好的工作方法能决定你花多大的力气走这么远。

好了,上个月公众号还有333位粉丝,今天就用这篇文章祝福仅有的327位粉丝都能有更好的工作方法。

猴年马月真的到了

哇哦~不知不觉又到了月底,忙到今天都没抽空写博客,这样真的不好~可能主要原因还是最近都没有动脑。

中午pan总又请我吃兰州拉面了,主要还是想大家聊聊吧。是要向我传递一些信号、灌输一些信息。刚来公司的时候,还会跟他一起探讨,几次过后,发现跟他根本不在一个水平线上,我完全没法跟上他的节奏,于是乎也就变成了一个听众,一直都觉得,要有平等的沟通,而不是一味的听取,这样就是你不如人才会只听不说。但是我只是个凡人,我可以超越一部分人,我不可能超越所有人,一定会遇到在某些领域强于我的某些人。可能悉心听取也是一种成长吧。又或者说,对一类人来说他更喜欢说,更喜欢跟不如自己的人在一起来提升自己的优越感,我身边有这样的人,甚至偶尔我会觉得我也是这种人。

人,越缺少什么,越是会炫耀什么。

你不会看到王思聪说自己有钱,也不会看到金三胖说自己有权。

pan总是个很明白的人,在这个团队中,他清楚的知道自己的定位,也清楚的知道怎样让团队去更好,最重要的是,他能够帮助团队中每个人清楚的找到自己的定位。做事的人很重要。最近很多时候都觉得自己时间不够时间不够,如果把做项目的一些时间哪来学习新技术,思考一些问题和读书,一定会带了更长远的进步,而不是眼前的几个臭钱。需要从中找到一个平衡点。

最近花了一阵子强行调整作息时间,终于把生物钟给转过来了,现在都是早上起来写代码,晚上早点睡觉,额,也就差不多提前到12点之前。

时间飞快,又是一个学期半年过去。越往后,越是觉得自己这些年来收获太少,或者说跟想要的生活所需要的财富、知识、思想没有一项是自己满意的,甚至在很多时候会在一些方面觉得自己做起事情来束手束脚,再也没有那些年意气风发自信满满的感觉。或许是缺少一个积极的状态吧。

有时候就是要学会拒绝,事情堆积那么多,却没有一件事情办得漂亮。睡觉吧。也算是在6月的最后一天,完成了这篇流水账。

2016年06月30日23:49:32

如果愿意对一个人说出“晚安”,那算是在内心接受了一个人吧(冷漠脸)。