AWS 使用tag進行精細權限控制

AWS一個賬號下面可以通過IAM創建多個用戶,但默認情況下,資源是沒有用戶屬性的,一個賬號下的資源,只要用戶有這種資源的操作權限,那麼不過是你自己創建的還是其他用戶創建的,你都可以操作。

但在客戶的實際使用場景中,有時需要隔離各用戶之間的資源。按照AWS的建議,那你需要創建不同的賬號,比如你有開發測試資源環境,還有生產資源環境,那麼你需要創建兩個賬號,但創建兩個賬號,在查詢費用的時候不方便,AWS提供consolidateBill的授權方案,可以合併賬單。

所以AWS官方是沒有一套簡單的方法可以實現我們想要的效果的。

具體可以參考AWS開發者論壇很stackoverflow上的一些帖子

https://forums.aws.amazon.com/message.jspa?messageID=346577

https://forums.aws.amazon.com/thread.jspa?threadID=187874

https://stackoverflow.com/questions/25909203/how-to-differentiate-between-different-aws-environments-dev-test-stage-prod

 

那在同一個賬號下,能不能做到不同用戶的資源隔離呢。

通過IAM策略的靈活配置和aws全局變量,可以部分滿足一些場景的需求。

   

在看場景之前,我們先了解一下,AWS IAM的授權機制:

AWS是通過策略來定義權限,再將這些策略授予用戶、組或者角色,使用戶、組或者角色擁有相應的權限。

IAM 策略是包含一個或多個語句的JSON 文檔。每個語句的結構如下:

{

  "Statement":[{

   "Effect":"effect",

   "Action":"action",

   "Resource":"arn",

    "Condition":{

      "condition":{

       "key":"value"

        }

      }

    }

  ]

}

 

組成語句的各個元素如下:

Effect effect 可以是 Allow Deny。默認情況下 IAM 用戶沒有使用資源和 API 操作的權限,因此,所有請求均會被拒絕。顯式允許將覆蓋默認規則。顯式拒絕將覆蓋任何允許。

Actionaction 是對其授予或拒絕權限的特定 API 操作。

Resource操作影響的資源。有些 Amazon EC2 API 操作允許您在策略中包括該操作可以創建或修改的特定資源。要在語句中指定資源,您需要使用其 Amazon 資源名稱 (ARN)。如果 API 操作不支持 ARN,請使用 * 通配符指定操作可以影響所有資源。

Condition條件是可選的。它們可以用於控制策略生效的條件。

由此可以看出,

第一、要想進行資源隔離,resource是關鍵。但問題來了,就如上面所說,並不是所有操作都支持資源級權限。

第二、即使有些操作是支持資源級權限的,那麼怎麼唯一標示一個資源或一批資源呢?AWS使用Amazon 資源名稱 (ARN)來標示資源。

Amazon Elastic Compute Cloud (Amazon EC2) ARN 樣例

arn:aws:ec2:region:account-id:customer-gateway/cgw-id

arn:aws:ec2:region:account_id:dedicated-host/host_id

arn:aws:ec2:region:account-id:dhcp-options/dhcp-options-id

arn:aws:ec2:region::image/image-id

arn:aws:ec2:region:account-id:instance/instance-id

arn:aws:iam::account:instance-profile/instance-profile-name

arn:aws:ec2:region:account-id:internet-gateway/igw-id

arn:aws:ec2:region:account-id:key-pair/key-pair-name

arn:aws:ec2:region:account-id:network-acl/nacl-id

arn:aws:ec2:region:account-id:network-interface/eni-id

arn:aws:ec2:region:account-id:placement-group/placement-group-name

arn:aws:ec2:region:account-id:route-table/route-table-id

arn:aws:ec2:region:account-id:security-group/security-group-id

arn:aws:ec2:region:account-id:snapshot/snapshot-id

arn:aws:ec2:region:account-id:subnet/subnet-id

arn:aws:ec2:region:account-id:volume/volume-id

arn:aws:ec2:region:account-id:vpc/vpc-id

arn:aws:ec2:region:account-id:vpc-peering-connection/vpc-peering-connection-id

