Added Zabbix autoregister scripts
This commit is contained in:
342
Zabbix-fix.md
Normal file
342
Zabbix-fix.md
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
# Zabbix Auto-Registration Deployment
|
||||||
|
|
||||||
|
Deployment scripts and documentation for Zabbix Agent 2 with PSK-encrypted auto-registration against `zabbix.snarfnet.net`.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This project automates the end-to-end setup of Zabbix active agent auto-registration:
|
||||||
|
|
||||||
|
1. **Server-side:** Creates auto-registration actions via the Zabbix API so new agents are automatically assigned to host groups and linked to templates.
|
||||||
|
2. **Agent-side:** Installs and configures Zabbix Agent 2 with PSK encryption on Linux (x86_64 and ARM) and Windows hosts.
|
||||||
|
|
||||||
|
When an agent starts with `ServerActive` and `HostMetadata` configured, it reaches out to the Zabbix server on port 10051. The server matches the metadata against auto-registration action conditions and automatically adds the host.
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `configure_server_autoregistration.sh` | Creates host groups and auto-registration actions on the Zabbix server via API |
|
||||||
|
| `deploy_zabbix_agent_linux.sh` | Agent install for Linux x86_64 (RHEL, Debian, Ubuntu) |
|
||||||
|
| `deploy_zabbix_agent_linux_arm.sh` | Agent install for Linux ARM (aarch64, armhf, Raspberry Pi) |
|
||||||
|
| `deploy_zabbix_agent_windows.ps1` | Agent install for Windows x86_64 |
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- **Zabbix Server 7.0** running and accessible
|
||||||
|
- **PSK encryption** already configured on the server (Administration → General → Autoregistration)
|
||||||
|
- **Port 10051/TCP** exposed and reachable from agent hosts (see [Kubernetes Exposure](#kubernetes-exposure) if running in k8s)
|
||||||
|
- `curl` and `jq` on the machine running the server config script
|
||||||
|
- `openssl` on agent hosts (for PSK key generation if not providing one)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 1: Expose Zabbix Server Trapper Port (Kubernetes)
|
||||||
|
|
||||||
|
If your Zabbix server runs in Kubernetes, port 10051 must be exposed externally for agents to connect. The web UI (443) is not sufficient — agents need the trapper port.
|
||||||
|
|
||||||
|
### Ports Required
|
||||||
|
|
||||||
|
| Port | Service | Direction | Purpose |
|
||||||
|
|------|---------|-----------|---------|
|
||||||
|
| **10051/TCP** | zabbix-server | Inbound from agents | Active check-ins, auto-registration |
|
||||||
|
| 443/TCP | zabbix-web | Inbound from users | Web UI and API |
|
||||||
|
|
||||||
|
### Option A: LoadBalancer Service (recommended)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: zabbix-server-trapper
|
||||||
|
namespace: zabbix
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
|
selector:
|
||||||
|
app: zabbix-server # match your pod labels
|
||||||
|
ports:
|
||||||
|
- name: trapper
|
||||||
|
port: 10051
|
||||||
|
targetPort: 10051
|
||||||
|
protocol: TCP
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option B: NodePort Service
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: zabbix-server-trapper
|
||||||
|
namespace: zabbix
|
||||||
|
spec:
|
||||||
|
type: NodePort
|
||||||
|
selector:
|
||||||
|
app: zabbix-server # match your pod labels
|
||||||
|
ports:
|
||||||
|
- name: trapper
|
||||||
|
port: 10051
|
||||||
|
targetPort: 10051
|
||||||
|
nodePort: 30051
|
||||||
|
protocol: TCP
|
||||||
|
```
|
||||||
|
|
||||||
|
With NodePort, update agent `ServerActive` to use `<node-ip>:30051` or put a load balancer in front.
|
||||||
|
|
||||||
|
### Option C: Nginx Ingress TCP Passthrough
|
||||||
|
|
||||||
|
Add to the ingress controller's TCP ConfigMap:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: tcp-services
|
||||||
|
namespace: ingress-nginx
|
||||||
|
data:
|
||||||
|
"10051": "zabbix/zabbix-server:10051"
|
||||||
|
```
|
||||||
|
|
||||||
|
Ensure the ingress controller's Service also exposes port 10051.
|
||||||
|
|
||||||
|
### DNS Considerations
|
||||||
|
|
||||||
|
Make sure `zabbix.snarfnet.net` resolves to the IP where port 10051 is exposed. If the web UI and trapper are on different IPs, either:
|
||||||
|
- Point the main DNS record to the trapper LB and use a separate record for the web UI
|
||||||
|
- Or update `ServerActive` in agent configs to a dedicated trapper hostname
|
||||||
|
|
||||||
|
### Verify Connectivity
|
||||||
|
|
||||||
|
From an agent host:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nc -zv zabbix.snarfnet.net 10051
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: `Connection to zabbix.snarfnet.net 10051 port [tcp/*] succeeded!`
|
||||||
|
|
||||||
|
If you get "connection refused" — the port isn't exposed or the trapper process isn't running.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 2: Configure Server Auto-Registration Actions
|
||||||
|
|
||||||
|
Run the server configuration script to create host groups and auto-registration actions:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash configure_server_autoregistration.sh -u Admin -p 'your_zabbix_admin_password'
|
||||||
|
```
|
||||||
|
|
||||||
|
### What it does
|
||||||
|
|
||||||
|
1. Authenticates with the Zabbix API at `https://zabbix.snarfnet.net/api_jsonrpc.php`
|
||||||
|
2. Finds or creates host groups: `Linux servers`, `Windows servers`
|
||||||
|
3. Looks up templates: `Linux by Zabbix agent active`, `Windows by Zabbix agent active`
|
||||||
|
4. Creates two auto-registration actions (skips if they already exist)
|
||||||
|
|
||||||
|
### Actions Created
|
||||||
|
|
||||||
|
| Action | Condition | Operations |
|
||||||
|
|--------|-----------|------------|
|
||||||
|
| Auto-register Linux hosts | Host metadata contains `Linux` | Add to group `Linux servers`, link template `Linux by Zabbix agent active` |
|
||||||
|
| Auto-register Windows hosts | Host metadata contains `Windows` | Add to group `Windows servers`, link template `Windows by Zabbix agent active` |
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-u Zabbix API username (required)
|
||||||
|
-p Zabbix API password (required)
|
||||||
|
-s Zabbix API URL (default: https://zabbix.snarfnet.net/api_jsonrpc.php)
|
||||||
|
-h Show help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Notes
|
||||||
|
|
||||||
|
- The API user must have **Super admin** role to create actions
|
||||||
|
- PSK configuration is assumed to already be in place (Administration → General → Autoregistration)
|
||||||
|
- The script is idempotent — safe to run multiple times
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 3: Deploy Agents
|
||||||
|
|
||||||
|
### Generate a Shared PSK Key
|
||||||
|
|
||||||
|
All agents must use the same PSK key that's configured on the server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl rand -hex 32
|
||||||
|
```
|
||||||
|
|
||||||
|
### Linux x86_64
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Auto-generate PSK (prints key at end)
|
||||||
|
sudo bash deploy_zabbix_agent_linux.sh
|
||||||
|
|
||||||
|
# With a specific PSK
|
||||||
|
sudo bash deploy_zabbix_agent_linux.sh "your_64_char_hex_psk_here"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Supports:** RHEL/CentOS/Rocky/Alma 8+, Ubuntu, Debian
|
||||||
|
|
||||||
|
**What it does:**
|
||||||
|
1. Detects OS family (RHEL or Debian-based)
|
||||||
|
2. Adds the Zabbix 7.0 repository and installs `zabbix-agent2`
|
||||||
|
3. Writes PSK file with restricted permissions (640, root:zabbix)
|
||||||
|
4. Configures `ServerActive=zabbix.snarfnet.net`, `HostMetadata=Linux`, TLS PSK settings
|
||||||
|
5. Enables and starts the `zabbix-agent2` service
|
||||||
|
|
||||||
|
### Linux ARM (Raspberry Pi, aarch64, armhf)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Auto-generate PSK
|
||||||
|
sudo bash deploy_zabbix_agent_linux_arm.sh
|
||||||
|
|
||||||
|
# With a specific PSK
|
||||||
|
sudo bash deploy_zabbix_agent_linux_arm.sh "your_64_char_hex_psk_here"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Supports:** Raspberry Pi OS, Ubuntu ARM, Debian ARM, any aarch64/armhf/armv6l Linux with systemd
|
||||||
|
|
||||||
|
**What it does:**
|
||||||
|
1. Detects architecture (aarch64, armv7l, armv6l)
|
||||||
|
2. Tries package manager install (apt on Debian/Ubuntu/Raspbian)
|
||||||
|
3. Falls back to pre-compiled static binary tarball from Zabbix CDN
|
||||||
|
4. Creates systemd service unit for binary installs
|
||||||
|
5. Creates `zabbix` user if needed
|
||||||
|
6. Writes PSK file and agent configuration
|
||||||
|
7. Enables and starts the service
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Run as Administrator
|
||||||
|
|
||||||
|
# Auto-generate PSK
|
||||||
|
.\deploy_zabbix_agent_windows.ps1
|
||||||
|
|
||||||
|
# With a specific PSK
|
||||||
|
.\deploy_zabbix_agent_windows.ps1 -PskKey "your_64_char_hex_psk_here"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Supports:** Windows Server 2016+, Windows 10/11 (x86_64)
|
||||||
|
|
||||||
|
**What it does:**
|
||||||
|
1. Downloads Zabbix Agent 2 MSI from official CDN
|
||||||
|
2. Installs silently to `C:\Program Files\Zabbix Agent 2`
|
||||||
|
3. Writes PSK file with ACL-restricted permissions (Administrators + SYSTEM only)
|
||||||
|
4. Writes agent config with `HostMetadata=Windows` and TLS PSK settings
|
||||||
|
5. Adds Windows Firewall rule for port 10050 inbound (Domain/Private profiles)
|
||||||
|
6. Sets service to automatic start and starts it
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration Reference
|
||||||
|
|
||||||
|
| Setting | Value |
|
||||||
|
|---------|-------|
|
||||||
|
| Zabbix Server | `zabbix.snarfnet.net` |
|
||||||
|
| PSK Identity | `PSK_autoregister` |
|
||||||
|
| Host Metadata (Linux) | `Linux` |
|
||||||
|
| Host Metadata (Windows) | `Windows` |
|
||||||
|
| PSK File (Linux) | `/etc/zabbix/zabbix_agent2.psk` |
|
||||||
|
| PSK File (Windows) | `C:\Program Files\Zabbix Agent 2\zabbix_agent2.psk` |
|
||||||
|
| Agent Config (Linux) | `/etc/zabbix/zabbix_agent2.conf` |
|
||||||
|
| Agent Config (Windows) | `C:\Program Files\Zabbix Agent 2\zabbix_agent2.conf` |
|
||||||
|
| Trapper Port | 10051 (agent → server, active checks + registration) |
|
||||||
|
| Agent Port | 10050 (server → agent, passive checks) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Notes
|
||||||
|
|
||||||
|
- PSK key must be **identical** on the server and all agents using the same identity
|
||||||
|
- PSK files are permission-locked (640 on Linux, ACL-restricted on Windows)
|
||||||
|
- Use unique PSK identities per environment to segment (e.g., `PSK_prod`, `PSK_dev`)
|
||||||
|
- Rotate PSK keys by updating the server autoregistration config and redeploying agents
|
||||||
|
- The server config script does **not** modify PSK settings — manage those separately in the Zabbix UI
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Connectivity Test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From agent → server (must succeed for auto-registration)
|
||||||
|
nc -zv zabbix.snarfnet.net 10051
|
||||||
|
```
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Test-NetConnection -ComputerName zabbix.snarfnet.net -Port 10051
|
||||||
|
```
|
||||||
|
|
||||||
|
### Agent Logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Linux
|
||||||
|
journalctl -u zabbix-agent2 --since "5 minutes ago"
|
||||||
|
tail -f /var/log/zabbix/zabbix_agent2.log
|
||||||
|
grep -iE "error|failed|denied|psk|tls" /var/log/zabbix/zabbix_agent2.log
|
||||||
|
```
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Windows
|
||||||
|
Get-Content "C:\Program Files\Zabbix Agent 2\zabbix_agent2.log" -Tail 50
|
||||||
|
Select-String -Path "C:\Program Files\Zabbix Agent 2\zabbix_agent2.log" -Pattern "error|failed|denied|psk|tls"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Server Logs (on Zabbix server)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tail -f /var/log/zabbix/zabbix_server.log | grep -i "autoregistration\|psk\|tls\|cannot"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
| Symptom | Cause | Fix |
|
||||||
|
|---------|-------|-----|
|
||||||
|
| `connection refused` on 10051 | Port not exposed (Kubernetes) or trapper not running | Expose port 10051 via LoadBalancer/NodePort; check `StartTrappers` in server config |
|
||||||
|
| `connection timed out` on 10051 | Firewall blocking traffic | Open outbound 10051 on agent host; open inbound 10051 on server/cluster |
|
||||||
|
| `TLS handshake failed` | PSK key or identity mismatch | Verify key matches exactly; check for trailing newlines in PSK file |
|
||||||
|
| Agent connects but host doesn't appear | Auto-registration action missing or disabled | Run `configure_server_autoregistration.sh`; verify actions are enabled in UI |
|
||||||
|
| Action exists but doesn't trigger | HostMetadata doesn't match condition | Verify agent config has `HostMetadata=Linux` or `HostMetadata=Windows` |
|
||||||
|
| Hostname conflict | Host with same name already exists | Delete/rename existing host in Zabbix, or change `HostnameItem` |
|
||||||
|
| Script creates actions with invalid JSON | Log messages captured in variables | Fixed in current version — `log()` writes to stderr |
|
||||||
|
|
||||||
|
### Verify Agent Config
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Linux — confirm critical settings
|
||||||
|
grep -E "^Server=|^ServerActive=|^HostMetadata=|^TLS" /etc/zabbix/zabbix_agent2.conf
|
||||||
|
|
||||||
|
# Check PSK file has no trailing newline
|
||||||
|
cat -A /etc/zabbix/zabbix_agent2.psk
|
||||||
|
# Should end with $ immediately after hex string, no extra lines
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verify Server Actions via API
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Get auth token
|
||||||
|
TOKEN=$(curl -s -X POST https://zabbix.snarfnet.net/api_jsonrpc.php \
|
||||||
|
-H "Content-Type: application/json-rpc" \
|
||||||
|
-d '{"jsonrpc":"2.0","method":"user.login","params":{"username":"Admin","password":"YOUR_PASS"},"id":1}' \
|
||||||
|
| jq -r '.result')
|
||||||
|
|
||||||
|
# List autoregistration actions
|
||||||
|
curl -s -X POST https://zabbix.snarfnet.net/api_jsonrpc.php \
|
||||||
|
-H "Content-Type: application/json-rpc" \
|
||||||
|
-d "{\"jsonrpc\":\"2.0\",\"method\":\"action.get\",\"params\":{\"filter\":{\"eventsource\":\"2\"}},\"auth\":\"${TOKEN}\",\"id\":2}" \
|
||||||
|
| jq '.result[] | {name, status}'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Deployment Order Summary
|
||||||
|
|
||||||
|
1. **Expose port 10051** on your Kubernetes cluster (LoadBalancer/NodePort/Ingress TCP)
|
||||||
|
2. **Verify connectivity** from an agent host: `nc -zv zabbix.snarfnet.net 10051`
|
||||||
|
3. **Run server config script** to create auto-registration actions
|
||||||
|
4. **Deploy agents** with the shared PSK key
|
||||||
|
5. **Verify** hosts appear in Zabbix UI under their respective host groups
|
||||||
342
zabbix-autoregister/README.md
Normal file
342
zabbix-autoregister/README.md
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
# Zabbix Auto-Registration Deployment
|
||||||
|
|
||||||
|
Deployment scripts and documentation for Zabbix Agent 2 with PSK-encrypted auto-registration against `zabbix.snarfnet.net`.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This project automates the end-to-end setup of Zabbix active agent auto-registration:
|
||||||
|
|
||||||
|
1. **Server-side:** Creates auto-registration actions via the Zabbix API so new agents are automatically assigned to host groups and linked to templates.
|
||||||
|
2. **Agent-side:** Installs and configures Zabbix Agent 2 with PSK encryption on Linux (x86_64 and ARM) and Windows hosts.
|
||||||
|
|
||||||
|
When an agent starts with `ServerActive` and `HostMetadata` configured, it reaches out to the Zabbix server on port 10051. The server matches the metadata against auto-registration action conditions and automatically adds the host.
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `configure_server_autoregistration.sh` | Creates host groups and auto-registration actions on the Zabbix server via API |
|
||||||
|
| `deploy_zabbix_agent_linux.sh` | Agent install for Linux x86_64 (RHEL, Debian, Ubuntu) |
|
||||||
|
| `deploy_zabbix_agent_linux_arm.sh` | Agent install for Linux ARM (aarch64, armhf, Raspberry Pi) |
|
||||||
|
| `deploy_zabbix_agent_windows.ps1` | Agent install for Windows x86_64 |
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- **Zabbix Server 7.0** running and accessible
|
||||||
|
- **PSK encryption** already configured on the server (Administration → General → Autoregistration)
|
||||||
|
- **Port 10051/TCP** exposed and reachable from agent hosts (see [Kubernetes Exposure](#kubernetes-exposure) if running in k8s)
|
||||||
|
- `curl` and `jq` on the machine running the server config script
|
||||||
|
- `openssl` on agent hosts (for PSK key generation if not providing one)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 1: Expose Zabbix Server Trapper Port (Kubernetes)
|
||||||
|
|
||||||
|
If your Zabbix server runs in Kubernetes, port 10051 must be exposed externally for agents to connect. The web UI (443) is not sufficient — agents need the trapper port.
|
||||||
|
|
||||||
|
### Ports Required
|
||||||
|
|
||||||
|
| Port | Service | Direction | Purpose |
|
||||||
|
|------|---------|-----------|---------|
|
||||||
|
| **10051/TCP** | zabbix-server | Inbound from agents | Active check-ins, auto-registration |
|
||||||
|
| 443/TCP | zabbix-web | Inbound from users | Web UI and API |
|
||||||
|
|
||||||
|
### Option A: LoadBalancer Service (recommended)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: zabbix-server-trapper
|
||||||
|
namespace: zabbix
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
|
selector:
|
||||||
|
app: zabbix-server # match your pod labels
|
||||||
|
ports:
|
||||||
|
- name: trapper
|
||||||
|
port: 10051
|
||||||
|
targetPort: 10051
|
||||||
|
protocol: TCP
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option B: NodePort Service
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: zabbix-server-trapper
|
||||||
|
namespace: zabbix
|
||||||
|
spec:
|
||||||
|
type: NodePort
|
||||||
|
selector:
|
||||||
|
app: zabbix-server # match your pod labels
|
||||||
|
ports:
|
||||||
|
- name: trapper
|
||||||
|
port: 10051
|
||||||
|
targetPort: 10051
|
||||||
|
nodePort: 30051
|
||||||
|
protocol: TCP
|
||||||
|
```
|
||||||
|
|
||||||
|
With NodePort, update agent `ServerActive` to use `<node-ip>:30051` or put a load balancer in front.
|
||||||
|
|
||||||
|
### Option C: Nginx Ingress TCP Passthrough
|
||||||
|
|
||||||
|
Add to the ingress controller's TCP ConfigMap:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: tcp-services
|
||||||
|
namespace: ingress-nginx
|
||||||
|
data:
|
||||||
|
"10051": "zabbix/zabbix-server:10051"
|
||||||
|
```
|
||||||
|
|
||||||
|
Ensure the ingress controller's Service also exposes port 10051.
|
||||||
|
|
||||||
|
### DNS Considerations
|
||||||
|
|
||||||
|
Make sure `zabbix.snarfnet.net` resolves to the IP where port 10051 is exposed. If the web UI and trapper are on different IPs, either:
|
||||||
|
- Point the main DNS record to the trapper LB and use a separate record for the web UI
|
||||||
|
- Or update `ServerActive` in agent configs to a dedicated trapper hostname
|
||||||
|
|
||||||
|
### Verify Connectivity
|
||||||
|
|
||||||
|
From an agent host:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nc -zv zabbix.snarfnet.net 10051
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: `Connection to zabbix.snarfnet.net 10051 port [tcp/*] succeeded!`
|
||||||
|
|
||||||
|
If you get "connection refused" — the port isn't exposed or the trapper process isn't running.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 2: Configure Server Auto-Registration Actions
|
||||||
|
|
||||||
|
Run the server configuration script to create host groups and auto-registration actions:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash configure_server_autoregistration.sh -u Admin -p 'your_zabbix_admin_password'
|
||||||
|
```
|
||||||
|
|
||||||
|
### What it does
|
||||||
|
|
||||||
|
1. Authenticates with the Zabbix API at `https://zabbix.snarfnet.net/api_jsonrpc.php`
|
||||||
|
2. Finds or creates host groups: `Linux servers`, `Windows servers`
|
||||||
|
3. Looks up templates: `Linux by Zabbix agent active`, `Windows by Zabbix agent active`
|
||||||
|
4. Creates two auto-registration actions (skips if they already exist)
|
||||||
|
|
||||||
|
### Actions Created
|
||||||
|
|
||||||
|
| Action | Condition | Operations |
|
||||||
|
|--------|-----------|------------|
|
||||||
|
| Auto-register Linux hosts | Host metadata contains `Linux` | Add to group `Linux servers`, link template `Linux by Zabbix agent active` |
|
||||||
|
| Auto-register Windows hosts | Host metadata contains `Windows` | Add to group `Windows servers`, link template `Windows by Zabbix agent active` |
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
```
|
||||||
|
-u Zabbix API username (required)
|
||||||
|
-p Zabbix API password (required)
|
||||||
|
-s Zabbix API URL (default: https://zabbix.snarfnet.net/api_jsonrpc.php)
|
||||||
|
-h Show help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Notes
|
||||||
|
|
||||||
|
- The API user must have **Super admin** role to create actions
|
||||||
|
- PSK configuration is assumed to already be in place (Administration → General → Autoregistration)
|
||||||
|
- The script is idempotent — safe to run multiple times
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step 3: Deploy Agents
|
||||||
|
|
||||||
|
### Generate a Shared PSK Key
|
||||||
|
|
||||||
|
All agents must use the same PSK key that's configured on the server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
openssl rand -hex 32
|
||||||
|
```
|
||||||
|
|
||||||
|
### Linux x86_64
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Auto-generate PSK (prints key at end)
|
||||||
|
sudo bash deploy_zabbix_agent_linux.sh
|
||||||
|
|
||||||
|
# With a specific PSK
|
||||||
|
sudo bash deploy_zabbix_agent_linux.sh "your_64_char_hex_psk_here"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Supports:** RHEL/CentOS/Rocky/Alma 8+, Ubuntu, Debian
|
||||||
|
|
||||||
|
**What it does:**
|
||||||
|
1. Detects OS family (RHEL or Debian-based)
|
||||||
|
2. Adds the Zabbix 7.0 repository and installs `zabbix-agent2`
|
||||||
|
3. Writes PSK file with restricted permissions (640, root:zabbix)
|
||||||
|
4. Configures `ServerActive=zabbix.snarfnet.net`, `HostMetadata=Linux`, TLS PSK settings
|
||||||
|
5. Enables and starts the `zabbix-agent2` service
|
||||||
|
|
||||||
|
### Linux ARM (Raspberry Pi, aarch64, armhf)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Auto-generate PSK
|
||||||
|
sudo bash deploy_zabbix_agent_linux_arm.sh
|
||||||
|
|
||||||
|
# With a specific PSK
|
||||||
|
sudo bash deploy_zabbix_agent_linux_arm.sh "your_64_char_hex_psk_here"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Supports:** Raspberry Pi OS, Ubuntu ARM, Debian ARM, any aarch64/armhf/armv6l Linux with systemd
|
||||||
|
|
||||||
|
**What it does:**
|
||||||
|
1. Detects architecture (aarch64, armv7l, armv6l)
|
||||||
|
2. Tries package manager install (apt on Debian/Ubuntu/Raspbian)
|
||||||
|
3. Falls back to pre-compiled static binary tarball from Zabbix CDN
|
||||||
|
4. Creates systemd service unit for binary installs
|
||||||
|
5. Creates `zabbix` user if needed
|
||||||
|
6. Writes PSK file and agent configuration
|
||||||
|
7. Enables and starts the service
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Run as Administrator
|
||||||
|
|
||||||
|
# Auto-generate PSK
|
||||||
|
.\deploy_zabbix_agent_windows.ps1
|
||||||
|
|
||||||
|
# With a specific PSK
|
||||||
|
.\deploy_zabbix_agent_windows.ps1 -PskKey "your_64_char_hex_psk_here"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Supports:** Windows Server 2016+, Windows 10/11 (x86_64)
|
||||||
|
|
||||||
|
**What it does:**
|
||||||
|
1. Downloads Zabbix Agent 2 MSI from official CDN
|
||||||
|
2. Installs silently to `C:\Program Files\Zabbix Agent 2`
|
||||||
|
3. Writes PSK file with ACL-restricted permissions (Administrators + SYSTEM only)
|
||||||
|
4. Writes agent config with `HostMetadata=Windows` and TLS PSK settings
|
||||||
|
5. Adds Windows Firewall rule for port 10050 inbound (Domain/Private profiles)
|
||||||
|
6. Sets service to automatic start and starts it
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration Reference
|
||||||
|
|
||||||
|
| Setting | Value |
|
||||||
|
|---------|-------|
|
||||||
|
| Zabbix Server | `zabbix.snarfnet.net` |
|
||||||
|
| PSK Identity | `PSK_autoregister` |
|
||||||
|
| Host Metadata (Linux) | `Linux` |
|
||||||
|
| Host Metadata (Windows) | `Windows` |
|
||||||
|
| PSK File (Linux) | `/etc/zabbix/zabbix_agent2.psk` |
|
||||||
|
| PSK File (Windows) | `C:\Program Files\Zabbix Agent 2\zabbix_agent2.psk` |
|
||||||
|
| Agent Config (Linux) | `/etc/zabbix/zabbix_agent2.conf` |
|
||||||
|
| Agent Config (Windows) | `C:\Program Files\Zabbix Agent 2\zabbix_agent2.conf` |
|
||||||
|
| Trapper Port | 10051 (agent → server, active checks + registration) |
|
||||||
|
| Agent Port | 10050 (server → agent, passive checks) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Notes
|
||||||
|
|
||||||
|
- PSK key must be **identical** on the server and all agents using the same identity
|
||||||
|
- PSK files are permission-locked (640 on Linux, ACL-restricted on Windows)
|
||||||
|
- Use unique PSK identities per environment to segment (e.g., `PSK_prod`, `PSK_dev`)
|
||||||
|
- Rotate PSK keys by updating the server autoregistration config and redeploying agents
|
||||||
|
- The server config script does **not** modify PSK settings — manage those separately in the Zabbix UI
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Connectivity Test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From agent → server (must succeed for auto-registration)
|
||||||
|
nc -zv zabbix.snarfnet.net 10051
|
||||||
|
```
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
Test-NetConnection -ComputerName zabbix.snarfnet.net -Port 10051
|
||||||
|
```
|
||||||
|
|
||||||
|
### Agent Logs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Linux
|
||||||
|
journalctl -u zabbix-agent2 --since "5 minutes ago"
|
||||||
|
tail -f /var/log/zabbix/zabbix_agent2.log
|
||||||
|
grep -iE "error|failed|denied|psk|tls" /var/log/zabbix/zabbix_agent2.log
|
||||||
|
```
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Windows
|
||||||
|
Get-Content "C:\Program Files\Zabbix Agent 2\zabbix_agent2.log" -Tail 50
|
||||||
|
Select-String -Path "C:\Program Files\Zabbix Agent 2\zabbix_agent2.log" -Pattern "error|failed|denied|psk|tls"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Server Logs (on Zabbix server)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tail -f /var/log/zabbix/zabbix_server.log | grep -i "autoregistration\|psk\|tls\|cannot"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
| Symptom | Cause | Fix |
|
||||||
|
|---------|-------|-----|
|
||||||
|
| `connection refused` on 10051 | Port not exposed (Kubernetes) or trapper not running | Expose port 10051 via LoadBalancer/NodePort; check `StartTrappers` in server config |
|
||||||
|
| `connection timed out` on 10051 | Firewall blocking traffic | Open outbound 10051 on agent host; open inbound 10051 on server/cluster |
|
||||||
|
| `TLS handshake failed` | PSK key or identity mismatch | Verify key matches exactly; check for trailing newlines in PSK file |
|
||||||
|
| Agent connects but host doesn't appear | Auto-registration action missing or disabled | Run `configure_server_autoregistration.sh`; verify actions are enabled in UI |
|
||||||
|
| Action exists but doesn't trigger | HostMetadata doesn't match condition | Verify agent config has `HostMetadata=Linux` or `HostMetadata=Windows` |
|
||||||
|
| Hostname conflict | Host with same name already exists | Delete/rename existing host in Zabbix, or change `HostnameItem` |
|
||||||
|
| Script creates actions with invalid JSON | Log messages captured in variables | Fixed in current version — `log()` writes to stderr |
|
||||||
|
|
||||||
|
### Verify Agent Config
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Linux — confirm critical settings
|
||||||
|
grep -E "^Server=|^ServerActive=|^HostMetadata=|^TLS" /etc/zabbix/zabbix_agent2.conf
|
||||||
|
|
||||||
|
# Check PSK file has no trailing newline
|
||||||
|
cat -A /etc/zabbix/zabbix_agent2.psk
|
||||||
|
# Should end with $ immediately after hex string, no extra lines
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verify Server Actions via API
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Get auth token
|
||||||
|
TOKEN=$(curl -s -X POST https://zabbix.snarfnet.net/api_jsonrpc.php \
|
||||||
|
-H "Content-Type: application/json-rpc" \
|
||||||
|
-d '{"jsonrpc":"2.0","method":"user.login","params":{"username":"Admin","password":"YOUR_PASS"},"id":1}' \
|
||||||
|
| jq -r '.result')
|
||||||
|
|
||||||
|
# List autoregistration actions
|
||||||
|
curl -s -X POST https://zabbix.snarfnet.net/api_jsonrpc.php \
|
||||||
|
-H "Content-Type: application/json-rpc" \
|
||||||
|
-d "{\"jsonrpc\":\"2.0\",\"method\":\"action.get\",\"params\":{\"filter\":{\"eventsource\":\"2\"}},\"auth\":\"${TOKEN}\",\"id\":2}" \
|
||||||
|
| jq '.result[] | {name, status}'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Deployment Order Summary
|
||||||
|
|
||||||
|
1. **Expose port 10051** on your Kubernetes cluster (LoadBalancer/NodePort/Ingress TCP)
|
||||||
|
2. **Verify connectivity** from an agent host: `nc -zv zabbix.snarfnet.net 10051`
|
||||||
|
3. **Run server config script** to create auto-registration actions
|
||||||
|
4. **Deploy agents** with the shared PSK key
|
||||||
|
5. **Verify** hosts appear in Zabbix UI under their respective host groups
|
||||||
330
zabbix-autoregister/configure_server_autoregistration.sh
Normal file
330
zabbix-autoregister/configure_server_autoregistration.sh
Normal file
@@ -0,0 +1,330 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Zabbix Server Auto-Registration Configuration Script
|
||||||
|
# Creates auto-registration actions via the Zabbix API.
|
||||||
|
# Target server: zabbix.snarfnet.net
|
||||||
|
#
|
||||||
|
# Usage: bash configure_server_autoregistration.sh -u <api_user> -p <api_password>
|
||||||
|
#
|
||||||
|
# Prerequisites: curl, jq
|
||||||
|
#
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# --- Defaults ---
|
||||||
|
ZABBIX_URL="https://zabbix.snarfnet.net/api_jsonrpc.php"
|
||||||
|
API_USER=""
|
||||||
|
API_PASSWORD=""
|
||||||
|
AUTH_TOKEN=""
|
||||||
|
|
||||||
|
# --- Parse Arguments ---
|
||||||
|
usage() {
|
||||||
|
cat << EOF
|
||||||
|
Usage: $0 -u <username> -p <password> [-s <server_url>]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-u Zabbix API username (e.g., Admin)
|
||||||
|
-p Zabbix API password
|
||||||
|
-s Zabbix API URL (default: ${ZABBIX_URL})
|
||||||
|
-h Show this help
|
||||||
|
|
||||||
|
Example:
|
||||||
|
$0 -u Admin -p zabbix
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
while getopts "u:p:s:h" opt; do
|
||||||
|
case ${opt} in
|
||||||
|
u) API_USER="${OPTARG}" ;;
|
||||||
|
p) API_PASSWORD="${OPTARG}" ;;
|
||||||
|
s) ZABBIX_URL="${OPTARG}" ;;
|
||||||
|
h) usage ;;
|
||||||
|
*) usage ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "${API_USER}" ] || [ -z "${API_PASSWORD}" ]; then
|
||||||
|
echo "ERROR: -u and -p are required."
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Functions ---
|
||||||
|
|
||||||
|
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >&2; }
|
||||||
|
|
||||||
|
api_call() {
|
||||||
|
local payload="$1"
|
||||||
|
local response
|
||||||
|
response=$(curl -s -X POST "${ZABBIX_URL}" \
|
||||||
|
-H "Content-Type: application/json-rpc" \
|
||||||
|
-d "${payload}")
|
||||||
|
|
||||||
|
# Check for errors
|
||||||
|
local error
|
||||||
|
error=$(echo "${response}" | jq -r '.error // empty')
|
||||||
|
if [ -n "${error}" ]; then
|
||||||
|
log "ERROR: API call failed:"
|
||||||
|
echo "${response}" | jq '.error' >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${response}"
|
||||||
|
}
|
||||||
|
|
||||||
|
authenticate() {
|
||||||
|
log "Authenticating with Zabbix API..."
|
||||||
|
local response
|
||||||
|
response=$(api_call "{
|
||||||
|
\"jsonrpc\": \"2.0\",
|
||||||
|
\"method\": \"user.login\",
|
||||||
|
\"params\": {
|
||||||
|
\"username\": \"${API_USER}\",
|
||||||
|
\"password\": \"${API_PASSWORD}\"
|
||||||
|
},
|
||||||
|
\"id\": 1
|
||||||
|
}")
|
||||||
|
|
||||||
|
AUTH_TOKEN=$(echo "${response}" | jq -r '.result')
|
||||||
|
if [ -z "${AUTH_TOKEN}" ] || [ "${AUTH_TOKEN}" = "null" ]; then
|
||||||
|
log "ERROR: Authentication failed. Check username/password."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
log "Authenticated successfully."
|
||||||
|
}
|
||||||
|
|
||||||
|
get_or_create_hostgroup() {
|
||||||
|
local group_name="$1"
|
||||||
|
|
||||||
|
# Try to find existing group
|
||||||
|
local response
|
||||||
|
response=$(api_call "{
|
||||||
|
\"jsonrpc\": \"2.0\",
|
||||||
|
\"method\": \"hostgroup.get\",
|
||||||
|
\"params\": {
|
||||||
|
\"filter\": {
|
||||||
|
\"name\": [\"${group_name}\"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
\"auth\": \"${AUTH_TOKEN}\",
|
||||||
|
\"id\": 3
|
||||||
|
}")
|
||||||
|
|
||||||
|
local groupid
|
||||||
|
groupid=$(echo "${response}" | jq -r '.result[0].groupid // empty')
|
||||||
|
|
||||||
|
if [ -n "${groupid}" ]; then
|
||||||
|
log " Found host group '${group_name}' (ID: ${groupid})"
|
||||||
|
echo "${groupid}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create the group
|
||||||
|
log " Creating host group '${group_name}'..."
|
||||||
|
response=$(api_call "{
|
||||||
|
\"jsonrpc\": \"2.0\",
|
||||||
|
\"method\": \"hostgroup.create\",
|
||||||
|
\"params\": {
|
||||||
|
\"name\": \"${group_name}\"
|
||||||
|
},
|
||||||
|
\"auth\": \"${AUTH_TOKEN}\",
|
||||||
|
\"id\": 4
|
||||||
|
}")
|
||||||
|
|
||||||
|
groupid=$(echo "${response}" | jq -r '.result.groupids[0] // empty')
|
||||||
|
if [ -z "${groupid}" ]; then
|
||||||
|
log "ERROR: Failed to create host group '${group_name}'."
|
||||||
|
echo "${response}" | jq . >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log " Created host group '${group_name}' (ID: ${groupid})"
|
||||||
|
echo "${groupid}"
|
||||||
|
}
|
||||||
|
|
||||||
|
get_template_id() {
|
||||||
|
local template_name="$1"
|
||||||
|
|
||||||
|
local response
|
||||||
|
response=$(api_call "{
|
||||||
|
\"jsonrpc\": \"2.0\",
|
||||||
|
\"method\": \"template.get\",
|
||||||
|
\"params\": {
|
||||||
|
\"filter\": {
|
||||||
|
\"host\": [\"${template_name}\"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
\"auth\": \"${AUTH_TOKEN}\",
|
||||||
|
\"id\": 5
|
||||||
|
}")
|
||||||
|
|
||||||
|
local templateid
|
||||||
|
templateid=$(echo "${response}" | jq -r '.result[0].templateid // empty')
|
||||||
|
|
||||||
|
if [ -z "${templateid}" ]; then
|
||||||
|
# Try searching by visible name
|
||||||
|
response=$(api_call "{
|
||||||
|
\"jsonrpc\": \"2.0\",
|
||||||
|
\"method\": \"template.get\",
|
||||||
|
\"params\": {
|
||||||
|
\"search\": {
|
||||||
|
\"name\": \"${template_name}\"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
\"auth\": \"${AUTH_TOKEN}\",
|
||||||
|
\"id\": 6
|
||||||
|
}")
|
||||||
|
templateid=$(echo "${response}" | jq -r '.result[0].templateid // empty')
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${templateid}" ]; then
|
||||||
|
log " WARNING: Template '${template_name}' not found. Skipping template link."
|
||||||
|
echo ""
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
log " Found template '${template_name}' (ID: ${templateid})"
|
||||||
|
echo "${templateid}"
|
||||||
|
}
|
||||||
|
|
||||||
|
create_autoregistration_action() {
|
||||||
|
local action_name="$1"
|
||||||
|
local metadata_value="$2"
|
||||||
|
local groupid="$3"
|
||||||
|
local templateid="$4"
|
||||||
|
|
||||||
|
# Check if action already exists
|
||||||
|
local response
|
||||||
|
response=$(api_call "{
|
||||||
|
\"jsonrpc\": \"2.0\",
|
||||||
|
\"method\": \"action.get\",
|
||||||
|
\"params\": {
|
||||||
|
\"filter\": {
|
||||||
|
\"name\": \"${action_name}\",
|
||||||
|
\"eventsource\": \"2\"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
\"auth\": \"${AUTH_TOKEN}\",
|
||||||
|
\"id\": 7
|
||||||
|
}")
|
||||||
|
|
||||||
|
local existing
|
||||||
|
existing=$(echo "${response}" | jq -r '.result[0].actionid // empty')
|
||||||
|
if [ -n "${existing}" ]; then
|
||||||
|
log " Action '${action_name}' already exists (ID: ${existing}). Skipping."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build operations array
|
||||||
|
local operations="[
|
||||||
|
{
|
||||||
|
\"operationtype\": \"4\",
|
||||||
|
\"opgroup\": [
|
||||||
|
{
|
||||||
|
\"groupid\": \"${groupid}\"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}"
|
||||||
|
|
||||||
|
# Add template link if we have a template ID
|
||||||
|
if [ -n "${templateid}" ]; then
|
||||||
|
operations="${operations},
|
||||||
|
{
|
||||||
|
\"operationtype\": \"6\",
|
||||||
|
\"optemplate\": [
|
||||||
|
{
|
||||||
|
\"templateid\": \"${templateid}\"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
operations="${operations}]"
|
||||||
|
|
||||||
|
# Create the action
|
||||||
|
log " Creating auto-registration action '${action_name}'..."
|
||||||
|
response=$(api_call "{
|
||||||
|
\"jsonrpc\": \"2.0\",
|
||||||
|
\"method\": \"action.create\",
|
||||||
|
\"params\": {
|
||||||
|
\"name\": \"${action_name}\",
|
||||||
|
\"eventsource\": \"2\",
|
||||||
|
\"status\": \"0\",
|
||||||
|
\"filter\": {
|
||||||
|
\"evaltype\": \"0\",
|
||||||
|
\"conditions\": [
|
||||||
|
{
|
||||||
|
\"conditiontype\": \"24\",
|
||||||
|
\"operator\": \"2\",
|
||||||
|
\"value\": \"${metadata_value}\"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
\"operations\": ${operations}
|
||||||
|
},
|
||||||
|
\"auth\": \"${AUTH_TOKEN}\",
|
||||||
|
\"id\": 8
|
||||||
|
}")
|
||||||
|
|
||||||
|
local actionid
|
||||||
|
actionid=$(echo "${response}" | jq -r '.result.actionids[0] // empty')
|
||||||
|
if [ -n "${actionid}" ]; then
|
||||||
|
log " Created action '${action_name}' (ID: ${actionid})"
|
||||||
|
else
|
||||||
|
log " ERROR: Failed to create action '${action_name}'."
|
||||||
|
echo "${response}" | jq . >&2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
logout() {
|
||||||
|
api_call "{
|
||||||
|
\"jsonrpc\": \"2.0\",
|
||||||
|
\"method\": \"user.logout\",
|
||||||
|
\"params\": [],
|
||||||
|
\"auth\": \"${AUTH_TOKEN}\",
|
||||||
|
\"id\": 99
|
||||||
|
}" > /dev/null 2>&1 || true
|
||||||
|
log "Logged out."
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Main ---
|
||||||
|
|
||||||
|
log "=== Zabbix Server Auto-Registration Configuration ==="
|
||||||
|
log "Server: ${ZABBIX_URL}"
|
||||||
|
|
||||||
|
# Check dependencies
|
||||||
|
for cmd in curl jq; do
|
||||||
|
if ! command -v "${cmd}" &> /dev/null; then
|
||||||
|
log "ERROR: '${cmd}' is required but not installed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Authenticate
|
||||||
|
authenticate
|
||||||
|
|
||||||
|
# Get/create host groups
|
||||||
|
log "Setting up host groups..."
|
||||||
|
LINUX_GROUP_ID=$(get_or_create_hostgroup "Linux servers")
|
||||||
|
WINDOWS_GROUP_ID=$(get_or_create_hostgroup "Windows servers")
|
||||||
|
|
||||||
|
# Find templates
|
||||||
|
log "Looking up templates..."
|
||||||
|
LINUX_TEMPLATE_ID=$(get_template_id "Linux by Zabbix agent active")
|
||||||
|
WINDOWS_TEMPLATE_ID=$(get_template_id "Windows by Zabbix agent active")
|
||||||
|
|
||||||
|
# Create auto-registration actions
|
||||||
|
log "Creating auto-registration actions..."
|
||||||
|
create_autoregistration_action "Auto-register Linux hosts" "Linux" "${LINUX_GROUP_ID}" "${LINUX_TEMPLATE_ID}"
|
||||||
|
create_autoregistration_action "Auto-register Windows hosts" "Windows" "${WINDOWS_GROUP_ID}" "${WINDOWS_TEMPLATE_ID}"
|
||||||
|
|
||||||
|
# Logout
|
||||||
|
logout
|
||||||
|
|
||||||
|
log ""
|
||||||
|
log "=== Configuration Complete ==="
|
||||||
|
log ""
|
||||||
|
log "Summary:"
|
||||||
|
log " - Linux hosts with metadata 'Linux' → group 'Linux servers' + template"
|
||||||
|
log " - Windows hosts with metadata 'Windows' → group 'Windows servers' + template"
|
||||||
|
log ""
|
||||||
|
log "Agents configured with the matching PSK key should now auto-register."
|
||||||
157
zabbix-autoregister/deploy_zabbix_agent_linux.sh
Normal file
157
zabbix-autoregister/deploy_zabbix_agent_linux.sh
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Zabbix Agent 2 Deployment Script - Linux
|
||||||
|
# Installs and configures Zabbix Agent 2 with PSK auto-registration
|
||||||
|
# Target server: zabbix.snarfnet.net
|
||||||
|
#
|
||||||
|
# Usage: sudo bash deploy_zabbix_agent_linux.sh [psk_key]
|
||||||
|
# psk_key - (optional) 128-char hex PSK. If omitted, one is generated.
|
||||||
|
#
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ZABBIX_SERVER="zabbix.snarfnet.net"
|
||||||
|
PSK_IDENTITY="PSK_autoregister"
|
||||||
|
PSK_FILE="/etc/zabbix/zabbix_agent2.psk"
|
||||||
|
AGENT_CONF="/etc/zabbix/zabbix_agent2.conf"
|
||||||
|
HOST_METADATA="Linux"
|
||||||
|
|
||||||
|
# --- Functions ---
|
||||||
|
|
||||||
|
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }
|
||||||
|
|
||||||
|
detect_os() {
|
||||||
|
if [ -f /etc/os-release ]; then
|
||||||
|
. /etc/os-release
|
||||||
|
OS_ID="${ID}"
|
||||||
|
OS_VERSION="${VERSION_ID%%.*}"
|
||||||
|
else
|
||||||
|
log "ERROR: Cannot detect OS. /etc/os-release not found."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
install_agent_rhel() {
|
||||||
|
local major_ver="$1"
|
||||||
|
log "Installing Zabbix Agent 2 on RHEL/CentOS ${major_ver}..."
|
||||||
|
|
||||||
|
# Install Zabbix repo
|
||||||
|
rpm -Uvh "https://repo.zabbix.com/zabbix/7.0/rhel/${major_ver}/x86_64/zabbix-release-latest-7.0.el${major_ver}.noarch.rpm" 2>/dev/null || true
|
||||||
|
dnf clean all
|
||||||
|
dnf install -y zabbix-agent2 zabbix-agent2-plugin-*
|
||||||
|
}
|
||||||
|
|
||||||
|
install_agent_debian() {
|
||||||
|
local codename="$1"
|
||||||
|
log "Installing Zabbix Agent 2 on Debian/Ubuntu (${codename})..."
|
||||||
|
|
||||||
|
wget -q "https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest+ubuntu_all.deb" -O /tmp/zabbix-release.deb
|
||||||
|
dpkg -i /tmp/zabbix-release.deb
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y zabbix-agent2 zabbix-agent2-plugin-*
|
||||||
|
rm -f /tmp/zabbix-release.deb
|
||||||
|
}
|
||||||
|
|
||||||
|
install_agent() {
|
||||||
|
detect_os
|
||||||
|
case "${OS_ID}" in
|
||||||
|
rhel|centos|rocky|alma|fedora)
|
||||||
|
install_agent_rhel "${OS_VERSION}"
|
||||||
|
;;
|
||||||
|
debian|ubuntu)
|
||||||
|
local codename
|
||||||
|
codename=$(lsb_release -cs 2>/dev/null || echo "jammy")
|
||||||
|
install_agent_debian "${codename}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log "ERROR: Unsupported OS '${OS_ID}'. Install zabbix-agent2 manually, then re-run."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_psk() {
|
||||||
|
openssl rand -hex 32
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_agent() {
|
||||||
|
local psk_key="$1"
|
||||||
|
|
||||||
|
log "Writing PSK to ${PSK_FILE}..."
|
||||||
|
echo "${psk_key}" > "${PSK_FILE}"
|
||||||
|
chmod 640 "${PSK_FILE}"
|
||||||
|
chown root:zabbix "${PSK_FILE}"
|
||||||
|
|
||||||
|
log "Configuring ${AGENT_CONF}..."
|
||||||
|
cp "${AGENT_CONF}" "${AGENT_CONF}.bak.$(date +%s)"
|
||||||
|
|
||||||
|
# Apply configuration
|
||||||
|
sed -i "s|^Server=.*|Server=${ZABBIX_SERVER}|" "${AGENT_CONF}"
|
||||||
|
sed -i "s|^ServerActive=.*|ServerActive=${ZABBIX_SERVER}|" "${AGENT_CONF}"
|
||||||
|
sed -i "s|^Hostname=.*|# Hostname=|" "${AGENT_CONF}"
|
||||||
|
|
||||||
|
# Add/update settings that may not exist
|
||||||
|
grep -q "^HostnameItem=" "${AGENT_CONF}" && \
|
||||||
|
sed -i "s|^HostnameItem=.*|HostnameItem=system.hostname|" "${AGENT_CONF}" || \
|
||||||
|
echo "HostnameItem=system.hostname" >> "${AGENT_CONF}"
|
||||||
|
|
||||||
|
grep -q "^HostMetadata=" "${AGENT_CONF}" && \
|
||||||
|
sed -i "s|^HostMetadata=.*|HostMetadata=${HOST_METADATA}|" "${AGENT_CONF}" || \
|
||||||
|
echo "HostMetadata=${HOST_METADATA}" >> "${AGENT_CONF}"
|
||||||
|
|
||||||
|
grep -q "^TLSConnect=" "${AGENT_CONF}" && \
|
||||||
|
sed -i "s|^TLSConnect=.*|TLSConnect=psk|" "${AGENT_CONF}" || \
|
||||||
|
echo "TLSConnect=psk" >> "${AGENT_CONF}"
|
||||||
|
|
||||||
|
grep -q "^TLSAccept=" "${AGENT_CONF}" && \
|
||||||
|
sed -i "s|^TLSAccept=.*|TLSAccept=psk|" "${AGENT_CONF}" || \
|
||||||
|
echo "TLSAccept=psk" >> "${AGENT_CONF}"
|
||||||
|
|
||||||
|
grep -q "^TLSPSKIdentity=" "${AGENT_CONF}" && \
|
||||||
|
sed -i "s|^TLSPSKIdentity=.*|TLSPSKIdentity=${PSK_IDENTITY}|" "${AGENT_CONF}" || \
|
||||||
|
echo "TLSPSKIdentity=${PSK_IDENTITY}" >> "${AGENT_CONF}"
|
||||||
|
|
||||||
|
grep -q "^TLSPSKFile=" "${AGENT_CONF}" && \
|
||||||
|
sed -i "s|^TLSPSKFile=.*|TLSPSKFile=${PSK_FILE}|" "${AGENT_CONF}" || \
|
||||||
|
echo "TLSPSKFile=${PSK_FILE}" >> "${AGENT_CONF}"
|
||||||
|
}
|
||||||
|
|
||||||
|
start_agent() {
|
||||||
|
log "Enabling and starting zabbix-agent2..."
|
||||||
|
systemctl enable zabbix-agent2
|
||||||
|
systemctl restart zabbix-agent2
|
||||||
|
systemctl status zabbix-agent2 --no-pager
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Main ---
|
||||||
|
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
echo "This script must be run as root." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
PSK_KEY="${1:-}"
|
||||||
|
if [ -z "${PSK_KEY}" ]; then
|
||||||
|
PSK_KEY=$(generate_psk)
|
||||||
|
log "Generated new PSK key."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Validate PSK is valid hex and at least 32 chars
|
||||||
|
if ! echo "${PSK_KEY}" | grep -qE '^[0-9a-fA-F]{32,128}$'; then
|
||||||
|
log "ERROR: PSK must be a 32-128 character hex string."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "=== Zabbix Agent 2 Deployment ==="
|
||||||
|
log "Server: ${ZABBIX_SERVER}"
|
||||||
|
log "PSK Identity: ${PSK_IDENTITY}"
|
||||||
|
|
||||||
|
install_agent
|
||||||
|
configure_agent "${PSK_KEY}"
|
||||||
|
start_agent
|
||||||
|
|
||||||
|
log "=== Deployment Complete ==="
|
||||||
|
log "PSK Identity: ${PSK_IDENTITY}"
|
||||||
|
log "PSK Key: ${PSK_KEY}"
|
||||||
|
log ""
|
||||||
|
log "IMPORTANT: Use this same PSK identity and key in your Zabbix server"
|
||||||
|
log "auto-registration encryption settings."
|
||||||
266
zabbix-autoregister/deploy_zabbix_agent_linux_arm.sh
Normal file
266
zabbix-autoregister/deploy_zabbix_agent_linux_arm.sh
Normal file
@@ -0,0 +1,266 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Zabbix Agent 2 Deployment Script - Linux ARM (aarch64 / armhf)
|
||||||
|
# Installs and configures Zabbix Agent 2 with PSK auto-registration
|
||||||
|
# Target server: zabbix.snarfnet.net
|
||||||
|
#
|
||||||
|
# Usage: sudo bash deploy_zabbix_agent_linux_arm.sh [psk_key]
|
||||||
|
# psk_key - (optional) 128-char hex PSK. If omitted, one is generated.
|
||||||
|
#
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ZABBIX_SERVER="zabbix.snarfnet.net"
|
||||||
|
ZABBIX_VERSION="7.0.0"
|
||||||
|
PSK_IDENTITY="PSK_autoregister"
|
||||||
|
PSK_FILE="/etc/zabbix/zabbix_agent2.psk"
|
||||||
|
AGENT_CONF="/etc/zabbix/zabbix_agent2.conf"
|
||||||
|
HOST_METADATA="Linux"
|
||||||
|
INSTALL_DIR="/opt/zabbix-agent2"
|
||||||
|
|
||||||
|
# --- Functions ---
|
||||||
|
|
||||||
|
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }
|
||||||
|
|
||||||
|
detect_arch() {
|
||||||
|
ARCH=$(uname -m)
|
||||||
|
case "${ARCH}" in
|
||||||
|
aarch64|arm64)
|
||||||
|
ARCH_LABEL="aarch64"
|
||||||
|
TARBALL_ARCH="linux_arm64"
|
||||||
|
;;
|
||||||
|
armv7l|armhf)
|
||||||
|
ARCH_LABEL="armhf"
|
||||||
|
TARBALL_ARCH="linux_arm"
|
||||||
|
;;
|
||||||
|
armv6l)
|
||||||
|
ARCH_LABEL="armv6"
|
||||||
|
TARBALL_ARCH="linux_arm"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log "ERROR: Unsupported architecture '${ARCH}'."
|
||||||
|
log " Use deploy_zabbix_agent_linux.sh for x86_64 systems."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
log "Detected architecture: ${ARCH} (${ARCH_LABEL})"
|
||||||
|
}
|
||||||
|
|
||||||
|
detect_os() {
|
||||||
|
if [ -f /etc/os-release ]; then
|
||||||
|
. /etc/os-release
|
||||||
|
OS_ID="${ID}"
|
||||||
|
OS_VERSION="${VERSION_ID%%.*}"
|
||||||
|
else
|
||||||
|
OS_ID="unknown"
|
||||||
|
OS_VERSION="0"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
install_agent_package_manager() {
|
||||||
|
detect_os
|
||||||
|
case "${OS_ID}" in
|
||||||
|
debian|ubuntu|raspbian)
|
||||||
|
log "Installing via apt (Debian/Ubuntu/Raspbian)..."
|
||||||
|
# Determine arch string for the repo
|
||||||
|
local dpkg_arch
|
||||||
|
dpkg_arch=$(dpkg --print-architecture)
|
||||||
|
|
||||||
|
wget -q "https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest+ubuntu_all.deb" -O /tmp/zabbix-release.deb 2>/dev/null || \
|
||||||
|
wget -q "https://repo.zabbix.com/zabbix/7.0/debian/pool/main/z/zabbix-release/zabbix-release_latest+debian${OS_VERSION}_all.deb" -O /tmp/zabbix-release.deb 2>/dev/null || true
|
||||||
|
|
||||||
|
if [ -f /tmp/zabbix-release.deb ]; then
|
||||||
|
dpkg -i /tmp/zabbix-release.deb
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y zabbix-agent2 && { rm -f /tmp/zabbix-release.deb; return 0; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Package manager install failed, falling back to binary tarball..."
|
||||||
|
rm -f /tmp/zabbix-release.deb
|
||||||
|
install_agent_binary
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log "No ARM package available for '${OS_ID}', using binary tarball..."
|
||||||
|
install_agent_binary
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
install_agent_binary() {
|
||||||
|
log "Installing Zabbix Agent 2 from pre-compiled binary..."
|
||||||
|
|
||||||
|
local tarball_url="https://cdn.zabbix.com/zabbix/binaries/stable/7.0/${ZABBIX_VERSION}/zabbix_agent2-${ZABBIX_VERSION}-${TARBALL_ARCH}-static.tar.gz"
|
||||||
|
local tarball_path="/tmp/zabbix_agent2.tar.gz"
|
||||||
|
|
||||||
|
log "Downloading from: ${tarball_url}"
|
||||||
|
if ! wget -q "${tarball_url}" -O "${tarball_path}" 2>/dev/null && \
|
||||||
|
! curl -sL "${tarball_url}" -o "${tarball_path}" 2>/dev/null; then
|
||||||
|
log "ERROR: Failed to download Zabbix Agent 2 binary."
|
||||||
|
log " URL: ${tarball_url}"
|
||||||
|
log " You may need to check https://www.zabbix.com/download for the correct ARM binary."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create directories
|
||||||
|
mkdir -p "${INSTALL_DIR}/bin"
|
||||||
|
mkdir -p /etc/zabbix
|
||||||
|
mkdir -p /var/log/zabbix
|
||||||
|
mkdir -p /var/run/zabbix
|
||||||
|
|
||||||
|
# Extract
|
||||||
|
tar -xzf "${tarball_path}" -C "${INSTALL_DIR}" --strip-components=1 2>/dev/null || \
|
||||||
|
tar -xzf "${tarball_path}" -C "${INSTALL_DIR}" 2>/dev/null
|
||||||
|
|
||||||
|
# Find the binary
|
||||||
|
local agent_bin
|
||||||
|
agent_bin=$(find "${INSTALL_DIR}" -name "zabbix_agent2" -type f | head -1)
|
||||||
|
if [ -z "${agent_bin}" ]; then
|
||||||
|
log "ERROR: Could not find zabbix_agent2 binary in extracted archive."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Move binary to expected location
|
||||||
|
cp "${agent_bin}" "${INSTALL_DIR}/bin/zabbix_agent2"
|
||||||
|
chmod +x "${INSTALL_DIR}/bin/zabbix_agent2"
|
||||||
|
ln -sf "${INSTALL_DIR}/bin/zabbix_agent2" /usr/sbin/zabbix_agent2
|
||||||
|
|
||||||
|
# Create zabbix user if it doesn't exist
|
||||||
|
if ! id -u zabbix &>/dev/null; then
|
||||||
|
useradd -r -s /sbin/nologin -d /var/lib/zabbix -M zabbix
|
||||||
|
fi
|
||||||
|
|
||||||
|
chown -R zabbix:zabbix /var/log/zabbix /var/run/zabbix
|
||||||
|
|
||||||
|
# Set config path for binary installs
|
||||||
|
AGENT_CONF="/etc/zabbix/zabbix_agent2.conf"
|
||||||
|
|
||||||
|
# Create systemd service
|
||||||
|
create_systemd_service
|
||||||
|
|
||||||
|
rm -f "${tarball_path}"
|
||||||
|
log "Binary installation complete."
|
||||||
|
}
|
||||||
|
|
||||||
|
create_systemd_service() {
|
||||||
|
log "Creating systemd service..."
|
||||||
|
cat > /etc/systemd/system/zabbix-agent2.service << 'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Zabbix Agent 2
|
||||||
|
After=syslog.target
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Environment="CONFFILE=/etc/zabbix/zabbix_agent2.conf"
|
||||||
|
Type=simple
|
||||||
|
Restart=on-failure
|
||||||
|
PIDFile=/var/run/zabbix/zabbix_agent2.pid
|
||||||
|
KillMode=control-group
|
||||||
|
ExecStart=/usr/sbin/zabbix_agent2 -c $CONFFILE
|
||||||
|
ExecStop=/bin/kill -SIGTERM $MAINPID
|
||||||
|
RestartSec=10s
|
||||||
|
User=zabbix
|
||||||
|
Group=zabbix
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_psk() {
|
||||||
|
openssl rand -hex 32
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_agent() {
|
||||||
|
local psk_key="$1"
|
||||||
|
|
||||||
|
log "Writing PSK to ${PSK_FILE}..."
|
||||||
|
echo "${psk_key}" > "${PSK_FILE}"
|
||||||
|
chmod 640 "${PSK_FILE}"
|
||||||
|
chown root:zabbix "${PSK_FILE}"
|
||||||
|
|
||||||
|
log "Writing agent configuration to ${AGENT_CONF}..."
|
||||||
|
# Back up existing config if present
|
||||||
|
[ -f "${AGENT_CONF}" ] && cp "${AGENT_CONF}" "${AGENT_CONF}.bak.$(date +%s)"
|
||||||
|
|
||||||
|
cat > "${AGENT_CONF}" << EOF
|
||||||
|
# Zabbix Agent 2 Configuration
|
||||||
|
# Auto-generated by ARM deployment script on $(date '+%Y-%m-%d %H:%M:%S')
|
||||||
|
# Architecture: ${ARCH} (${ARCH_LABEL})
|
||||||
|
|
||||||
|
Server=${ZABBIX_SERVER}
|
||||||
|
ServerActive=${ZABBIX_SERVER}
|
||||||
|
HostnameItem=system.hostname
|
||||||
|
HostMetadata=${HOST_METADATA}
|
||||||
|
|
||||||
|
# PSK Encryption
|
||||||
|
TLSConnect=psk
|
||||||
|
TLSAccept=psk
|
||||||
|
TLSPSKIdentity=${PSK_IDENTITY}
|
||||||
|
TLSPSKFile=${PSK_FILE}
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
LogFile=/var/log/zabbix/zabbix_agent2.log
|
||||||
|
LogFileSize=10
|
||||||
|
|
||||||
|
# Performance
|
||||||
|
BufferSend=5
|
||||||
|
BufferSize=100
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chown root:zabbix "${AGENT_CONF}"
|
||||||
|
chmod 644 "${AGENT_CONF}"
|
||||||
|
}
|
||||||
|
|
||||||
|
start_agent() {
|
||||||
|
log "Enabling and starting zabbix-agent2..."
|
||||||
|
systemctl enable zabbix-agent2
|
||||||
|
systemctl restart zabbix-agent2
|
||||||
|
|
||||||
|
sleep 2
|
||||||
|
if systemctl is-active --quiet zabbix-agent2; then
|
||||||
|
log "Zabbix Agent 2 is running."
|
||||||
|
systemctl status zabbix-agent2 --no-pager
|
||||||
|
else
|
||||||
|
log "WARNING: Agent may not have started. Check logs:"
|
||||||
|
log " journalctl -u zabbix-agent2 -n 20"
|
||||||
|
log " cat /var/log/zabbix/zabbix_agent2.log"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Main ---
|
||||||
|
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
echo "This script must be run as root." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
PSK_KEY="${1:-}"
|
||||||
|
if [ -z "${PSK_KEY}" ]; then
|
||||||
|
PSK_KEY=$(generate_psk)
|
||||||
|
log "Generated new PSK key."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Validate PSK is valid hex and at least 32 chars
|
||||||
|
if ! echo "${PSK_KEY}" | grep -qE '^[0-9a-fA-F]{32,128}$'; then
|
||||||
|
log "ERROR: PSK must be a 32-128 character hex string."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
detect_arch
|
||||||
|
|
||||||
|
log "=== Zabbix Agent 2 Deployment (ARM) ==="
|
||||||
|
log "Server: ${ZABBIX_SERVER}"
|
||||||
|
log "PSK Identity: ${PSK_IDENTITY}"
|
||||||
|
log "Architecture: ${ARCH_LABEL}"
|
||||||
|
|
||||||
|
install_agent_package_manager
|
||||||
|
configure_agent "${PSK_KEY}"
|
||||||
|
start_agent
|
||||||
|
|
||||||
|
log "=== Deployment Complete ==="
|
||||||
|
log "PSK Identity: ${PSK_IDENTITY}"
|
||||||
|
log "PSK Key: ${PSK_KEY}"
|
||||||
|
log ""
|
||||||
|
log "IMPORTANT: Use this same PSK identity and key in your Zabbix server"
|
||||||
|
log "auto-registration encryption settings."
|
||||||
199
zabbix-autoregister/deploy_zabbix_agent_windows.ps1
Normal file
199
zabbix-autoregister/deploy_zabbix_agent_windows.ps1
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
#Requires -RunAsAdministrator
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Zabbix Agent 2 Deployment Script - Windows
|
||||||
|
Installs and configures Zabbix Agent 2 with PSK auto-registration.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
Target server: zabbix.snarfnet.net
|
||||||
|
Downloads Zabbix Agent 2 MSI, installs it, configures PSK encryption,
|
||||||
|
and starts the service for auto-registration.
|
||||||
|
|
||||||
|
.PARAMETER PskKey
|
||||||
|
Optional. A 64-character hex PSK key. If omitted, one is generated.
|
||||||
|
|
||||||
|
.PARAMETER ZabbixVersion
|
||||||
|
Optional. Zabbix version to install. Defaults to 7.0.0.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
.\deploy_zabbix_agent_windows.ps1
|
||||||
|
.\deploy_zabbix_agent_windows.ps1 -PskKey "aabbccdd..."
|
||||||
|
#>
|
||||||
|
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $false)]
|
||||||
|
[string]$PskKey = "",
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $false)]
|
||||||
|
[string]$ZabbixVersion = "7.0.26"
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- Configuration ---
|
||||||
|
$ZabbixServer = "zabbix.snarfnet.net"
|
||||||
|
$PskIdentity = "PSK_autoregister"
|
||||||
|
$HostMetadata = "Windows"
|
||||||
|
$InstallDir = "C:\Program Files\Zabbix Agent 2"
|
||||||
|
$ConfFile = "$InstallDir\zabbix_agent2.conf"
|
||||||
|
$PskFile = "$InstallDir\zabbix_agent2.psk"
|
||||||
|
$MsiUrl = "https://cdn.zabbix.com/zabbix/binaries/stable/7.0/$ZabbixVersion/zabbix_agent2-$ZabbixVersion-windows-amd64-openssl.msi"
|
||||||
|
$MsiPath = "$env:TEMP\zabbix_agent2.msi"
|
||||||
|
|
||||||
|
# --- Functions ---
|
||||||
|
|
||||||
|
function Write-Log {
|
||||||
|
param([string]$Message)
|
||||||
|
Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] $Message"
|
||||||
|
}
|
||||||
|
|
||||||
|
function New-PskKey {
|
||||||
|
$bytes = New-Object byte[] 32
|
||||||
|
$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
|
||||||
|
$rng.GetBytes($bytes)
|
||||||
|
return ($bytes | ForEach-Object { $_.ToString("x2") }) -join ''
|
||||||
|
}
|
||||||
|
|
||||||
|
function Install-ZabbixAgent {
|
||||||
|
Write-Log "Downloading Zabbix Agent 2 v$ZabbixVersion..."
|
||||||
|
|
||||||
|
try {
|
||||||
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||||
|
Invoke-WebRequest -Uri $MsiUrl -OutFile $MsiPath -UseBasicParsing
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Log "ERROR: Failed to download MSI from $MsiUrl"
|
||||||
|
Write-Log " $_"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Log "Installing Zabbix Agent 2..."
|
||||||
|
$msiArgs = @(
|
||||||
|
"/i", $MsiPath,
|
||||||
|
"/qn",
|
||||||
|
"/l*v", "$env:TEMP\zabbix_agent2_install.log",
|
||||||
|
"SERVER=$ZabbixServer",
|
||||||
|
"SERVERACTIVE=$ZabbixServer",
|
||||||
|
"INSTALLFOLDER=`"$InstallDir`""
|
||||||
|
)
|
||||||
|
$process = Start-Process msiexec.exe -ArgumentList $msiArgs -Wait -PassThru
|
||||||
|
if ($process.ExitCode -ne 0) {
|
||||||
|
Write-Log "ERROR: MSI installation failed with exit code $($process.ExitCode)"
|
||||||
|
Write-Log " Check log: $env:TEMP\zabbix_agent2_install.log"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Remove-Item $MsiPath -Force -ErrorAction SilentlyContinue
|
||||||
|
Write-Log "Installation complete."
|
||||||
|
}
|
||||||
|
|
||||||
|
function Set-AgentConfiguration {
|
||||||
|
param([string]$Key)
|
||||||
|
|
||||||
|
Write-Log "Writing PSK to $PskFile..."
|
||||||
|
Set-Content -Path $PskFile -Value $Key -NoNewline
|
||||||
|
$acl = Get-Acl $PskFile
|
||||||
|
$acl.SetAccessRuleProtection($true, $false)
|
||||||
|
$adminRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
|
||||||
|
"BUILTIN\Administrators", "FullControl", "Allow")
|
||||||
|
$systemRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
|
||||||
|
"NT AUTHORITY\SYSTEM", "FullControl", "Allow")
|
||||||
|
$acl.AddAccessRule($adminRule)
|
||||||
|
$acl.AddAccessRule($systemRule)
|
||||||
|
Set-Acl -Path $PskFile -AclObject $acl
|
||||||
|
|
||||||
|
Write-Log "Configuring $ConfFile..."
|
||||||
|
if (Test-Path $ConfFile) {
|
||||||
|
Copy-Item $ConfFile "$ConfFile.bak.$(Get-Date -Format 'yyyyMMddHHmmss')"
|
||||||
|
}
|
||||||
|
|
||||||
|
$config = @"
|
||||||
|
# Zabbix Agent 2 Configuration
|
||||||
|
# Auto-generated by deployment script on $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
|
||||||
|
|
||||||
|
Server=$ZabbixServer
|
||||||
|
ServerActive=$ZabbixServer
|
||||||
|
HostnameItem=system.hostname
|
||||||
|
HostMetadata=$HostMetadata
|
||||||
|
|
||||||
|
# PSK Encryption
|
||||||
|
TLSConnect=psk
|
||||||
|
TLSAccept=psk
|
||||||
|
TLSPSKIdentity=$PskIdentity
|
||||||
|
TLSPSKFile=$PskFile
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
LogFile=$InstallDir\zabbix_agent2.log
|
||||||
|
LogFileSize=10
|
||||||
|
|
||||||
|
# Performance
|
||||||
|
BufferSend=5
|
||||||
|
BufferSize=100
|
||||||
|
"@
|
||||||
|
|
||||||
|
Set-Content -Path $ConfFile -Value $config
|
||||||
|
Write-Log "Configuration written."
|
||||||
|
}
|
||||||
|
|
||||||
|
function Start-ZabbixAgent {
|
||||||
|
Write-Log "Configuring Zabbix Agent 2 service..."
|
||||||
|
|
||||||
|
$svc = Get-Service -Name "Zabbix Agent 2" -ErrorAction SilentlyContinue
|
||||||
|
if (-not $svc) {
|
||||||
|
Write-Log "ERROR: Zabbix Agent 2 service not found. Installation may have failed."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Set-Service -Name "Zabbix Agent 2" -StartupType Automatic
|
||||||
|
Restart-Service -Name "Zabbix Agent 2" -Force
|
||||||
|
Start-Sleep -Seconds 2
|
||||||
|
|
||||||
|
$svc = Get-Service -Name "Zabbix Agent 2"
|
||||||
|
if ($svc.Status -eq "Running") {
|
||||||
|
Write-Log "Zabbix Agent 2 is running."
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Log "WARNING: Service status is '$($svc.Status)'. Check logs at $InstallDir\zabbix_agent2.log"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Add-FirewallRule {
|
||||||
|
$ruleName = "Zabbix Agent 2 (TCP-In 10050)"
|
||||||
|
$existing = Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue
|
||||||
|
if (-not $existing) {
|
||||||
|
Write-Log "Adding firewall rule for port 10050..."
|
||||||
|
New-NetFirewallRule -DisplayName $ruleName `
|
||||||
|
-Direction Inbound -Protocol TCP -LocalPort 10050 `
|
||||||
|
-Action Allow -Profile Domain, Private | Out-Null
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Log "Firewall rule already exists."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Main ---
|
||||||
|
|
||||||
|
Write-Log "=== Zabbix Agent 2 Deployment (Windows) ==="
|
||||||
|
Write-Log "Server: $ZabbixServer"
|
||||||
|
Write-Log "PSK Identity: $PskIdentity"
|
||||||
|
|
||||||
|
# Generate or validate PSK
|
||||||
|
if ([string]::IsNullOrEmpty($PskKey)) {
|
||||||
|
$PskKey = New-PskKey
|
||||||
|
Write-Log "Generated new PSK key."
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($PskKey -notmatch '^[0-9a-fA-F]{32,128}$') {
|
||||||
|
Write-Log "ERROR: PSK must be a 32-128 character hex string."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Install-ZabbixAgent
|
||||||
|
Set-AgentConfiguration -Key $PskKey
|
||||||
|
Add-FirewallRule
|
||||||
|
Start-ZabbixAgent
|
||||||
|
|
||||||
|
Write-Log "=== Deployment Complete ==="
|
||||||
|
Write-Log "PSK Identity: $PskIdentity"
|
||||||
|
Write-Log "PSK Key: $PskKey"
|
||||||
|
Write-Log ""
|
||||||
|
Write-Log "IMPORTANT: Use this same PSK identity and key in your Zabbix server"
|
||||||
|
Write-Log " auto-registration encryption settings."
|
||||||
Reference in New Issue
Block a user