固件提取系列-UBI文件系统提取以及重打包

記憶體方案克服嵌入式設計的功耗和安全挑戰

作者:Andre Hassan,Kilopass公司市場行銷與應用總監

無線監控設備和電子錢包正創造出一種以電池供電的全新SoC設計。利用嵌入式處理能力和無線連接,這些SoC可在數月或數年內連續工作而無需充電或更換電池。本文將討論這些SoC對SRAM、ROM和NVM的要求,並提出一種能因應這一類新設計限制的創新方案。

據研究機構IMS Research的《全球遠端監控服務市場──2012年版》研究報告顯示,2011年全球遠端監控服務市場的規模超過290億美元,相當於全年中每月經常性收益(RMR)為24億美元。此外,在同一年中已為5,400萬個用戶位置提供了諸如警報、遠端視訊監控、實體存取控制、火災偵測和個人應急等服務。IMS Research並於其《2012年全球可穿戴技術市場── 一種定量市場評估》報告中指出,2011年共售出1,400萬套可穿戴式設備,預計該市場將在2016年實現至少60億美元的營收規模。

行動金融交易經歷數度磨合後,以金融機構針對通訊服務供應商和手機供應商究竟誰該做什麼的糾纏中起步。然而,Frost & Sullivan在其《行動金融服務──技術與市場分析》報告中指出,由於更多具有近場通訊(NFC)功能的行動設備出現以及通訊服務供應商和金融機構間合作關係日益密切,基於NFC的行動商務正接近成長爆發點。此外,這些合作夥伴關係也鼓勵了半導體供應商、行動設備製造商和行動業者將更多支援NFC功能的行動設備推向市場。

新興設計限制
在影響無線設備提供遠端監控和金融交易服務功能的二大關鍵設計元素中,最重要的因素就是功耗,因為用戶會期望這些設備將始終如願地完成任務。就像一只打開就可用的皮包一樣,支援NFC的電子錢包即使在手機沒電的情況下,也必須具有可支付的能力。遠端監控設備的用戶都具有同樣‘隨需即用’的期盼。

第二個關鍵的設計要素是安全,它要能抵禦侵入和非侵入式篡改(tampering)以及遠端攻擊。用戶對於金融交易的安全訴求是顯而易見的。就像駭客攻擊網際網路一樣,駭客也可能入侵遺失或被盜的手機,以轉移資金或篡改原用戶的身份。而另一種較不明顯、但對OEM來說同樣重要的是──防範演算法智財權(IP)被盜和偽造。

越來越多的遠端監控設備透過無線連接到雲端,如微軟的HealthVault可接收心率手錶、血壓計而來的健康和健身資料。隨著醫療保健服務走出醫療院所,開始在家中對老年人提供健康照護,那麼針對患者生命體徵的數位監控和處方藥利用就必須是安全的。如果駭客在監控設備上傳重要健康資訊到雲端時入侵系統,將導致用戶個人資訊暴露在危險中。

具挑戰性的設計要求
當今的嵌入式設計可能包含圖1中所示的元件──一款內建SRAM的MCU以及一款用於韌體和資料儲存的外接EEPROM/Flash,對於該設計造成明顯的功率限制。最明顯的是板上SRAM會持續用電以保持儲存的數據。例如在65nm及以下的更小製程幾何,製程本身不可避免的漏電流加大了SRAM正常運作所需的功耗。

若SRAM被設置在非保持待機模式,則會對功耗和性能產生顯著的影響。與外接元件通訊的功耗損失來自於外部互連所產生的更高電壓和電容(P=CV^2 F;其中,功率P、電容C、電壓V、頻率F)。在每次喚醒時,都要從外接EEPROM或串列快閃記憶體中載入程式,太費時間,使系統失去了即時響應能力。

使用其它儲存元件──eFuse和ROM──的NVM技術解決了功耗問題,但也有其局限性。由於eFuse的密度低,限制了容量。ROM在成本、性能和功耗方面較具優,但卻受制於設計、驗證和製造週期。經由過孔(via)或擴散(diffusion)作用,將數據儲存在ROM陣列晶片。在製造光罩前,ROM中的內容必須被包括在SoC的GDSII。一旦SoC製造完成後,要改變其ROM內容,需要一套新光罩及完整的製造週期,二者都既耗時又費錢。使用同一基本設計的多個ROM版本開銷不菲,還帶來了挑戰(例如,供應預測和庫存管理;若非在正確時間擁有正確的產品組合,則會錯失良機)。

嵌入式設計的安全漏洞
在圖1的簡單設計中,安全性的漏洞顯而易見。外接EEPROM/快閃記憶體儲存的內很容易受到非侵入和侵入式攻擊。透過實體連接或經由巧妙的軟體破解,即可監控在CPU和外接記憶體間造成任何數據流動的駭客攻擊。

嵌入式以及外部浮閘非揮發性記憶體技術也容易受到幾種低成本的非侵入式(包括電壓施擾和數據殘留)資訊攻擊,以及半侵入式方法(包括UV攻擊、故障注入和電壓對比)的攻擊。

基於熔絲熔斷連接(eFuse)或硬線記憶體(ROM)的嵌入式非揮發性記憶體對於非侵入式攻擊具有免疫力。但透過半侵入式方法,如元件反處理和借助聚焦離子束(FIB)顯微鏡來觀察矽化物或金屬連接中斷,也可輕易獲取其儲存的內容。

整合的記憶體系統
對於要求高安全、極低功耗的系統來說,需要一款更好的記憶體系統架構。這種架構的要素之一是在晶片中整合外部EEPROM/快閃記憶體NVM,從而立竿見影地收到降低功耗、提高安全、以及減少系統元件數(因整合在一個元件內)BOM的好處。

然而,在65nm及以下製程節點,無法再進一步整合外部EEPROM/快閃記憶體,用於製作EEPROM和Flash的浮閘結構在技術和商業兩方面都存在挑戰。浮閘技術也許會向更先進製程節點遷移,但以當今的發展來看,在65nm及以下節點,浮閘技術不在考慮之內。

