# 安裝 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

### 使用 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

## 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

* 可以看到第四個節點是 enforcer node

## 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

## 使用 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 都有正確連接。




## 注意 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
```