使用 AWS SSM 的 SSH 日誌記錄和會話管理

已發表: 2022-03-11

設置自定義工具或腳本以在 Linux 上保留 SSH 日誌可能很乏味且容易出錯。

工程師可以使用rootshscreen或其他實用程序來記錄用戶活動,但如果用戶權限設置不正確,熟練的用戶可以刪除審計日誌以掩蓋他們的踪跡。 另一種選擇是在內核級別設置日誌記錄,但所需的專業知識並不常見。

值得慶幸的是,有一種方法可以記錄用戶活動,甚至無需編寫單個 Linux 命令! 我們需要這些服務:

  • EC2
  • IAM(身份和訪問管理)
  • KMS(密鑰管理服務)
  • CloudWatch Logs(和/或 S3)
  • AWS 系統管理器(以前稱為 SSM)

讓我們看看如何設置它們。

EC2 和 IAM

啟動 EC2 實例通常相當容易,但在啟動期間必須完成一項關鍵任務:我們需要將 IAM 角色附加到我們的實例,否則我們將無法達到本文末尾詳述的預期結果文章。

我們與 EC2 實例關聯的 IAM 角色必須具有內置的AmazonSSMManagedInstanceCore策略,以及此策略(附加為內聯或客戶管理):

 { "Version": "2012-10-17", "Statement": [ { "Action": [ "logs:CreateLogStream", "logs:DescribeLogStreams", "logs:DescribeLogGroups", "logs:PutLogEvents" ], "Effect": "Allow", "Resource": "*" } ] }

除了 IAM 角色,我們通常使用這個 EC2 實例配置:

  • 操作系統是 Amazon Linux 2,因為默認情況下它安裝了 AWS Systems Manager 代理(SSM 代理)。 (Ubuntu 發行版也是如此,這也是一種選擇。)
  • 實例類型是 t3.micro(但任何類型都可以)。
  • AWS 分配給 VPC 的默認安全組將起作用,因為我們不需要為此練習打開 SSH 端口。

我們可以開始設置 KMS,而無需等待 EC2 實例啟動。

知識管理系統

如果我們希望傳送到 CloudWatch 的所有會話日誌都以加密方式存儲,我們需要一個 KMS 密鑰。 讓我們轉到 KMS 服務並創建一個密鑰。

帶有麵包屑“KMS”、“客戶管理的密鑰”和“創建密鑰”的 AWS 屏幕截圖,當前位於第 1 步:“配置密鑰”。 “密鑰類型”可以設置為“對稱”(選中)或“非對稱”。在“高級選項”下,“密鑰材料來源”設置可以是“KMS”(選中)、“外部”或“自定義密鑰存儲(CloudHSM)”。
第 1 步:選擇對稱密鑰類型。

具有相同麵包屑的 AWS 屏幕截圖,現在在第 2 步:“添加標籤”。別名字段設置為“cwlg”,可選描述字段留空,可選標籤字段未添加任何標籤。
第 2 步:命名我們的密鑰。

具有相同麵包屑的 AWS 屏幕截圖,現在在第 3 步:“定義關鍵管理權限”。第一個字段“關鍵管理員”有一個空白搜索框,其中包含 10 行結果(第 1 頁,共 3 頁),其中包含名稱、路徑和類型列。只有第一行(具有相應的列值“admin”、“/”和“User”)選中了相應的複選框。另一個字段“密鑰刪除”有一個選項“允許密鑰管理員刪除此密鑰”,它的複選框也被選中。
第 3 步(可選):分配管理員。

我們建議分配一個管理員,以便 AWS 賬戶根用戶以外的用戶可以管理密鑰,但如果其他人不需要訪問,我們可以跳過第 3 步。

在這裡,我們選擇了 IAM 用戶“admin”作為密鑰管理員,但我們可以自由選擇任何用戶或角色。 我們還可以選擇禁用管理員的密鑰刪除權限。

具有相同麵包屑的 AWS 屏幕截圖,現在在第 4 步:“定義密鑰使用權限”。第一個字段“此帳戶”具有與第 3 步相同的搜索結果,但沒有一個被選中。另一個字段“其他 AWS 賬戶”沒有添加任何內容。
第 4 步:跳過用戶分配頁面。

我們不會將任何用戶分配給此密鑰,因為我們希望此密鑰僅供 CloudWatch Logs 服務用於 SSH 日誌加密和解密操作。

