AWS 最佳实践
我是 AWS 的重度用户,重度到「饭可以一日不吃,AWS 不可一日不用」,每天我的例行工作就是「吃饭,睡觉,上 AWS」。纵观过去几年我在 Juniper 和 Tubi 的经验,我在 Arcblock 过去的一个月渐渐摸索出来一些使用 AWS 的最佳实践 —— 虽然这些实践的对象是 AWS,但也许对你使用其它云的姿势也有一些借鉴意义。
原则
首先,使用云服务,我们要定义一些基本的原则:
- R1. 安全性和易用性有不可调和的矛盾。我们不能牺牲安全性来获得易用性。因而,只能通过打造尽可能简单的工具在确保安全性的前提下,保持一定的易用性。
- R2. 所有资源,如无必要,不能拥有外部访问权限。
- R2. 测试账号和生产账号要完全隔离。测试账号作为一个沙箱,允许工程师做各种高风险的尝试。生产账号只能通过特定权限的脚本访问,将误操作的风险降到最低。
- R3. 不断培训整个团队,让大家降低对 Console 的依赖直到最终不使用 Console
实践
MFA
两步验证(Multi-Factor Authentication)必须在第一时间就使能。我们创建一个 IAM 用户,其能够访问的任何服务都有一个先决条件,必须使能两步验证。你可以为 IAM policy 里加入这样的条件:
{
"Condition": {
"Effect": "Allow",
"Action": [
"ec2:*",
"s3:*"
],
"Bool": {
"aws:MultiFactorAuthPresent": true
}
}
}
这样,工程师在访问 EC2 / S3 时,必须要有两步验证的信息。当然,你需要允许用户在没有两步验证的情况下添加两步验证的设备,否则就自己把自己将死了。
这样带来的问题是工程师使用起来会非常麻烦,尤其是通过 access key 访问 API 时,将会不胜其烦。为此我们可以封装一下 STS,每隔一天需要这么 run 一下,才能获得临时 session 级的权限:
Bastion / VPN server
我们行走江湖讲究一个「藏」字,你暴露出来的点越少,越安全。
Bastion / VPN server 都是用于访问内部资源的。内部的服务器你不想把某些接口暴露出来,比如 ssh,rpc 等,但无论是内部测试还是为了管理上的临时访问,都需要把这些接口暴露出来。这时候,有专门的跳板机,或者 VPN server 可以在安全和易用上面取得一些平衡。
为了进一步的安全,bastion / VPN server 还可以把 known port 迁移到其它 port 上面 —— 这样,scanner 无法简单通过端口扫描知道你的 bastion / VPN server 的存在。比如,SSH 不起在 22 端口,而是起在 9527 端口。
SSH
使用 SSH 访问一台服务器进行一些操作很多时候是必要的,然而,随着机器数量的增多,怎么管理 ssh key 就是一件头疼的事情 —— 用一个或者多个 ssh key 并将其私钥分享给整个 team 显然不是件安全的事情 —— 如果某个工程师离职怎么办?分享给他的 key 是否要作废?如果作废,已有那么多使用这个 key 的服务器怎么办?如果不作废,安全如何保障?
所以最好的办法是每个工程师都使用自己的 key,并不存在大家公用一个 key 的情况。当一台机器 provision 出来,为每个工程师创建账号并使能他们的 ssh public key。这样问题就来了,1) 从哪里找得到工程师的 ssh public key?2) 新来一个工程师怎么办?或者某个工程师离职怎么办?
对于 1),如果我们将用户和 IAM 关联起来,那么可以取到用户上传到 IAM 的 ssh key;对于 2) 当用户增减时,我们只需要增减每台机器上的用户即可,不会影响到其它人。
很多公司部署了 bastion server 来保护内部资源,然而 bastion server 和其它 server 使用了相同的 key。这就好比你把安全体系做得像俄罗斯套娃一样让人眼花缭乱,但层层递进的锁,都可以用同一把钥匙打开,这样是不安全的。
