使用 Identity-Aware Proxy 設定情境感知存取權

本指南說明如何使用存取層級和 Identity and Access Management (IAM) 條件架構,擴充 Identity-Aware Proxy (IAP) 存取權政策。 存取層級可根據 IP 位址和使用者裝置屬性,限制資源存取權。IAM 條件可根據網址主機、路徑、日期和時間限制存取權。

例如,根據政策設定,您的敏感應用程式可以執行下列操作:

  • 在所有員工都使用公司網路中受信任的公司裝置時,授予這些員工存取權。
  • 在遠端存取群組中的員工使用任何網路中受信任的公司裝置,且這些裝置擁有安全密碼與最新修補程式等級時,授予這些員工存取權。
  • 如果網址路徑開頭為 /admin,則僅授予「Privileged Access」(特殊權限存取) 群組中的員工存取權。

事前準備

在您開始之前,您需要擁有下列項目:

  • 要新增個人或群組存取權的受 IAP 保護應用程式。
  • 您要授予存取權的使用者或群組名稱。

設定存取層級

如要根據 IP 位址或使用者裝置屬性限制存取權,請建立存取層級。部分屬性 (例如裝置屬性) 需要 Chrome Enterprise 進階版授權。只有在設定存取層級時,系統才會驗證授權,不會影響執行階段存取權。如要瞭解如何建立存取層級,請參閱 Access Context Manager 指南。 IAP 會使用存取層級名稱,將其與受 IAP 保護的應用程式建立關聯。

IAP 不支援使用範圍政策。存取層級必須在組織存取權政策中設定。詳情請參閱「建立存取權政策」。

編輯 IAM 政策

受 IAP 保護的應用程式具有 IAM 政策,可將 IAP 角色繫結至應用程式。

在 IAM 政策中新增 IAM 條件繫結,即可根據要求屬性進一步限制資源存取權。這些要求屬性包括:

  • 存取層級
  • URL 主機/路徑
  • 日期/時間

請注意,與 IAM 條件繫結中指定的 request.host 和 request.path 相比,要求值必須完全相同。舉例來說,如果您限制存取開頭為 /internal admin 的路徑,使用者可以前往 /internal%20admin 略過限制。如要進一步瞭解主機名稱和路徑條件,請參閱「使用主機名稱和路徑條件」。

請按照下列程序,在 IAM 政策中新增及編輯條件繫結。

控制台

如要使用 Google Cloud 控制台新增條件繫結,請按照下列步驟操作:

  1. 前往 IAP 管理員頁面。

    前往 IAP 管理員頁面

  2. 找出要更新 IAM 權限的資源,然後勾選旁邊的核取方塊。

  3. 在右側的「資訊面板」中,按一下「新增主體」。

  4. 在「New principal」(新增主體) 方塊中,輸入要指派角色的主體。

  5. 在「請選擇角色」下拉式選單中,選取「受 IAP 保護的網頁應用程式使用者」角色,並指定主體必須符合哪些存取層級條件,才能存取資源。

    • 如要指定現有的存取層級,請從「存取層級」下拉式選單中選取。您必須選取「受 IAP 保護的網頁應用程式使用者」角色,並具備組織層級權限,才能查看現有的存取層級。您必須獲派下列其中一個角色:
      • Access Context Manager 管理員
      • Access Context Manager 編輯者
      • Access Context Manager 讀取者
    • 如要建立及管理存取層級,請使用 Access Context Manager。
  6. 如要為主體新增更多角色,請按一下「Add another role」(新增其他角色)。

  7. 新增完角色之後,點選 [Save] (儲存)。

    現在,您已將條件繫結新增至資源。

