贯彻10项原则,构建Linux系统安全体系

通过大量的实践经验,我们总结出10个最关键且有效的安全原则,分别是纵深防御、运用PDCA模型、最小权限法则、白名单机制、安全的失败、避免通过隐藏来实现安全、入侵检测、不要信任基础设施、不要信任服务、交付时保持默认是安全的。

1. 纵深防御

在安全领域,有一种最基本的假设—任何单一的安全措施都是不充分的,任何单一的安全措施都是可以绕过的。

试想一下,在谍战影片中,最核心的机密文件一般放在哪里?

最核心的机密文件不会放在别人轻易接触到的地方,而是放在有重兵把守的深宅大院里面,房间的门会配置重重的铁锁,进入房间后还有保险柜,打开保险柜之后,发现原来机密文件还是加密过的。在这样的场景中,守门的精兵强将、铁锁、保险柜都是防止机密文件被接触到的防御手段,加密是最后一道防御,防止机密文件万一被窃取后导致的信息泄露。这是典型的纵深防御的例子。

早在1998年的时候,由美国国家安全局和国防部联合组织编写的《信息保障技术框架(Information Assurance Technical Framework,IATF)》开始出版。该书针对美国的“信基础设施”防护,提出了“纵深防御策略”(该策略包括了网络与基础设施防御、区域边界防御、计算环境防御和支撑性基础设施等深度防御目标)。从此,信息安全领域的纵深防御的思想被广泛流传了下来。

纵深防御(Defense in depth),也被称为“城堡方法(Castle Approach)”,是指在信息系统上实施多层的安全控制(防御)。实施纵深防御的目标是提供冗余的安全控制,也就是在一种控制措施失效或者被突破之后,可以用另外的安全控制来阻挡进一步的危害。换句话说,纵深防御的目标也就是增加攻击者被发现的机率和降低攻击者攻击成功的机率。

纵深防御的概念,可以参考图1:

贯彻10项原则,构建Linux系统安全体系

图1 纵深防御体系

如图1所示,为了保护核心数据,我们需要在多个层面进行控制和防御,一般来说包括物理安全防御(例如,服务器加锁、安保措施等)、网络安全防御(例如,使用防火墙过滤网络包等)、主机安全防御(例如,保障用户安全、软件包管理和文件系统防护等)、应用安全防御(例如,对Web应用防护等),以及对数据本身的保护(例如,对数据加密等)。如果没有纵深防御体系,就难以构建真正的系统安全体系。

2. 运用PDCA模型

在实施了纵深防御策略以后,我们还需要不断的检查策略的有效性,细致分析其中潜在的问题,调查研究新的威胁,从而不断的改进和完善。

我们需要牢记的一句话是“安全不是一劳永逸的,它不是一次性的静态过程,而是不断演进、循环发展的动态过程,它需要坚持不懈的持续经营。”因此,笔者认为,动态运营安全是一条需要持续贯彻的原则,而PDCA模型恰好能有效的辅助这种运营活动。《ISO/IEC 27001:2005 信息安全管理体系规范与使用指南》中也明确指出,“本国际标准采用了‘计划-执行-检查-改进’(PDCA)模型去构架全部信息安全管理体系(Information Security Management System,ISMS)流程。”

PDCA(Plan–Do–Check–Act,计划—执行—检查—改进),也被称为戴明环(Deming Cycle),是在管理科学中常用的迭代控制和持续改进的方法论。PDCA迭代循环所强调的持续改进也正是精益生产(Lean Production)的灵魂。

标准的PDCA循环改进流程如图2所示:

贯彻10项原则,构建Linux系统安全体系

图2 标准的PDCA循环改进流程

在安全领域实施PDCA的方法和步骤如下:

在计划阶段的任务是

(1)梳理资产:遗忘的资产往往成为入侵的目标,也往往导致难以在短时间内发现入侵行为。对资产“看得全,理的清,查得到”,已经成为企业在日常安全建设中首先需要解决的问题;同时在发生安全事件时,全面及时的资产数据支持,也将大大缩短排查问题的时间周期,减少企业损失。资产梳理的方法包括使用配置管理数据库(Configuration Management Database,CMDB)、网段扫描、网络流量分析、对相关人员(如业务方、运营方、开发方、运维方)进行访谈等。需要梳理的对象包括:服务器IP地址信息(公网、内网)、域名信息、管理平台和系统地址、网络设备IP地址信息以及与这些资产相关的被授权人信息。

(2)制定安全策略:安全策略既包括安全技术策略,也包括安全管理策略。实现两手抓,两手都要硬。安全技术策略,包括安全工具和系统、平台。如果没有它们的辅助,那么就没有办法阻止恶意入侵。安全管理策略,包括制度和流程。如果没有它们发挥强有力的作用,那么就会使得安全技术策略的效力也大打折扣。

