iT邦幫忙

2026 iThome 鐵人賽

DAY 7
0
IT Operation

從前後端踏上 AWS 雲端架構勇者之路系列 第 7

把允許(allow)加在最後有用嗎?移出群組就沒權限了嗎?

  • 分享至 

  • xImage
  •  

今天週末來聊個輕鬆的小技巧,也是我之前犯過的錯 XD

前一天我們有聊到要改政策的權限,假設我們在前面有加了一條「拒絕列出使用者」。但之後進來的新人不想動別人寫的東西,就在最後面又加一條「允許列出使用者」:

先複習一下 Day 06 教的政策長相,一份權限政策裡面是一條一條的規則,每條規則主要就三個欄位:

欄位 意思 這篇會看到的值
Effect 這條規則的效果:是放行還是擋下 Allow(允許)或 Deny(拒絕)
Action 管哪一個動作,寫法是「服務:動作」 iam:ListUsers,IAM 這個服務的「列出使用者」
Resource 對哪些東西 *,就是全部

JSON 裡還會看到三個包裝用的欄位:Version 是語法版本、Statement 是裝規則的清單、Sid 是這條規則的名字(選填,給自己看的,改了不影響效果)

念出來就像是:「允許或拒絕(Effect)做某個動作(Action)對某些東西(Resource)」

Allowiam:ListUsers*,就是「允許列出所有使用者」;把 Allow 換成 Deny,就變成「拒絕列出所有使用者」

回到那份政策。裡面同一個動作 iam:ListUsers 同時有一條 Allow(允許)、一條 Deny(拒絕)

這裡舉出兩個版本,唯一的差別是這兩條規則誰在前、誰在後:

順序 版本甲 版本乙
規則 1 允許 iam:ListUsers 拒絕 iam:ListUsers
規則 2 拒絕 iam:ListUsers 允許 iam:ListUsers

版本甲:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowList",
      "Effect": "Allow",
      "Action": "iam:ListUsers",
      "Resource": "*"
    },
    {
      "Sid": "DenyList",
      "Effect": "Deny",
      "Action": "iam:ListUsers",
      "Resource": "*"
    }
  ]
}

版本乙就是把兩條規則上下對調:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyList",
      "Effect": "Deny",
      "Action": "iam:ListUsers",
      "Resource": "*"
    },
    {
      "Sid": "AllowList",
      "Effect": "Allow",
      "Action": "iam:ListUsers",
      "Resource": "*"
    }
  ]
}

寫過前端可能就會直接心裡 OS:後面的蓋掉前面的啊,CSS 是這樣、變數重新賦值也是這樣

但 AWS 不是這樣 XD

AWS 官方文件講得很清楚:

  • 預設全部拒絕(root 例外)
  • 要有一條明確的允許,動作才會過
  • 明確的拒絕會蓋過明確的允許

所以每次你點一個東西,AWS 判斷的順序是這樣:

一個動作准不准,AWS 這樣判:先看有任何一條明確拒絕嗎?有就拒絕;沒有再看有任何一條允許嗎?有就允許;兩個都沒有也是拒絕,沒寫到預設不給;底下註明政策裡寫的先後順序不重要

  1. 先找有沒有任何一條明確拒絕,找到就直接拒絕,後面不看了
  2. 沒有拒絕,再找有沒有任何一條允許,有就過
  3. 兩個都沒有,也是拒絕,這就是 Day 06 說的「沒寫到,就預設不給」

回到那兩個版本:甲和乙都有一條拒絕 iam:ListUsers,第一步就被抓到,兩個版本都拒絕。允許放前面放後面完全沒差

為什麼順序不重要?畢竟 AWS 不是從上往下讀到第一條就停

它是把這個人拿得到的每一份政策全部翻過一遍,先找有沒有拒絕;一條都沒有,才回頭找允許

兩個常見的錯誤名詞會是:

  • 明確拒絕:有人真的寫了一條 Deny 擋你。錯誤訊息會提到 explicit deny
  • 預設拒絕:根本沒有任何一條寫到這個動作。錯誤訊息 no identity-based policy allows(沒有任何一份掛在你身上的政策允許這個動作)