反熔絲方案
在記憶未被存取時,NVM技術本質上並不耗電,本文討論的所有嵌入式NVM方案都滿足行動監控設備和電子錢包晶片要求的低功耗性能。然而,就可用的嵌入式NVM來說,反熔絲技術(圖2)在功耗、安全和編程靈活性方面得分最高。表1列出了行動SoC的一些典型特徵。

反熔絲OTP在功耗和安全性方面的優勢來自於數據如何儲存於基本儲存位元單元的方式。例如,Kilopass公司開發的一種反熔絲位元單元包括兩種NMOS電晶體:一個用於編程;另一個選擇以串聯耦合的電晶體。在編程電晶體上施加電壓,將使其閘極絕緣擊穿,從而在電晶體的閘極和通道間產生連接。因此,高阻值的閘極絕緣變成低阻值的矽晶連接:將單元狀態從零‘0’變為‘1’(見圖3)。

編程反熔絲位元單元會在閘極氧化物內一小部份位置不定的區域引發實體性能變異。因透過電流感應過程來確定一個位元是初始‘0’還是編程‘1’,從而使位元單元較不至於輕易受到低成本、非侵入式(電壓干擾和數據殘留)及半侵入式(UV攻擊、故障注入、電壓對比)攻擊的傷害。此外,因為沒有確定的方式來定位和查看氧化層擊穿,使得記憶體的內容可抵禦實體攻擊(反製程處理和FIB檢查)。這是反熔絲記憶體技術被廣泛用於加密密鑰儲存的原因之一(見圖4)。

嵌入式設計的價值存在於韌體內。當整合於晶片時,它就可抵抗實體的駭客攻擊。程式碼包含不同內容:(1)主控程式,被鎖定在不可更改的OTP NVM內以確保萬無一失;(2)儲存在可若干次編程(FTP)NVM內、用於安全更新一部份的程式碼;(3)可避開被動或實體攻擊、用於驗證的另一個安全儲存區域。

嵌入式程式的典型大小為32KB至128KB。此類應用包括藍牙、Zigbee和Wi-Fi週邊(從用於監控健康和健身的無線設備設計,到更複雜的家庭自動化和用於數位錢包、無線金融交易及電子識別──駕照、護照、收費及其它應用的安全及NFC設備)。這些應用都具有以電池供電、方便存取網路的特點,例如,可使用安全並經過驗證的智慧手機應用遠端存取這些應用。

兩年多前,Kilopass公司推出邏輯反熔絲技術,並透過推出Gusto(用於程式碼儲存的一種高密度嵌入式反熔絲NVM)來滿足程式碼儲存需求。隨著Gusto越來越常被用於程式碼儲存,加上為了滿足‘物聯網’(IoT)需求的新興市場趨勢,Kilopass最近發佈了第二代程式碼儲存產品Gusto-2。它滿足了低功耗和小外形尺寸需求,以及未來從手機錢包應用到低功耗藍牙設備的安全需求。Gusto-2一開始採用65nm/55nm製程,接著就是40nm。

功耗和面積構成表1中所描述SoC的一部份。待機功耗將比SRAM小得多。而陣列空間將媲美類似容量的SRAM。它具有400MB/s的數據吞吐率。最初的儲存容量為256Kb和512Kb,後續還會有1024Kb。另外,它支援多種同步數據路徑的CPU匯流排架構,以便能有效地實現就地執行(execute-in-place)存取。

遠端監控和電子金融交易是驅動新一代SoC設計的應用,這種新的SoC將具有低能耗、高性能、以及尺寸小到足以裝進空間有限的消費電子設備等特性。這種SoC要求記憶體子系統能滿足在功耗和安全性的嚴格需求。

打造千万级流量系统——秒杀系统

kaixin201505

于 2021-05-14 07:18:06 发布

架构设计方法
架构设计都有哪些方法呢?架构设计遵循特定的方法,比如 TOGAF(The Open Group Architecture Framework,开放组体系结构框架)、五视图方法等。其中 TOGAF 主要针对复杂的企业系统架构,比较重,不大适合迭代速度非常快的互联网产品,所以互联网公司常用的主要是五视图方法。

什么叫五视图方法?

它是指从业务逻辑、开发环境、运行状态、物理部署、数据关系等方面绘制出相应的逻辑视图、开发视图、运行视图、物理视图、数据视图来设计架构。 其中,逻辑视图、开发视图、运行视图属于软件架构的内容,物理视图、数据视图属于系统架构的内容。

秒杀系统架构设计
采用五视图方法来介绍下

逻辑架构

物理架构

首先,为了实现动静分离,我们需要部署 CDN 节点,将秒杀系统静态页面和静态数据利用 CDN 缓存起来,以便利用 CDN 的就近访问能力提供更高的性能。比如我们可以在中国和新加坡都部署 CDN 节点,以便为中国用户和海外用户提供更好的访问速度。

第二,动静分离意味着除了 CDN 外,我们还需要部署秒杀后端节点。

为了实现秒杀后端节点的高可用,我们需要使用云架构保障其基础设施层的高可用。而且需要部署到云的多个可用区,防止单一可用区发生故障影响服务。

第三,为了将不同可用区作为一个整体对外提供服务,我们需要部署路由器、防火墙、交换机、SLB(Server Load Balancer,负载均衡器)。

其中,路由器是负责接收外网请求并转发到内网;防火墙负责过滤掉有风险的数据,比如过滤掉黑客发起的网络攻击;交换机负责将请求转发到具体的可用区内;SLB 是负载均衡器,它可以将可用区内多个节点作为一个整体对外提供访问,并将请求均衡地转发到后端各节点。

SLB 之间采用主备的方式部署,如果可用区 1 的 SLB 挂了,可用区 2 的 SLB 会自动接管属于可用区1 的流量,并将流量转发给可用区 1 内的云主机。

