技术开发 频道

架构师如何才能够设计一个安全的架构

  【IT168技术】架构师不可能做到全知全能,但是仍然担负着成功交付可用的解决方案的任务。满足安全需求常常是其中不可或缺的一环,而且这一点常常没有明确指出。本演讲从整体上讨论架构的安全性,比如如何撰写安全的代码、部署中的安全、架构层的物理隔离、加密、证书的使用等等方面。


全球系统架构师大会现场报道

纠正系统架构的安全认识
▲Coding the Architecture创始人Simon Brown

  以下是精彩演讲:

  随着互联网安全形势的日益严峻,对于架构师们来讲,为什么需要一个安全的架构以及怎么建设安全架构成为了迫在眉睫的重要任务。为什么来这里讲安全,很多人没听过泽西岛,在英国的南部,是一个离岸的辖区,金融机构在岛上非常盛行,对安全很重要,要安全维护,要有系统享受低税,很多做JAVA的项目,大部分泽西的工作,离岸的银行小公司对安全特别关注的。

  纠正系统架构的安全认识

  肯定是重要的。特别泽西岛有自己交易的信息、银行的信息、养老金的信息,所有的资料在泽西岛里面安全保护起来。离开泽西岛也要保障安全,如果不把安全做好,肯定要有糟糕的事情发生。

  我讲一些最近大家都知道的一些安全的漏洞,比如说Linkedln,有一些密码泄露了。也是最近轰动的事情。

  安全适用于方方面面,我们讲软件架构的时候,并不只是看一个地方来求安全,安全应该在整个完整的软件系统当中,都能渗透在安全中,包括所有的级别层所有的元件都需要做到安全。很多人认为安全是人份认证、授权,很多人认为安全是两个问题,但是安全还有其他的问题,比如说防黑客、防攻击、加密等。

  安全这个问题很难对现有的代码进行安全的加装或改装。如果安全出现问题,要解决安全问题,从架构的基础上来解决的。如果架构的问题一开始没做好,事后补相当困难。跟性能、扩展性都是很重要的,一开始没有照顾好的话,未来提升就很难了。

  安全在整个软件架构的角色当中是怎样的位置

  我们需要在整个软件开发过程中都要进行考虑的问题。我曾经讲过一个故事,一个面向公众的互联网网站。这个网站是一个针对当地泽西岛的一个听众,泽西岛10万人,是很小的用户群,是一个全新的互联网系统软件服务。这个互联网服务,可以去登陆获得一个用户名,之后获得这些权限。他们请我去看软件系统,我去看软件系统的时候,假装用户去体验一番。

  我很快发现我可以做跨站的脚本攻击。比如说创造账户,有名字、地址、电邮、电子卡信息。而在地址这一栏,可以写Java脚本,可以注入Java脚本。这个例子是很小的例子,可以对网站做的攻击远远不止这一点,有很多东西可以做。

  我只用了五分钟、十分钟就发现了这些漏洞。当然,这个网站还没有完全上线,只是进行前期的测试,在这个时候发现问题算是万幸。其实在登陆面可以创建自己的密码,很多网站可以是1位到20位需要多少的标点。有些网站需要密码的强度。这个网站也是一样,列出网站应该这样。登陆账户的时候,我说密码太烦了。前台认证并没有很复杂,随便一个词就可以接受了,有些比较弱,有攻击密码。

  我在做银行互联网的时候,有做一个双重认证。在页面看十分钟,HTTP的对话就超时了,为什么超时?这是安全的功能。比如说共享一个电脑,在网吧、咖啡店上网的话,有超时的保护。有不同的安全要求。回到我刚才讲的网站,这个网站肯定不是登陆之后一直在线的,对话的时段是非常短的,因为里面有一些非常机密的个人信息。但是,你登陆了网站之后,登陆永远不超时。把游览器关掉再打开,永远不会中断,就算点登出,不会登出,管理有问题的。我们要做安全的策略性平台,如果有这么多的漏洞,是非常危险的。

  这个项目正在进行用户的接受度检测的过程,还没有上线,他们请我去做了检查。经过了各方面的检查,他们说我们只有四个星期就上线了,找了很多问题,项目四个月之后才能上线,很多顾客对这个问题根本就不敏感。

  架构师是“T”型人才 是一个建筑师

  要有知识的深度,同时也有不同方案的广度,我们面临的软件架构师是一个建筑师,这种解决方案必须要知道不同的解决方案不同的软件开发都需要通才的能力。我们从安全的角度来说,软件架构师的工作非常复杂的,特别是windows的环境有很多学习的地方。广度也很重要,有各种各样的安全问题,在整个架构、编码的过程中,不同地方都会出现漏洞。如果没有足够的经验,甚至不知道哪个地方有可能出问题。比如说我们项目的架构师可能是一个通才,有一定的深度,有技术的专长,必须要知道在哪些地方有可能出现问题。

