防御-DDoS-的终极奥义又拍云-SCDN

现如今不论是年轻的 80、90 后,还是 70、60 后,都在享受互联网带来的舒适和便利。在家就可以“逛商场”,完全不受时间的限制;在线支付既方便又安全;业余娱乐项目多种多样,打农药、吃鸡、追剧、看直播。在享受互联网便利的背后,不少提供服务的企业平台却面临着头疼的问题:随着企业价值、知名度的提高,很可能会引起业内竞争对手的眼红,也更易成为专业黑客的攻击目标,而最常见的就是 DDoS 攻击。 DDoS 的危害DDoS(Distributed Denial of Service)全称分布式拒绝服务,其主要就是通过数以万计的僵尸网络向目标主机同一时间发送大量的请求,继而瘫痪目标,令网站无法有效的进行存取,最终影响平台的运作。轻则导致网站服务器宕机,利益受损;重则导致企业整个产品链全面受阻,所有业务瘫痪,攻击引发的政治影响、社会舆论的压力给企业带来名誉损失,连锁反应严重。 虽然这么多年来 DDoS 攻击的频率,强度和复杂程度在不断提高,但是对易受攻击的服务器执行大规模攻击的方法并没有改变。这种攻击模式很受黑客的欢迎,因为这是相对便宜而且简单的攻击方法。当攻击者将目标瞄准了某个平台,占满其带宽并导致网站 Web 服务连接明显减速甚至完全失败时,就发生了攻击。目前 DDoS 攻击每秒流量可达到 1 Tbps 以上,就像 2018 年初对 Github 的攻击一样。 可以说,DDoS 是目前最凶猛、最难防御的网络攻击之一。这个世界级难题还没有得到完美彻底的解决,但采取适当的措施以降低攻击带来的影响和损失是十分必要的。将 DDoS 防御作为整体安全策略的重要部分来考虑,防御 DDoS 攻击与防数据泄露、防恶意植入、反病毒保护等安全措施同样不可或缺。 DDoS 的防御目前大多数网站都会使用 CDN 产品进行网站加速,CDN 在用户和源站之间安插了众多的边缘节点,通过缓存技术既能加快网站访问速度,同时也可以隐藏源站 IP,对恶意请求进行拦截,起到防护的作用。又拍云 CDN 自带的访问控制功能包含访问限制、各种防盗链、安全防护等功能,针对有特征的 HTTP 请求(例如:IP 地址、User-Agent 等)可以起到拦截作用。详情可以参考文章:CDN 访问控制的那些事 但是 HTTP 拦截需要有一个前提,那就是请求必须有一个特征。比如恶意请求都是从某个 IP 段发出的,那么把这个 IP 段封掉就行了。或者,它们的 User Agent 字段有特征(包含某个特定的词语),那就把带有这个词语的请求拦截。但是,真正的 DDoS 攻击可能是没有特征的,它的请求看上去跟正常请求一样,而且来自不同的 IP 地址,以致于没法拦截。这就是 DDoS 攻击特别难防的原因。 防御 DDoS 的终极武器——SCDN针对上述问题,又拍云推出了 DDoS 防护和 CDN 加速组合式解决方案——SCDN 安全加速。 ...

October 9, 2019 · 1 min · jiezi

夜空中最靓的二狗子是如何让-HTTPS-快上加快的