第四,部署完各节点后,还需要设置域名解析,将域名解析到我们部署的 SLB 外网 IP 上。通常,对于流量大的系统,会采用多个负载均衡器,然后使用动态 DNS 解析的方案做多个 SLB 的 DNS 负载均衡,以防单个 SLB 无法扛住大流量。

数据架构

数据架构通常用 E-R 图(Entity Relationship Diagram,实体-联系图)表示,我们通常用它来表示数据对象与属性、用户之间的关系。

在需求分析过程中,我们了解到秒杀系统主要有两大主要数据:活动信息和商品信息。除了这两大主要数据外,还有两大次要数据:订单和黑名单。其中订单是用户抢购商品并下单生成的,而黑名单是为了反黄牛而设计的,通常通过大数据分析统计生成,如果用户 ID 在黑名单中,则不允许抢购商品。

结合需求分析过程,我们得知:

活动信息,包括专题、场次、描述、时间、限购策略、商品列表、状态等信息;
商品信息,包括商品 ID、名称、描述、规格、原价、活动价、活动库存等信息;
订单信息,包括订单 ID、用户 ID、商品 ID、商品价格、商品数量、总价、收货地址、创建时间等信息;
黑名单,包括用户 ID 列表。

这些数据中,活动信息、商品信息、黑名单都是由管理员在管理后台管理的,只有订单信息是由用户在商城下单创建的,管理员可以通过管理后台查看订单信息。

其中物理架构用于指导运维工程师部署软件,以便实现基础设施的“三高”;数据架构用于指导开发人员做数据库表设计,以及指导测试人员进行软件功能测试时检查数据准确性。

严格来讲,逻辑架构属于软件架构而不是系统架构。那为什么我要给你介绍逻辑架构呢?主要是因为它能帮助我们从顶层了解系统的功能划分,从而更方便进行系统架构设计。

DDD 原理及秒杀系统领域模型
在电商系统中,我们通常把完整的购物流程划分为下单前和下单后。下单是由用户在商城发起的,下单后订单涉及关单、支付、退款、筛单、投递、售后等流程。

其中,关单涉及库存系统,支付流程涉及支付系统,退款流程涉及客服、支付和财务系统,筛单涉及风控系统,投递涉及物流和仓储系统,售后涉及售后系统。

1.什么是 DDD?

DDD(Domain Drive Design,领域驱动设计)是一种软件设计方法,是指在软件设计的过程中始终围绕领域来构建模型。构建领域模型的过程就叫“领域建模”。

DDD 就是为了解决各个业务系统的职责划分,围绕业务对象而进行模型建构。

2.如何使用 DDD 对秒杀系统领域建模?

战略建模:是指从宏观上构建领域模型。

战术建模:从具体细节上构建领域模型,它是对战略建模中限界上下文的具体实现。
还是以秒杀系统为例,秒杀系统的战术建模就是分析活动领域中各个对象的类型,针对类型特点做抽象设计。

高可用架构设计
云架构分层设计及其高可用

云架构分为:

IDC(Internet Data Center,互联网数据中心) 基础设施层
物理主机层
IaaS 层
PaaS 层
SaaS 层
它们分别提供了 IDC 基础设施高可用、物理主机高可用、虚拟主机高可用、基础组件高可用、应用服务高可用等能力。

1.IDC 基础设施层

IDC 基础设施层主要包括电源、网络、空调、消防等设备,甚至包括 IDC 机房所在的大楼的物理条件。

电源和网络的高可用是如何做的呢?通常是采用冗余的方案:配备多条线路。

2.物理主机层

将存储和计算分离,并提供足够的并发性能,一般采用 NAS(Network Attached Storage:网络附属存储),通过高速网卡和交换机提供高并发和高性能访问能力。

NAS 机器上的磁盘采用 RAID (Redundant Arrays of Independent Disks,磁盘阵列) 提升性能和可用性。如:用两块磁盘组成 RAID 1,其中一块磁盘当作数据镜像磁盘。假如单个磁盘故障率为 0.1%,那么两块磁盘组成 RAID 1 后,整体故障率为 0.0001%。

3.IaaS 层

IaaS 是 “Infrastructure as a Service” 基础设施即服务的缩写,通过虚拟化技术在宿主机上虚拟出多个运行环境,应用部署在虚拟出来的运行环境里。目前比较常用的是主机虚拟化和容器虚拟化。

什么是主机虚拟化技术呢?主机虚拟化是指利用软件来虚拟整套计算机硬件,也就是 VM (Virtual Machine,虚拟机) 。操作系统可以运行在虚拟机上。

业内比较成熟的方案主要有 VMware、KVM、Xen,配合 OpenStack 之类的云计算管理平台来管理、调度虚拟机。我们经常听到的云主机就是利用了主机虚拟化技术。

虚拟机通常配合 SDN (Software Defined Network,软件定义网络) 和 SDS (Software Defined Storage,软件定义存储) 等技术来使用,用来实现虚拟机的网络高可用和存储高可用。

4.PaaS 层

PaaS 是“Platform as a Service” 平台即服务的缩写,云产商将通用组件打包部署在已有的主机上,并提供访问组件的 SDK 或者 API,开发者修改应用的代码引入 SDK 或者调用 API 来访问云产商提供的通用组件。比如:在阿里云上购买数据库产品,修改应用程序代码访问购买的数据库产品。

5.SaaS 层

SaaS 是“Software as a Service” 软件即服务的缩写,不仅提供软件的后端,还提供软件的前端页面,达到开箱即用的效果。

SaaS 系统可以通过同城双活、异地备份、多云部署等方案来降低单云单机房故障的风险。比如:将系统同时部署在阿里云和 AWS 上,即使 AWS 故障了,也能快速切到阿里云。不同云之间使用专线同步数据。

先来看一个案例:

假如某电商创业公司,在起步阶段业务 DAU (Daily Active User,日活跃用户) 10 万左右,团队 20 人;发展阶段 DAU 100 万左右,团队 50 人;成熟阶段 DAU 500 万左右,团队 200 人。公司计划在快速发展阶段加入秒杀功能,应该如何基于云架构来设计系统架构呢?