${PageNumber}

  我们面临的风险是什么呢?

  攻击、黑客、宕机、拒绝服务、密码泄露、机密信息外泄、安全受损等很多问题都可能来自于安全的问题。这显然是我们从架构角度认真对待不同的风险。这就提出一个很有意思的问题,我们是不是可以样样精通呢?我问过“T”型的人才,我们有知识的深度,如果是Java的架构师,必须要真的理解Java,我们要做高性能的系统,这方面的知识,怎么做可扩展性,还有高可靠性。

  必须要保持这种意识

  所有不同的领域我们都有一定的宽度和广度,安全是其中一点。我们之前看到编码是整个所有活动当中的中心,是不是所有的知识都可以做编码呢?如果是一个小小的项目可以做自己的编码,同时也应该知道可用性、安全性以及扩展性的种种知识。这是不是意味着样样都精通呢?我给大家讲安全课,但是我不是安全专家。但是安全是我们作为架构师必须有意识、必须有概念,而且要知道安全环境不断的改变,有新的不同攻击、不同黑客,必须要保持这种意识。所以我们必须有安全的意识,而意识是一个关键词。

  刚才讲了“T”型人才,是一个通才型的专才。做软件团队的时候,可能有一个人来做这个工作,可能有一个专门软件架构师来做技术主管的角色。这个人就是我们的通才化的全才。但是你能找到这样一个人吗?我们可能要面试很多人、招聘很多人,是不是能找到通才化的人才呢?不一定的。最近我建立一个系统,是一个混合项目,我们可以有多个人进行架构的支撑,共同协同工作,联合起来形成了足够宽度和深度,一方面有通才型的专才,另一方面专家提供深度的支持。

  一般我做的项目里面可能会请一个专家,专家有相关的经验,有些是没有的。给大家看一个很有意思的博客,在英国看到的。如果系统里面有SQL的出入,就有流程或者基础设施的问题。如果你的问题有安全隐患的话,系统安全隐患,就是说明现在做错了,要看哪些地方做错了,如果没有这方面的专家怎么办?或者根本没有意识到潜在的安全问题或者已有的安全问题。

  安全怎么融入到系统当中

  从最根本的角度来看安全有什么要求。就像十年之前搞架构的时候,有哪些具体要求,哪些东西要做哪些不要做的。必须要清楚地知道,在建造架构的时候哪些东西需要做,怎么才能高效。我觉得安全也是一样,很多人都是从用户的角度来获取用户的需求。用户的角度确实不错,希望能够找一些好的、简单适用的。他们不是技术性的人才,视角不是特别独特。在编写用户表述的要求时,有不同的模板。所做的一切要清楚在你的系统里面,用系统的人分成哪些类的。

  去年我做了一个项目的架构分析,大概里面有两到三百个使用者所提供的一些要求,用户扮演着不同的角色。到底这些用户分成哪些?比如说超级用户还是管理员,还是一般性的用户。但是分不出来类。我觉得挺有意思的。

  如果我设计软件的话,必须要知道软件针对的受众是谁,谁会用。今天早上给大家看图,第一个就是上下文背景,中间是系统,下面还有与之沟通的系统,最上面是我们讲的用户。我们知道到底哪些类型的用户在使用我们的系统。为什么这点很重要?从安全角度讲很重要。问这个团队到底懂不懂安全,谁在用我们的系统?这些人用我们的系统,有什么样的功能?我们这些使用者所提供的一些,也从相关来讲比较高端的视角来分析一下类别。

  对于这方面的信息不是已经过时了,非常适用的。在英国一些咨询管理公司,要求做成文件发给我们,尤其是技术方面的要求。技术要求包括扩展性、安全、性能等。这些从特点来讲比较技术性的,而且非常详实。写这些要求的人,不是技术出身的,是商界出身的,他也不清楚产品规格里面细节多细合适,所以来一句系统是非常安全,对于系统的安全来一句就够了。作为架构师这句话牛头不对马嘴,确实要做到安全。

  用户或者SQL的攻击注入时,怎么样做到安全?

  很多英国的公司从安全的角度讲,做得很烂,因为团队不知道安全到底意味着什么。可能在网上随便问一些人到底该怎样做。

  作为架构师要分析需求的话,并不是说做大型的前端设计,而是做一些简单的,获取、捕获使用者的要求,做高级的架构设计,比较要考虑到扩展性、安全,如果没有考虑到这些,在打造架构的时候,可能会丢失非常宝贵的元素。可以开一些研讨会、交换文件,这种工作坊和小型研讨会的形式非常好,知道使用系统的是这部分用户。

  客户给的要求是系统非常安全,就要问他非常安全是有多安全,工作坊可以面对面的交流,谁在用我们系统,哪些方面的内容影响了他们对系统的使用,为什么会这样?这样会有非常具体的用户对系统的要求。除了捕获信息之外,还要置疑他们。我们团队必须要不断的置疑挑战我们一开始所制定出来的具体要求。到底我们开发的时候优先级别会怎样。觉得要求根本没必要,换一种方式行不行,我觉得就已经够了,要挑战不同的要求,不仅是功能性的,还有非功能性的,比如说安全,也要跟客户谈一谈。每次在系统里面引入安全的时候,要做一些权衡、妥协、让步。

  一般来讲,典型的让步、取舍是可用性、易用性和复杂性。也就是说,安全的话更复杂了。比如说我去银行要做,ID非常长,记不下来,输入密码登陆,到了第二页,要输入安全代码,有一个小键盘,类似于口令牌,随即生成输入进去。等我通过这么多安全检查进这个网站的时候,对话已经超时了,我输入这么多的密码,已经查不到我账户信息了,这是非常长、非常复杂的过程,用电子安全指令等。确实很安全,但是影响了便捷程度。这时要做取舍,是易用还是复杂安全性。