二狗子是某不知名网站的站长,他热衷于通过博客分享日常的一些工作、生活、技术等,立志要成为夜空中最靓的仔。 但是前段时间有几个用户反馈,网站总是莫名会跳转到一个 xx 网站,除此之外访问速度也有点慢。作为夜空中最靓的仔,怎么可能会让劫持这种事情困扰用户,于是全站快速启用了 HTTPS。网站是安全了,但是有什么办法可以加快访问速度,二狗子再一次陷入了沉思。 HSTS一个夜深人静的夜晚,二狗子开始深入研究 HTTPS 。他从维基百科查找了 HTTPS 的传输过程,只有熟悉了整个过程才能更好了解如何优化 HTTPS。 二狗子想着 HTTPS 虽然已经启用,但是无法确认用户是直接访问 http:// 还是 https:// ,按照普遍的用户习惯都是直接输入站点域名,再由浏览器直接补充协议类型。但是这就存在一个问题,如果在网站设置当用户访问域名的时候强制 https 进行 301 或者 302 跳转,但是这个过程中使用到 HTTP 因此容易发生劫持,受到第三方的攻击。 有什么更好的办法来避免这种情况呢?话说有矛就有盾,二狗子深入研究发现 HSTS 是可以避免这种情况。 HSTS 是国际互联网工程组织 IETF 正在推行一种新的 Web 安全协议,网站采用 HSTS 后,用户访问时无需手动在地址栏中输入 https://,浏览器会自动采用 HTTPS 访问网站地址,从而保证用户始终访问到网站的加密链接,保护数据传输安全。 HSTS 主要是通过服务器发送响应头的方式控制浏览器操作; 首先在服务器响应头中添加:Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload]设置 max-age 参数,最长建议设置 6 个月;当用户下次使用 http 访问,客户端就会进行内部 307 跳转;开启 HSTS 可以有效防范攻击,同时省去 301/302 跳转时间,大大提升网站安全系数和用户体验。 HTTP/2开启 HSTS 后,二狗子更加兴奋,决定不睡觉继续深入研究。 ...

August 28, 2019 · 1 min · jiezi

OpenResty-社区王院生APISIX-的高性能实践

2019 年 7 月 6 日,OpenResty 社区联合又拍云,举办 OpenResty × Open Talk 全国巡回沙龙·上海站,OpenResty 软件基金会联合创始人王院生在活动上做了《APISIX 的高性能实践》的分享。OpenResty x Open Talk 全国巡回沙龙是由 OpenResty 社区、又拍云发起,邀请业内资深的 OpenResty 技术专家,分享 OpenResty 实战经验,增进 OpenResty 使用者的交流与学习,推动 OpenResty 开源项目的发展。活动将陆续在深圳、北京、武汉、上海、成都、广州、杭州等城市巡回举办。 王院生,OpenResty 社区、OpenResty 软件基金会联合创始人,《OpenResty 最佳实践》主要作者,APISIX 项目发起人和主要作者。 以下是分享全文: 大家好,我是王院生,很高兴来到上海。首先做下自我介绍,我于 2014 年加入奇虎 360,在那时认识了 OpenResty,此前我是一个纯粹的 C/C++ 语言开发者。在 360 工作期间,利用工作闲暇时间写了《OpenResty 最佳实践》,希望能影响更多的人正确掌握 OpenResty 入门。2017 年我作为技术合伙人和春哥(章亦春,agentzh)一起创业。今年我个人的重心有所调整并在今年三月份离职,准备将更多精力投入到开源上,于是发起了 APISIX 这个项目,企业宗旨是依托开源社区,致力于微服务 API 相关技术的创新和实现。 什么是 API 网关 API 网关的地位越来越重要,它几乎劫持了所有流量,内外之间完成了用户的安全控制、审计,通过自定义插件的方式满足企业自身特定需求,最常见的自由身份认证等。随着服务在数量和复杂度上的不断增长,更多的企业采用了微服务的方式,这时通过 API 网关来完成统一的流量管理和调度就非常有必要。 微服务网关和传统意义上的 API 网关有一些不同,主要包括下面几点: 动态更新:在微服务之前,服务不像现在这样经常来回地变化。比如微服务需要做横向扩充,或者故障恢复、热备、切换等,IP 、节点等变动更加频繁。举例如微博上一旦出现了爆点事件,就急速扩充计算点,必须要非常快地扩充新机器来扛压。波峰波谷变化明显,分钟级别的机器动态管理,已经越发是常态。更低延迟:通常动态就意味着可能会做一些延迟(复杂度增加),在微服务里面,对于延迟要求比较高,尤其对于现在的用户体验,超过 1 秒以上的延迟是完全不可接受的。用户自定义插件:API 网关是给企业用户使用的,它一定存在私有逻辑(比如特殊的认证授权等),所以微服务网关必须能够支持企业用户自定义插件。更集中的管理 API:如前面所说 API 网关劫持了用户的所有流量,所以用网关来做统一的 API 管理是非常必要的。在网关角度可以看到 API 是如何设计,是否存在延迟、安全问题,以及响应速度和健康信息等。我们要做的微服务 API 网关产品,除了上面的基本要求,还有一些是我们区别于其他人的: ...