如要移除條件繫結,請執行下列操作:

  1. 前往 IAP 管理員頁面。

    前往 IAP 管理員頁面

  2. 找出要移除主體 IAM 角色的資源,然後勾選旁邊的核取方塊。

  3. 在右側的「資訊面板」,點選「角色 / 主體」下方要從主體移除的角色。

  4. 按一下主體旁的「移除」。

  5. 在隨即顯示的「Remove role from principal」(移除主體的角色) 對話方塊中,按一下「Remove」(移除)。如要從所選資源的主體中移除所有非繼承角色,請先勾選核取方塊,再按一下「移除」。

gcloud

目前您只能使用 gcloud 工具設定專案層級條件繫結。

如要設定條件式繫結,請按照下列程序編輯專案的 policy.yaml 檔案:

  1. 使用下列 gcloud 指令,開啟應用程式的 IAM 政策:

    gcloud iap web get-iam-policy --project=PROJECT_ID > policy.yaml

  2. 編輯 policy.yaml 檔案,指定下列項目:

    • 要套用 IAM 條件的使用者和群組。
    • iap.httpsResourceAccessor 角色,可授予資源存取權。
    • IAM 條件。

      下列程式碼片段顯示僅指定一個屬性的 IAM 條件。如果符合 ACCESS_LEVEL_NAME 存取層級規定,且資源網址路徑開頭為 /,這項條件就會授予使用者和群組存取權。

    bindings:
    ...
      - members:
        - group:EXAMPLE_GROUP@GOOGLE.COM
        - user:EXAMPLE_USER@GOOGLE.COM
        role: roles/iap.httpsResourceAccessor
        condition:
                  expression: "accessPolicies/ORGANIZATION_NUMBER/accessLevels/ACCESS_LEVEL_NAME" in
                              request.auth.access_levels && request.path.startsWith("/")
                  title: CONDITION_TITLE
    ...

  3. 使用 set-iam-policy 指令將政策繫結至應用程式。

    gcloud iap web set-iam-policy --project=PROJECT_ID policy.yaml

您的 IAM 政策現在包含條件式繫結。

API

如要編輯應用程式的 policy.json 檔案,請按照下列步驟操作 (視應用程式類型而定)。如要進一步瞭解如何使用 IAM API 管理存取權政策,請參閱「管理受 IAP 保護資源的存取權」。

執行下列應用程式專屬 API 步驟前,請先匯出下列變數:

 export PROJECT_NUM=PROJECT_NUMBER
 export IAP_BASE_URL=https://iap.googleapis.com/v1/projects/${PROJECT_NUM}/iap_web
 # Replace POLICY_FILE.JSON with the name of JSON file to use for setIamPolicy
 export JSON_NEW_POLICY=POLICY_FILE.JSON
 

### App Engine

 1. Export the following App Engine variables:
 <pre class="devsite-click-to-copy prettyprint lang-html" suppresswarning="suppresswarning">
 \# The APP_ID is usually the project ID
 export GAE_APP_ID=<var>APP_ID</var>
 export GAE_BASE_URL=${IAP_BASE_URL}/appengine-${GAE_APP_ID}</pre>

 1. Get the IAM policy for the App Engine app using the `getIamPolicy` method. The empty data bit at the end turns the `curl` request into POST instead of GET.
curl -i -H "Authentication: Bearer $(gcloud auth print-access-token)" \\
    ${GAE_BASE_URL}/:getIamPolicy -d ''
1. 將 IAM 條件繫結新增至 IAM 政策 JSON 檔案。 以下是編輯過的 `policy.json` 檔案範例,可將 `iap.httpsResourceAccessor` 角色繫結至兩位使用者,授予他們受 IAP 保護資源的存取權。系統已新增 IAM 條件,只有在符合 ACCESS_LEVEL_NAME 存取層級規定,且資源網址路徑開頭為「/」時,才會授予資源存取權。每個繫結只能有一個條件。