具有相同麵包屑的 AWS 屏幕截圖,現在在第 5 步:“審查”。第一個字段“密鑰配置”將“密鑰類型”列為“對稱”,將“密鑰規範”列為“SYMMETRIC_DEFAULT”,將“密鑰使用”列為“加密和解密”,將“來源”列為“AWS_KMS 。”下一個字段“別名和描述”列出了一個別名“cwlg”,沒有描述。下一個字段“標籤”不顯示任何數據。最後一個字段“密鑰策略”包括一個預先填充了 JSON 格式策略的文本框。
第 5 步:查看我們的配置並交換默認密鑰策略。

在 Review 頁面上,我們需要更改 KMS 生成的密鑰策略,因為它不包括 CloudWatch Logs 使用密鑰的權限。 我們將用此策略替換它:

 { "Version": "2012-10-17", "Statement": [ { "Sid": "Enable IAM User Permissions", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::ACCOUNT_ID:root" }, "Action": "kms:*", "Resource": "*" }, { "Sid": "Allow access for Key Administrators", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::ACCOUNT_ID:user/USERNAME" }, "Action": [ "kms:Create*", "kms:Describe*", "kms:Enable*", "kms:List*", "kms:Put*", "kms:Update*", "kms:Revoke*", "kms:Disable*", "kms:Get*", "kms:Delete*", "kms:TagResource", "kms:UntagResource", "kms:ScheduleKeyDeletion", "kms:CancelKeyDeletion" ], "Resource": "*" }, { "Sid": "Allow access to CloudWatch Log", "Effect": "Allow", "Principal": { "Service": "logs.REGION.amazonaws.com" }, "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey" ], "Resource": "*", "Condition": { "ArnLike": { "kms:EncryptionContext:aws:logs:arn": "arn:aws:logs:REGION:ACCOUNT_ID:*" } } } ] }

確保替換所有佔位符:

  • ACCOUNT_ID成為我們的 AWS 賬戶 ID。
  • USERNAME成為在步驟 3 中選擇的管理員用戶名。如果我們選擇退出該步驟,則在此處刪除第二個語句塊(帶有"Sid": "Allow access for Key Administrators" )。
  • REGION成為我們將服務部署到的區域標識符代碼(例如us-west-1 )。

有了這個,KMS 準備好了。

CloudWatch 日誌組

接下來,我們需要一個 CloudWatch Log 組(和/或一個 S3 存儲桶——見下文),SSM 代理可以在其中發送 SSH 會話日誌。 讓我們創建它。

帶有麵包屑“CloudWatch”、“CloudWatch Logs”、“日誌組”和“創建日誌組”的 AWS 屏幕截圖。沒有多步驟側邊欄。第一個字段“日誌組詳細信息”具有三個子字段:“日誌組名稱”(設置為“ssm-session-demo”)、“保留設置”(從下拉列表中設置為“永不過期”)和“KMS 密鑰 ARN - 可選”(設置為以“arn:aws:kms”開頭的截斷值)。第二個字段“標籤”沒有標籤。
創建“CloudWatch Logs”日誌組。

請注意 KMS 密鑰 ARN 字段:在 KMS 部分的第 5 步中創建密鑰後,AWS 會在此處為我們提供所需的值。

(如果我們之前沒有將正確的策略與我們的 KMS 密鑰相關聯,允許 CloudWatch Logs 服務使用該密鑰,此時我們將收到與 KMS 密鑰相關的錯誤。)

將 SSH 日誌存儲在 S3 存儲桶中