August 20, 2019 · 3 min · jiezi

性感与色情有多远——你不知道的图片鉴黄那些事

图片鉴黄服务市场容量巨大,作为移动互联网行业最为热门的创业领域,移动社交类App每天生产大量图片,并有无数色情图片混杂其中,所以高效准确地鉴别和剔除淫秽色情信息成为一项十分艰巨的任务。此外,移动直播的大热也导致图片鉴黄需求大增,尤其对于中小开发团队而言,直播平台很可能因为人力监管问题而在涉黄审核方面出现风险。而自主研发鉴黄功能或增加审核人员又会增加产品和服务外的支出,给前期开发造成额外压力。利用人工智能图像识别技术进行高效准确的自动化鉴黄服务,能降低企业使用鉴黄服务的技术门槛,帮助企业有效减少相关人力成本的投入。如何界定性感与色情△ 传统神经网络与深度神经网络机器学习是人工智能的核心,简单来讲它就是:运用一套通用的算法——泛型算法,建立起数据逻辑,利用模仿人脑的机制来解释数据,让机器自动学习良好的特征,从而减少人工审核的过程。举例来说,想要教会机器去识别色情图像,需利用成千上万的图片样本去“训练”它,提取色情图片特征并不断记忆。每张图片中的任何一个点都包括亮度值、色相值、饱和度值,通过设置这三个值的大小范围,机器能识别出“肉色”,进而猜测出图片里裸露的人体皮肤区域。色情图片最明显的特点就是画面中人体皮肤颜色所占比例较大,当机器识别图片中有类似人体肤色区域后,需要进一步确认区域的来源,看他们是没有穿衣服的女主角还是正常物体。假设两块黄色区域分别是两条腿或者两只胳膊,另一块区域是人的身体,这些区域的长度值、宽度值符合人体大小比例,且彼此位置满足一定的几何关系,则有很大可能是色情图片,如果这些区域之间大小和位置不像是人的身体,则可以排除色情图片的嫌疑。△ 计算肤色区域的几何关系△ 图片区分标准色情:裸露敏感部位,包含露骨镜头,描述性交行为和色情场景的图片。性感:衣着暴露但没有裸露敏感部位。正常:非色情,非性感图片。色情与艺术的鉴定标准是人定的,理论上讲可以通过刻意训练、调整阈值等手段让机器更符合自己的标准,色情图片数量越多,风格和场景越多样化,机器学习结果越准确。机器学习的一个主要优势在于可以利用大数据样本,在学习的过程中不断提高识别精度。得益于今年来计算机速度的提升、大规模集群技术的兴起、GPU 的应用以及众多优化算法的出现,耗时数月的训练过程可缩短为数天甚至数小时,机器学习可以被广泛运用,大大提升鉴黄效率。人工智能图片鉴黄:机器学习与人工审核相结合△ 又拍云智能鉴黄工作流程又拍云“智能鉴黄”功能将自动对直播、视频、图片等内容进行鉴别。目前在一张图片鉴黄的完整过程是将它拿到鉴黄中心鉴别,完毕后,再把结果发送至图片审核平台进行最终确认。对于疑是色情图片将由人工审核确认,而这部分将会随着训练次数的增加而不断减少,帮助运营团队节省人工审核成本。如何进行直播鉴黄通常情况下,视频直播鉴黄服务利用视频截图、图像识别、语音审核、弹幕监控、关键词提取等方式识别色情内容。其中视频直播的鉴黄可按照以下步骤:识别图像中是否存在人物体征并统计人数;识别图像中人物的性别、年龄区间;识别人物的肤色、肢体器官暴露程度;识别人物的肢体轮廓,分析动作行为;提取音频信息关键词,判断是否存在敏感信息;实时分析弹幕文本内容,判断当前视频是否存在违规行为。每分钟视频采集关键帧的频率可由客户自主设定,从1秒到几十秒均可,例如可以默认5秒采集一次关键帧用于识别。推荐阅读:“人机"对战:电脑太简单了,我是射手 skrskrskrAI 这么优秀,连我鉴黄师的饭碗都抢了