(3)制定安全策略的实施方案:在这个阶段,需要制定具体的安全策略实施方法、实施负责人、实施步骤、实施周期。

(4)制定安全策略的验证方案:制定验证方案的的目的,是在检查阶段能够以此为基准检查确认安全策略的有效性。

在执行阶段的任务是实施计划阶段制定的方案。这个阶段的工作包括物理防护、网络防护、主机防护、应用防护和数据防护以及安全管理制度的实施。

在检查阶段的任务是按照计划阶段制定的验证方案验证安全策略的有效性,从而确认安全策略的效果。这个阶段的工作包括自我检查、漏洞扫描、网络扫描、应用扫描、渗透测试等,也包括安全管理制度实施效果的检查。这一阶段的成果是下一阶段的输入。

在改进阶段的任务是以检查阶段的输出为指导,完善安全策略,进入下一个升级迭代。

3. 最小权限法则

最小权限法则(Principle of Least Privilege,PoLP)是指仅仅给予人员、程序、系统最小化的、恰恰能完成其功能的权限。

在系统运维工作中,最小化权限法则应用的一些例子包括:

服务器网络访问权限控制。例如,某些后端服务器不需要被外部访问,那么在部署时,就不需要给予公网IP地址。这些服务器包括MySQL、Redis、Memcached以及内网API服务器等。

使用普通用户运行应用程序。例如,在Linux环境中,监听端口在1024以上的应用程序,除有特殊权限需求以外,都应该使用普通用户(非root用户)来运行。在这种情况下,可以有效的降低应用程序漏洞带来的风险。

为程序设置Chroot环境。在经过Chroot之后,程序所能读取和写入到的目录和文件将不在是旧系统根下的而是新根下(即被指定的新的位置)的目录结构和文件。这样,即使在最糟糕的情况下发生了入侵事件,也可以组织黑客访问到系统的其他目录和文件。

数据库访问控制。例如,针对报表系统对MySQL数据库的访问控制,一般情况下,授予SELECT权限即可,而不应该给予ALL的权限。

