安全性公告

我們會不定期發布與 Kubernetes Engine 有關的安全性公告,並在這裡提供所有 Google Kubernetes Engine 安全性公告的內容說明。

發現安全漏洞之後,我們通常會保密,直到相關單位能夠將安全漏洞解決為止。在這種情況下,只要保密規定尚未撤銷,GKE 的版本資訊都只會將漏洞稱為「安全性更新」。保密規定撤銷後,我們就會更新版本資訊,向使用者說明修補內容中解決的安全漏洞為何。

訂閱 GKE 安全性公告。 訂閱

2018 年 12 月 3 日

說明 嚴重性 附註

Kubernetes 最近發現新的安全性漏洞 CVE-2018-1002105,讓權限相對較低的使用者能略過 Kubelet API 的授權,進而針對叢集中任一節點的所有 Pod 進行任意的作業。詳情請參閱 Kubernetes 公告事項所有的 Google Kubernetes Engine (GKE) 主要執行個體都受這些安全漏洞的影響,我們已將叢集升級到最新的修補版本。您不需要採取任何動作。

我該怎麼做?

您不需要採取任何動作。GKE 主要執行個體已升級。

這項修補內容會在 GKE 1.9.7-gke.11、1.10.6-gke.11、1.10.7-gke.11、1.10.9-gke.5、1.11.2-gke.18 及更新的版本中提供。

這項修補內容解決了哪項安全漏洞?

這項修補內容解決了下列安全漏洞:

安全漏洞 CVE-2018-1002105 讓權限相對較低的使用者能略過 Kubelet API 的授權,這讓使用者有權發出可升級的權限提升要求,並對 Kubelet API 進行任意呼叫。這個安全漏洞在 Kubernetes 中的嚴重性為「重大」。有鑒於 GKE 實作上的某些細項能防堵未經驗證的權限提升路徑,這個安全漏洞的嚴重性為「高」。

CVE-2018-1002105

2018 年 11 月 13 日

說明

2018 年 11 月 16 日更新:我們已為所有可能受到影響的憑證完成撤銷與輪替作業,因此您無須採取任何進一步行動。

Google 日前在 Calico Container Network Interface (CNI) 外掛程式中發現一個問題。在特定設定中,這個外掛程式會記錄機密資訊。這個問題已列入 Tigera Technical Advisory 的追蹤清單,編號為 TTA-2018-001

  • 執行偵錯層級的記錄工作時,Calico CNI 外掛程式會將 Kubernetes API 的用戶端設定寫入記錄檔。
  • 如果 CNI 網路設定中已設定「k8s_auth_token」欄位,Calico CNI 會一併將 Kubernetes API 憑證寫入資訊層級的記錄檔。
  • 另外,系統在執行偵錯層級的記錄工作時,如果服務帳戶憑證已明確設定 (無論是在 Calico 讀取的 Calico 設定檔或 Calico 使用的環境變數中),Calico 元件 (calico/node、felix、CNI) 都會將這項資訊寫入記錄檔。

這些憑證具備下列權限:


bgpconfigurations.crd.projectcalico.org     [create get list update watch]
bgppeers.crd.projectcalico.org              [create get list update watch]
clusterinformations.crd.projectcalico.org   [create get list update watch]
felixconfigurations.crd.projectcalico.org   [create get list update watch]
globalbgpconfigs.crd.projectcalico.org      [create get list update watch]
globalfelixconfigs.crd.projectcalico.org    [create get list update watch]
globalnetworkpolicies.crd.projectcalico.org [create get list update watch]
globalnetworksets.crd.projectcalico.org     [create get list update watch]
hostendpoints.crd.projectcalico.org         [create get list update watch]
ippools.crd.projectcalico.org               [create get list update watch]
networkpolicies.crd.projectcalico.org       [create get list update watch]
nodes                                       [get list update watch]
pods                                        [get list watch patch]
namespaces                                  [get list watch]
networkpolicies.extensions                  [get list watch]
endpoints                                   [get]
services                                    [get]
pods/status                                 [update]
networkpolicies.networking.k8s.io           [watch list]
      

如果 Google Kubernetes Engine 叢集已啟用叢集網路政策和 Stackdriver Logging,就會將 Calico 服務帳戶憑證記錄至 Stackdriver,未啟用網路政策的叢集則不受影響。