在起步阶段,公司业务用户比较少,系统风险也小。可以考虑在 IaaS 云产商的两个机房分别购买 1 台云主机组成双活来部署业务服务。如果云产商有容器云,可以优先考虑使用容器。业务服务依赖的基础组件可以使用 PaaS,一些云产商会提供免费额度。

到了发展阶段,此时业务处于快速发展时期,通常会引入一些新的营销手段刺激消费,比如秒杀。

由于这个时候用户量已经非常可观,再加上秒杀功能会带来庞大流量,需要注重系统可用性,比如要求系统可用性达到 99.99%。

为了防止单一可用区出现故障,核心业务服务和秒杀系统最好部署在多个可用区,每个可用区部署多个服务器实例,并由 SLB 组件做服务器的负载均衡。那如何防止单一 SLB 实例出现故障呢?通常是采用多个 SLB 实例,并由 DDNS 做 SLB 实例的负载均衡。

另外,在秒杀系统内部做限流的时候,也可以选用云厂商提供的 MQ (Message Queue,消息队列) 组件限制并发流量,以便减少下游系统的压力,提升整体稳定性。

最后是成熟阶段,此时业务核心功能基本稳定,用户量初具规模。如果发生事故,很容易影响公司营收,这也就要求诸如秒杀这类涉及交易流程的系统,具有更高的可用性,比如高达 99.999%。

那么,我们可以做哪些事情呢?这个时候就可以考虑多云架构、异地多活、异地备份等措施避免更极端的故障,比如地震、洪水破坏可用区。

故障转移和恢复:如何通过主备切换缩减故障时间?
1.什么是主备切换

所谓主备切换,按主从关系划分的话,有狭义和广义之分。

狭义上的主备切换,有明确的主从角色划分,主节点承担了主要的集群管理工作,当主节点故障,从节点变成主节点,接管主节点的工作。这种主备切换比较适合有状态的系统,也就是有数据存储功能的系统,比如存储系统等。

广义上的主备切换,它没有明确的主从角色划分,任何一个节点发生故障,它的工作就会分配到其他任何一个正常节点上,不需要指定主节点。这种主备切换比较适合无状态的系统,也就是没有数据存储功能的系统,比如 http 服务。

主备切换在转移故障的时候,主要分三步:

第一步故障自动侦测(Auto-detect),采用健康检查、心跳等技术手段自动侦测故障节点;

第二步自动转移(FailOver),当侦测到故障节点后,采用摘除流量、脱离集群等方式隔离故障节点,将流量转移到正常节点;

第三步自动恢复(FailBack),当故障节点恢复正常后,自动将其加入集群中,确保集群资源与故障前一致。

2.云架构各系统中的主备切换

在云架构拓扑图中,总体可以分为三大类节点:网络节点、计算节点、存储节点。

其中,存储节点属于存储系统,主要用于将数据存储到磁盘,在云架构中属于最底层,是整个云架构的基石。

计算节点主要是云主机,用于运行业务系统,它的数据由存储系统负责存储。

网络节点包括:DNS、CDN、路由器、防火墙、交换机、SLB。它们主要用于将外网流量接入到内网的可用区内,最终转发到各个计算节点。

从这个云架构拓扑图的组成部分我们就知道,存储系统、业务系统、SLB 和 DNS 非常重要。

存储系统的主备切换

通常,NAS 存储系统中会用到一种叫 DRBD (Distributed Replicated Block Device,分布式复制块设备) 的技术。该技术能将存储节点的磁盘作为块设备,通过互相映射的方式实现互相备份。如下图所示:

Heartbeat 是什么呢?Heartbeat 是 Linux-HA 工程的一个组成部分,用于实现高可用集群。简单来说,Heartbeat 部署在集群内节点上,用于给节点提供心跳机制,各节点通过侦测其他节点心跳来判断其他节点是否有故障。如果侦测到故障节点,则由正常节点接管故障节点的流量,然后继续侦测故障节点的心跳。

除了 Heartbeat 外,使用 Keepalived 也能为集群节点提供心跳和主备切换功能。与 Heartbeat 用于存储系统的主备切换不同, Keepalived 常用于负载均衡器的主备切换。

业务系统的主备切换

以 Nginx 为例,为了给后端服务做健康检查,我们可以在 Nginx 配置文件中添加如下配置:

upstream test_web {
server 192.168.1.21:80;
server 192.168.1.22:80;
check interval=3000 rise=2 fall=5 timeout=1000 type=http;
}
interval:用于配置健康检查的间隔,如 3000 毫秒;
rise:用于配置连续几次请求成功后表示该节点恢复了,如 2 次;
fall:用于配置连续几次请求失败后表示该节点出故障了,如 5 次;
timeout:用于配置健康检查请求的超时时间,超时后表示请求失败,如 1000 毫秒;
type:用于配置请求协议的类型,如 HTTP 请求。
SLB 和 DNS 的主备切换

案例三:

某电商平台初期用户量较少,系统部署在单一可用区内,只使用了一个 SLB 对外提供服务。有一天,运营人员配置了一场促销活动,但是系统所在的可用区网络故障,导致整个活动受影响无法正常进行,错失了活动的最佳时机。

后来,研发人员和运营人员对系统架构进行了调整,将系统部署在两个可用区,每个可用区有两个 SLB,由 DDNS 负责 SLB 的负载均衡。在后续促销活动中,虽然也发生了类似的故障,但由于有多个 SLB,以及用 DDNS 为 SLB 做域名解析负载均衡和健康检查,DDNS 自动将流量调度到了正常的可用区,保障了促销活动的顺利进行。

在案例三中,SLB 负责可用区内业务节点的健康检查和负载均衡,确保流量始终转发到正常的节点上。DDNS 负责多个 SLB 的健康检查和负载均衡,确保域名解析始终解析到正常的 SLB 的 IP 上。

实际上,DDNS 可能并不一定完全满足需求。DNS 中 IP 更新是有时间限制的,通常默认是 5 分钟。也就是说,假如 SLB 故障,IP 列表更新了,由于本地 DNS 有缓存,可能会导致 5 分钟内请求都失败。而且用户的本地 DNS 可能会被恶意劫持,导致客户端请求失败。