兩種都是被擋,但修法不一樣:前者要去找那條拒絕是誰寫的、為什麼寫;後者補一條允許就好

預設拒絕最常見的樣子是,一個人的政策只允許 iam:ListUsers,如果他好奇點進 EC2(AWS 租主機的服務)的頁面,就會被擋。沒有人擋他,是沒有人放行他。這時候去找「誰加了拒絕」是白找的,該確認的是「誰該幫他加允許,還是他本來就不該進去」

所以該做的不是在最後面加允許,而是回頭問那條拒絕是誰加的,以及為什麼加。要嘛拿掉它,要嘛這個人本來就不該列出使用者

權限是從哪裡來的?

剛剛說 AWS 判斷時會翻「這個人拿得到的每一份政策」,那一個人到底會從哪裡拿到政策?

我們來看一個人員調動的例子。小芸目前有兩份政策,名字分別叫 Lookup 和 Edit:

權限來源 掛在哪 允許什麼
Lookup 直接掛在小芸身上 iam:ListUsers 列出使用者
Edit 掛在 Editors 群組,小芸是成員 iam:UpdateUser 修改使用者

兩份政策都很短。Lookup 直接掛在小芸身上:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iam:ListUsers",
      "Resource": "*"
    }
  ]
}

Edit 掛在 Editors 群組上:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iam:UpdateUser",
      "Resource": "*"
    }
  ]
}

這次調動只做一件事:就是 把小芸移出 Editors 群組。兩份政策都沒有 Deny

小芸的權限從哪裡來:移出群組前,小芸身上直接掛 Lookup(允許列出使用者),同時在群組 Editors 裡拿到 Edit(允許修改使用者);移出群組後,到 Editors 的那條線斷掉,Edit 這條沒了,直接掛在身上的 Lookup 這條還在

所以移出群組之後:

  • Edit 那條來源沒了,小芸再做 iam:UpdateUser 會被拒絕,這拒絕是政策「沒寫到」那種拒絕
  • Lookup 是直接掛在她身上的,跟群組無關,iam:ListUsers 就照常運作~

這邊有幾個很常見的誤會,順手清一下:

  • 「群組叫 Editors,那她當然能修改」:群組名字不會給權限,掛在群組上的那份政策才會。名字叫什麼跟能做什麼是兩件事
  • 「直接掛在身上的政策比群組的大」:沒有誰比誰大哈哈,它們只是不同來源。判斷的時候全部一起翻出來確認
  • 「移出群組她的帳號會不會跟著消失?」:都不會哩,移出群組只動成員關係,帳號、密碼

這就是實務上最容易出包的地方:要拔一個人的權限,得把每個來源都拔掉。這也是為什麼 Day 06 建議政策盡量掛群組、不要直接掛人:來源比較,查得也清楚些~

小結

最後小結一下~

重點 記住這句
怎麼判斷政策權限 先找明確拒絕,有就擋;再找允許,有就過;都沒有也是擋
順序 政策裡允許、拒絕寫前寫後都一樣,拒絕永遠蓋過允許
兩種被擋 明確拒絕是有人寫了 Deny;預設拒絕是根本沒寫到
權限來源 直接掛在身上的+所在群組掛的,判斷時全部一起翻
拔權限 移出群組只斷那一個來源,身上直接掛的還在;要拔乾淨得每個來源都得拔

下次如果你聽到同事說「我加了一條允許在最後」、「他已經移出群組了」

你可以先問,這個人拿得到的政策,除了群組就沒其他來源哩?

希望這篇讓你看懂權限是怎麼算出來的,我們下篇見 :D


上一篇
MFA 過了卻 AccessDenied?權限到底要掛在哪裡
下一篇
你知道你上網有兩個 IP 嗎?進 AWS 前先搞懂家裡的網路
系列文
從前後端踏上 AWS 雲端架構勇者之路9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言