我們已部署可遷移 Calico CNI 外掛程式的修正內容,使其僅會記錄警告層級的資訊並改用新的服務帳戶。我們會在日後推出的版本中部署經過修補的 Calico 程式碼。

在接下來的一週當中,我們會陸續撤銷所有可能受到影響的憑證。撤銷作業完成後,這則公告也會隨之更新,因此您無須採取任何進一步行動 (相關輪替作業已於 2018 年 11 月 16 日完成)。

如果想要立即輪替這類憑證,請執行以下指令,系統會在幾秒內自動為服務帳戶重新建立新的密碼:


kubectl get sa --namespace kube-system calico -o template --template '&#123&#123(index .secrets 0).name&#125&#125' | xargs kubectl delete secret --namespace kube-system
      

偵測

GKE 會記錄所有對 API 伺服器的存取。如要確認是否有人在 Google Cloud 已知的 IP 範圍外使用 Calico 憑證,請執行以下 Stackdriver 查詢。請注意,這項作業只會傳回從 GCP 網路以外位置發出的呼叫相關記錄,請根據您使用的環境自訂這項查詢。


resource.type="k8s_cluster"
protoPayload.authenticationInfo.principalEmail="system:serviceaccount:kube-system:calico"
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "8.34.208.0/20")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "8.35.192.0/21")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "8.35.200.0/23")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "108.59.80.0/20")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "108.170.192.0/20")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "108.170.208.0/21")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "108.170.216.0/22")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "108.170.220.0/23")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "108.170.222.0/24")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.224.0.0/13")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "162.216.148.0/22")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "162.222.176.0/21")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "173.255.112.0/20")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "192.158.28.0/22")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "199.192.112.0/22")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "199.223.232.0/22")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "199.223.236.0/23")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "23.236.48.0/20")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "23.251.128.0/19")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.204.0.0/14")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.208.0.0/13")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "107.167.160.0/19")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "107.178.192.0/18")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "146.148.2.0/23")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "146.148.4.0/22")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "146.148.8.0/21")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "146.148.16.0/20")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "146.148.32.0/19")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "146.148.64.0/18")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.203.0.0/17")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.203.128.0/18")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.203.192.0/19")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.203.240.0/20")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "130.211.8.0/21")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "130.211.16.0/20")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "130.211.32.0/19")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "130.211.64.0/18")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "130.211.128.0/17")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "104.154.0.0/15")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "104.196.0.0/14")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "208.68.108.0/23")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.184.0.0/14")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.188.0.0/15")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.202.0.0/16")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.190.0.0/17")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.190.128.0/18")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.190.192.0/19")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.235.224.0/20")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.192.0.0/14")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.196.0.0/15")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.198.0.0/16")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.199.0.0/17")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.199.128.0/18")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.200.0.0/15")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "2600:1900::/35")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.190.224.0/20")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.232.0.0/15")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.234.0.0/16")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.235.0.0/17")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.235.192.0/20")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.236.0.0/14")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.240.0.0/15")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.203.232.0/21")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "130.211.4.0/22")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.220.0.0/14")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.242.0.0/15")
NOT ip_in_net(protoPayload.requestMetadata.callerIp, "35.244.0.0/14")
      

2018 年 8 月 14 日

說明 嚴重性 附註

Intel 已揭露下列 CVE:

上述 CVE 統稱為「L1 終端機錯誤」(L1TF)。

這些 L1TF 安全漏洞會攻擊處理器層級的資料結構設定,藉此濫用推測性執行功能。「L1」是指 1 級資料快取 (L1D),這是一種用於加快記憶體存取速度的小型核心資源。

歡迎參閱 Google Cloud 網誌文章,進一步瞭解這些安全漏洞和 Compute Engine 的解決方式。

對 Google Kubernetes Engine 的影響

用於執行 Kubernetes Engine 及隔離各個客戶叢集與節點的基礎架構具備充分的防護機制,因此未受到已知攻擊的影響。

使用 Google Container-Optimized OS 映像檔的 Kubernetes Engine 節點集區如果已啟用自動升級功能,就會自動更新至修補完成的 COS 映像檔版本 (自 2018 年 8 月 20 日當週起可用)。

