---
module: devops.security
title: Host Security & Anti-Virus
tab: Overview
order: 20
audience: dev
---

> **DRAFT · internal.** Rewritten 2026-07-02 after auditing the prod VMs. The first pass reported a
> bare posture ("no firewall/fail2ban") — that was mis-scoped; there IS custom IDS + FIM. Scripts:
> `hiveops-devops/scripts/ops/security/`.

## Controls actually in place

| Control | How | Hosts | PCI |
|---------|-----|-------|-----|
| **Intrusion detection + auto-block** | `security-monitor.sh` (every 5 min): scans nginx logs for attack patterns (`.env`, `.git`, `id_rsa`, `/actuator/env`, `/actuator/heapdump`, webshells…) → **`iptables -I INPUT -s <ip> -j DROP`**; Slack alerts; daily/weekly reports | `.250`, `.252` | Req 1/10/11 (compensating) |
| **File-integrity monitoring** | `aide-check.sh` (daily 03:15): AIDE `--check` → email `alerts@bcos.cloud` on any change | `.250`, `.188` | **Req 11.5** |
| **Firewall** | `iptables` (managed via security-monitor blocks) + almost certainly **OpenStack security groups** at the network layer | all | Req 1 |
| **TLS** | `acme.sh` auto-renew | `.250`, `.252` | — |

So iptables auto-blocking and AIDE FIM are live — the box is **not** wide open.

## Anti-virus (ClamAV) — remediated 2026-07-02 (#16)

Audit 2026-07-02 found AV broken/missing on most hosts (PCI Req 5 gap, incl. the CDE) — someone had
disabled `clamav-freshclam` + `clamd` on 2026-06-09 (resource reasons). **Remediated the same day.**

**Approach (script: `scripts/ops/security/clamav-remediate.sh`):** `freshclam` (signature updates,
cheap) **+ a daily 04:30 `clamscan`** of writable/ingress dirs. **Do NOT enable the resident `clamd`
daemon** — it holds the ~2 GB signature DB in RAM permanently (that's why it was disabled); `clamscan`
loads it only transiently per run.

| VM | ClamAV | Notes |
|----|--------|-------|
| services `.250`, cdn `.252`, database `.188` (CDE) | ✅ freshclam + clamscan | CDE PCI gap closed |
| share `.254`, ollama `.7` | ✅ installed + freshclam + clamscan | ample RAM (3.9 / 16 GB) |
| **proxy `.253`** | ❌ **EXCLUDED** | **957 MB VM — too small; installing it OOM'd the VM** (see gotcha below). Agentless scan if AV ever required. |

Daily health check (platform.production-checks §4) flags per-VM state; also reads
`/var/log/clamav/scan-status.log` for detections. Alerting on detection currently uses local `mail`
(unreliable — see #21).

> ⚠️ **Gotcha — check VM RAM before installing heavy tools.** `bcos-proxy` is only **957 MB**.
> Installing ClamAV there (freshclam + a 2 GB clamscan) **OOM'd the guest** — it hung mid-`apt` and
> needed a **hard reboot** (`openstack server reboot --hard`) to recover; soft reboot doesn't work on
> a hung guest. Core services were unaffected. Always `free -m` a VM before adding memory-heavy agents.
> Tiny VMs (proxy) → agentless/remote scanning, not on-host clamscan.

## Firewall & SSH — confirmed 2026-07-02 (#17)

**Firewall of record = OpenStack security groups** (host `ufw` is not the control and is not needed).
Public (`0.0.0.0/0`) ingress surface:
- `HTTPS ingress` SG → **443**
- `hiveiq-services` SG → **80** + ICMP. SSH **22 restricted** to internal CIDRs (`10.10.10.0/24`,
  `10.200.0.0/24` VPN) + one admin IP (`45.16.76.42/32`); Loki **3100** restricted to `10.10.10.0/24`.

**SSH brute-force = mitigated.** All VMs: `passwordauthentication no` (key-only), root key-only. So
password brute-force is impossible → **fail2ban is optional** (log-noise only, not a security gap).

**Optional hygiene:** delete the dead **`SSH ingress` SG** (opens 22 to `0.0.0.0/0` but is attached to
no server — latent risk); consider `permitrootlogin no`.

See **platform.production-checks**, **devops.backups**, **platform.topology**.