针对这种情况,有的公司会选择实现 HTTPDNS 接口给客户端下发 IP 列表。

通常,一个 HTTPDNS 返回的结构是这样子的:

{
“www.mi.com": {
“ips": [
“103.104.168.101″,
“116.211.122.1″
],
“ttl": 57
}
}
客户端拿到域名与 IP 列表的对应关系后,缓存在本地,然后随机选择一个 IP 建立连接。如果连接失败则从剩下的 IP 中再随机取 IP 来建立连接,直到连接成功或者达到最大重试次数。假如发现该数据过期了,则客户端会重新发起 HTTPDNS 请求获取最新的 IP 列表。

过载保护:如何通过熔断和限流解决流量过载问题?
1.过载保护的重要性

什么是过载保护呢?所谓过载保护,是指负载超过系统的承载能力时,系统会自动采取保护措施,确保自身不被压垮。

熔断的基本原理

什么是熔断?熔断就是在系统濒临崩溃的时候,立即中断服务,从而保障系统稳定避免崩溃。 它类似于电器中的“保险丝”或“断路器”,当电流过大的时候,“保险丝”会先被烧掉,断开电流,以免电路过热烧毁电器引起火灾。软件系统中的熔断也是如此,当系统满足某个判断条件时,就会拒绝处理请求,避免系统压力过大被压垮。

限流的基本原理

它的目的是确保系统高效、稳定地运行,确保请求能够快速处理的同时,保障系统不被流量压垮。

限流算法主要有:

计数器限流:也叫固定窗口限流算法
首先,选定一个时间窗口作为一个周期,假设为 5 秒;

第二步,设定 5 秒内允许通过的流量,如 1000 个请求;

第三步,每次请求,计数器都加 1;

第四步,判断计数器数值是否超过 1000 ,超过了就触发限流策略,如:拒绝或者延迟处理请求等;

最后,如果时间过了 5 秒,则重置计数为 0,开始一个新的周期。

该限流算法的优点是实现简单,缺点是面对突发流量时不够精确。面对瞬时流量时,会存在资源利用率的剧烈抖动。

滑动窗口限流
滑动窗口限流算法是对计数器限流算法的优化。它的主要原理是将计数器限流算法中的一个周期拆分成很多等分,比如将 5 秒的周期拆成 5 个 1 秒,每次统计从当前时间开始过去 5 秒内的流量,每隔 1 秒往后滑动 1 秒。

令牌桶限流
令牌桶算法的基本原理是,使用一个定时器以恒定速度往桶里颁发令牌,桶满了则丢弃多余令牌。请看示意图:

在令牌桶算法中,一般只有拿到令牌的请求才会被处理,没拿到的将会被拒绝。这个过程就像景区的人工售票窗口售票,只有买到票了才能检票进入景区。这其中,令牌就是门票,令牌桶就是售票窗口,负责发令牌的线程就类似于售票员,处理请求的线程就是检票员。

漏桶限流。
漏桶算法的原理跟令牌桶有点相似,只不过漏桶算法采用“生产者-消费者”模型。在“生产者”一端,所有请求进队列,队列满了则丢弃请求。在“消费者”一端,以恒定速度消费队列并处理请求。

以上这几种限流算法中,流量控制效果从好到差依次是:漏桶限流 > 令牌桶限流 > 滑动窗口限流 > 计数器限流。

其中,只有漏桶算法真正实现了恒定速度处理请求,能够绝对防止突发流量超过下游系统承载能力。不过,漏桶限流也有个不足,就是需要分配内存资源缓存请求,这会增加内存的使用率。而令牌桶限流算法中的“桶”可以用一个整数表示,资源占用相对较小,这也让它成为最常用的限流算法。

正是因为这些特点,漏桶限流和令牌桶限流经常在一些大流量系统中结合使用。比如秒杀系统中就同时使用了这两种限流算法。

过载保护设计实战

前面我为你介绍了一些常用过载保护手段的原理,那具体怎么实现呢?接下来我就以秒杀系统为案例来介绍下吧。

在秒杀系统中,瞬时并发能达到 100 万 QPS。由于自身资源的限制,秒杀系统的核心业务逻辑处理请求的能力为 50 万 QPS,而下游的 Redis 的并发能力为 10 万 QPS。假如一场秒杀活动中预计会有 300 万次以上请求,请问该如何设计过载保护?

我们来分析一下。从这个案例中,我们能提取到 4 个参数。它们分别是:总请求量 300 万次、瞬时并发 100 万 QPS、秒杀系统自身承载能力 50 万 QPS、下游 Redis 承载能力 10 万 QPS。如果要做过载保护,这几个数据就是关键。

我们先来看,哪个是秒杀系统的流量瓶颈,先解决它。你找到了吗?这个瓶颈就是下游 Redis 的并发能力,仅为 10 万 QPS,这在秒杀活动当中很容易被流量压垮。那该怎么办呢?我们可以采用漏桶限流来控制 Redis 的请求,让它保持在恒定速度。

接下来,当请求进入秒杀系统后,需要确保核心逻辑处理的请求不超过 50 万 QPS。为此,我们需要选择一种既稳定又快速的限流方法,比如令牌桶限流算法。因为令牌桶不会像计数器限流和滑动窗口限流那样会导致资源使用率抖动,也不需要像漏桶限流那样由于缓存请求而无法得到立即处理。

在实际当中,流量进入系统前,令牌桶中有一部分预先分配的令牌,可能会出现瞬间流量超过 50 万 QPS的情况。为了以防万一,我们可以把令牌桶限流上限稍微调低,比如 45 万 QPS,确保瞬时流量不超过 50 万 QPS。

最后,由于总请求量在 300 万次以上,整个秒杀过程会持续数秒。为了避免因下游服务网络延迟问题导致请求堆积压垮系统,还需要加上熔断措施。当请求延迟超过某个临界值的时候,拒绝后续请求,直到延迟恢复正常。