針對未啟用自動升級功能的 Kubernetes Engine 節點集區,您必須等到修補完成的 COS 映像檔版本上線後再進行手動升級

2018 年 8 月 6 日;最後更新時間:2018 年 9 月 5 日

說明 嚴重性 附註

2018 年 9 月 15 日更新:

我們日前揭露了 CVE-2018-5391,這個安全漏洞與 CVE-2018-5390 均屬於核心層級的網路安全漏洞,可提高針對不安全系統進行的阻斷服務 (DoS) 攻擊效率。兩者的主要差異在於不肖人士可以透過 IP 連線利用 CVE-2018-5391。我們已更新這則公告,以補充這兩個安全漏洞的相關資訊。

說明

CVE-2018-5390 (或稱為「SegmentSmack」) 屬於核心層級的網路安全漏洞,可透過 TCP 連線提高針對不安全系統進行的阻斷服務 (DoS) 攻擊效率。

CVE-2018-5391 (或稱為「FragmentSmack」) 屬於核心層級的網路安全漏洞,可透過 IP 連線提高針對不安全系統進行的阻斷服務 (DoS) 攻擊效率。

對 Google Kubernetes Engine 的影響

截至 2018 年 8 月 11 日,所有 Kubernetes Engine 主要執行個體皆已採用最新的防護機制,因此未受到這兩個安全漏洞的影響。另外,已啟用自動升級功能的 Kubernetes Engine 叢集也未受到這兩個安全漏洞的影響。 如果您的 Kubernetes Engine 節點集區未啟用自動升級功能,且上次手動升級時間早於 2018 年 8 月 11 日,則會受到這兩個安全漏洞的影響。

修補完成的版本

由於這個安全漏洞較為嚴重,建議您在修補內容上線後立即手動升級節點。

2018 年 5 月 30 日

說明 嚴重性 附註

我們日前在 Git 中發現一個安全漏洞。如果您允許未經授權的使用者透過 gitRepo 磁碟區建立 Pod,這個安全漏洞可能會允許升級 Kubernetes 權限。我們已發現這個 CVE,其標記為 CVE-2018-11235

我會受到影響嗎?

如果您符合以下所有條件,這個安全漏洞就會對您造成影響:

  • 未受信任的使用者可以建立 Pod (或觸發 Pod 建立作業)。
  • 在防範主機的根存取要求方面,未受信任使用者建立的 Pod 會受到限制 (例如透過 PodSecurityPolicy 加以限制)。
  • 未受信任使用者建立的 Pod 可以使用 gitRepo 磁碟區類型。

所有 Kubernetes Engine 節點均會受到這個安全漏洞的影響。

我該怎麼做?

禁止使用 gitRepo 磁碟區類型。如要透過 PodSecurityPolicy 禁止任何人使用 gitRepo 磁碟區,請在 PodSecurityPolicy 的 volumes 許可清單中省略 gitRepo

如果想將禁止使用 gitRepo 磁碟區的行為套用至其他存放區,您可以透過 initContainer 將 Git 存放區複製到 EmptyDir 磁碟區中:


apiVersion: v1
kind: Pod
metadata:
  name: git-repo-example
spec:
  initContainers:
    # This container clones the desired git repo to the EmptyDir volume.
    - name: git-clone
      image: alpine/git # Any image with git will do
      args:
        - clone
        - --single-branch
        - --
        - https://github.com/kubernetes/kubernetes # Your repo
        - /repo # Put it in the volume
      securityContext:
        runAsUser: 1 # Any non-root user will do. Match to the workload.
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
      volumeMounts:
        - name: git-repo
          mountPath: /repo
  containers:
    ...
  volumes:
    - name: git-repo
      emptyDir: {}

解決這個安全漏洞的修補內容為何?

我們會在即將推出的 Kubernetes Engine 版本中發布修補內容。如需相關詳情,日後請持續鎖定這個頁面。

2018 年 5 月 21 日

說明 嚴重性 附註

我們日前在 Linux 核心中發現多個安全漏洞,這些安全漏洞可能會導致透過未經授權程序提交的權限得以升級,或是因為觸發核心當機情況而阻斷服務。我們已發現這些 CVE,其標記分別為 CVE-2018-1000199CVE-2018-8897CVE-2018-1087。所有 Kubernetes Engine 均會受到這些安全漏洞的影響,建議您按照下列步驟操作,以升級至最新修補版本。

