# 安裝 Neuvector all-in-one (Docker、Podman) ## 安裝 NV 1. 須先安裝好 docker 2. 部署 allinone NV container ``` $ mkdir /var/neuvector # CLUSTER_JOIN_ADDR 這是讓 enforce 或是 scanner 用來連接到的 IP 位址,通常是 allinone NV 本機 IP $ docker run -d --name allinone \ --pid=host \ --privileged \ -e CLUSTER_JOIN_ADDR=192.168.11.138 \ -e NV_PLATFORM_INFO=platform=Docker \ -e CTRL_PERSIST_CONFIG=1 \ -p 18300:18300 \ -p 18301:18301 \ -p 18400:18400 \ -p 18401:18401 \ -p 10443:10443 \ -p 18301:18301/udp \ -p 8443:8443 \ -v /lib/modules:/lib/modules:ro \ -v /var/neuvector:/var/neuvector \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /sys/fs/cgroup:/host/cgroup:ro \ -v /proc:/host/proc:ro \ neuvector/allinone:5.3.3 ``` 3. 部署 scanner ``` $ docker run -td --name scanner \ -e CLUSTER_JOIN_ADDR=192.168.11.138 \ -e NV_PLATFORM_INFO=platform=Docker \ -p 18402:18402 -v /var/run/docker.sock:/var/run/docker.sock:ro \ neuvector/scanner:latest ``` 4. 登入 NV ![image](https://hackmd.io/_uploads/HJxqb5GAC.png) ### 使用 docker-compose 安裝 ``` $ cd /usr/bin $ sudo wget https://github.com/docker/compose/releases/download/v2.29.7/docker-compose-linux-x86_64 $ sudo mv docker-compose-linux-x86_64 docker-compose $ sudo chmod 755 docker-compose ``` * 編輯 docker-compose.yml ``` $ mkdir NV;cd NV $ nano docker-compose.yml version: '2' services: allinone: pid: host image: neuvector/allinone:5.3.3 container_name: allinone privileged: true environment: - CLUSTER_JOIN_ADDR=192.168.11.138 - NV_PLATFORM_INFO=platform=Docker - CTRL_PERSIST_CONFIG=1 ports: - 18300:18300 - 18301:18301 - 18400:18400 - 18401:18401 - 10443:10443 - 18301:18301/udp - 8443:8443 volumes: - /lib/modules:/lib/modules:ro - /var/neuvector:/var/neuvector - /var/run/docker.sock:/var/run/docker.sock:ro - /proc:/host/proc:ro - /sys/fs/cgroup:/host/cgroup:ro scanner: image: neuvector/scanner:latest container_name: scanner environment: - CLUSTER_JOIN_ADDR=192.168.11.138 ports: - 18402:18402 volumes: - /var/run/docker.sock:/var/run/docker.sock:ro ``` * 啟動 container ``` $ docker-compose up -d ``` * 登入 NV ![image](https://hackmd.io/_uploads/HJxqb5GAC.png) ## HA 部屬 * 部屬 3 個 Allinone node + 1 個 enforcer node * 透過 `CLUSTER_JOIN_ADDR=192.168.11.137,192.168.11.138,192.168.11.139` 將三個 Allinone 的 NV 組成一個集群 * 需要宣告 `CTRL_PERSIST_CONFIG=1` 環境變數 NV 才會把備份設定存到 `/var/neuvector` 目錄 ``` # 分別在三台 node 上執行 $ docker run -d --name allinone \ --pid=host \ --privileged \ -e CLUSTER_JOIN_ADDR=192.168.11.137,192.168.11.138,192.168.11.139 \ -e NV_PLATFORM_INFO=platform=Docker \ -e CTRL_PERSIST_CONFIG=1 \ -p 18300:18300 \ -p 18301:18301 \ -p 18400:18400 \ -p 18401:18401 \ -p 10443:10443 \ -p 18301:18301/udp \ -p 8443:8443 \ -v /lib/modules:/lib/modules:ro \ -v /var/neuvector:/var/neuvector \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /sys/fs/cgroup:/host/cgroup:ro \ -v /proc:/host/proc:ro \ neuvector/allinone:5.3.3 ``` * 部屬 scanner ``` $ docker run -td --name scanner \ -e CLUSTER_JOIN_ADDR=192.168.11.137 \ -e NV_PLATFORM_INFO=platform=Docker \ -p 18402:18402 -v /var/run/docker.sock:/var/run/docker.sock:ro \ neuvector/scanner:latest ``` * 如果要再新增節點要透過 enforcer 的方式新增 ``` # 在第四台 node 上執行 $ docker run -d --name enforcer \ --pid=host \ --privileged \ -e CLUSTER_JOIN_ADDR=192.168.11.137,192.168.11.138,192.168.11.139 \ -e NV_PLATFORM_INFO=platform=Docker \ -p 18301:18301 \ -p 18401:18401 \ -p 18301:18301/udp \ -v /lib/modules:/lib/modules:ro \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /sys/fs/cgroup:/host/cgroup:ro \ -v /proc:/host/proc:ro \ neuvector/enforcer:5.3.3 ``` * 在 NV 介面可以看到有四個 node ![image](https://hackmd.io/_uploads/H1G-Gfd00.png) * 可以看到第四個節點是 enforcer node ![image](https://hackmd.io/_uploads/rJKWfGORR.png) ## allinone manager UI 自簽憑證 * 產生自簽憑證 ``` $ mkdir ssl; cd ssl $ wget https://raw.githubusercontent.com/cooloo9871/SelfSigned-RootCA/refs/heads/master/mk $ bash mk create nv.example.com 192.168.11.160 ``` * 建立 allinone NV,須注意自己的憑證位置 ``` $ docker run -d --name allinone \ --pid=host \ --privileged \ -e CLUSTER_JOIN_ADDR=192.168.11.160 \ -e NV_PLATFORM_INFO=platform=Docker \ -e CTRL_PERSIST_CONFIG=1 \ -p 18300:18300 \ -p 18301:18301 \ -p 18400:18400 \ -p 18401:18401 \ -p 10443:10443 \ -p 18301:18301/udp \ -p 8443:8443 \ -v /lib/modules:/lib/modules:ro \ -v /var/neuvector:/var/neuvector \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /sys/fs/cgroup:/host/cgroup:ro \ -v /proc:/host/proc:ro \ -v /root/ssl/cert-key.pem:/etc/neuvector/certs/ssl-cert.key \ -v /root/ssl/cert.pem:/etc/neuvector/certs/ssl-cert.pem \ neuvector/allinone:5.3.3 ``` * 檢查憑證,輸出會與 cert.pem 內容一致 ``` $ echo | \ openssl s_client -servername nv.example.com -connect nv.example.com:8443 2>/dev/null | \ openssl x509 -text ``` * 將 ca.pem 匯入瀏覽器後,可以 https 信任憑證,注意是 8443 port ![image](https://hackmd.io/_uploads/Bymcgpc0R.png) ## 使用 API 掃描本地 image * 使用帳號密碼 login 產生 token ``` $ curl -s -k -X 'POST' \ 'https://192.168.11.138:10443/v1/auth' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d '{ "client_ip": "", "password": { "username": "admin", "password": "admin" }, "Token": { "token": "", "state": "", "redirect_endpoint": "" } }' | jq -r '.token.token' > token # Keep login session alive $ _token_=$(cat token) $ curl -s -k -X 'PATCH' \ 'https://192.168.11.138:10443/v1/auth' \ -H 'accept: application/json' \ -H "X-Auth-Token: $_token_" ``` * 掃描本地 image ``` $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE neuvector/scanner latest a5813fe43c91 2 days ago 384MB neuvector/allinone 5.4.0 6826eacb29f5 7 weeks ago 911MB $ curl -s -k -H "Content-Type: application/json" -H "X-Auth-Token: $_token_" -d '{"request": {"tag": "latest", "repository": "neuvector/scanner", "scan_layers": true}}' "https://192.168.11.138:10443/v1/scan/repository" | jq . { "report": { "author": "", "base_os": "sles:15.6", "checks": [ { "automated": false, "category": "image", "description": "Ensure a user for the container has been created", "level": "WARN", "message": [], "profile": "Level 1", "remediation": "", "scored": true, "tags_v2": {}, "test_number": "I.4.1", "type": "image" }, { "automated": false, "category": "image", "description": "Ensure that HEALTHCHECK instructions have been added to container images", "level": "WARN", "message": [], "profile": "Level 1", "remediation": "", "scored": false, "tags_v2": {}, "test_number": "I.4.6", "type": "image" }, ...... ``` ## 升級 ``` $ docker stop allinone $ docker rename allinone allinone-bk ``` * 安裝新版本 NV ``` $ docker run -d --name allinone \ --pid=host \ --privileged \ -e CLUSTER_JOIN_ADDR=192.168.11.105 \ -e NV_PLATFORM_INFO=platform=Docker \ -e CTRL_PERSIST_CONFIG=1 \ -p 18300:18300 \ -p 18301:18301 \ -p 18400:18400 \ -p 18401:18401 \ -p 10443:10443 \ -p 18301:18301/udp \ -p 8443:8443 \ -v /lib/modules:/lib/modules:ro \ -v /var/neuvector:/var/neuvector \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /sys/fs/cgroup:/host/cgroup:ro \ -v /proc:/host/proc:ro \ neuvector/allinone:5.3.4 ``` * NV 數據都是保存在 `/var/neuvector` 路徑下,只要有掛載這個路徑升級 NV 後原有的資料都還會存在。 ## allinone Replacing Internal Certificates ### 部屬 allinone 節點 * 產生自簽名憑證 ``` $ mkdir ssl; cd ssl $ vim ca.cfg [req] distinguished_name = req_distinguished_name x509_extensions = v3_req prompt = no [req_distinguished_name] C = TW ST = Taipei L = San Jose O = NeuVector Inc. OU = Neuvector CN = Neuvector [v3_req] keyUsage = digitalSignature, keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth, clientAuth subjectAltName = @alt_names [alt_names] DNS.1 = Neuvector $ openssl genrsa -out ca.key 2048 $ openssl req -x509 -sha256 -new -nodes -key ca.key -days 3650 -subj "/C=TW/ST=Taipei/L=Taipei/O=NeuVector Inc./OU=Neuvector/CN=Neuvector" -out ca.crt $ openssl genrsa -out tls.key 2048 $ openssl req -new -key tls.key -sha256 -out cert.csr -config ca.cfg # 檢查 CSR 內容 $ openssl req -in cert.csr -noout -text Certificate Request: Data: Version: 1 (0x0) Subject: C = TW, ST = Taipei, L = San Jose, O = NeuVector Inc., OU = Neuvector, CN = Neuvector ...... # 簽署 CSR 成為 X.509 憑證 $ openssl x509 -req -sha256 -in cert.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out tls.crt -days 3650 -extensions 'v3_req' -extfile ca.cfg # 檢查 X.509 憑證的詳細內容 $ openssl x509 -in tls.crt -text Certificate: Data: Version: 3 (0x2) Serial Number: 36:0a:3c:c5:84:cb:02:50:e7:7f:a8:ca:5b:a3:06:10:53:86:b3:3a Signature Algorithm: sha256WithRSAEncryption Issuer: C = TW, ST = Taipei, L = Taipei, O = NeuVector Inc., OU = Neuvector, CN = Neuvector ...... $ NV:~/ssl # ls -l total 32 -rw-r--r-- 1 root root 365 May 19 13:20 ca.cfg -rw-r--r-- 1 root root 1363 May 19 13:22 ca.crt -rw------- 1 root root 1704 May 19 13:21 ca.key -rw-r--r-- 1 root root 41 May 19 13:25 ca.srl -rw-r--r-- 1 root root 1017 May 19 13:23 cert.csr -rw-r--r-- 1 root root 1436 May 19 13:25 tls.crt -rw------- 1 root root 1704 May 19 13:23 tls.key $ mv ca.crt ca.cert $ mv tls.crt cert.pem $ mv tls.key cert.key $ NV:~/ssl # ls -l total 32 -rw-r--r-- 1 root root 1363 May 19 13:22 ca.cert -rw-r--r-- 1 root root 365 May 19 13:20 ca.cfg -rw------- 1 root root 1704 May 19 13:21 ca.key -rw-r--r-- 1 root root 41 May 19 13:25 ca.srl -rw-r--r-- 1 root root 1017 May 19 13:23 cert.csr -rw------- 1 root root 1704 May 19 13:23 cert.key -rw-r--r-- 1 root root 1436 May 19 13:25 cert.pem $ NV:~/ssl # pwd /root/ssl ``` * 部屬 allinone,並指定掛載內部憑證 ``` $ docker run -d --name allinone \ --pid=host \ --privileged \ -e CLUSTER_JOIN_ADDR=192.168.11.119 \ -e NV_PLATFORM_INFO=platform=Docker \ -e CTRL_PERSIST_CONFIG=1 \ -p 18300:18300 \ -p 18301:18301 \ -p 18400:18400 \ -p 18401:18401 \ -p 10443:10443 \ -p 18301:18301/udp \ -p 8443:8443 \ -v /lib/modules:/lib/modules:ro \ -v /var/neuvector:/var/neuvector \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /sys/fs/cgroup:/host/cgroup:ro \ -v /proc:/host/proc:ro \ -v /root/ssl/:/etc/neuvector/certs/internal/:ro \ neuvector/allinone:5.3.3 ``` ### 部屬 enforcer 節點 * 將在 allinone 的憑證複製到 enforcer 節點上,並指定掛載內部憑證 ``` $ scp -r ssl 192.168.11.118:~ $ docker run -d --name enforcer \ --pid=host \ --privileged \ -e CLUSTER_JOIN_ADDR=192.168.11.119 \ -e NV_PLATFORM_INFO=platform=Docker \ -p 18301:18301 \ -p 18401:18401 \ -p 18301:18301/udp \ -v /lib/modules:/lib/modules:ro \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /sys/fs/cgroup:/host/cgroup:ro \ -v /proc:/host/proc:ro \ -v /root/ssl/:/etc/neuvector/certs/internal/:ro \ neuvector/enforcer:5.3.3 ``` ### 部屬 scanner * 指定掛載內部憑證 * 如果是部屬 5.4 以後的版本,scanner 的 tag 要換成 `6`,`neuvector/scanner:6` ``` $ docker run -td --name scanner \ -e CLUSTER_JOIN_ADDR=192.168.11.119 \ -e NV_PLATFORM_INFO=platform=Docker \ -p 18402:18402 \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /root/ssl/:/etc/neuvector/certs/internal/:ro \ neuvector/scanner:latest ``` ### 驗證 * 驗證所有 node 以及 System Components 都有正確連接。 ![image](https://hackmd.io/_uploads/BJnULSdWxe.png) ![image](https://hackmd.io/_uploads/SkKDIH_Zex.png) ![image](https://hackmd.io/_uploads/Hy4O8H_Zxl.png) ![image](https://hackmd.io/_uploads/S1gt8SObgg.png) ## 注意 5.4.2 以後的版本都需要自己先產生內部憑證並掛載,因為後續版本的 NV 不會自己產生內部通訊用的憑證 ## 在 Podman 安裝 allinone 5.4.4 ``` $ sudo podman version Client: Podman Engine Version: 4.9.3 API Version: 4.9.3 Go Version: go1.22.2 Built: Thu Jan 1 08:00:00 1970 OS/Arch: linux/amd64 ``` 使用 podman 做出 docker.sock ``` $ sudo mkdir /var/neuvector $ sudo ln -s /run/podman/podman.sock /var/run/docker.sock $ sudo ls -l /var/run/docker.sock lrwxrwxrwx 1 root root 23 Jun 23 15:18 /var/run/docker.sock -> /run/podman/podman.sock ``` * 產生自簽名憑證 ``` $ mkdir ssl; cd ssl $ nano ca.cfg [req] distinguished_name = req_distinguished_name x509_extensions = v3_req prompt = no [req_distinguished_name] C = TW ST = Taipei L = San Jose O = NeuVector Inc. OU = Neuvector CN = Neuvector [v3_req] keyUsage = digitalSignature, keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth, clientAuth subjectAltName = @alt_names [alt_names] DNS.1 = Neuvector $ openssl genrsa -out ca.key 2048 $ openssl req -x509 -sha256 -new -nodes -key ca.key -days 3650 -subj "/C=TW/ST=Taipei/L=Taipei/O=NeuVector Inc./OU=Neuvector/CN=Neuvector" -out ca.crt $ openssl genrsa -out tls.key 2048 $ openssl req -new -key tls.key -sha256 -out cert.csr -config ca.cfg # 檢查 CSR 內容 $ openssl req -in cert.csr -noout -text Certificate Request: Data: Version: 1 (0x0) Subject: C = TW, ST = Taipei, L = San Jose, O = NeuVector Inc., OU = Neuvector, CN = Neuvector ...... # 簽署 CSR 成為 X.509 憑證 $ openssl x509 -req -sha256 -in cert.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out tls.crt -days 3650 -extensions 'v3_req' -extfile ca.cfg # 檢查 X.509 憑證的詳細內容 $ openssl x509 -in tls.crt -text Certificate: Data: Version: 3 (0x2) Serial Number: 36:0a:3c:c5:84:cb:02:50:e7:7f:a8:ca:5b:a3:06:10:53:86:b3:3a Signature Algorithm: sha256WithRSAEncryption Issuer: C = TW, ST = Taipei, L = Taipei, O = NeuVector Inc., OU = Neuvector, CN = Neuvector ...... $ NV:~/ssl # ls -l total 32 -rw-r--r-- 1 root root 365 May 19 13:20 ca.cfg -rw-r--r-- 1 root root 1363 May 19 13:22 ca.crt -rw------- 1 root root 1704 May 19 13:21 ca.key -rw-r--r-- 1 root root 41 May 19 13:25 ca.srl -rw-r--r-- 1 root root 1017 May 19 13:23 cert.csr -rw-r--r-- 1 root root 1436 May 19 13:25 tls.crt -rw------- 1 root root 1704 May 19 13:23 tls.key $ mv ca.crt ca.cert $ mv tls.crt cert.pem $ mv tls.key cert.key $ NV:~/ssl # ls -l total 32 -rw-r--r-- 1 root root 1363 May 19 13:22 ca.cert -rw-r--r-- 1 root root 365 May 19 13:20 ca.cfg -rw------- 1 root root 1704 May 19 13:21 ca.key -rw-r--r-- 1 root root 41 May 19 13:25 ca.srl -rw-r--r-- 1 root root 1017 May 19 13:23 cert.csr -rw------- 1 root root 1704 May 19 13:23 cert.key -rw-r--r-- 1 root root 1436 May 19 13:25 cert.pem $ NV:~/ssl # pwd /root/ssl ``` * 部屬 allinone,並指定掛載內部憑證 ``` $ sudo podman run -d --name allinone \ --pid=host \ --privileged \ -e CLUSTER_JOIN_ADDR=10.10.7.43 \ -e NV_PLATFORM_INFO=platform=Docker \ -e CTRL_PERSIST_CONFIG=1 \ -p 18300:18300 \ -p 18301:18301 \ -p 18400:18400 \ -p 18401:18401 \ -p 10443:10443 \ -p 18301:18301/udp \ -p 8443:8443 \ -v /lib/modules:/lib/modules:ro \ -v /var/neuvector:/var/neuvector \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /sys/fs/cgroup:/host/cgroup:ro \ -v /proc:/host/proc:ro \ -v /home/bigred/ssl:/etc/neuvector/certs/internal/:ro \ docker.io/neuvector/allinone:5.4.4 ``` * 佈署 scanner ``` $ sudo podman run -td --name scanner \ -e CLUSTER_JOIN_ADDR=10.10.7.43 \ -e NV_PLATFORM_INFO=platform=Docker \ -p 18402:18402 \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /home/bigred/ssl:/etc/neuvector/certs/internal/:ro \ docker.io/neuvector/scanner:6 ``` ``` $ sudo podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 05086fd23737 docker.io/neuvector/allinone:5.4.4 58 seconds ago Up 59 seconds 0.0.0.0:18301->18301/udp, 0.0.0.0:8443->8443/tcp, 0.0.0.0:10443->10443/tcp, 0.0.0.0:18300-18301->18300-18301/tcp, 0.0.0.0:18400-18401->18400-18401/tcp allinone cf2e1b87978a docker.io/neuvector/scanner:6 3 seconds ago Up 4 seconds 0.0.0.0:18402->18402/tcp scanner ```