# Persistent Data for NeuVector Policy and Configuration <style> .indent-title-1{ margin-left: 1em; } .indent-title-2{ margin-left: 2em; } .indent-title-3{ margin-left: 3em; } </style> ## Preface <div class="indent-title-1"> 本篇文章會採取 Step by Step 和 ScreenShot 的介紹, - 如何將 Neuvector 的 Policy and Configuration 透過 Kubernetes Persistent Volume 永久保存資料 可以透過點擊展開以下目錄,選擇想看的內容,跳轉至特定章節 :::warning :::spoiler 文章目錄 [TOC] ::: </div> ## Intro <div class="indent-title-1"> 預設情況下,NeuVector 將各種設定檔儲存在 Controller-Pods 的 **`/var/neuvector/config/backup`** 中。 NeuVector 可以將 configuration ( 設定 ) 和 policy ( 規則 ) 儲存到硬碟上,這樣即使 Controller 故障,設定和規則也不會遺失。這可以通過將一個 Kubernetes volume 掛載到 Controller pod 中的 **`/var/neuvector/`** 目錄區來實現。 如果 K8S 集群完全故障,當創建新 K8S 集群時,設定和規則會自動恢復。設定和規則也可以手動從 Volume 中恢復或刪除。 如果在 HA 配置中執行多個 Controller-Pods,只要其中一個 Controller-Pod 始終處於運作狀態,所有資料都會在 Controller 之間同步。 如果希望儲存 violations ( 違規 )、threats ( 威脅 )、vulnerabilities ( 漏洞 ) 和 events ( 事件 ) 等 Logs,請在 "Settings" 中啟用 SYSLOG server。 如果沒有使用「Kuberentes Persistent Volume」,NeuVector 就不會將設定或規則儲存到硬碟上。在停止所有 Neuvector-Controller-Pods 之前,請先備份 Controller 的設定和規則,這可以在「Settings」>「Configuration」中完成。 如果要確保設定和規則在 Neuvector Controller 更新時不會遺失,可以將 Neuvector Controller 部署在高可用性 (HA) 配置中,以 3 或 5 個 Neuvector-Controller-Pods 運行。 </div> ## 環境介紹 - 將 Neuvector 5.2.0 安裝在 OpenShift 4.12 之上 ## Step1: Create Persistent Volume Claim <div class="indent-title-1"> ``` $ nano neuvector-pvc.yaml ``` 檔案內容如下 : ```yaml! apiVersion: v1 kind: PersistentVolumeClaim metadata: name: neuvector-data namespace: neuvector spec: accessModes: - ReadWriteMany volumeMode: Filesystem resources: requests: storage: 1Gi ``` :::danger Note: 1. 如果在您的環境中有 StorageClass 則可跳過 Step2 建立 Persistent Volume 2. NeuVector 對於 accessModes 的要求必須是 ReadWriteMany(RWX). ::: ### 建立 PVC ``` $ oc create -f neuvector-pvc.yaml ``` </div> ## Step2: Create Persistent Volume <div class="indent-title-1"> ``` $ nano neuvector-pv.yaml ``` 檔案內容如下 : ```yaml! apiVersion: v1 kind: PersistentVolume metadata: name: neuvector-data spec: capacity: storage: 1Gi accessModes: - ReadWriteMany hostPath: path: "/var/neuvector" ``` ### 建立 PV ``` $ oc create -f neuvector-pv.yaml ``` </div> ### 檢查 PV 和 PVC 是否 Bound 在一起 <div class="indent-title-1"> ``` $ oc get pv,pvc ``` 螢幕輸出 : ``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/neuvector-data 1Gi RWX Retain Bound neuvector/neuvector-data 18m NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/neuvector-data Bound neuvector-data 1Gi RWX 18 ``` </div> ## Step3: Modify the NeuVector-Controller sample yaml file ### If Neuvector is existed <div class="indent-title-1"> :::danger :::spoiler {state="open"} <Font size=4>Note: 可以先依照以下步驟,匯出 Neuvector 的所有設定檔 </Font> <div class="indent-title-1"> Settings --> Configuration --> Export --> All --> Submit ![](https://hackmd.io/_uploads/BJkzbUWx6.png) </div> 如果 Volume 重新掛載到 Neuvector Controller 之後,有發現設定檔有殘缺,就可以 Import 回去 <div class="indent-title-1"> 點 Choose File --> 再點擊向上的箭頭,匯入檔案 ![](https://hackmd.io/_uploads/rkrI-L-la.png) </div> ::: </div> #### 執行以下命令修改 neuvector-controller-pod <div class="indent-title-1"> ``` $ oc edit deploy neuvector-controller-pod ``` 修改檔案內容如下 : ```yaml! ... metadata: name: neuvector-controller-pod spec: template: spec: containers: - env: - name: CTRL_PERSIST_CONFIG ## 新增這個 ENV ... volumes: - #hostPath: ## 註解掉這行 # path: /var/neuvector ## 註解掉這行 # type: "" ## 註解掉這行 name: nv-share persistentVolumeClaim: ## 新增 PVC claimName: neuvector-data ## 指定 Pods 使用哪個 PVC ``` </div> #### Rollout Restart Controller Pods <div class="indent-title-1"> ``` $ oc rollout restart deploy neuvector-controller-pod ``` </div> #### 檢視 Pods 被滾動式重新佈署之後的狀態 <div class="indent-title-1"> ``` $ watch -n 1 oc get pods -l app=neuvector-controller-pod ``` 成功部屬後的螢幕輸出 ```! NAME READY STATUS RESTARTS AGE neuvector-controller-pod-7bd8dd947f-8tw66 1/1 Running 0 8m34s neuvector-controller-pod-7bd8dd947f-qtghq 1/1 Running 0 9m50s neuvector-controller-pod-7bd8dd947f-vf94c 1/1 Running 0 7m19s ``` </div> ### If Neuvector doesn't existed <div class="indent-title-1"> ``` $ nano neuvector.yaml ``` 修改檔案內容如下 : ```yaml! ... spec: template: spec: volumes: - name: nv-share # hostPath: // replaced by persistentVolumeClaim # path: /var/neuvector // replaced by persistentVolumeClaim persistentVolumeClaim: claimName: neuvector-data ``` </div> ### Add the following environment variable in the Controller <div class="indent-title-1"> ```yaml! - name: CTRL_PERSIST_CONFIG ``` </div> ## Step4: Build Neuvector <div class="indent-title-1"> ``` $ oc create -f neuvector.yaml ``` </div> ### 檢視 Neuvector Pods 運作狀況 <div class="indent-title-1"> ``` $ oc get pods ``` 螢幕輸出 : ``` NAME READY STATUS RESTARTS AGE neuvector-controller-pod-74d88c4df6-7kqxk 1/1 Running 0 4m4s neuvector-controller-pod-74d88c4df6-m9spn 1/1 Running 0 4m3s neuvector-controller-pod-74d88c4df6-vp96s 1/1 Running 0 4m3s neuvector-enforcer-pod-4zsj8 1/1 Running 0 4m3s neuvector-enforcer-pod-f5znw 1/1 Running 0 4m3s neuvector-enforcer-pod-tqhz5 1/1 Running 0 4m3s neuvector-manager-pod-6bb5555c7b-85sdk 1/1 Running 0 4m4s neuvector-operator-86dd64f497-nqmbg 1/1 Running 2 19d neuvector-scanner-pod-56c798bb86-8ktcl 1/1 Running 0 4m3s neuvector-scanner-pod-56c798bb86-rvftv 1/1 Running 0 4m3s ``` </div> ## Step5: 建立掃描 Image Registry 的規則 <div class="indent-title-1"> Assets -> Registries -> Add - Name: `quay.io` - Registry: `https://quay.io/` - User Name: `hahappyman` - Password: `***` - Filter: `hahappyman/alpine-*` 勾選 Scan Layers -> Submit ![](https://hackmd.io/_uploads/H1uRPa8Ja.png) 點擊 Start Scan 按鈕 ![](https://hackmd.io/_uploads/H1v6daLJa.png) </div> ### 檢視掃描 Image Registry 的相關設定是否被保存到 Node 上 <div class="indent-title-1"> ```! $ cat <<EOF | oc debug node/worker2.ocp4.example.com 2> /dev/null chroot /host /bin/bash -c "[[ -d /var/neuvector/config/backup/ ]] && cat /var/neuvector/config/backup/registry.backup || ls -al /var/neuvector" EOF ``` 因為本次範例 PV 使用的是 HostPath ,資料可能只存在特定的 Node 上,Neuvector 的 Controller 會自行同步,所以有的節點的 /var/neuvector 目錄底下沒有資料,如以下螢幕輸出 ``` total 4 drwxr-xr-x. 2 root root 6 Aug 1 04:25 . drwxr-xr-x. 26 root root 4096 Aug 1 04:25 .. ``` 正確螢幕輸出如下 ```! {"auth_token":"","auth_with_token":false,"aws_key":null,"cfg_type":2,"creater_domains":null,"disable_files":false,"domains":null,"filters":["hahappyman/*"],"gcr_key":null,"gitlab_api_url":"","gitlab_private_token":"","ibmcloud_account":"","ibmcloud_token_url":"","jfrog_aql":false,"jfrog_mode":"","name":"quay.io","parsed_filters":[{"organization":"hahappyman","repository":".*","tag":".*"}],"password":"tZS7XXX6T0bkk0Pim8y3//qb0xmTVx5eGboJcrck","poll_period":0,"registry":"https://quay.io/","repo_limit":200,"rescan_image":true,"scan_layers":true,"schedule":"manual","tag_limit":20,"type":"Docker Registry","username":"hahappyman"} ``` - 此時就可以看到掃描 Image Registry 的設定被儲存在 Node 上 - Image 掃描的結果也會被儲存到 `/var/neuvector/registry/` 目錄下 </div> ## Step6: 建立 Admission Control 規則 <div class="indent-title-1"> Policy -> Admission Control -> Add - Criterion: - `Run as privileged` - `Namespace is one of [test]` - Mode: `Protect` ![](https://hackmd.io/_uploads/HJMmqpUyT.png) 勾選 Status: `Enabled`,並切換到 `Protect` Mode ![](https://hackmd.io/_uploads/rJ9FqaL1T.png) </div> ### 測試 Admission Control 規則 <div class="indent-title-1"> ``` $ oc run nginx --image=nginx:stable -n test --privileged=true ``` 螢幕輸出 : ```! Error from server: admission webhook "neuvector-validating-admission-webhook.neuvector.svc" denied the request: Creation of Kubernetes Pod is denied. ``` </div> ### 檢視 Admission Control 規則是否被保存到 Node 上 <div class="indent-title-1"> ```! $ cat <<EOF | oc debug node/worker2.ocp4.example.com 2> /dev/null chroot /host /bin/bash -c "[[ -d /var/neuvector/config/backup/ ]] && cat /var/neuvector/config/backup/admission_control.backup || ls -al /var/neuvector" EOF ``` 螢幕輸出 : ```json! {"id":1000,"category":"Kubernetes","comment":"","criteria":[{"name":"runAsPrivileged","op":"=","value":"true","value_slice":null,"path":"runAsPrivileged"},{"name":"namespace","op":"containsAny","value":"test","value_slice":null,"path":"namespace"}],"disable":false,"critical":false,"cfg_type":2,"rule_type":"deny","use_as_risky_role_tag":false,"rule_mode":"protect"} ...以下省略 ``` </div> ## Step7: 刪除 Neuvector <div class="indent-title-1"> ``` $ oc delete -f neuvector.yaml ``` - 須確認 Pods 都已被刪除 </div> ## Step8: 重新建立 Neuvector <div class="indent-title-1"> ``` $ oc create -f neuvector.yaml ``` </div> ### 檢視 Pods 運作狀態 <div class="indent-title-1"> ``` $ oc get pods ``` 螢幕輸出 : ``` NAME READY STATUS RESTARTS AGE neuvector-controller-pod-74d88c4df6-h7npj 1/1 Running 0 3m43s neuvector-controller-pod-74d88c4df6-k6fvg 1/1 Running 0 3m43s neuvector-controller-pod-74d88c4df6-th8lj 1/1 Running 0 3m43s neuvector-enforcer-pod-b2n8r 1/1 Running 0 3m43s neuvector-enforcer-pod-mzvkb 1/1 Running 0 3m43s neuvector-enforcer-pod-rdvq8 1/1 Running 0 3m43s neuvector-manager-pod-6bb5555c7b-zlq78 1/1 Running 0 3m43s neuvector-operator-86dd64f497-nqmbg 1/1 Running 2 19d neuvector-scanner-pod-56c798bb86-qpfc6 1/1 Running 0 3m43s neuvector-scanner-pod-56c798bb86-v29w8 1/1 Running 0 3m43 ``` </div> ## Step9: 確認設定和規則都還存在 連線至 Neuvector Web Console ### 掃描 Image Registry 的相關設定 <div class="indent-title-1"> ![](https://hackmd.io/_uploads/HJlCBRLkT.png) </div> ### Admission Control 規則 <div class="indent-title-1"> ![](https://hackmd.io/_uploads/SyaMLCIJp.png) </div> ## Config 會被備份的種類 <div class="indent-title-1"> ``` $ ls -l /var/neuvector/config/backup ``` 螢幕輸出 : ``` total 1332 -rw-------. 1 root root 2615 Sep 19 08:11 admission_control.backup -rw-------. 1 root root 96 Sep 19 07:53 compliance.backup -rw-------. 1 root root 378 Sep 19 07:53 crd.backup -rw-------. 1 root root 14903 Sep 19 07:53 dlp_group.backup -rw-------. 1 root root 2539 Sep 19 07:53 dlp_rule.backup -rw-------. 1 root root 29463 Sep 19 07:53 domain.backup -rw-------. 1 root root 41 Sep 19 07:53 eula_oss.backup -rw-------. 1 root root 488 Sep 19 07:53 federation.backup -rw-------. 1 root root 433060 Sep 19 07:53 file_monitor.backup -rw-------. 1 root root 554801 Sep 19 07:53 file_rule.backup -rw-------. 1 root root 80549 Sep 19 07:53 group.backup -rw-------. 1 root root 72943 Sep 19 08:06 policy.backup -rw-------. 1 root root 93486 Sep 19 07:53 process_profile.backup -rw-------. 1 root root 464 Sep 19 07:53 pwd_profile.backup -rw-------. 1 root root 664 Sep 19 07:53 registry.backup -rw-------. 1 root root 1738 Sep 19 07:53 response_rule.backup -rw-------. 1 root root 1295 Sep 19 07:53 system.backup -rw-------. 1 root root 532 Sep 19 08:02 user.backup -rw-r--r--. 1 root root 45 Sep 19 07:53 version.backup -rw-------. 1 root root 76 Sep 19 07:53 vulnerability.backup -rw-------. 1 root root 14903 Sep 19 07:53 waf_group.backup -rw-------. 1 root root 1481 Sep 19 07:53 waf_rule.backup ``` </div> ## Ref - [Backups and Persistent Data - Neuvector docs](https://open-docs.neuvector.com/deploying/production#backups-and-persistent-data)