${PageNumber}

  如果要胜任软件架构师的角色,需要多种能力

  理解要求非常重要,作为架构师必须理解要求是什么,比如说不能只做前期的设计,交给后期去实施,这不是我们做的,但我们必须要知道安全的要求,安全的要求必须要吃透。安全是一个非常关键,从架构师的角度来说,认真对待安全的要求。特别是项目的技术主管,要教练和指导你的员工,作为技术主管来说,必须有这个能力。而且安全搞不好是一个大风险。

  安全问题怎么样能够在架构里面得到诠释

  安全可以融入到所有领域的,现在看到的有三级显示,Web服务器、应用服务器、数据库。在Web服务器上避免攻击,应用服务器获得授权的人才能进入,数据库是确保数据安全保存在这里。中间部分是保障基础设施的安全,包括防火墙等。稍候会讲怎么有效获得授权。

  这是一种非常常见也是非常传统打造安全的方式。可能在服务器上放很小的代码,数据库里面放很多数据,中间应用服务器获取这些相关信息。因为肯定关注安全,信息存储是否安全。

  稍候看一看这些架构,看到Web服务器使用了相关安全服务,这是很常见的,但是这些所谓的Web服务非常不安全,比如输入ID开发工具,你的Web服务创建了一些本地的组建,你发现这里不需要授权,随便什么人都可以进来,因此在这个领域我觉得安全是可以发挥重要的作用的。

  我们在做架构的时候,如果把服务器从物理上分得开,不一定真正安全了。物理分开的话,中间信息传输出现影响。每个层级有安全,不同的层级间的安全很重要的。如果从物理上分割开来,中间的联系也会成为攻击的对象。

  千万不要把编码放的到处都是,放在核心中央层

  这样的话攻击你就只可能攻击你表面,核心保护很好。这里有非常有意思的问题,为什么用物理上分开来的应用服务器,人们觉得集成实时的,总是搞架构把应用服务器分开来,但是我们也可以找一些其他的方法,现在有很多互联网的创业公司就是这么做的。我想希望大家好好想想你干吗这么做,做一件事情必须事出有因才行。这实际上就是我们讲得做出取舍。安全得到保障,复杂性获得一些影响。在我们的安全因素的话,讲到最小的特权原则。只有必须要发生的事情才能发生,不能把所有的东西全部部署到服务器上从来都不用。

  许可一个进程操作的话,要确保进程必须要操作的,其他不需要操作不要放在这里。这点是所有软件架构师在系统里面必须要牢记的。

  怎么通过不同的方式来把安全引入到系统里面

  现在讲验证、授权、审核是三个比较常见的方法。首先,验证。我是用户,是谁呢?权力是什么?用什么东西?这很重要,可以帮助你了解到用户的需求以及不同类型的用户在系统里面扮演不同的角色该怎样具体做呢?有这样的系统怎样能够做好本地的验证和授权。其实很多方法都可以。

  先来看看一个简单的两级的方式,Web服务器和数据库直接进行对换。讲到安全、认证、授权最简单的方法,系统认出你的用户,在系统里面有一个用户的名单,有他们使用的权力,通过映射的方式,客户来了映射能做什么,是不是最高效能,不一定。

  早上说过我们有不同的选择,要解决这样的问题,选择很多的,还有另外一个方法,比如说设计自己的架构,不把你的数据放在数据库里,大的企业会有一种主动的目录和一些算法,是包含了用户和他的一些资格说明,这样的话就可以加以利用了。你不会把用户放在你的数据库里,可以把用户放在别的地方,这样的话管理的负担也小了。有新的用户在中间的注册器里面注册新用户就可以了。

  但也许它的角色放在数据库,因为不同角色有不同的授权。所以用户和他的资历放在外面,但是角色放在数据库里,这也是很好分解的办法。或者甚至把授权也放在主动的目录当中,形成不同的群组,这是可以选择的方法。但是会不会比之前的方法更好呢?同样,这并不是我能回答的问题。有些企业、有些组织很愿意做这种,觉得这个够了,可以对于用户的目录专门存放用户的信息。但是其他的一些企业、一些组织并不喜欢把你自己的群组放在自己的服务器上。有些时候可以,有些时候不愿意使用。

  还有其他的方法,可以用安全令牌的服务,有人做身份基金会的工作,实际上就是把安全进行集中化,不管是身份验证还是授权都能够集中起来,我两年前做的一个项目,有一个单独的令牌的系统,这里面给我们带来的复杂性是不可想象的,本来只有一个人做这个项目,压力非常大,非常复杂。这也是一种选择。对某一种企业来说,也许是最好的选择。

  哪一个方案是最“好”的?其实没有所谓的最好的方案,永远只能对你来说最好,对这个环境来说最好,所以哪个是最好呢?还是回到今天早上讲过的,从高层的角度上了解我们的需求,了解我们环境的约束性、局限性。如果在大企业工作的话,可能会有一个主动的目录服务器了。可以去找这个有关的部门,可以找你服务器来做验证。可不可以把决策和授权放在目录当中,可以选择最好的解决方案。

  有一个大的英国超市,用明文来记密码,密码以明文的形式寄到邮箱,回归到之前的架构,如果数据库是够安全的话,明文也没问题的。对于这篇文章之后,有一个很好的明文建议,如果用明文密码会加密,而且是散列的处理。我不是一个安全专家,但是我知道至少有不同的方法来把密码进行分类散列,比如说用一些随机的数字进行加密和散列,这都是很好的进行密码散列的方法。当然我们也选择一个最适合我们的方法。

  审查、审计也是一方面,我们要有一个审计的线索。比如说我们在泽西岛是离岸的环境,做很多交易,必须知道哪些用户做了什么?为什么要这么做?因为有人对这个网站提出一些索赔,丢失了信息我们要追诉回去,看一下他的信息怎么丢的,有没有修改。