总的设计方案如下图所示:

KV 存储:etcd 和 Redis 高可用原理和部署方法
什么是 KV 存储?

KV 是 Key-Value 的缩写,KV 存储也叫键值对存储。简单来说,它是利用 Key 做索引来实现数据的存储、修改、查询和删除功能。

常用的高性能 KV 存储主要有 Redis、Memcached、etcd、Zookeeper 等,其中 Redis 和 Memcached 主要用来缓存业务数据, etcd 和 Zookeeper 主要用来存储元数据。

1.Redis 高可用原理及部署方法

它主要通过支持主从模式、哨兵模式、集群模式这三种模式,来满足不同业务特点和可用等级的需求。 其中,主从模式部署最简单,用得也最多,集群模式比较复杂,但可用性最高。

Redis 的部署方法

主从模式

主从模式最大的优点是部署简单,最少两个节点便可以构成主从模式,并且可以通过读写分离避免读和写同时不可用。不过,一旦 Master 节点出现故障,主从节点就无法自动切换,直接导致 SLA 下降。所以,主从模式一般适合业务发展初期,并发量低,运维成本低的情况。

哨兵模式

哨兵模式适合读请求远多于写请求的业务场景,比如在秒杀系统中用来缓存活动信息。

集群模式

虽然集群模式避免了 Master 单节点的问题,但集群内同步数据时会占用一定的带宽。所以,只有在写操作比较多的情况下人们才使用集群模式,其他大多数情况,使用哨兵模式都能满足需求。

etcd 高可用原理及部署方法
etcd 支持 HTTPS 访问、划分命名空间、 RBAC 权限控制,可以有效保证数据安全。

Raft 协议是 etcd 中保证分布式系统强一致性的算法。Raft 协议维护了集群节点的角色状态——Leader(领导者)、Follower(跟随者)、Candidate(候选者)。

Web 安全:如何解决重放攻击和 XSS 注入?
Web 安全风险有哪些?

什么是 OWASP 呢?OWASP 是 Open Web Application Security Project 的缩写,它是一个组织,中文名称叫“开放式Web应用程序安全项目”。OWASP 每年都会发布排名前十的 Web 安全风险,也就是前面提到的 OWASP Top 10 。比如 2020 年 OWASP Top 10 如下:

注入
失效身份验证和会话管理
敏感信息泄露
XML 外部实体注入攻击(XXE)
存取控制中断
安全性错误配置
跨站脚本攻击(XSS)
不安全的反序列化
使用具有已知漏洞的组件
日志记录和监控不足

“注入”允许攻击者上传一段可解释执行的代码片段,而该代码片段可能帮助攻击者获取系统管理权限或者隐私信息。比如,黑客可能通过“SQL 注入”获取数据库表中所有的用户名和密码,或者通过“shell 脚本注入”等方式获取系统管理权限,进而危害整个系统的安全。

XXE 主要是将恶意代码注入 XML 文件中,利用服务器解析 XML 文件的漏洞来获取服务器上的额外数据。而 XSS 主要是利用浏览器渲染前端页面的漏洞,将恶意代码注入页面的数据中,窃取用户信息或执行恶意操作。

“注入”的攻击对象主要是两类:

针对系统的注入,主要用于在系统中执行恶意代码,如利用“shell脚本注入”上传获取系统权限的脚本;

针对用户的注入,主要用于获取用户身份信息并执行损害用户利益的操作,如利用 XSS 获取用户登录信息并发起转账请求。

除了以上因系统自身缺陷导致的风险外,攻击者还有一些利用网络缺陷发起的攻击手段,比如:中间人攻击、重放攻击、DDoS 攻击。

中间人攻击, 简单来说就是攻击者通过技术手段,侵入发送方和接收方之间的计算机(如网络代理服务),拦截网络请求窃取并篡改数据。我们通常可以利用加密等方式有效防止中间人攻击,如使用 HTTPS 代替 HTTP。

什么是重放攻击呢?所谓重放攻击,就是把以前发过的数据原封不动地重新发送给接收方。这个发过的数据,可能是攻击者窃听到的别人的数据,也有可能是攻击者曾经自己发过的数据。

重放攻击通常用来恶意消耗 Web 系统有限的资源,比如某电商平台的竞争对手或者恶意用户可能利用重放攻击来恶意占用爆款商品的库存,或者在秒杀活动的时候快速刷走活动商品。我们熟悉的“黄牛”,就是利用“秒杀器”之类的工具,快速提交重复的请求来刷走秒杀商品。

DDoS 攻击又是什么呢?DDoS的全称是 Distributed Denial of Service,即“分布式拒绝服务”,它的前身是 DoS (Denial of Service,拒绝服务)。DDoS 攻击通常是利用大量计算机同时向服务器发送大量垃圾数据,让服务器因为资源限制而无法处理正常的用户请求。

重放攻击和 DDoS 攻击有个相同点:都是利用大量请求快速占用系统资源。有时候,当重放攻击的请求量达到一定量级(如单节点达到 1000 次),就发生质的转变,可视为 DDoS 攻击。目前各大云产商基本都有预防 DDoS 攻击的能力。

如何预防重放攻击?

通常有三种方法预防范重放攻击:加随机数、加时间戳、加序列号。

加随机数,我们可以让后端生成一个随机数给前端,并将该随机数记录为未使用,同时设置有效期。在后续前后端交互中,后端会接收前端请求,并校验是否有该随机数,是否未使用,是否未过期。如果请求中没有该参数,或者该随机数已使用或者已过期,则拒绝请求。

这个方法的优点是不容易伪造,但它需要额外保存使用过的随机数,若记录的时间段较长,则保存和查询的开销较大。

加时间戳, 我们可以在前端生成一个时间戳,然后把它作为参数发给后端,后端校验该时间戳与当前时间是否相差在一个允许的范围内(比如 10 秒),如果超过了,则拒绝请求。

