前不久和小伙伴们讨论了一个基础的安全问题:一个朋友开的公司的服务器集群被黑了,攻击者在机器上安装了远程操作程序——被肉鸡了。但经过讨论后发现,机器的最基本的防护都没有。这无异于大姑娘在街上裸奔——就算长得再丑也最终会被爆的。本文就这个讨论,总结一下在工程实践上,服务器集群的“入门级安全防护“该如何实施。

 
安全第一

本文仅仅针对初创公司,没有资源建立完善运维团队的场景。本文介绍的方法都是一个开发手工可以搞定的。

服务器是如何被攻破的

线上服务器,无论是自建机房还是云服务,管理员都不太可能直接接触到机器本身。大多数时候管理者都是通过网络与服务器通讯。这就涉及到了服务器一定要打开一些端口才能允许这种交互。作为管理员是通过网络使用服务器的资源,作为用户也是如此。作为攻击者当然也可以通过同样的方式来访问主机。毕竟都是大门嘛,你能进,他也能进。

因此,从攻击者的角度,最低成本的攻击方式是用脚本自动扫描,看看一个服务器(IP)到底开了多少端口。如果是使用默认端口的话,攻击者就可以猜测这个端口背后的程序是否可能有漏洞。比如Web的默认端口是80,而80背后大概率可能就是nginx或者apache。而这些软件的某个版本存在漏洞或者配置不当,就会造成极大的安全隐患。比如apache如果配置不当,攻击者可以顺着apache用https://foo.com/../../etc 这样的url访问到非常敏感的信息,从而为下一步的提升权限、做任意的操作、安装黑客工具做第一步准备。而如果攻击者发现3306这种端口是开的,就会直接尝试用弱口令或者Mysql特定版本的漏洞来尝试访问Mysql,然后干他任何想干的事情。

众多端口中,SSH服务的安全风险相当的高,一旦被攻破,攻击者可以任何执行器想要执行的指令。而其他的协议,比如3306连通,背后是mysql,攻击者就必须按照mysql的通讯协议来尝试各种机会,大部分情况只能对mysql本身做一些事情,但不能对机器做一些事情。但无论哪一种,对于被攻击者来说都是巨大的损失。轻则所有机器要reset,重新安装部署;重则一个公司彻底信誉扫地,垮掉(比如大量用户信息丢失,被篡改)。

So, take it seriously.

那么如何防护呢?

整体思路

整个防护的思路就是,将生产服务器的对外网的接触面降低到最少。将所有的管理类访问收到以跳板机为中心的SSH主机上。其余的访问只能访问生产机器提供的服务本身。

 
网络隔离

下面一一讲解。

限制开放端口

任何时候,只要是生产服务器,投入使用之前必须限制开放端口。你需要开放什么服务,就只开放那个服务必要的端口。例如,对于一个web服务来讲只需要打开80/443两个端口。具体做法是,使用iptable命令来DROP掉除了必要端口外所有的INPUT的网络请求。

生产机之间最好也可以做这种封闭,但是如果运维资源实在紧张,可以只做对外出口的限制。毕竟,如果攻击者已经可以进入到生产机内网环境随意SSH了,就已经算是攻破了。

绝对不要把数据库的端口对外网打开。我已经见过太多案例,开发者在服务器上装了个mongo或者mysql就不管了,结果被别人整库拖库的事情。数据库属于内部服务,根本就没有打开的必要。

配置时切记不要把管理用的SSH端口给封住了,这样管理员自己也访问不了主机就尴尬了……

关闭不必要的对外主动连接

生产服务一般也不需要主动发起对外的网络连接。一些例外的情况比如支付服务,微信授权服务,第三方的数据统计分析服务等。这些情况可以方便的通过IP/域名的白名单来处理。除此之外,生产机不应该能够主动发起任何对外网的访问。

修改默认端口

攻击者会尝试根据端口猜背后的程序是什么。比如对于端口22,攻击者会猜这是个SSH,然后会尝试弱口令等方式来攻击。如果你把SSH的端口随便改成一个比如4328,那么攻击者就得花更多的力气才能做这个猜测。如果攻击者不是针对你的话,也就不会废这个功夫猜了,毕竟不设防的机器多的是,何必死磕你的。

其他服务的端口也可以类似处理,比如MySql,Redis等。但是值得注意的是,因为浏览器访问Web时,如果不明确在URL里写端口,就会用80/443,并且端口还可能影响Cookie的有效性。所以Web的默认端口是不方便改的。

学会使用SSH

在*nix环境下,SSH是标准的远程主机访问的协议。所有对集群的管理都要使用SSH,因此对SSH的配置要格外留神。

总是使用生产级别的SSH认证方式

SSH支持相当多的认证方式。只有两种我认为是可以在生产中使用的:

  • 高强度公钥私钥对(比如用RSA-1024)

  • Kerberos

高强度公钥私钥因为配置方便,用得更广泛。而Kerberos需要比较复杂的配置,一般常见于大型企业内部。

不要使用任何基于密码的认证方式。如果你用了密码就要记住,为了记住这个密码一定是有某个含义的,这就为字典攻击提供了条件。并且密码在网络上传输也是非常不安全的。反复输入密码会进一步增加密码被记录的概率。记得,你和服务器之间隔着互联网,你永远不知道有谁在中间。