arn:aws:ec2:region:account-id:***-connection/***-id

arn:aws:ec2:region:account-id:***-gateway/vgw-id

 

這裏我們看到,大部分資源是使用ID來唯一標示的,但是ID是創建資源時,由AWS自動生成的,沒什麼可以利用的規律。這個問題就有點棘手了。

 

下面我們針對幾種場景來試着解決一下上面提出的問題。

 

  • VPC隔離

目標:每個用戶創建、管理並控制自己的VPC

我們先看一下VPC的操作(僅限VPC,暫不包括VPC下的組件):

DescribeVpcsCreateVpcDeleteVpcModifyVpcAttribute

首先所有describe操作都不支持資源級權限,所以想要互相看不見暫時辦不到。

很不幸,上面所有這些操作都不支持資源級權限。

所以,我建議,VPC由管理員(有權限的用戶)統一管理,其他用戶只讀。

VPC中大部分組件的刪除操作可以支持資源級權限。但如上面所說,大部分資源都是以ID來唯一標示的,VPC下面的組件有很多,而且是動態的,隨時增加,那有沒有辦法可以標示出這些組件是屬於我的呢。

答案是肯定的,AWS提供Tag來給資源打標籤,我們可以規定大家按一定的規則來給資源加上Tag,比如加上(creator:username)。那麼在進行VPC組件刪除操作的時候就可以通過condition條件ec2:ResourceTag/tag-key進行控制。但這方案也有一定缺陷,因爲Tag是會被任何有權限的用戶修改的,別的用戶改了這個資源的Tag,或者你自己改了這個Tag,那麼你就不能繼續限制對它的操作了。

subnet子網的刪除操作是不支持資源級權限的。同樣建議子網定義由專門的網絡管理員操作。

 

  • 只允許客戶在指定的VPC中創建和管理虛機

還是一樣,先來看一下有關虛機的操作:

RunInstancesStartInstancesRebootInstancesStopInstancesTerminateInstances

1)創建虛機:

RunInstances 是支持資源級權限的,它支持:

Image:使用什麼樣的鏡像

Key pair:使用哪個key pair

Security group:使用哪個安全組

Subnet:使用哪個子網

這裏沒有VPC,但是有subnet,我們再看一下subnet支持的condition

ec2:AvailabilityZone

ec2:Region

ec2:ResourceTag/tag-key

ec2:Vpc

這裏是有VPC的。所以在指定的VPC中創建虛機是可以的。

2)管理虛機

StartInstancesRebootInstancesStopInstancesTerminateInstances

這些操作是不能限定VPC的,可以限定單臺虛機資源,但這樣就達不到我們想要的效果。還好這些操作的condition條件都有ec2:ResourceTag/tag-key。同樣使用和上面相同的方法,對我們自己的虛機打上我們的Tag,我們就可以限定只有我自己才能操作這些我打了tag的虛機。

 

  • 一個大問題

雖然我們可以給資源打tag,但是正如上面所說,有一個大問題,我們怎麼阻止其他用戶修改我的tag呢?

我們先來看一下ec2Tag的相關操作:

CreateTagsDeleteTags。這兩個操作都是支持資源級權限的。我們是否也可以使用ec2:ResourceTag/tag-key來隔離各個用戶的操作呢。看上去好像可以。但這裏有一個前提,是你先要有一個tag-key,例如creator:username。那麼創建這個tag的時候你是不能用conditionec2:ResourceTag/creator username的,因爲初始情況,是一個tag都沒有的,所以加了這個condition,你就無法創建tag。那麼只能不加,不加的話,你就無法限制其他用戶對tag的修改。但DeleteTags你可以使用這種方法,來限制其他用戶的刪除。

看到這裏其實感覺有點悖論,是先有雞還是先有蛋的問題。或者把create modify操作分開的話,也可以部分解決這個問題,但不幸的是這兩個操作也不是分開的。

 

但我們還是找到了一種稍微折中一點的辦法。放棄一些tag使用的功能,換來這個問題的解決。思路就是做到只能創建,不能修改。AWS CreateTags 創建Tag是支持一種condition ec2:CreateAction,可以限定只有在虛機創建的時候可以創建tag,創建完以後,你就不能修改和新增其他tag了。這樣通過控制tag的使用,達到了管理tag的效果。

 

寫到這裏,主要場景和解題思路已經講完了。

下面我們來實操一下。

 

  • 創建兩個用戶,不要分配權限。

  • 用戶管理員創建兩個VPC,在每個VPC裏創建一個子網。

  • 下面來創建策略

{

    "Version":"2012-10-17",

    "Statement": [

        {

            //基本ec2查詢操作和一些創建虛機必要的,但不涉及資源權限的操作

            "Effect":"Allow",

            "Action": [

                "ec2:Describe*",

                "ec2:AttachVolume",

                "ec2:CreateVolume",

               "ec2:AttachNetworkInterface",

                "ec2:DetachVolume",

                "ec2:DeleteVolume"

            ],

            "Resource": "*"

        },

        {

        //限定只能在虛機創建時,創建tag

            "Effect":"Allow",

            "Action": [

                "ec2:CreateTags"

            ],

            "Resource":"arn:aws:ec2: region:account:*/*",

            "Condition": {

                "StringEquals": {

                    "ec2:CreateAction": [

                       "RunInstances",

                       "CreateVolume"

                    ]

                }

            }

        },

 

        {

          //限定當該虛機的creator標籤等於當前用戶時,才能進行該虛機的操作。

            "Effect":"Allow",

            "Action": [

               "ec2:RebootInstances",

                "ec2:StartInstances",

                "ec2:StopInstances",

               "ec2:TerminateInstances"

            ],

            "Condition": {

                "StringEquals": {

                   "ec2:ResourceTag/creator": "${aws:username}"

                }

            },

            "Resource": "*"

        },

        {

         //限定當前用戶只能在指定的vpc中啓動虛機

            "Effect":"Allow",

            "Action":"ec2:RunInstances",

            "Resource":"arn:aws:ec2: region:account:subnet/*",

            "Condition": {

                "StringEquals": {

                    "ec2:Vpc":"arn:aws:ec2: region:account:vpc/vpc-id"

                }

            }

       },

        {

        //其他必要的虛機啓動資源授權

            "Effect":"Allow",

            "Action":"ec2:RunInstances",

            "Resource": [

               "arn:aws:ec2:eu-central-1::image/ami-*",

               "arn:aws:ec2:eu-central-1:286883986851:volume/*",

               "arn:aws:ec2:eu-central-1:286883986851:network-interface/*",

               "arn:aws:ec2:eu-central-1:286883986851:key-pair/*",

               "arn:aws:ec2:eu-central-1:286883986851:security-group/*"

            ]

        }

    ]

}

  • 更換vpc-id,創建另一個策略。

  • 將兩個策略分別分配給兩個用戶。

然後就可以測試效果了。大家自己動動手吧。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章