该方法优点是不用像加随机数那样额外保存其他信息,但前端和后端认证双方需要准确的时间同步,同步越好,受攻击的可能性就越小。所以,当系统变得庞大时,跨越的区域较广,要做到精确的时间同步就变得不容易了。

加序列号, 每次请求或返回的时候,我们都可以在上一次请求或返回的序号上加 1 ,并将当前序号记录下来。如果收到不连续的序号,则认为是非法数据。

该方法优点是不需要时间同步,保存的信息量比随机数方式小。缺点是一旦攻击者对报文解密成功,就可以获得流水号,从而每次将流水号递增欺骗认证端。

我们都知道,一个正常用户在发起抢购商品的请求前,需要先进入秒杀活动页或者商品详情页,而这两个页面都会请求后端接口,以获取活动信息和商品信息。基于此,我们就可以利用这两个页面来做文章。

具体来说,就是在这两个页面调用后端接口的时候,由后端给前端下发一个短时间内可以作为唯一标识的东西,比如用随机数和时间戳拼接得到的数字。同时,后端将这个唯一标识记录下来,有效期设置为活动结束时间。

当用户在前端发出请求抢购商品的时候,后端从抢购接口处接收到请求,此时它先判断是否有该唯一标识,如果没有该标识或者该标识已经被用过,则拒绝请求。

由于唯一标识的生成算法是由后端控制,攻击者无法伪造,只能通过接口获取。所以,当攻击者通过接口获取唯一标识的时候,我们可以对攻击者进行常规限流,如限制每个 IP 每秒请求数。

需要注意的是,秒杀系统最好开启代理层的粘性会话(Sticky Session)功能,以便将同一个用户的请求转发到同一个服务节点。这样就可以利用服务节点的本地内存缓存,来快速校验唯一标识,以及针对 IP 限流。

如何防 XSS ?

前面提到了“注入”的风险,比如在提交表单的时候,攻击者可能在表单某个字段里填上一段可被系统执行的脚本代码。如果系统没有安全校验并执行了该代码的话,可能就会遭到攻击者入侵,导致用户数据泄漏。

举个例子,某系统查询账号信息的 SQL 可能是这样拼接而成的:

“SELECT * FROM accounts WHERE custID='" + ID + “‘"
如果攻击者将参数 ID 填写为:

or ‘1’=’1′
这将会导致所有账号信息被泄漏。

XSS 产生的本质原因和这个类似,也是通过前端传入非法脚本代码到后端。只不过与 SQL 注入不同的是,XSS 是在前端获取用户信息并发起非法请求,而 SQL 注入是在后端获取用户信息。

我们要怎么防范 XSS 风险呢?

首先,我们要对前端输入的数据进行校验,过滤掉非法关键字。比如,我们可以让前端对商品图片 URL 输入框的数据进行校验,过滤掉诸如“javascript:”这样的前端关键字。

其次,后端对前端输入的数据进行转码后,再存入数据库,如进行 URLEncode 和 Escape 。在拼接 SQL 语句的时候,不要用简单的字符串拼接,而是利用占位符和参数通过 SQL 语句生成函数的来生成,如下所示:

