Teleport是一款Golang語言開發的用來替代sshd的ssh服務器,支持通過 SSH 或者 HTTPS 遠程訪問,支持集羣、Web登陸、SSH歷史記錄還重放用以操作分享和安全審計,基於Golang ssh包構建開發,實現完全兼容OpenSSH。

最近Teleport 4.2版本中新增加ssh增強的回話記錄功能用來接收非結構化的ssh會話,並將其通過結構化事件流來輸出。該功能使用到了Linux內核中集成的一項新技術eBPF(簡稱爲BPF)。用來完善Teleport審計功能的不足之處。本文蟲蟲就給大家介紹Teleport中是如何做的。

背景

Teleport的一個優勢就是,可以對ssh會話全程記錄。該功能可以捕獲用戶屏幕上顯示的所有內容。之後,可以使用該記錄回放還原所有操作,以便於審計。這些記錄易於理解,並提供了有關用戶在會話過程中所做操作和顯示的信息

然而,和其他同類工具一樣(堡壘機),Teleport也有不足之處,用戶可以使用一些方法繞過會話記錄。其中包括:

混淆命令:

比如通過加密或者其他方式對命令予以混淆。比如下面的語句,用base64編碼對要執行的命令進行了混淆。

echo Y3VybCBodHRwOi8vd3d3LmV4YW1wbGUuY29tCg== | base64 -d | sh

這樣實際的執行命令(curl example.com)不會直接被記錄。

Shell腳本:

如果用戶通過上傳並執行腳本的方式,也不能捕獲腳本中運行的命令,只能捕獲腳本的輸出。

終端控制:

ssh終端可以支持多種控件,比如用戶可以禁用終端回顯的控件,在一些應用程序通常會使用。例如sudo命令當它們提示用戶輸入密碼時。這是也不能在ssh記錄中捕獲它們。

此外,由於TTY流是非結構化性質,會話記錄在某種程度上可能難以捕獲和監視。

技術實現

爲了解決安全審計的這些不足,Teleport需要一種能將非結構化ssh會話轉換爲結構化事件流的方法。這就是本文要說的增強回話記錄功能,具體功能展示如下:

技術選型

通過多種方法對比,包括了內容從正則表達式模式匹配之類的臨時方法到自己解析原始SSH會話之類的方法,還探索了Linux提供的各種API和系統,例如Audit,fanotify和BPF等,在走技術對比時候,要考慮的兩個標準是準確性和性能問題:

減少誤報,最好減少到零。監控系統(安全審計),首先要考慮是的準確性問題,如果報警很多,則對警報的關注度就會減少。可能會導致嚴重問題被忽略掉。

減少由監控引起的任何性能影響,最好爲零。監控系統要儘量避免影響系統的性能。

多種方法中,誤報問題都很嚴重。無法對構成SSH會話的字節流進行準確的解析和解釋,不能防止警報疲勞。

還有一些方法,會有性能問題。比如Linux Audit。

通過查看文件系統訪問,有一些替代方法。最突出的兩個是inotify和fanotify。inotify不錯,做爲了初始備選項,但是其缺少遞歸目錄監視功。fanotify更有希望,也存在兩個問題。

布倫丹.格雷格在BPF性能工具書中提到,在重負載時,opensnoop比對fanotify,fanotify 佔了67%的CPU,而opensnoop只用到1%。

Linux內核最近合併到一個補丁,以提高fanotify的性能,使其更適合於對整個文件系統監視,這樣可以在Teleport中的使用更加緊密地契合。然而,補丁需要在Linux 5.1中才被合併,目前還沒有開箱即用的主流發行版支持。

考慮到這些考慮因素,Teleport最終選擇了基於BPF程序鏈構建的解決方案,該解決方案減少了誤報並且對性能的影響最小。

BPF介紹

BPF,原本是Unix的一個包過濾器,伯克利包過濾器(Berkeley Packet Filter)。後來被移植到了Linux中。2013 年,Alexei Starovoitov 對 BPF 做完善和改進,新版本被命名爲 eBPF (extended BPF),簡寫爲BPF,而將老的BPF叫做cBPF(classic BPF)。eBPF在增加了映射和尾調用等新特性,並且還重寫了JIT 編譯器。新版語言比 cBPF 更接近原生機器語言。BPF允許用戶空間程序以安全和高效的方式從內核中的某些位置掛接併發出事件。

