Concept
IAM是AWS云平臺中負責身份認證,和權(quán)限控制的服務(wù)。AWS云雖然分了很多個區(qū)(Region),但IAM是Global,全局的。所以,它的數(shù)據(jù)和配置的更改,也是Eventually Consistent的。
Best Practices
在講IAM的權(quán)限控制是怎么工作之前,先強調(diào)兩個最重要的安全理念。
Grant Least Privilege
在AWS里面,每一個用戶默認都是沒有任何權(quán)限的。他甚至不能查看自己的密碼或access key,丟失了也只能重新生成。
Lock Away Your AWS Account Root User
AWS賬戶開通的時候,你的登錄郵箱和密碼,就成為了這個賬戶下的超級管理員,它默認是什么都可以干的。所以,和在Linux下不要濫用root一樣,不要用這個超級帳號做日常操作,而是創(chuàng)建一個有Full Administrator權(quán)限的用戶。
How It Works?
權(quán)限控制有兩個基本概念:
1.Authentication-確認是否為有效用戶,是否允許登錄/接入
2.Authorization-確認用戶當前請求的操作(讀寫資源),是否合法
所以,IAM最重要就是管理Identity,和控制Resource的操作。
Identity/Principal
從資源訪問的角度來看,使用AWS資源的其實不單單是具體的人,還可能是Application。所以,AWS里面的身份,分幾種:
·User
·Application
·Federated User
·Role
能在AWS IAM控制臺里創(chuàng)建的,只有User和Role。而User在創(chuàng)建的時候,可以指定它的訪問類型。是憑借用戶名密碼在Console登錄,還是使用Access Key ID及Secret通過API來訪問,還是兩者皆可。
要特別注意的是,User是直接操作AWS資源的用戶,而不是你自己開發(fā)并部署在AWS的系統(tǒng)里面的用戶。IAM的User是有數(shù)量限制的,最多5000個。
如果你開發(fā)的系統(tǒng)需要操作AWS資源,比如說上傳文件到S3,那你需要用的是Federated User。通過OpenID Connect(如Google/Facebook)或者SAML 2.0(如Microsoft AD),你的系統(tǒng)用戶可以在登錄后換取代表某個AWS Role的臨時token來訪問AWS資源。
Authentication
訪問和使用AWS資源有兩種方式,一種是通過頁面登錄,也就是Console。一種是通過AWS API,也就是接口,包括CLI,SDK或HTTPS請求。
IAM User在Console頁面登錄需要提供AWS帳號名,IAM User名和密碼。AWS帳號名是AWS云服務(wù)開通時,系統(tǒng)生成的一串數(shù)字,或者是你賦予的別名。它其實就是一個多租戶系統(tǒng)里面的租戶帳號。AWS還會為每個帳號提供一個獨特的登錄鏈接,比如我的測試帳號:https://kcawsfree.signin.aws.amazon.com/console。kcawsfree就是我?guī)ぬ柕膭e名。
而如果是使用API訪問AWS,我們是需要用IAM User的Access Key ID及Secret來為這個HTTP請求生成簽名的。為請求簽名,是大多數(shù)的API集成的一種安全性考量。微信,支付寶等平臺都這么做。為什么呢?
1.確認請求發(fā)起方是合法的,就是確保你就是你。
2.保護數(shù)據(jù)傳輸過程的安全,就是確保數(shù)據(jù)沒被篡改。
3.防止重放攻擊,就是確保一個請求不被多次使用,濫用或者冒用。
簽名需要根據(jù)什么信息生成呢?可以說是包含了請求唯一性的所有信息:
請求的接口版本號請求的操作是什么(Action)請求的日期所有請求的參數(shù)等
AWS的請求樣例:
https://iam.amazonaws.com/?Action=AddUserToGroup
&GroupName=Managers
&UserName=Bob
&Version=2010-05-08
&AUTHPARAMS
其實,如果你是使用AWS SDK或者CLI,它會根據(jù)你配置的Access Key自動簽名。只有當你自己發(fā)起一個HTTP請求的時候,才需要自己實現(xiàn)簽名的邏輯。
Authorization
所謂是否有足夠的權(quán)限,就是驗證以下三者在一個請求的場景下,是否被允許:
1.主體(Identity)
2.操作(Action)
3.資源(Resource)
AWS是通過策略(Policy)來定義權(quán)限(Permissions)的。最基本的策略有兩大類。一種是Identity-based policy,另一種是Resource-based policy。前一種掛在User/Role/Group上面,用以定義這些被掛載的主體,能對什么資源進行怎樣的操作。而后一種直接掛載在AWS資源上面,用以定義哪些主體可以對這個資源做什么樣的操作。
AWS Policy的Permissions定義,在內(nèi)部是通過一個JSON格式來表示的。我們來看一個樣例:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListAndDescribe",
"Effect": "Allow",
"Action": [
"dynamodb:List*",
"dynamodb:Describe*"
],
"Resource": "*"
},
{
"Sid": "SpecificTable",
"Effect": "Allow",
"Action": [
"dynamodb:BatchGet*",
"dynamodb:Get*",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:BatchWrite*",
"dynamodb:Delete*",
"dynamodb:Update*",
"dynamodb:PutItem"
],
"Resource": "arn:aws:dynamodb:*:*:table/MyTable"
},
{
"Sid": "AllowAllActionsForEC2",
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*"
},
{
"Sid": "DenyStopAndTerminateWhenMFAIsNotPresent",
"Effect": "Deny",
"Action": [
"ec2:StopInstances",
"ec2:TerminateInstances"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": false
}
}
}
]
}
這個策略控制了DynamoDB和EC2的訪問權(quán)限。它看起來很復雜,但其實結(jié)構(gòu)很清晰。這里面最主要的元素就是Effect,Action和Resource。它們確定了什么資源上的哪些操作,是被允許,還是禁止的。它們是AND的邏輯組合。
Statement里前兩個Permission,允許用戶獲取DynamoDB里面的資源信息,但是只有MyTable這個表能做寫操作。而后兩部分允許用戶對EC2做任何操作,但是停止和結(jié)束Instance則必須通過了MFA登錄認證后才可以。
Policy Evaluation Logic
一個用戶或者角色主體上,可以擁有多個不同的Policy。所以,Policy的權(quán)限驗證邏輯,可謂相當復雜。在講驗證流程前,我再重復一次AWS權(quán)限的設(shè)計原則,這對流程的理解很重要。
·如果有顯式的Deny,就禁止。
·Grant Least Privilege原則。如果沒有顯式賦予權(quán)限,也就是沒有任何Policy為請求的資源和操作定義了Allow權(quán)限,那這個主體就沒有權(quán)限(Implicit Deny)。
AWS對收到的操作請求,會根據(jù)以下的流程來判斷這個請求的主體是否有操作權(quán)限:
1.Deny evaluation
2.AWS Organizations service control policies(SCP)
3.Resource-based policies
4.IAM permissions boundaries
5.Session policies
6.Identity-based policies
第一步,首先把2至6里面的所有policy的顯式Deny拿出來。如果當前的請求屬于Deny的范圍,直接禁止操作。這個就是第一個原則。
第二步到第六步,是具體的policy。如果該主體有這個類型的policy存在,就按照第二個原則處理。如果沒有,跳到下一個policy類別的檢查。
那么多種的Policy類別,為什么是這個排列順序呢?我是這么理解的:
1.Organization SCP作為組織級別策略,優(yōu)先級最高。
2.Resource-based policy可以跨帳號賦予權(quán)限,級別比后面的高一些。
3.Permission Boundary的作用是提前為用戶定義一個最大的權(quán)限范圍,避免意外打開了權(quán)限的情況,所以比后面的級別要高。
4.Session policies是會話級別,允許臨時賦予權(quán)限,所以比Identity-based policies高。
5.Identity-based policies是最穩(wěn)定的,所以檢查放在最后。
不過,這里有一個特例,就是Resource-based policy。如果它是Implicit Deny的情況,還是會繼續(xù)后面的檢查,不會阻止。還有一個復雜的情況是關(guān)于Session policy的,這個就不在本文解釋了。
其實,即便邏輯復雜,判斷是否有權(quán)限還是可以簡單地總結(jié)為一句話:
只有具備顯式的Allow,并且沒有顯式的Deny,才有權(quán)限。
或者
如果沒有顯式的Allow,或者有顯式的Deny,就沒有權(quán)限。