# RMM & Patch Management — SNS Support

**Entity:** SNS Support · **Status:** Buildable now

## What it is

Remote monitoring and management (RMM) for maintaining hosts without SSH-ing into
each one manually. Patch management ensures security updates land promptly.
This is the recurring-revenue engine — what you sell as "managed services."

## Stack

| Component | Software | FOSS | Role |
|-----------|----------|------|------|
| RMM / remote management | MeshCentral | Yes | Remote access, terminal, file transfer, inventory |
| Patch management | unattended-upgrades + Ansible | Yes | Auto security patches + scheduled full updates |
| Configuration drift | Ansible (periodic runs) | Yes | Detect and correct drift from desired state |
| Inventory | MeshCentral + Ansible facts | Yes | Hardware/software inventory per host |
| Ticketing (future) | Zammad or FreeScout | Yes | Client-facing ticket system when needed |

## Architecture

```
┌─────────────────────────────────┐
│  MeshCentral (VM on Proxmox)    │
│  - Web UI (Authelia-gated)      │
│  - Agent management             │
│  - Remote terminal/desktop      │
└──────────────┬──────────────────┘
               │
    ┌──────────┼──────────┬──────────────┐
    ▼          ▼          ▼              ▼
 Host A     Host B     Host C      Client PC
 (agent)    (agent)    (agent)     (agent)
```

## MeshCentral

**Why MeshCentral over commercial RMM (ConnectWise, Datto, NinjaRMM):**
- Fully FOSS (Apache 2.0 license)
- Self-hosted — no per-device SaaS fees
- Supports Linux, Windows, macOS agents
- Web-based remote desktop/terminal
- Device groups, user permissions, audit logging
- Good enough for 1–50 managed endpoints

**Limitations (the ceiling):**
- No built-in patch management (that's Ansible's job)
- No PSA/ticketing integration (add Zammad when needed)
- Single-node only (no built-in HA)

## Patch Strategy

| Patch type | Method | Timing | Approval |
|------------|--------|--------|----------|
| Security (critical) | unattended-upgrades | Daily, automatic | None needed |
| Security (kernel) | Ansible playbook | Weekly maintenance window | Auto (reboot scheduled) |
| Feature / major version | Ansible playbook | Monthly, manual trigger | Sam approves |
| Application updates | Docker image pull + restart | Per-app schedule | CI/CD pipeline |

### unattended-upgrades config (every host):
```
Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Mail "sam@snsnetlabs.com";
```

### Ansible patch playbook (weekly):
```yaml
# playbooks/patch.yml
- hosts: all
  become: true
  tasks:
    - name: Update all packages
      apt:
        upgrade: safe
        update_cache: yes

    - name: Check if reboot required
      stat:
        path: /var/run/reboot-required
      register: reboot_file

    - name: Schedule reboot (Sunday 03:00)
      command: shutdown -r 03:00
      when: reboot_file.stat.exists
```

## Build Steps

1. **MeshCentral VM:** Clone Debian 12 template. 2 vCPU, 2GB RAM.
   ```bash
   # Install
   apt install nodejs npm
   mkdir /opt/meshcentral && cd /opt/meshcentral
   npm install meshcentral
   node node_modules/meshcentral --install
   ```

2. **Caddy reverse proxy:** `mesh.internal.sns` → MeshCentral port 443.
   Gate behind Authelia for web UI access.

3. **Deploy agents:** MeshCentral generates install scripts per OS.
   Add to Ansible `base-hardening` role so every new host gets an agent.

4. **Ansible scheduled runs:**
   ```bash
   # Cron on Ansible control node (or Gitea Actions scheduled workflow)
   0 2 * * 0  ansible-playbook /srv/ansible/playbooks/patch.yml
   ```

5. **Drift detection:**
   ```bash
   # Weekly: run playbook in check mode, alert on changes
   ansible-playbook site.yml --check --diff | mail -s "Drift report" sam@snsnetlabs.com
   ```

## Security Posture

- **MeshCentral:** Authelia 2FA required. Agent-to-server communication is TLS.
  No agents phone home to the internet (server is on-prem only via VPN).
- **Ansible:** SSH key-only, no passwords. Runs from a dedicated control node.
  Playbooks in Gitea (version controlled, auditable).
- **Patch lag:** Critical security patches land within 24h (unattended-upgrades).
  Kernel patches within 7 days (next maintenance window).
- **Client separation:** MeshCentral device groups + Ansible inventory groups.
  Each client's hosts are isolated from others.

## Upgrade Path

- **Zammad / FreeScout:** Client-facing ticketing when you have 3+ managed clients.
- **Rundeck:** If Ansible ad-hoc commands need a web UI for on-call staff.
- **Commercial RMM (Tactical RMM):** FOSS alternative with built-in patching if
  MeshCentral + Ansible combo gets too manual at 50+ endpoints.

<!-- ponytail: MeshCentral + Ansible instead of commercial RMM. Ceiling: no
     integrated patching UI, no ticketing. Upgrade: Tactical RMM (FOSS) or
     add Zammad for tickets when client count justifies it. -->