March 29, 2019 · 1 min · jiezi

我眼中的 Nginx(五):Nginx — 子请求设计之道

张超:又拍云系统开发高级工程师,负责又拍云 CDN 平台相关组件的更新及维护。Github ID: tokers,活跃于 OpenResty 社区和 Nginx 邮件列表等开源社区,专注于服务端技术的研究;曾为 ngx_lua 贡献源码,在 Nginx、ngx_lua、CDN 性能优化、日志优化方面有较为深入的研究。子请求、父请求和主请求Nginx 所处理的大部分请求,都是在接收到客户端发来的 HTTP 请求报文后创建的,这些请求直接与客户端打交道,称之为主请求;与之相对的则是子请求,顾名思义,子请求是由另外的请求创建的,比如主请求(当然子请求本身也可以创建子请求),当一个请求创建一个子请求后,它就成了该子请求的父请求。从源码层面来说,当前请求的主请求通过 r->main 指针获取,父请求则通过 r->parent 指针获取。使用子请求机制的意义在于,它能够分散原本集中在单个请求里的处理逻辑,简化任务,大大降低请求的复杂度。例如当既需要访问一个 MySQL 集群,又需要访问一个 Redis 集群时,我们就可以分别创建一个子请求负责和 MySQL 的交互,另外一个负责和 Redis 的交互,简化主请求的业务复杂度。而且创建子请求的过程不涉及任何的网络 I/O,仅仅是一些内存的分配,其代价非常可控,因此在笔者看来,子请求机制是 Nginx 里最为巧妙的设计之一。子请求创建与驱动通常需要创建子请求时,模块开发者们可以调用函数 ngx_http_subrequest 来实现,默认情况下,子请求会共享父请求的内存池,变量缓存,下游连接和 HTTP 请求头等数据。当子请求创建完毕后,它会被挂到 r->main->posted_requests 链表上,这个链表用以保存需要延迟处理的请求(不局限于子请求)。因此子请求会在父请求本地调度完毕后得到运行的机会,这通常是子请求获得首次运行机会的手段。我们知道 Nginx 针对一个 HTTP 请求,将其处理逻辑分别划分到了 11 个不同的阶段。当一个子请求被创建出来后,它首先运行的是 find config 阶段,即寻找一个合适的 location,然后开始后续的逻辑处理。通常,如果一个子请求不涉及任何的网络 I/O 操作,或者定时器处理,一次调度即可完成当前的子请求;而如果子请求需要处理一些网络、定时器事件,那么后续该子请求的调度,都会由这些事件来驱动,这使得它的调度和普通的主请求变得无差别。既然除第一次外,子请求的驱动可能是由网络事件来驱动的,那么子请求的调度就是乱序的了。假设当前主请求需要向后端请求一个大小 2MB 的资源,我们通过产生两个子请求,分别获取 0-1MB 和 1MB - 2MB 的部分,然后发往下游,因为网络的不确定性,很有可能后者(1MB - 2MB)先获取到并往下游传输。那么此时下游所得到的数据就成了脏数据了。为了解决这个问题,Nginx 为子请求机制引入了另外一个称为 postpone_filter 的模块。该模块的目的在于,判断当前准备发送数据的请求,是否是“活跃的”,如果当前请求不是“活跃”的,则它期望发送的数据会被暂时保存起来,直到某一刻它“活跃”了,才能将这些数据发往下游。怎么判断一个请求是否是“活跃”的?我们需要先了解父、子请求之间的保存形式。对于当前请求,它的子请求以链表的方式被维护起来,而前面提到,子请求也可以创建子请求,因此这些请求间完整的保存形式可以理解成一颗分层树,如下图所示。上图中,每个红圈表示一个请求,每一层的请求分别是上一层请求的子请求。从树遍历的角度讲,在这样一棵树上,哪个节点应该最先被处理?结合子请求机制的实际意义来分析,子请求是为了分摊父请求的处理逻辑,降低业务复杂度。换而言之,父请求是依赖于子请求的。很大程度上父请求可能需要等到当前子请求运行完毕后根据子请求反馈的结果来做一些收尾工作。所以需要采用的是类似后序遍历的规则。即上图最右下角的请求是第一个“活跃”的请求。从源码层面来说,这颗分层树的保存用到了两个数据结构,r->postponed 和 r->parent这两个指针,遍历 r->postponed 来按序访问当前请求的子请求(树中同层的兄弟节点);遍历 r->parent 访问到父请求(树中上一层的父节点)。postpone_filter 模块会判断当前请求是否“活跃”,如果不“活跃”,则把将要发送的数据临时拦截到它自己的 r->postponed链表上(所以这个链表上其实既有数据也有请求);如果是活跃的,则遍历它的 r->postponed 链表,要么把被临时拦截下来的数据发送出去,要么找到第一个子请求,将其标记为 “活跃”,然后返回。等到该子请求处理结束,重新将其父请求标记为“活跃”,这样一来,当父请求再一次运行到 postpone_filter 模块的时候,又可以遍历 r->postponed 链表,循环往复直到所有请求或者数据处理完毕。感兴趣的同学可以自行阅读相关源码(http://hg.nginx.org/nginx/file/tip/src/http/ngx_http_postpone_filter_module.c)。使用了子请求机制的模块目前整个 Nginx 生态圈,有很多使用子请求的例子,最著名的便是 ngx_lua 的子请求和 Nginx 官方的 slice_filter 模块了。ngx_lua 提供给用户的 API (ngx.location.capture)灵活性非常大。 包括针对是否共享变量也可自行选择。特别地,ngx_lua 的子请求运行时,会阻塞父请求(挂起其对应的 Lua 协程)。直到子请求运行完毕,子请求的响应头、响应体(所以如果响应体比较大,则会消耗很多内存)等信息都会返回给父请求。ngx_lua 的子请求是不经过 postpone_filter模块的,它在一个较早的 filter 模块(ngx_http_lua_capture_filter) 里就完成了对子请求响应体的拦截。Nginx 官方提供的 slice_filter模块,可以将一个资源下载,拆分成若干个 HTTP Range 请求,这样做最大的好处是分散热点。这个模块允许我们设置一个指令 slice_size,用以设置后续 Range 请求的区间大小。该模块会陆续创建子请求(在前一个完成后),直到所需资源下载完毕。另外, Nginx/1.13.1 也引入了一个称为 Background subrequests 的机制(用以更新缓存)。基于这个机制,Nginx/1.13.4 引入了一个 mirror 模块,通过创建子请求,可以让用户自定义一些后台任务。比如预热一些资源,直接将它们放入 Nginx 自身的 proxy_cache 缓存中。陷阱与缺陷前文说到,子请求创建出来时,复用了父请求的一些数据,这无形中引入了一些坑点。比如变量缓存,如果在子请求中访问并缓存了某个变量,当后续在父请求中使用时,我们就会得到之前的缓存数据,这可能造成工程师们花费大量的时间和精力去调试这个问题。另外笔者认为一个非常重大的缺陷是,子请求复用了父请求的内存池,以 slice_filter 模块举例,它将一个 HTTP 请求划分成若干个的子请求,每个子请求向后端发起 HTTP Range 请求,在资源非常大 ,而配置的 slice_size 相对比较小的时候,会造成有大量的子请求的创建,整个资源下载过程可能会持续很长一段时间,这导致父请求的内存池在一段时间内没有释放,加之如果并发数比较大,可能会造成进程内存使用率变得很高,严重时可能会 OOM,影响到服务。因此在考虑使用的时候,需要权衡这些问题,有必要的话可能需要自行修改源码,以满足业务上的需要。虽然一些缺点是在所难免的,但是子请求机制很大程度上简化了请求的处理逻辑,它分而治之的处理思想非常值得我们去学习和借鉴,无论如何,子请求机制也将是后续进行系统设计时的一大参考范例。《我眼中的 Nginx》系列:我眼中的 Nginx(一):Nginx 和位运算我眼中的 Nginx(二):HTTP/2 dynamic table size update我眼中的 Nginx(三):Nginx 变量和变量插值我眼中的 Nginx(四):是什么让你的 Nginx 服务退出这么慢? ...

March 27, 2019 · 1 min · jiezi