${PageNumber}

  怎么能写出安全的代码?

  网上有很多信息,主要有两个主流:第一,要避免数字被修改。第二,限制接入。

  当然免疫性很好的,如果免疫的话就不能修改。这是一个很好的属性。如果这个数据有一定的对象,而这个对象数据是不能修改的,免疫了就不能修改了,所以从根本上来说是安全的。如果有功能性的语言,用这个数值改变,因为免疫不能改变了。你想象一下,有一定的人、把这个人加入到列表当中。怎么样让他把所有的人列出来呢?也许在下面给一条getPeople的指令。

  给一些简单的建议,比如说用一些接入的修订词,特别是对外API的时候,要有各种的假定,比如说接入的修饰词和修饰条件。如果所有的东西都是对外公开,没有安全的问题才怪!

  scott/tiger,有人在笑,很多人拿到密码都没有改,用户和密码缺省或者原始的数据密码都不改,这必须要改,改成一个比较有利的密码。

  讲到数据的时候,真的希望能够限制消费者对数据的接入,限制消费者对数据的使用,这可以帮我们收载他们的访问范围。不管我们的网站在什么地方,我们用SQL的数据库怎么做呢,我们用特别的一些代码通过SQL进行数据库的接入,有些时候不喜欢这种方法,觉得过程非常复杂。虽然复杂,但是有一个精简、简单、安全的API,很多人用SQL,就是为了安全性。

  2000年的时候,我在一个小的电商公司做网站,他们首次在搞商务网站。他们有一个电商网站,而且是一个盒子,只需要拿一个光盘装到系统上就是一个电商网站了。想存储他们的信用卡号码。客户回到电商时,不需要把信用卡再输一遍,这是盒子提供的,总要有一个地方来放信用卡信息吧!他们看一看数据库里面有没有栏目没有用到,他们发现中间名没人用,就把中间名放信用卡了,只用输入(英文),没有经过加密,对信用卡进行外键的字符串。我们也知道对这样的外键的字符串可以破解的。这种安全只不过是把字符串进行排列,并没有进行任何的安全加密,只不过支付串操作两次就已经万无一失了。

  我们讲过数据代码,也应该谈一下配置、部署,所以有数据库。网络服务器要跟数据库进行沟通的话,必须要用户名和密码。数据库的用户名和密码什么地方?往往是在网页服务上,往往都是明文。如果有人攻击网页服务器,必须提取文件系统,提取之后可以看到明文的文件,这个发生了很多。

  怎么样解决这些问题呢?

  要确保这个信息加密。用Java系统也有加密的配置办法,这都有办法,只是有没有这个意识。我们可以用一些CQL服务器受信任的连接就可以避免了。

  之前我在泽西岛做的项目是离岸银行,他们很重视,我们做自己的虚拟机、手提电脑来写代码,但是要部署到银行系统,我们要用一些连续的工具放入U盘上,把U盘交给银行的人,接入另外一个网络,装入软件当中。这里我们的开发团队和部署团队是物理隔离的,避免了开发团队能够染指生产的系统。

  问题在做部署的人根本不太理解做开发的原意,不是一个技术人员。所以我们在自己废寝忘食的写了这么多代码,交给他之后,不懂怎么部署,物理隔离不能保障安全,这个过程或者流程肯定有漏洞的。不是说一定能解决这样的问题。

  生产的资质、资格也是一个问题。比如说有一个经过测试的环境,这个环境把它放入生产的系统当中,当中有这个隔离。把生产的用户名和密码放在什么地方呢?也许你可以放在配置服务器的一个地点,但这个要看多么看重安全性,如果连续交付很有意思了,连续交付有关的资质就要考虑怎么存放。

  运行时间方面和安全有什么关系呢?

  这里说到重要的原则“最小特权原则”,我们看一看这个模型。在Java应用里面可以用Java2的安全模型,允许你做一部分的工作,比如说只能进入到这方面的网络或者只能用这部分的接口,这就是Java的安全模型。如果网站被黑的话,肯定会直接攻击里面用户。一般不会这么做,会密码也不改,不限制账户的使用,导致黑客很轻易获取信息。

  之前我在电商工作过,就有一些信息方面的问题,找到他们的日志文件,发现有很多的错误信息,成千上万的错误信息。人们要输入信用卡信息,信用卡信息也都在日志文件里面。在日志文件里面,地址、名字、信用卡信息以及信用卡盗窃事件都有。

  我们还要有效监控管理界面方面的安全,不能把东西放在云端上就觉得什么事都搞定了,还要看监控确保运行合理合适。我在做顾问的时候,曾经帮一个电商的网站做很短的项目。如果我打开我的浏览器连上网,完全可以看想看的页面,没有最基本的二进制密码保护。

  架构师要知道基础结构

  我是项目上的软件架构师,不做基础设施的设计,但是不必须要了解到防火墙的设置等。因为确保基础的设施才能支持我们软件的架构。另外,从软件的角度来讲,也非常的重要。最早不是我做的,我做的很多系统都是在泽西岛,因为很多的数据都有地域限制,必须要用本地的服务器,要把服务器信息拿出去的话,第一件事情是把原来的安全保护、防火墙没有用的东西都拿走,这样可以减少空间内容。要和基础设施团队DMZ来谈一谈防火墙等。从软件架构师角度来讲,要使用web服务或者RMI等不同服务,软件架构团队和基础设施团队必须要有沟通才行。

  攻击者、黑客以及我们的漏洞

  我在伦敦工作的时候,很多是做公司内部的,回到泽西岛的时候,做了很多互联网的界面,影响到数据安全性。如果大家觉得讲得这些内容比较陌生的话,希望大家能够好好地看一看开源的应用安全项目。

  列出了10个最主要的,注入、跨站脚本攻击、验证、对话管理等。从安全角度讲是值得一看的东西。有一次看了CQL的注入,我不是一个安全专家,但是我看了CQL注入知道成为安全隐患,因为电击链接可以看到很多信息。

  现在看到的是中文版,叫做OWASP,中文版的,喜欢网站是因为告诉我们最主要的攻击方式,给一些例子,该怎样修复这些漏洞,避免这些攻击再次发生。

  最近经历一件事是很多系统都要做深度测试。找一些外部第三方的团队或者公司来看不看能不能黑你的系统,看系统到底多牢固。我们会发现他们攻击的时候,很多之前没有注意到的漏洞浮出水面。这些团队给一些例子,既然找到漏洞,告诉我们该怎样把漏洞一个个补好。非常建议第三方来做测试。

  最后总结

  安全非常重要,但是安全也非常复杂。作为一个软件的开发员、程序员,要做到敏捷、持续的交付、关注模式,非常流行的词汇。但是安全不是热门词汇,要注意安全的重要性。比如说做网银、网络界面不能忽视安全。今天上午讲了文本介入,搞文本轻一点就行了,不能太复杂,做一个软件的架构,给别人用,不给文件不知道安全怎么做,不知道安全怎么做,可能会加一些编码,这些编码反而让你的安全系统安全用不上了,可能一两年之后安全彻底失明了。因此我们提供不太厚的文件,里面有关键信息。

  刚才讲了怎么样收集用户的一些要求,把它进行排序。当然不能完全依赖他的想法,但是要让他知道安全方面哪些最重要的。安全很重要,而且适用于整个软件架构的所有环节。从外部端到数据库端,从跨件的脚本到注入等,都要确保里面内容是安全的。上下文非常关键,这里有一些安全方面的非常好的实践。如果之是照搬别人的非常复杂,所以要知道哪些是需要取舍的,做这些风险会带来什么影响,会泄露什么数据?这些数据有价值还是没价值的?用这些为什么而用,提高应用性和复杂性。

  一个人不可能样样精通,我对安全不是专家,但是对安全要了解一些情况。我们知道行业不断变化,速度非常快。既然不可能把所有的知识都学的很透彻,至少我们能够粗浅的像蜻蜓点水了解一些东西。另外,千万别做一个不负责任的软件架构师。因为我们架构师就像一个领导者一样,确保所有的工作都能有效。

  以上是我讲的内容,谢谢!

0
相关文章