2015年已经有消息报道RSA-1024可以通过暴力破解,但是耗费了相当大的计算资源。目前看,对于小公司RSA-1024还是安全的。但是你可以轻易地改用RSA-2048来产生公钥私钥对,指数级提高破解的难度。

RSA-1024的意思是用RSA算法产生长度为1024bit的公钥私钥对。越长的公钥私钥对越难被暴力破解。破解RSA-2048比RSA-1024需要的计算量大概大2^32倍。详情见这里

作为入口要定时更换认证key

如果是采用公钥私钥对作为SSH的认证,建议每个季度/每半年更换一次公钥私钥对。如如果采用Kerberos作为SSH的认证,建议每个季度/每半年换一次密码。之所以这样做是因为,这个更换的周期会远远小于常规暴力破解的时间。

访问生产资源时总是经过跳板机

也许你有很多服务器主机,但是如果运维资源部不足,没法很好的挨个配置主机的SSH端口设置,可以只开一台机器的SSH端口到外网,允许远程访问。这台对外网打开SSH的机器俗称“跳板机“。

为什么使用跳板机呢?这是因为可以在一台机器上做所有的安全防护配置。在公司过规模小的时候,一个人就可以手工把所有的访问权限在这一台机器上搞了。

利用跳板机:

  • 可以使用SSH的ProxyCommand。它可以让你访问远程主机时必须经过跳板机。这样整个集群只需要在跳板机上开到外网的SSH端口了。

  • 可以使用SSH的端口转发(Local Port Forwarding和Remote Port Forwarding)。这个功能可以允许你用SSH包装其他协议的数据,于是你可以经过跳板机的SSH端口访问其他主机的mysql、redis、mongodb……

    关于端口转发,这里推荐一个特别好的工具叫做SSL Tunnel Manager

当然,成熟的技术团队中,除了Lead、DBA和Ops,其他人不应该有权限访问生产服务。要做到这一点需要补充很多基础设施(比如带有Audit和ACL的生产数据库查询、比较方便的查询生产服务的log)。本文主要说小团队的低成本的事情,就不展开了。

确保你的软件源安全可靠

也许很多人对2015年的XCodeGhost不陌生。一些开发人员通过非官方渠道下载了XCode开发App。其中携带的被恶意篡改的基础库和App一起被打包,发布,最终安装在用户的设备上。这个问题可不一定只发生在XCode上。

每天开发者build程序都要使用各种开发工具,从外网各个地方下各种代码包。怎么确保这些东西就不出问题?最基础的防护是:总是从软件提供的官方渠道下载。就算再慢,被墙,也要想办法。如果技术手段无法约束,就必须行政手段强行禁止国内的各种下载网站下开发软件。

但如果访问这官方服务时断时续,或者比较浪费带宽(带宽费用相对比较贵),就要考虑自建“镜像”。像Artifactory就是很好的工具,可以充当内网的maven镜像库。

关注入口相关程序的漏洞

网络请求从连接到被执行,需要经过

  • 硬件(固件)

  • 操作系统

  • 系统库(比如openssl)

  • 程序库(比如jdk和依赖的各种jar)

  • 你的程序

时刻留意这个链条上的漏洞信息(新闻/社交网站讨论等),尤其是你开放的端口的对应服务的漏洞(比如开了443要特别留意操作系统、openssl和nginx的漏洞)。大多数时候漏洞比较偏门,或者说只有学术研究价值,这种可以忽略。但如果发现有漏洞的讨论已经非常普遍,就说明这个漏洞的影响相当大,并且非常容易被利用,抓紧时间升级和修复。

如果你用的是云服务,一般厂商都会有对受影响设施升级的公告,可能会造成停服务。请时刻留意。

管好你的秘钥

用了很强的认证方式后,还要记得好好保管。要是不注意,自己把私钥泄露到了公开的地方,再强的算法也保护不了你。任何情况下不要在网络上传递秘钥。如果要传递给别人,请用纸和笔。

此外,所有的私钥,密码最终都会记录在你自己的电脑上。所以如果你去上个厕所,别人偷偷跑过来从你的没锁的电脑上拿到私密的信息,那么以上所有的防护就都没有用了。因此,离开座位时请总是锁上你的屏幕

如果用Mac,推荐“触发角”功能。配置好后,鼠标一推就锁屏了。

总结

做到本文所说的所有策略,其实并不能保证绝对的安全。并且还有许多安全问题本文并没有考虑,比如注入攻击,CRSF,带有密码的服务配置,内网服务API的ACL,DDoS,社工学骗管理密码,短信炸弹等。

但是按照本文做了,你的服务器绝不会被攻击者以毫无成本的扫描直接攻破。攻击者必须针对你做定制的攻击方案才有可能成功。这会极大的提高攻击成本。如果你的公司还是个不起眼的小公司,那么基本上不会招眼——太不划算了。

值得注意的是,初创公司就算再怎么预算紧张,也一定要有人来负责运维。就算是开发顶一下也好,兼职也好,但机器不能没人管,不管是自建集群还是云服务。只有这个人存在,上面说的这些事情才有指望可以做好。

随着业务的扩大,服务商业价值增加,随之而来的就是更多的关注和更多的有针对性的攻击的风险。这时候,也许公司已经可以雇得起一个专心做安全的团队,购买防护软件/硬件,或者可以找到一个靠谱的安全领域的合作机构,来处理更复杂的安全攻击。

祝好运!