# Podman Deploy Neuvector AllInOne ## Deploy allinone (NO privileged mode) with podman ### 1. 準備環境 1. 建立 NeuVector 用於持久化儲存設定檔的目錄 ``` sudo mkdir /var/neuvector ``` 2. 設定開機自動啟動並立即啟動 Podman socket ``` sudo systemctl enable --now podman.socket ``` 3. 建立一個 systemd 服務,將 Podman 的 socket 軟連結到傳統 Docker 的 socket 路徑,這是為了讓需要和 Docker API 互動的應用程式 (如此處的 NeuVector) 能無縫地與 Podman 運作 ``` $ sudo tee /etc/systemd/system/podman-docker-symlink.service <<'EOF' [Unit] Description=Create symlink from docker.sock to podman.sock After=podman.socket [Service] Type=oneshot ExecStart=/bin/ln -sf /run/podman/podman.sock /var/run/docker.sock RemainAfterExit=yes [Install] WantedBy=multi-user.target EOF ``` 4. 設定開機自動啟動並立即啟動建立 symlink 的服務 ``` sudo systemctl enable --now podman-docker-symlink.service ``` ### 2. 建立 NeuVector 內部元件 (Controller, Enforcer, Scanner) 之間加密通訊所需的 TLS 憑證 1. 建立存放憑證的目錄,並進入該目錄 ``` sudo mkdir -p /etc/neuvector/certs/internal; cd /etc/neuvector/certs/internal ``` 2. 建立 OpenSSL 設定檔,用於定義憑證的內容 (如國家、組織、SANs 等) ``` sudo tee /etc/neuvector/certs/internal/ca.cfg <<'EOF' [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 EOF ``` 3. 產生 CA (憑證頒發機構) 的私鑰 ``` sudo openssl genrsa -out ca.key 2048 ``` 4. 使用 CA 私鑰產生 CA 的根憑證 ``` sudo 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.cert ``` 5. 產生給服務使用的私鑰 ``` sudo openssl genrsa -out cert.key 2048 ``` 6. 產生憑證簽署請求 (CSR) ``` sudo openssl req -new -key cert.key -sha256 -out cert.csr -config ca.cfg ``` 7. 使用 CA 簽署 CSR,產生最終給服務使用的憑證 ``` sudo openssl x509 -req -sha256 -in cert.csr -CA ca.cert -CAkey ca.key -CAcreateserial -out cert.pem -days 3650 -extensions 'v3_req' -extfile ca.cfg ``` ### 3. 啟動 NeuVector App Container 1. 動態獲取主機指定網路介面 (此處為 ens18) 的 IP 位址,並存入變數 `IP`,這個 IP 將用來告訴 NeuVector 元件如何互相連線 ``` NIC='ens18' && \ IP=$(ip -4 -o addr show ${NIC} | awk '{print $4}' | cut -d/ -f1) ``` 2. 啟動 NeuVector 的 All-in-One main container (包含 Controller, Enforcer, Manager) ``` sudo podman run -d --name allinone \ --pid=host \ --cap-add=SYS_ADMIN \ --cap-add=NET_ADMIN \ --cap-add=SYS_PTRACE \ --cap-add=IPC_LOCK \ --security-opt label=disable \ --security-opt apparmor=unconfined \ --security-opt seccomp=unconfined \ -e CLUSTER_JOIN_ADDR=${IP} \ -e NV_PLATFORM_INFO=platform=Docker \ -e CTRL_PERSIST_CONFIG=1 \ -p 18300:18300 \ -p 18301:18301 \ -p 18400:18400 \ -p 18401:18401 \ -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 /etc/neuvector/certs/internal:/etc/neuvector/certs/internal/:ro \ docker.io/neuvector/allinone:5.4.5 ``` > - `--pid=host, --cap-add=...` 等參數是為了賦予 container 足夠的權限來監控主機的程序與網路活動 > - `-e CLUSTER_JOIN_ADDR=${IP}` 設定叢集加入位址 > - `-v 掛載主機路徑`,讓 container 能存取 Docker socket、主機核心模組、cgroup 及程序資訊,並持久化設定與讀取憑證 3. 啟動 NeuVector 的 Scanner container,專門用於執行映像檔弱點掃描,它會透過 `CLUSTER_JOIN_ADDR` 連接到 All-in-One Neuvector Controller ``` sudo podman run -td --name scanner \ -e CLUSTER_JOIN_ADDR=${IP} \ -e NV_PLATFORM_INFO=platform=Docker \ -p 18402:18402 \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /etc/neuvector/certs/internal:/etc/neuvector/certs/internal/:ro \ docker.io/neuvector/scanner:latest ``` ### 4. 設定 Neuvector Allinone container 開機自動啟動 1. 建立環境變數檔 ``` sudo mkdir -p /etc/neuvector sudo tee /etc/neuvector/allinone.env >/dev/null <<'EOF' # 請把下行改成你的 IP CLUSTER_JOIN_ADDR=192.168.11.131 NV_PLATFORM_INFO=platform=Docker CTRL_PERSIST_CONFIG=1 EOF ``` 2. 建立 Quadlet `.container` 檔案 ```bash sudo nano /etc/containers/systemd/allinone.container ``` 設定內容如下 : > 注意,`CLUSTER_JOIN_ADDR` 的值需依照環境而設定 ``` [Unit] Description=NeuVector All-in-One (via Podman Quadlet) Wants=network-online.target After=network-online.target RequiresMountsFor=/var/neuvector /lib/modules /etc/neuvector/certs/internal [Container] Image=docker.io/neuvector/allinone:5.4.5 ContainerName=allinone # Namespaces / 安全性(等同你原本的 --pid/--cap-add/--security-opt) PodmanArgs=--pid=host --security-opt apparmor=unconfined AddCapability=SYS_ADMIN AddCapability=NET_ADMIN AddCapability=SYS_PTRACE AddCapability=IPC_LOCK SecurityLabelDisable=true # --security-opt label=disable SeccompProfile=unconfined # --security-opt seccomp=unconfined # 環境變數 EnvironmentFile=/etc/neuvector/allinone.env # Port 對應(含 UDP) PublishPort=18300:18300 PublishPort=18301:18301 PublishPort=18400:18400 PublishPort=18401:18401 PublishPort=18301:18301/udp PublishPort=8443:8443 # Volume 對應 Volume=/lib/modules:/lib/modules:ro Volume=/var/neuvector:/var/neuvector Volume=/var/run/docker.sock:/var/run/docker.sock:ro Volume=/sys/fs/cgroup:/host/cgroup:ro Volume=/proc:/host/proc:ro Volume=/etc/neuvector/certs/internal:/etc/neuvector/certs/internal:ro # 若希望啟動時一定拉一次映像檔,可取消註解 # Pull=always [Service] Restart=always RestartSec=5s TimeoutStartSec=600 [Install] WantedBy=multi-user.target ``` 2. 重載 systemd daemon: ``` sudo systemctl daemon-reload ``` 3. 啟用並立即啟動服務: ``` sudo systemctl start allinone.service ``` > 如果噴錯代表 podman Quadlet 的設定檔有寫錯,請執行以下命令確認設定檔哪裡有錯 > `sudo /usr/libexec/podman/quadlet -dryrun` 4. 檢查 systemd 服務狀態: ``` systemctl status allinone.service ``` 正確執行結果: ``` ● allinone.service - NeuVector All-in-One (via Podman Quadlet) Loaded: loaded (/etc/containers/systemd/allinone.container; generated) Active: active (running) since Fri 2025-08-15 17:30:42 CST; 9min ago Main PID: 3957 (conmon) Tasks: 83 (limit: 50507) Memory: 897.2M CPU: 13.760s ...以下省略 ``` 5. 使用 podman 確認容器狀態: ```bash sudo podman ps -a --filter name=allinone ``` 正確執行結果: ``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e11bf0e3b2f7 docker.io/neuvector/allinone:5.4.5 5 minutes ago Up 5 minutes 0.0.0.0:8443->8443/tcp, 0.0.0.0:18300-18301->18300-18301/tcp, 0.0.0.0:18400-18401->18400-18401/tcp, 0.0.0.0:18301->18301/udp allinone ``` ### 5. 設定 Neuvector scanner container 開機自動啟動 1. 建立環境變數檔 ``` sudo tee /etc/neuvector/scanner.env >/dev/null <<'EOF' # 請把下行改成你的 IP CLUSTER_JOIN_ADDR=192.168.11.131 NV_PLATFORM_INFO=platform=Docker EOF ``` 2. 建立 Quadlet `.container` 檔案 ```bash sudo nano /etc/containers/systemd/scanner.container ``` 設定內容如下 : > 注意,`CLUSTER_JOIN_ADDR` 的值需依照環境而設定 ``` # /etc/containers/systemd/scanner.container [Unit] Description=NeuVector Scanner (via Podman Quadlet) Wants=network-online.target After=network-online.target [Container] ContainerName=scanner Image=docker.io/neuvector/scanner:latest EnvironmentFile=/etc/neuvector/scanner.env PublishPort=18402:18402 Volume=/var/run/docker.sock:/var/run/docker.sock:ro Volume=/etc/neuvector/certs/internal:/etc/neuvector/certs/internal:ro RestartPolicy=always [Install] WantedBy=multi-user.target ``` 2. 重載 systemd daemon: ``` sudo systemctl daemon-reload ``` 3. 啟用並立即啟動服務: ``` sudo systemctl start scanner.service ``` > 如果噴錯代表 podman Quadlet 的設定檔有寫錯,請執行以下命令確認設定檔哪裡有錯 > ``` > sudo /usr/libexec/podman/quadlet -dryrun > ``` 4. 檢查 systemd 服務狀態: ``` sudo systemctl status scanner.service ``` 正確執行結果: ``` ● scanner.service - NeuVector Scanner (via Podman Quadlet) Loaded: loaded (/etc/containers/systemd/scanner.container; generated) Active: active (running) since Fri 2025-08-15 17:56:43 CST; 6min ago Main PID: 4564 (conmon) Tasks: 12 (limit: 50507) Memory: 1.8G CPU: 20.587s ...以下省略 ``` 5. 使用 podman 確認容器狀態: ```bash sudo podman ps -a --filter name=scanner ``` 正確執行結果: ``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b4fede8ec2ac docker.io/neuvector/scanner:latest 8 minutes ago Up 8 minutes 0.0.0.0:18402->18402/tcp scanner ``` ### 6. 重新開機測試 1. 將主機重開 ``` sudo reboot ``` 2. 開機後,檢查 container 狀態 ``` sudo podman ps -a --filter name=scanner --filter name=allinone ``` 正確執行結果: ``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cde263d10568 docker.io/neuvector/scanner:latest 2 minutes ago Up 2 minutes 0.0.0.0:18402->18402/tcp scanner 69e22d0b9ae1 harbor.antony.com/neuvector/allinone:5.4.5 2 minutes ago Up 2 minutes 0.0.0.0:8443->8443/tcp, 0.0.0.0:18300-18301->18300-18301/tcp, 0.0.0.0:18400-18401->18400-18401/tcp, 0.0.0.0:18301->18301/udp allinone ``` 3. 打開瀏覽器,確認 Neuvector Web Console 是否正常 ![image](https://hackmd.io/_uploads/BkHwvK2_ll.png) 4. 登入管理網站 - 帳號 : `admin` - 密碼 : `admin` ![image](https://hackmd.io/_uploads/B1e6wF2ueg.png) ## 參考網站 - [Deploy allinone (NO privileged mode) with docker run - SUSE Security Docs](https://documentation.suse.com/cloudnative/security/5.4/en/docker.html#_deploy_allinone_no_privileged_mode_with_docker_run) - [安裝 Neuvector all-in-one (Docker、Podman)](https://hackmd.io/@7vxmAdNPTmmlYGSRMuvbmw/SJ4nTdzRC)