**policy.json 檔案範例**
{
"policy": {
  "bindings": [
        {
          "role": "roles/iap.httpsResourceAccessor",
          "members": [
              "group:EXAMPLE_GROUP@GOOGLE.COM",
              "user:EXAMPLE_USER@GOOGLE.COM"
          ],
          "condition": {
            "expression": "\"accessPolicies/ORGANIZATION_NUMBER/accessLevels/ACCESS_LEVEL_NAME\" in request.auth.access_levels && request.path.startsWith(\"/\")",
            "title": "CONDITION_NAME"
          }
        }
        ]
  }
}
1. 使用 `setIamPolicy` 方法設定新的 `policy.json` 檔案。
 curl -i -H "Authentication: Bearer $(gcloud auth print-access-token)" \\
     ${GAE_BASE_URL}:setIamPolicy -d @${JSON_NEW_POLICY}

#### App Engine 服務和版本

 You can also update the IAM policy of a App Engine
 service, all versions, or a specific version of a service. To do this for a specific version of a service:

 1. Export the following additional variables.

    export GAE_SERVICE=SERVICE_NAME
    export GAE_VERSION=VERSION_NAME
    
1. 更新匯出的 GAE_BASE_URL 變數。
export GAE_BASE_URL=${IAP_BASE_URL}/appengine-${GAE_APP_ID}/services/${GAE_SERVICE}/versions/${GAE_VERSION}
1. 使用上述 getIamPolicy 和 setIamPolicy 指令,取得及設定版本的 IAM 政策。

### GKE 和 Compute Engine

1. 匯出後端服務的專案 ID。
     export BACKEND_SERVICE_NAME=BACKEND_SERVICE_NAME

 2. Get the IAM policy for the Compute Engine app using the `getIamPolicy` method. The empty data bit at the end turns the `curl` request into POST instead of GET.
 <pre class="devsite-click-to-copy prettyprint lang-html" suppresswarning="suppresswarning">
 curl -i -H "Authentication: Bearer $(gcloud auth print-access-token)" \\
     ${IAP_BASE_URL}/compute/services/${BACKEND_SERVICE_NAME}:getIamPolicy \\
     -d ''</pre>
 3. Add your IAM conditional binding to the IAM policy JSON file.
    The following is an example of an edited `policy.json` file that binds the
    `iap.httpsResourceAccessor` role to two users, granting them access to the IAP-secured resources. An IAM
    condition has been added to grant them access to the resources only if the <var>ACCESS_LEVEL_NAME</var> access level requirement is met and the resource URL path starts with `/`.
    Each binding can have only one condition.

    <br/>**Example policy.json file**
{
  "policy": {
    "bindings": [
      {
        "role": "roles/iap.httpsResourceAccessor",
        "members": [
          "group:EXAMPLE_GROUP@GOOGLE.COM",
          "user:EXAMPLE_USER@GOOGLE.COM"
        ],
        "condition": {
          "expression": "\"accessPolicies/ORGANIZATION_NUMBER/accessLevels/ACCESS_LEVEL_NAME\" in request.auth.access_levels && request.path.startsWith(\"/\")",
          "title": "CONDITION_NAME"
        }
      }
    ]
  }
}
4. 使用 `setIamPolicy` 方法設定新的 `policy.json` 檔案。
     curl -i -H "Content-Type:application/json" \\
             -H "Authentication: Bearer $(gcloud auth print-access-token)" \\
             ${IAP_BASE_URL}/compute/services/${BACKEND_SERVICE_NAME}:setIamPolicy \\
             -d @${JSON_NEW_POLICY}

使用主機名稱和路徑條件

您可以使用要求網址的主機名稱和路徑,保護應用程式的存取權。舉例來說,如果網址路徑開頭為 /admin,則可使用 request.path.startsWith IAM 條件,僅向「Privileged Access」群組中的員工授予存取權。

如要進一步瞭解主機名稱和路徑條件的使用方式,請參閱「要求屬性」一文。

字串正規化

網址有主機名稱和路徑。舉例來說,網址 https://sheets.google.com/create?query=param 的主機名稱為 sheets.google.com,路徑為 /create。