為了使用 S3 存儲活動日誌而不是 CloudWatch Logs,我們需要將這些權限作為單獨的策略添加到我們的 EC2 實例配置文件中(或手動將它們與我們可能需要關聯的其他權限結合起來):

 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject" ], "Resource": "arn:aws:s3:::BUCKET_NAME/*" }, { "Effect": "Allow", "Action": [ "s3:GetEncryptionConfiguration" ], "Resource": "*" }, { "Effect": "Allow", "Action": "kms:GenerateDataKey", "Resource": "*" } ] }

在上面的代碼段中,請務必替換BUCKET_NAME佔位符。

既然我們已經設置了存儲日誌的位置(CloudWatch Logs、S3 存儲桶或兩者兼而有之),我們就可以利用 SSH 會話了。

AWS Systems Manager 會話管理器

這是最後一個關鍵步驟,我們在其中配置對 Linux 機器的安全訪問以進行 SSH 會話監控和日誌記錄。 我們將從會話管理器儀表板開始。

AWS Session Manager 控制面板的屏幕截圖,其中包含“工作原理”、“為什麼使用 Session Manager?”、“開始使用”、“更多資源”和右上角的“開始會話”部分。後一部分有一個橙色的“開始會話”按鈕和一個白色的“配置首選項”按鈕。
第 1 步:開始使用儀表板。

在儀表板上,單擊右上角“開始會話”框中的白色“配置首選項”按鈕以啟用會話日誌記錄。

在 Preferences 頁面上,我們將找到多個可以探索的部分,但我們的重點是將 SSH 會話日誌流式傳輸到 CloudWatch 或 S3,以使我們能夠快速查看 Linux 機器中發生的情況。

標題為“CloudWatch 日誌記錄”的 AWS 部分的屏幕截圖。它的第一個設置,也稱為“CloudWatch 日誌記錄”,有一個標記為 Enable 的複選框已選中。下一個設置“選擇您的首選日誌記錄選項”選擇了“流會話日誌(推薦)”而不是“上傳會話日誌”。下一個設置“強制加密”有一個標記為“僅允許加密的 CloudWatch 日誌組”的複選框已選中。最終設置“CloudWatch 日誌組”選擇了“從列表中選擇日誌組名稱”而不是“在文本框中輸入日誌組”。在它下面是一個列表“CloudWatch 日誌組”,其中選擇了“ssm-session-demo”。它有相應的列“加密”(設置為“加密”)、“過期事件”(設置為“永不過期”)、“度量過濾器”(設置為 0)、“存儲的字節數”(設置為 0)和“創建時間”時間戳。
步驟 2a:啟用 CloudWatch 日誌記錄。

在“CloudWatch 日誌記錄”部分之後,有一個“S3 日誌記錄”部分,我們可以在其中選擇存儲桶。

標題為“S3 日誌記錄”的 AWS 部分的屏幕截圖。它的第一個設置“向 S3 發送會話日誌”有一個標記為“啟用”的複選框,該複選框已被選中。它的下一個設置“強制加密”有一個標記為“僅允許加密的 S3 存儲桶”的複選框已選中。它的下一個設置“選擇 S3 存儲桶”選擇了“從列表中選擇存儲桶名稱”而不是“在文本框中輸入存儲桶名稱”。在其下方,從下拉列表中選擇“ssm-session-demo”。最後一個字段“S3 密鑰前綴 - 可選”為空白。
步驟 2b:啟用 S3 日誌記錄。

配置 SSH 日誌記錄後,我們可以通過 SSH 連接到我們的 Linux 機器並執行一些命令來查看活動是否被捕獲。

所以,讓我們開始一個會話。 在同一頁面上,我們將找到一個“會話”選項卡,我們可以在其中開始會話。 單擊“開始會話”按鈕將為我們提供一個 EC2 機器列表,我們可以在這些機器上啟動會話:

帶有麵包屑的 AWS 屏幕截圖 AWS Systems Manager、Session Manager 和 Start a session。 “目標實例”搜索框沒有填寫任何查詢,只有一個結果,“實例名稱”設置為“SSM Demo”。
第 3 步:選擇我們的 EC2 實例以啟動 SSH 會話。

如果我們沒有在列表中看到我們的 EC2 Linux 實例,我們應該檢查它是否處於運行狀態並具有與它相關聯的 IAM 權限,如前所述。

處理 SSM 代理“不支持流式日誌”錯誤

如果我們收到錯誤消息說安裝在我們的 EC2 機器上的 SSM 代理版本不支持流式 CloudWatch 日誌,請不要擔心。 有一種無痛的方法可以解決這個問題。

紅色背景上帶有白色文本的 AWS 錯誤消息的屏幕截圖。消息旁邊有一個帶圓圈的 X,“此實例上安裝的 SSM 代理版本不支持將日誌流式傳輸到 CloudWatch。請將 SSM 代理更新到最新版本,或在您的首選項中禁用流式日誌選項。”
潛在的“過時的 SSM 代理版本”錯誤。

要更新 SSM 代理,我們需要導航到AWS Systems Manager服務左側面板中的Run Command

AWS Systems Manager Run Command 控制面板的屏幕截圖,其中包含“工作原理”、“功能和優勢”、“用例和博客文章”、“文檔”以及右上角的“管理您的實例”部分。該部分僅包含一個橙色的“運行命令”按鈕。
第 1 步:從“運行命令”儀表板開始。

到達那里後,我們可以單擊橙色的“運行命令”按鈕,進入一個新頁面,我們可以在其中填寫一些參數。

帶有麵包屑的 AWS 屏幕截圖 AWS Systems Manager、Run Command 和 Run a command。標有“命令文檔”的搜索框列出了 10 行(超過 5 頁的第 4 頁),其中選擇了一個名為“AWS-UpdateSSMAgent”的行。它的“所有者”列中有“Amazon”,“平台類型”列中有“Windows、Linux”。底部的“文檔版本”字段從下拉列表中選擇了“1(默認)”。
第 2 步:選擇命令文檔。

我們首先從列表中選擇AWS-UpdateSSMAgent

標題為“目標”的 AWS 部分的屏幕截圖。第一個字段,也稱為“目標”,具有“指定實例標籤”、“手動選擇實例”(選中)和“選擇資源組”選項。底部是一個沒有查詢的“Instances”搜索框,其唯一的結果是“SSM Demo”,已選中。行中對應的實例 ID 被複製到“實例”正上方帶有 X 的框中。
第 3 步:選擇具有需要更新的 SSM 代理的 EC2 實例。

選擇後,我們將向下滾動,直到看到“目標”部分。 在那裡,我們需要選擇要更新 SSM 代理的 EC2 實例,然後在最後點擊“運行”按鈕。 這會將我們發送到可以監控更新進度的頁面。

帶有麵包屑“AWS Systems Manager”、“Run Command”和“Command ID”(後跟 GUID)的 AWS 屏幕截圖。第一部分“命令狀態”顯示成功指標,下一部分“目標和輸出”的唯一一行也顯示了成功指標,其中列出了之前的單個實例。底部還有兩個未展開的部分,“命令描述”和“命令參數”。
第 4 步:監控我們的更新進度。

代理更新不應超過五分鐘。 一旦完成,我們應該能夠在會話管理器中創建一個會話。

此時,我們應該啟動了一個 SSH 會話。

終端上方帶有會話 ID 和實例 ID 的 AWS 屏幕截圖。提示符是“sh-4.2$”,輸入了命令“whoami”和“pwd”,分別輸出“ssm-user”和“/usr/bin”。
通過 AWS Systems Manager Session Manager 使用 SSM 代理的 SSH 會話。

執行幾個命令後,讓我們導航到 CloudWatch Logs 日誌組(或我們的 S3 存儲桶,未顯示)並確認正在記錄活動。

帶有麵包屑“CloudWatch”、“CloudWatch Logs”、“日誌組”、“ssm-session-demo”和上一步的會話 ID 的 AWS 屏幕截圖。唯一的部分是一個搜索框“日誌事件”,其中的行都有一個時間戳和一個 JSON 格式的消息。其中一個被擴展以顯示其漂亮的 JSON 打印,並且右側有一個白色按鈕,標記為“複製”。
記錄在 CloudWatch Logs 中的 SSH 日誌事件。

我們現在有了一個啟用靜態加密的設置,記錄在我們的 Linux 機器中觸發的每個命令。

事實上,每個命令都可能超出我們的預期:會話期間提供或生成的任何秘密都將記錄在 CloudWatch 或 S3 中,任何擁有所需權限的人都可以看到。 為了防止這種情況,我們可以使用stty -echo; read passwd; stty echo; stty -echo; read passwd; stty echo; 對於我們需要在會話期間提供的每個秘密。

一個很棒的 SSM/SSH AWS 日誌記錄解決方案,有一些小注意事項

會話管理器是一個有用的工具,可以在無需打開端口 22 的情況下遠程訪問我們在 AWS 中的虛擬機。事實上,如果我們使用端口轉發或直接 SSH 連接,我們無法以這種方式生成 SSH 日誌,因為會話管理器文檔說明。

儘管如此,將會話管理器與會話記錄相結合是控制和監視虛擬機內活動的強大解決方案。 此外,我們不收取使用 Session Manager 服務的費用。 我們只需為我們的 EC2 實例和 CloudWatch Logs 或用於存儲日誌的 S3 存儲桶付費。

對於喜歡視頻教程的讀者,我在 YouTube 上更徹底地介紹了一個非常相似的過程。


進一步閱讀 Toptal 工程博客:

  • 案例研究:為什麼我將 AWS 雲基礎設施用於我的產品