在运维和运营过程中,未遵循最小权限法则将会对系统安全造成极其严重的威胁。例如,根据The Hack News网站(https://thehackernews.com/2018/06/redis-server-hacking.html,访问日期:2019年1月5日)报道,运行在公网上、未使用认证的Redis服务器中高达75%已经被黑客入侵。造成该严重安全问题的重要原因之一就是未遵循最小权限法则来限制Redis服务器其对外服务和使用较低权限的用户启动Redis服务。

4. 白名单机制

白名单机制(Whitelisting)明确定义什么是被允许的,而拒绝所有其他情况。

白名单机制和黑名单机制(Blacklisting)相对,后者明确定义了什么是不被允许的,而允许所有其他情况。单纯使用黑名单机制的显而易见的缺陷是,在很多情况下,我们是无法穷尽所有可能的威胁的;另外,单纯使用黑名单机制,也可能会给黑客通过各种变形而绕过的机会。使用白名单机制的好处是,那些未被预期到的新的威胁也是被阻止的。例如,在设置防火墙规则时,最佳实践是在规则最后设置成拒绝所有其他连接而不是允许所有其他连接。本书“第2章 Linux网络防火墙”中正是使用了这一原则来进行网络防护。

5. 安全的失败

安全的失败(Fail Safely)是指安全的处理错误。安全的处理错误是安全编程的一个重要方面。

在程序设计时,要确保安全控制模块在发生异常时是遵循了禁止操作的处理逻辑。如代码清单1-1所示:

代码清单1-1 不安全的处理错误

isAdmin = true;
try {
    codeWhichMayFail();
    isAdmin = isUserInRole(“Administrator”);
}
catch (Exception ex)
{
    log.write(ex.toString());
}

如果codeWhichMayFail()出现了异常,那么用户默认就是管理员角色了,这显然导致了一个非常严重的安全风险。

修复这个问题的处理方式很简单,如代码清单1-2所示。

代码清单1-2 安全的处理错误

isAdmin = false;
try {
    codeWhichMayFail();
    isAdmin = isUserInrole( "Administrator" );
}
catch (Exception ex)
{
    log.write(ex.toString());
}

在代码清单1-2中,默认用户不是管理员角色,那么即使codeWhichMayFail()出现了异常也不会导致用户变成管理员角色。这样就更加安全了。

6. 避免通过隐藏来实现安全

通过隐藏来实现安全(Security by obscurity)是指通过试图对外部隐藏一些信息来实现安全。举个生活中的例子。把贵重物品放在车里,然后给它盖上一个报纸,我们就认为它安全无比了。这就大错特错了。

在信息安全领域,通过隐藏来实现安全也是不可取的。例如,我们把Redis监听端口从TCP 6379改成了TCP 6380但依然是放在公网上提供服务并不明显提高Redis的安全性。又例如我们把WordPress的版本号隐藏掉就认为WordPress安全了也是极其错误的。当前互联网的高速连接速度和强大的扫描工具已经让试图通过隐藏来实现安全越来越变得不可能了。

7. 入侵检测

在入侵发生后,如果没有有效的入侵检测系统(Intrusion Detection System,IDS)的支持,我们的系统可能会长时间被黑客利用而无法察觉,导致业务长期受到威胁。例如,在2018年9月份,某知名国际酒店集团爆出发现约5亿预定客户信息发生泄露,但经过严密审查发现,其实自2014年以来,该集团数据库就已经持续的遭到了未授权的访问(https://answers.kroll.com/,访问日期:2018年12月31日)。该事件充分证明了建设有效入侵检测系统的必要性和急迫性。

入侵检测系统,按照部署的位置,一般可以分为网络入侵检测系统和主机入侵检测系统。

网络入侵检测系统部署在网络边界,分析网络流量,识别出入侵行为。

主机系统检测系统部署在服务器上,通过分析文件完整性、网络连接活动、进程行为、日志字符串匹配、文件特征等识别出是否正在发生入侵行为或者判断出是否已经发生入侵行为。

《Linux系统安全:纵深防御、安全扫描与入侵检测》“第11章 入侵检测系统”、“第12章 Linux Rootkit与病毒木马检查”、“第13章 日志和审计”将详细介绍入侵检测相关技术和实践。

8. 不要信任基础设施

在信息安全领域有一种误解,那就是“我使用了主流的基础设施,例如网站服务器、数据库服务器、缓存服务器,因此我不需要额外防护我的应用了。我完全依赖这些基础设施提供的安全措施。”

虽然主流的信息基础设施在设计和实现时会把安全放在重要的位置,但是如果没有健壮的验证机制和安全控制措施,这些应用反而成为基础设施中显而易见的攻击点,使得黑客通过应用漏洞完全控制基础设施。

Weblogic这样一个广泛使用的Web容器平台就曾经爆发过严重的安全漏洞。例如,在2017年12月末,国外安全研究者K.Orange在Twitter上爆出有黑产团体利用Weblogic反序列化漏洞(CVE-2017-3248)对全球服务器发起大规模攻击,大量企业服务器已失陷且被安装上了watch-smartd挖矿程序。这个例子告诉我们,要时时刻刻关注信息基础设施的安全,及时修正其存在的安全缺陷。

9. 不要信任服务

这里的服务是指任何外部或者内部提供的系统、平台、接口、功能,也包括自研客户端和作为客户端功能的软件,例如浏览器、FTP上传下载工具等。

在实践中,我们常常见到,对于由外部第三方提供的服务,特别是银行支付接口、短信通道接口,应用一般都是直接信任的,对其返回值或者回调请求缺少校验。同样,对于内部服务,应用一般也是直接信任的。事实上,这种盲目的信任关系会直接导致严重的安全风险。如外部和内部服务被成功控制后,我们的业务也可能会受到直接影响。来自自研客户端或者作为客户端功能的软件的数据,更是应该进行严格校验的,因为这些数据被恶意篡改的概率是非常大的。例如,黑客通过逆向工程(Reverse Engineering)对自研客户端进行反编译(Decompilation)往往可以直接分析出客户端和服务器端交互的数据格式从而可以进一步模拟请求或者伪造请求而尝试入侵。

10. 交付时保持默认是安全的

在交付应用时,我们要保证默认情况下的设置是安全的。比如,对于有初始密码的应用,我们要设置较强的初始密码,并且启用密码失效机制来强制用户在第一次使用的时候就必须修改掉默认密码。另一个例子是虚拟机镜像的交付。我们在烧制虚拟机镜像的时候,应该对镜像进行基础的安全设置,这包括删除无用的系统默认账号、默认密码设置、防火墙设置、默认启动的应用剪裁等。在虚拟机镜像交付给用户以后,用户可以按照实际需要再进行优化和完善,以满足业务需求。

本文主要内容摘要自我的新书《Linux系统安全:纵深防御、安全扫描与入侵检测》。通过学习《Linux系统安全:纵深防御、安全扫描与入侵检测》,可以系统性、整体化的构建Linux安全体系。

文章来源:微信公众号 运维技术实践

上一篇:选择现代数据仓库满足你的数据需求


下一篇:Hive的数据类型解析和表的操作实例