我該怎麼做?

如要進行升級,您必須先將主要執行個體升級至最新版本。這項修補內容將會在 Kubernetes Engine 1.8.12-gke.1、Kubernetes Engine 1.9.7-gke.1 和 Kubernetes Engine 1.10.2-gke.1 中發布,以上版本均包含適用於 Container-Optimized OS 和 Ubuntu 映像檔的修補內容。

如果您在修補內容發布前即已建立新的叢集,請務必指定叢集要使用的修補完成版本。如果您是已啟用節點自動升級功能,但尚未進行手動升級的客戶,您的節點會在接下來的幾週內升級至修補完成版本。

這項修補內容解決了哪些安全漏洞?

這項修補內容解決了下列安全漏洞:

CVE-2018-1000199:這個安全漏洞會影響 Linux 核心,使未經授權的使用者或程序能夠觸發系統核心當機情況,進而招致 DoS 攻擊或造成權限升級。這個安全漏洞的嚴重性為「高」,CVSS 為 7.8。

CVE-2018-8897:這個安全漏洞會影響 Linux 核心,使未經授權的使用者或程序能夠觸發系統核心當機情況,進而招致 DoS 攻擊。這個安全漏洞的嚴重性為「中」,CVSS 為 6.5。

CVE-2018-1087:這個安全漏洞會影響 Linux 核心的 KVM 管理程序,使未經授權的程序能夠觸發訪客核心當機情況,甚至有可能授予權限。我們已為 Kubernetes Engine 採用的基礎架構解決這個安全漏洞,因此 Kubernetes Engine 未受影響。這個安全漏洞的嚴重性為「高」,CVSS 為 8.0。

2018 年 3 月 12 日

說明 嚴重性 附註

Kubernetes 專案日前揭露了新的安全漏洞,標記分別為 CVE-2017-1002101CVE-2017-1002102。這兩個安全漏洞會允許容器存取位於該容器以外的檔案。所有 Kubernetes Engine 節點均會受到這些安全漏洞的影響,建議您儘快按照下列步驟操作,以升級至最新修補版本。

我該怎麼做?

由於這些安全漏洞較為嚴重,無論您是否已啟用節點自動升級功能,我們都建議您在修補內容發布後立即手動升級節點。我們會在 3 月 16 日之前向所有客戶推出修補內容,但視您的叢集所在區域而定,實際發布時間可能較早。詳情請參閱發布時間表

如要進行升級,您必須先將主要執行個體升級至最新版本。這項修補內容將會在 Kubernetes 1.9.4-gke.1、Kubernetes 1.8.9-gke.1 和 Kubernetes 1.7.14-gke.1 中發布。3 月 30 日以前,新的叢集將依預設使用修補完成的版本。如果您在此之前即已建立新的叢集,則必須指定叢集要使用的修補完成版本。

如果您是已啟用節點自動升級功能,但尚未進行手動升級的 Kubernetes Engine 客戶,您的節點將會在 4 月 23 日前升級至修補完成版本。不過考量到這些安全漏洞的性質,建議您在修補內容發布後立即手動升級節點。

這項修補內容解決了哪些安全漏洞?

這項修補內容解決了下列兩個安全漏洞:

CVE-2017-1002101:這個安全漏洞會允許容器透過子路徑磁碟區掛接項目,存取位於該磁碟區以外的檔案。也就是說,如果您是透過 PodSecurityPolicy 禁止容器存取主機路徑的磁碟區,可更新或建立 Pod 的攻擊者就能透過其他磁碟區類型掛接任何主機路徑。

CVE-2017-1002102:這個安全漏洞會允許使用特定磁碟區類型 (包括 Secret、Config Map、Projected 磁碟區或 Downward API 磁碟區) 的容器刪除位於該磁碟區以外的檔案。也就是說,如果使用前述任一磁碟區類型的容器遭到入侵,或是您允許未受信任的使用者建立 Pod,攻擊者就能利用該容器來刪除主機上的任何檔案。

如要進一步瞭解解決方式,請參閱 Kubernetes 網誌文章

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
Kubernetes Engine