sql := mysql.Raw(“SELECT * FROM accounts WHERE custID=’?'", ID)
这样可以利用 SQL 语句生成函数来校验参数合法性。
最后,前端在页面渲染的时候,也需要注意对一些关键字段进行字符转义,比如对字符串中的单引号(’)、双引号(")、尖括号(<>)进行转义,就能防止前端利用这些数据渲染页面的时候执行攻击者注入的 javascript 代码。

引自:拉勾打造千万级流量系统
————————————————
版权声明:本文为CSDN博主「kaixin201505」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Aplumage/article/details/116742769

iptables 的安裝與設定

iptables 的安裝與設定

防火牆(Firewall)簡介
1. 防火牆可作用在網路層/傳輸層(Network/Transport Layer)或應用層(Application Layer),網路層的防火牆處理速度較快,使用者感覺不到但容易破解,應用層的防火牆處理速度慢但可檢查的項目多,因此較不容易破解。
2. iptables 屬於網路層/傳輸層的防火牆,它將封包的處理分成三個tables, table中包含chains, chains 裡面包含 rules 和 policies。請參閱架構圖
3. 三個tables分別是
   (1) nat:提供位址轉換(Network Address Translation)功能
   (2) mangle:提供封包改寫(Mangling)功能
   (3) filter:提供封包過濾(Filtering)功能

移除 ipchain 模組
1. lsmod | grep ipchains
檢查 ipchains 是否載入 kernel(因為RedHat目前預設安裝的防火牆仍是使用 ipchains)
2. rmmod ipchains 從 kernel 移除 ipchains 模組
3. service ipchains stop 停止 ipchains 的執行
4. rpm -e ipchains-1.3.10-13 移除 ipchains 套件的安裝

安裝 iptables 模組
1. rpm -Uvh iptables-1.2.5-3.i386.rpm 安裝 iptables 套件
2. modprobe ip_tables 將 iptables 模組載入 kernel
3. lsmod ip_tables 檢查 kernel 是否有 iptables 模組
iptable 指令格式
  iptables [-t 表格名稱] 指令 條件 [目標|鏈]1. 指令集
-N建立一個新的(自定)鏈-X刪除一個空的(自定)鏈-P改變一個內建鏈的原則-L列出一個鏈中的規則-F清除一個(內建)鏈中的所有規則-A在一個鏈的最後面新增( append ) 一條規則-I在鏈內某個位置插入( insert ) 一條新規則-R在鏈內某個位置替換( replace ) 一條規則-D在鏈內某個位置刪除( delete ) 一條規則  2 . 目標集
ACCEPT通過這個鏈檢驗,接受這個封包SNAT改變封包來源IP欄位的值(nat, POST)DROP未通過這個鏈檢驗,立即丟棄這個封包DNAT改變封包目標IP欄位的值(nat, PRE,O)QUEUE將封包重導至本機端的佇列 ( queue ) 程式MASQUERADE動態的根據路由,來修改 Source Socket(nat, POST)RETURN通過這個鏈的檢驗,回到原來的鏈中REDIRECT重導封包至另外一個位址或連接埠TOS改變封包 TOS 欄位的值TTL改變封包 TTL 欄位的值REJECT未通過這個鏈檢驗,丟回錯誤封包作回應(filter,I,F,O)  3. 條件
-i
-o相關界面
–sport來源埠口-p所屬協定(tcp, udp, icmp)
-d目的地(Address/SubnetMask)-m state連線類型(ESTABLISHED, INVALID)
–dport目的地埠口–tcp-flags
–icmp-type
封包類型
INPUT
OUTPUT
FORWARD封包於防火牆中的流向-s來源地(Address/SubnetMask)
-j跳至目標或自定鏈在預設鏈中,規則(Rules)由第一條往下檢查,當在某一條規則滿足檢驗時(可能是拒絕或通行),往下的規則就不在檢驗。
在自定鏈中,規則(Rules)由第一條往下檢查,當在某一條規則滿足檢驗時(可能是拒絕或通行),往下的規則就不在檢驗,而跳回呼叫它的預設鏈,繼續往下檢驗。
設定使用 iptables
1. 啟動 kernel 的 ip_routing 功能
更改 /etc/sysctl.conf設定檔,設定 net.ipv4.ip_forward = 1

執行 echo “1″ > /proc/sys/net/ipv4/ip_forward
2. 啟動 iptables 服務
service iptables [start | restart | status]
當啟動 iptables時,會讀入 /etc/sysconfig/iptables 的檔案內容,該檔案儲存之前對防火牆設定的內容,如此一來重開機時,原來的設定還繼續可用。在 Fedora Core 3 安裝完 iptables 後,預設沒有產生 /etc/sysconfig/iptables 檔案,所以要使用 iptables 需先產生它
1. iptables -L
2. iptables-save > /etc/sysconfig/iptables
iptables 相關指令
1. iptables-save [-t table] > ipt.txt:將 iptables 的所有設定,寫到 ipt.txt 檔案
2. iptables-restore [-n] < ipt.txt:清除 iptables 目前的所有設定,然後 ipt.txt 檔案來設定 iptables
使用 nat table 來作 SNAT 或 MASQUERADE
1. nat table 的封包流向圖
2. NAT 有動態 NAT及靜態 NAT,靜態 NAT又可分為 SNAT(Source NAT)及 DNAT(Destination NAT)
3. 如果對外IP是動態IP使用 MASQUERADE,如果是靜態IP使用 SNAT(比較有效率)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth0 -j SNAT –to-source 對外IP1. 開啟瀏覽器執行http://Linux的IP:10000/,輸入帳號及密碼
2. 點選“網路”標籤
3. 點選“Linux Firewall”圖示()
如果是第一次執行,則出現此,此時只要選擇“Do network address translation on external interface”,並勾選 eth0,再按“Setup Firewall”按鈕,如果不是第一次的話,繼續第四步
4. 在“Showing IPtable”欄位,點選 nat table 後,按下“Showing IPtable”按鈕
5. 在“Packets after routing (POSTROUTING)
”區域,按下“Add rule”按鈕()
6. 在“Add rule”畫面,在“Action to take”欄位,勾選 Masquerade,在“Outgoing interface”欄位,點選 equals 及 eth0 ,按下“建立”按鈕()
使用 nat table 來作 DNAT
iptables -t nat -A PREROUTING -i eth0 -p tcp –dport 4899 -j DNAT –to-destination 192.168.0.171. 開啟瀏覽器執行http://Linux的IP:10000/,輸入帳號及密碼
2. 點選“網路”標籤
3. 點選“Linux Firewall”圖示()
4. 在“Showing IPtable”欄位,點選 nat table 後,按下“Showing IPtable”按鈕
5. 在“Packets before routing (PREROUTING)
”區域,按下“Add rule”按鈕()
6. 在“Add rule”畫面,在“Action to take”欄位,勾選 Destination NAT ,在“IPs and ports for DNAT”欄位,輸入 192.168.0.17,在“Incoming interface”欄位,點選 equals 及 eth0, 在“Network protocol”欄位,點選 equals 及 tcp,在“Destination TCP or UDP port”欄位,點選 equals ,“ports”欄位輸入 4899 後,按下“建立”按鈕()
使用 filter table 來作阻擋 ICMP 封包
filter table 的封包流向圖
iptables -t filter -A INPUT -i eth0 -p icmp -j DROP1. 開啟瀏覽器執行http://Linux的IP:10000/,輸入帳號及密碼
2. 點選“網路”標籤
3. 點選“Linux Firewall”圖示()
4. 在“Showing IPtable”欄位,點選 filter table 後,按下“Showing IPtable”按鈕
5. 在“Incoming packets (INPUT)
”區域,按下“Add rule”按鈕()
6. 在“Add rule”畫面,在“Action to take”欄位,勾選 Drop,在“Incoming interface”欄位,點選 equals 及 eth0
,在“Network protocol”欄位,點選 equals 及 icmp 後
,按下“建立”按鈕()
使用 iptable 作本機Transparent Proxy

iptables -t nat -A PREROUTING -i eth1 -p tcp –dport 80 -j REDIRECT –to-port 3128

vi /etc/squid/squid.conf 加入下列4行設定

httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy on
httpd_accel_uses_host_header on1. 開啟瀏覽器執行http://Linux的IP:10000/,輸入帳號及密碼
2. 點選“網路”標籤
3. 點選“Linux Firewall”圖示()
4. 在“Showing IPtable”欄位,點選 filter table 後,按下“Showing IPtable”按鈕
5. 在“Incoming packets (INPUT)
”區域,按下“Add rule”按鈕()
6. 在“Add rule”畫面,在“Action to take”欄位,勾選 REDIRECT,在“Incoming interface”欄位,點選 equals 及 eth1
,在“Network protocol”欄位,點選 equals 及 tcp 後
,按下“建立”按鈕()
使用 iptable 作遠端Transparent Proxy