Elastic Compute Cloud (EC2)

  • 要給 EC2 訪問其他 AWS 資源的權限,最安全的做法就是賦予 IAM Role。
  • AWS Application Migration Service (AWS MGN) 是推薦將應用程式遷移至 AWS 的服務。
  • 在 On-Demand 收費下,會計費的 EC2 狀態有:
    • 正在 running 的狀態。
    • 準備進入冬眠狀態 (hibernate) 的 stopping 狀態。
  • AWS EC2 在 stopped 或 hibernate 狀態下不會收取使用費,但會收取存儲費 (EBS)。
  • 每個 region 都有 CPU based 的限制,超過限制,機器就會開不起來。可以向 AWS 申請提高限制。
  • Hibernation (冬眠) EC2 提供你更快的啟動 EC2 Instance。
  • 已經啟動的 EC2 無法開啟冬眠功能。
  • EC2 的 placement group 可以決定機器部署時,彼此間的相近程度:
    • Cluster:機器部署在同一個 AZ,擁有最低的延遲。
    • Partition:機器部署在不同的邏輯分區中,彼此不會共用底層的硬體。
    • Spread:嚴格地將一小組實例放置在不同的底層硬體上,以減少相關故障。
  • EC2 的 placement group 如果因為硬體資源不夠無法啟動,可以關掉再重新啟動。

EC2 Debug 紀錄

某次我們發現 EC2 莫名其妙的當機。從 Grafana 上面看,EC2 在某個時刻後的 CPU 與記憶體使用率突然飆到 100%。 問題發生後,前輩開始找尋問題的原因。

首先進入 AWS 網頁主控台,在 EC2 管理頁面找到出問題的 EC2 Instance,在上面點擊右鍵,可以在 Monitor and troubleshoot 上面找到 Get system logGet instance screenshot。如果系統有噴出嚴重錯誤的 Log, 那麼也許就可以在 Get system log 上面看到。不過稍微查看之後,發現兩者都沒有記錄到任何問題。 於是我們決定將 EC2 Instance 重新開機,並在機器恢復正常後,登入並查看 /var/log/syslog 有沒有記錄到內容。

Get instance screenshot 這個功能再部分 CPU 上面不支援,詳情請參考文件

根據 Grafana 紀錄到的時間與 Log 顯示的資訊,我們發現 syslog 顯示在執行系統預設的 Cron Job 後出現問題。

2024-10-21T04:49:01.801940+00:00 hostname CRON[2978]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)

debian-sa1sysstat 提供的一個腳本,用來收集系統活動數據並將其存入日誌。 因為這是 Ubuntu 系統預設就會執行的 Cron Job,所以我們很驚訝這會導致機器出現問題。

也許導致機器出問題有其他原因,但前輩認爲這種情形非常不好判斷,加上發生的機率非常低。 與其繼續找下去,不如使用 Reboot 大法來得乾脆。只要 AWS 對機器的 Check 出現問題,就直接重新開機。 後續再繼續觀察這個情形是否還會發生。

於是我們在 CloudWatch 加上一段 Alarm,只要 StatusCheckFailed 到達 1,就直接讓機器重新啟動。

resource "aws_cloudwatch_metric_alarm" "instance_status_check_failed_alarm" {
  alarm_name          = "instance-status-check-failed-alarm"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = "1"
  metric_name         = "StatusCheckFailed"
  namespace           = "AWS/EC2"
  period              = "300"
  statistic           = "Maximum"
  threshold           = "1"
  alarm_actions       = ["arn:aws:automate:${data.aws_region.current.name}:ec2:reboot"]
  treat_missing_data  = "notBreaching"
  actions_enabled     = "true"
  dimensions = {
    InstanceId = aws_instance.main.id
  }
}

加上這個資源之後,我們需要確認一下 CloudWatch Alarm 是不是真的會重新啟動機器。 可以使用關閉預設網卡的方式,讓 AWS 無法確認機器的狀態,以此來觸發 CloudWatch Alarm。

sudo ifconfig ens5 down

限制使用者能使用的 AMI (Amazon Machine Images)

Datadog 資安實驗室發現 AWS AMI 存在名稱混淆攻擊 whoAMI,如果使用者沒有注意,就有可能使用到惡意的 EC2 映像檔案。 因為大部分用戶都會使用搜尋功能來找尋想要使用的 AMI,如果沒有針對 AMI 的 Provider 進行過濾, 而是只使用關鍵字來搜尋的話就有可能中招,因為惡意人士有可能發佈名稱很相似的 AMI。

Datadog 資安實驗室通報 AWS 後,AWS 在 2024 年底推出了 AMI 白名單的功能。

你可以使用 AWS CLI 來開啟 AMI 白名單,下面就來舉例如何限制用戶只能使用 Amazon 與 Canonical 發布的 AMI。

首先在 EC2 中啟用 Audit Mode。

aws ec2 enable-allowed-images-settings \
    --region us-west-2 \
    --allowed-images-settings-state audit-mode

如果成功啟用,預計會輸出會傳回。

{
  "AllowedImagesSettingsState": "audit-mode"
}

接著新增一個 image-criteria.json 檔案。

{
  "ImageCriteria": [
    {
      "ImageProviders": ["amazon", "099720109477"]
    }
  ]
}

使用指令輸入剛剛新增的 JSON 檔案並更新白名單的規則。

aws ec2 replace-image-criteria-in-allowed-images-settings \
    --region us-west-2 \
    --cli-input-json file:///absolute/path/to/image-criteria.json

Elastic Fabric Adapter (EFA)

  • Elastic Fabric Adapter (EFA) 是 Amazon EC2 執行個體適用的網路介面,可讓客戶在 AWS 上大規模執行需要高層級節點間通訊的應用程式。其客製化的作業系統 (OS) 略過硬體介面,可提升執行個體間通訊的效能。
  • 提供的 OS-bypass 功能,可以讓你的應用程式直接存取 EFA,而不是透過 OS 的網路介面,Windows 不支援

Elastic Network Adapter (ENA)

  • 簡單化的 EFA,不支援 OS-bypass。
  • Elastic Network Adapter (ENA) 是 Amazon EC2 執行個體適用的網路介面,可提供高頻寬、低延遲的網路效能。
  • 不用花錢

參考資料


This site uses Just the Docs, a documentation theme for Jekyll.