K8s 預設的網路連線並沒有做特別限制,參考 Cluster internal networking 提到 Kubernetes networking behavior allows traffic between pods in the cluster as a default behavior. Attackers who gain access to a single container may use it for network reachability to another container in the cluster. 也就是說當有個 Pod 的控制權被拿到之後,它就可以透過網路的方式去做探測或是橫向移動。
先做小實驗驗證如下,先在相同worker node 不同 namespace 下建立兩個 Pod 做網路的連通測試 :
# 透過 minikube 開二個 node 出來 (勘誤:這邊其實只有開一個 node,然後裡面有三個 Pod)
minikube delete && minikube start ;
# 觀察這些 node 的 label
kubectl get nodes --show-labels ;
apiVersion: v1
kind: Namespace
metadata:
name: client
---
apiVersion: v1
kind: Pod
metadata:
name: client
namespace: client
labels:
env: test
app: client
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- minikube
containers:
- name: client
image: aeifkz/my-ubuntu:v1.0
---
apiVersion: v1
kind: Namespace
metadata:
name: server
---
apiVersion: v1
kind: Pod
metadata:
name: server
namespace: server
labels:
env: test
app: server
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- minikube
containers:
- name: server
image: aeifkz/my-ubuntu:v1.0
---
apiVersion: v1
kind: Pod
metadata:
name: hacker
labels:
env: test
app: hacker
spec:
containers:
- name: hacker
image: aeifkz/my-ubuntu:v1.0
接著要進行網路的連通測試,但這邊會需要很多計算機網路概論的知識。所以這邊我只能先濃縮會用到的部分進行解說,以最小化的理論搭配現象去解說。
首先網路傳送資料的基本單位抽象來說為封包(雖然這個稱呼不夠精準,但也只能先這樣),一個封包的內容是參考了 OSI model 的七層架構去組合出其內容,相關的結構傳輸流程可以參考如下圖 :
來源 : OSI Model
OSI 的功能分層是有其好處的,第一個是可以最小化需要的功能,第二個是可以彈性切換。
常見各層對應的協定則如下圖所示,這次我們只專注在三層。分別是Data link、Network、Transport 這三層。
首先針對 Network 層,會看到 ICMP 協定,這部分可以透過 ping 指令來做測試,那因為只是針對Network 層做測試,所以只需要帶入IP資訊。再來是針對 Transport 層,這部分會透過 telnet 來做測試,這邊則會多出 port 的這個資訊進行測試。
至於 Data link 就比較特別一點了,會看到 ARP 這個協定。 ARP 是一個透過解析網路層位址來找尋資料鏈路層位址的網路傳輸協定,之所以會需要這個協定,是因為在區域網路中一台機器要跟另一台機器溝通時是透過MAC位址(也就是網卡的位址)進行溝通。這時候就會透過 ARP 協定去詢問該 IP 位址對應的 MAC 位址,之後再將這個 MAC 位址作為目的位址發送封包。
待會會用封包監聽的方式去觀察 ARP、ping、telnet 的網路行為,那因為要在 Pod 的容器中執行,所以這邊 image 裡面已經有安裝好 tcpdump 可以使用,之後寫入 pcap 檔案後再用 wireshark 去做觀察。
kubectl create -f network.yaml ;
# 取得 server pod 的 ip 位址,這邊是 10.244.0.6
kubectl -n server exec -it pods/server -- ifconfig ;
# 取得 client pod 的 ip 位址,這邊是 10.244.0.5
kubectl -n client exec -it pods/client -- ifconfig ;
kubectl -n server exec -it pods/server -- bash ;
# 先確認一下目前網卡的介面名稱
ifconfig ;
# 在 server 端透過 tcpdump 進行監聽,這邊不設定任何的 filter
tcpdump -i eth0 -w server.pcap ;
# 切換一個視窗進到 client 裡面
kubectl -n client exec -it pods/client -- bash ;
# 透過 ping 先送出 ICMP 封包進行測試
ping [server_ip] ;
# 透過 nc 測試開放的 port 連線
nc [server_ip] 30089 ;
# 模擬送了一些機敏資訊給 server
echo "abc=secret" ;
# 回到宿主機透過 kubectl cp 將檔案複製出來
kubectl cp -n server server:server.pcap ./server.pcap ;
封包監聽軟體可以使用 wireshark,以下分別是封包監聽幾個重要的截圖 :
ARP Request 封包
ARP Response 封包
ICMP 封包
TCP 封包
今日總結 :
本日回顧 :
次日預告 :