安全意味着BPF程序不會陷入無限循環而導致系統癱瘓。BPF程序不太可能像內核模塊一樣可能使整個操作系統崩潰。

BPF程序也很有效,如果不能足夠快地使用它們,則丟棄事件,而不是拖累整個系統的性能。

目前Linux中有大量的系統工具都是基於BPF進行了重構(比如iptables),布倫丹.格雷格的書《BPF高性能工具》中(blog中)介紹了大量的工具可以供大家學習。

Teleport對接BPF

Teleport中使用了三個BPF程序:execsnoop捕獲程序執行,opensnoop捕獲程序打開的文件,tcpconnect捕獲程序建立的TCP連接。

爲了更好地理解這些BPF程序的功能,可以運行時查看execsnoop的輸出man ls。

看起來,簡單地運行man二進制文件似乎是在幕後執行了許多其他程序。

Teleport 將這些程序嵌入其二進制文件中,並且在啓用"增強的會話記錄"功能後,它將生成並運行它們。

這些程序本身是調試和跟蹤的出色工具,它能給出系統上正在執行什麼操作,而不僅限於一個用戶。

要將程序執行與特定的SSH會話相關聯,還使用了cgroups(尤其是cgroupv2)。Teleport啓動SSH會話時,它將首先重新啓動自身並將其置於cgroup中。這不僅允許該進程,而且可以使用唯一ID跟蹤Teleport啓動的所有將來進程。Teleport運行的BPF程序已更新,還可以發出執行它們的程序的cgroup ID。這樣就可以將事件與特定的SSH會話和身份相關聯。

侷限性

目前Teleport沒有完成增強的會話記錄。仍然存在一些差距,將以後版本解決。

值得指出的是,通過會話記錄,Teleport可以捕獲由於其特權位置而構成會話的字節流(字節流必須流過Teleport)。至關重要的是,會話記錄的完整性不依賴於主機自己報告的任何信息。但是,增強的審覈功能依賴於主機準確地向Teleport報告信息。如果主機的完整性受到損害,則增強審覈的完整性也會收到影響。此外,Teleport僅監控系統中最關鍵的部分系統調用,而不是全部調用。

目前,增強的會話記錄最適合非root用戶,對有權訪問root的用戶可以通過多種方式禁用增強會話記錄。

實踐

在沒有背景的情況下,可以使用下面的腳本進行增強的會話記錄。

首先啓動Ubuntu 19.04或RHEL/CentOS 8 VM,然後運行上面的腳本。該腳本會安裝內核頭文件和bcc-tools,這是運行增強會話記錄的先決條件。此外,腳本還安裝jq,一個命令的json解析工具(蟲蟲以前文章介紹過,可以參考),這有助於可視化結構化事件流。

按照說明輸入終端後,屏幕上看到以下類似的信息:

由此可見,curl程序是由用戶以兩種方式執行的。首先是程序本身的執行。第二個是程序的行爲,curl發出了網絡請求,也可以看到它。你可以嘗試執行其他操作,例如混淆的命令,或者腳本方式執行等,應該在日誌中查看執行結果。

要求

Teleport增強會話記錄的最低要求需要啓動BPF支持的 Linux內核4.18 。目前有多個發行版本可直接使用它,包括Ubuntu 19.04,Debian 10和RHEL/CentOS 8。

還需要安裝內核頭文件和bcc-tools。對於上面列出的操作系統,發行版的包管理器中安裝它們,比如對Centos 8只需運行

yum install -y kernel-headers bcc-tools 

或者Ubuntu下執行

apt install -y linux-headers-$(uname -r) bpfcc-tools 

如果尚未打包bcc-tools,則必須從源代碼構建它們。

要在Teleport中啓用增強的會話記錄,只需在文件配置中將其啓用即可,如下所示:

ssh_service: 
enhanced_recording: 
enabled: yes 

結論

儘管沒有任何監控系統是絕對可靠的,但採用具有多種防護措施的縱深防禦策略可以幫助發現問題並採取適當的措施。Teleport的增強型會話記錄功能可以爲系統上運行的命令的安全審計,提供更強大的記錄和操作可見性。

相關文章