後端可以透過不同方式解讀主機名稱和路徑。為避免混淆,IAP 在檢查政策時會將主機名稱和路徑字串正規化。

如果要求含有非標準化路徑,IAP 會執行兩項政策檢查。如果非正規化路徑通過政策檢查,IAP 會將路徑正規化,並執行第二次政策檢查。非正規化和正規化後的路徑都通過政策檢查,系統才會授予存取權。

舉例來說,如果要求的路徑為 /internal;some_param/admin,IAP 會先對非正規化路徑 (/internal) 執行政策檢查。如果通過,IAP 會對正規化路徑 (/internal/admin) 執行第二次政策檢查。

主機名稱

主機名稱將依據以下標準來正規化:

  • 移除結尾的句點 (.)
  • 將字元轉換成小寫字元
  • 轉換成 ASCII

包含非 ASCII 字元的主機名稱將進一步透過 Punycode 編碼來正規化。您必須使用 Punycode 來編碼主機名稱字串,以便進行比對。

如要透過 Punycode 來編碼您的主機名稱字串,請使用 Punycoder 這類轉換器。

以下是正規化主機名稱範例:

  • FOO.com 已正規化為 foo.com
  • café.fr 已正規化為 xn--caf-dma.fr

路徑

路徑將依據以下標準來正規化:

  • 移除路徑參數
  • 移除絕對等值的相對路徑

路徑參數包含從 ; 到下一個 / 或路徑結尾的所有字元。

如果要求的路徑開頭為 ..;,系統會視為無效。例如,/..;bar/ 和 /bar/..;/ 會傳回 HTTP 400: Bad Request 錯誤。

以下是正規化路經範例:

  • /internal;some_param/admin 已正規化為 /internal/admin
  • /a/../b正規化為 /b
  • /bar;param1/baz;baz;param2正規化為 /bar/baz

子網域結尾

設為 request.host.endsWith("google.com") 的政策會同時比對 sub_domain.google.com 和 testgoogle.com。如果目標是將政策限制在所有結尾為 google.com 的子網域,請將政策設為 request.host.endsWith(".google.com")。

請注意,如果將政策設為 request.host.endsWith(".google.com"),則會與 sub_domain.google.com 相符,但由於額外的 .,因此不會與 google.com 相符。

Cloud 稽核記錄和存取層級

為受 IAP 保護的專案啟用 Cloud 稽核記錄,即可查看授權和未授權的存取要求。如要查看要求和要求者符合的所有存取層級,請完成下列步驟:

  1. 前往 Google Cloud 控制台,查看專案的 記錄檔探索工具。
    前往記錄頁面
  2. 在「resource selector」(資源選取器) 下拉式選單中,選取資源。 受 IAP 保護的 HTTPS 資源位於「App Engine Application」(App Engine 應用程式) 和「Compute Engine Backend Service」(Compute Engine 後端服務) 下方。 受 IAP 保護的 SSH 和 TCP 資源位於「Compute Engine VM instance」(Compute Engine VM 執行個體) 下方。
  3. 在「logs type」(記錄類型) 下拉式選單中,選取「data_access」。
    • 只有在您為 IAP 啟用 Cloud 稽核記錄後,資源有流量時,才會顯示 data_access 記錄類型。
  4. 按一下要查看的存取日期和時間,展開詳細資料。
    • 已授權存取權會顯示藍色 i 圖示。
    • 未經授權的存取權會顯示橘色 !! 圖示。
  5. 如要查看要求者符合的存取層級,請按一下展開各個部分,直到看到「protoPayload」>「requestMetadata」>「requestAttributes」>「auth」>「accessLevels」。

請注意,查看要求時,系統會顯示使用者符合的所有存取層級,包括存取要求時不需要的存取層級。查看未經授權的要求,並不會指出未符合哪些存取層級。判斷方式是比較資源條件與要求中顯示的存取層級。

如要進一步瞭解記錄,請參閱 Cloud 稽核記錄指南。