Compare commits

...
84 Commits
Author SHA1 Message Date
pipistrello f0889261b2 logging: make host-bound GitOps files reproducibly stageable
The Portainer stack consumes its compose file from Git but bind-mounts runtime configuration from stable paths under /mnt/containers/logging. The stable host copy of docker-compose.yaml had consequently fallen behind the deployed Git revision even though the running stack and dashboard files were current.\n\nAdd a root-run staging/check helper that copies and byte-verifies Compose, Loki, Alloy, syslog-ng, Grafana provisioning, and both dashboards without touching credentials or persistent data. Document the workflow and the final source-restricted passive Agent 2 interfaces for all four Telemt hosts.\n\nValidated with bash -n and git diff --check. Unrelated .DS_Store changes remain untracked/uncommitted.
2026-07-31 14:41:22 +03:00
pipistrello 9bebace46d logging: add 02-tekhnohim proxy to Telemt fleet
Extend the provisioned Telegram proxy fleet selector with visible host name 02-tekhnohim-docker while retaining the existing Agent 2 technical identity Fedora Kirochnaya.\n\nMake the collector read Prometheus metrics from 127.0.0.1:9090 inside the Telemt network namespace. This avoids dependence on host port 9092 and preserves the existing source-restricted metrics publication.\n\nValidated the dashboard with jq, the collector with bash -n, and the deployed Agent 2 keys on Client 02. The unrelated .DS_Store changes remain unstaged.
2026-07-31 14:18:36 +03:00
pipistrello 1fb6899b1f DEPOT logging: add Telemt fleet monitoring via Zabbix
Install and persist Grafana Zabbix plugin 6.5.0, provision the internal Zabbix datasource, and add a fleet dashboard modeled on client 02 Telemt panels.

Add an active-agent Zabbix 7 template plus a 30-second sanitized collector for active IP count/list, connections, traffic, and uptime. Active checks avoid inbound polling of client-private Docker hosts.

The exact Zabbix host names and required ZABBIX_API_TOKEN Portainer variable are documented. Compose validation passed on 10.0.0.6; the live plugin registered successfully under Grafana 13.1.0.
2026-07-31 11:55:55 +03:00
pipistrello 961f0112de 00-depot: add persistent Loki Alloy Grafana stack 2026-07-31 11:10:47 +03:00
pipistrello 7ac58cb1ea fix: change Outline SMTP port from 25 to 587 for authenticated relay 2026-05-15 21:44:30 +03:00
pipistrello 93ea5f9b69 yarn changed to node 2026-01-12 12:18:21 +03:00
pipistrello 740d92dc91 yarn install 2026-01-12 12:14:02 +03:00
pipistrello 288428b465 yarn fix again 2026-01-12 12:11:57 +03:00
pipistrello 7727af56b2 yarn fix... 2026-01-12 12:10:29 +03:00
pipistrello 6ee9cf24d8 yarn fix 2026-01-12 11:58:09 +03:00
pipistrello a1191fbb5e Yarn fix 2026-01-12 11:55:36 +03:00
pipistrello cf7e0a9658 fix 2025-10-17 10:59:28 +03:00
pipistrello 0fd67150cb initial 2025-10-17 10:55:08 +03:00
pipistrello 12f6168220 FILE_STORAGE_UPLOAD_MAX_SIZE 2025-03-10 16:38:55 +03:00
pipistrello e53b06fd8b syntax for from_email 2025-03-10 16:37:01 +03:00
pipistrello b24aea7687 default language added 2025-03-10 15:22:16 +03:00
pipistrello d163ea6ad7 testing another port 2025-03-07 12:44:13 +03:00
pipistrello db2c4078c5 test ssl version 2025-03-07 12:25:22 +03:00
pipistrello 59b4660d3c smtp secure 2025-03-07 12:13:14 +03:00
pipistrello 4e2b9e75b2 another smtp test 2025-03-07 12:07:38 +03:00
pipistrello cb6a43ec44 smtp testing 2025-03-07 11:55:36 +03:00
pipistrello 257b0d2dd9 ciphers 2025-03-07 11:49:03 +03:00
pipistrello fc3c362faf testing smtp config 2025-03-07 11:38:48 +03:00
pipistrello bb3f2020b0 added all networks 2025-03-07 11:22:17 +03:00
pipistrello 00ab82fef0 testing config added 2025-03-07 11:00:11 +03:00
pipistrello 8ec0eaa87e rust host configs: actual and old 2025-03-06 12:26:28 +03:00
pipistrello e5a6e36d18 rust for old web gui values 2025-03-06 09:42:18 +03:00
pipistrello abcc221a53 remove keycloak 2025-02-27 12:28:21 +03:00
pipistrello 1dbadd6f30 azure id 2025-02-27 12:26:12 +03:00
pipistrello 18069330f8 fedora syntax for volumes 2025-02-21 11:14:00 +03:00
pipistrello 26a0c80a87 syntax 2025-02-21 11:12:57 +03:00
pipistrello 5b0069271f caddy 2025-02-21 11:09:56 +03:00
pipistrello 52fdb6a0ad smtp alerts 2025-02-19 17:57:14 +03:00
pipistrello c93bb7797f no home environment 2025-02-19 16:51:50 +03:00
pipistrello 310282bf6c no user 2025-02-19 16:49:31 +03:00
pipistrello 96d60bcd60 syntax 2025-02-19 16:48:39 +03:00
pipistrello 39bcdadfec синтаксис! 2025-02-19 16:38:40 +03:00
pipistrello af121f7473 latest version 2025-02-19 16:33:04 +03:00
pipistrello 15d53f31bb return to privileged 2025-02-19 16:32:01 +03:00
pipistrello d82e13ab84 no privileged 2025-02-19 16:26:11 +03:00
pipistrello bd07f60432 fixed home volume 2025-02-19 16:16:02 +03:00
pipistrello 25df860655 new volumes 2025-02-19 16:08:40 +03:00
pipistrello 47c6225e93 image fix 2025-02-19 16:06:35 +03:00
pipistrello 7d523fb8e1 restoring version 28 2025-02-19 16:04:33 +03:00
pipistrello 373a958e34 image revert 2025-02-19 16:02:50 +03:00
pipistrello e2bbc0685f syntax 2025-02-19 15:55:40 +03:00
pipistrello 2b926aa029 syntax 2025-02-19 15:53:24 +03:00
pipistrello cee6ba7653 fixing volumes 2025-02-19 15:45:29 +03:00
pipistrello 7824fec28b config fix 2025-02-19 15:34:07 +03:00
pipistrello 3248607582 added oxidized config 2025-02-19 15:32:33 +03:00
pipistrello 3d8d4a9636 routerdb fix 2025-02-19 15:21:46 +03:00
pipistrello a38bdbe9bc home volume added 2025-02-19 15:18:39 +03:00
pipistrello b796af2315 trying version 29 2025-02-19 15:14:32 +03:00
pipistrello c62080e454 added config reload 2025-02-19 08:49:31 +03:00
pipistrello 946032f99b ipv6 fixes 2025-02-19 00:27:02 +03:00
pipistrello 136de980ae test auth 2025-02-19 00:16:41 +03:00
pipistrello 11d41854a1 пробуем связать контейнеры 2025-02-19 00:14:24 +03:00
pipistrello 6587486cb0 авторизация для прокси 2025-02-19 00:10:21 +03:00
pipistrello 90b62bcb89 disable ipv6 2025-02-19 00:06:55 +03:00
pipistrello e8fb7fbaf8 другой образ для shadowsocks 2025-02-18 23:54:56 +03:00
pipistrello aab6b562c5 command fix 2025-02-18 23:52:40 +03:00
pipistrello 4d99c6d1d1 environment fix 2025-02-18 23:50:35 +03:00
pipistrello 193f17ffe1 пробуем другой образ dante 2025-02-18 23:47:35 +03:00
pipistrello 34b2422da0 image versions 2025-02-18 23:36:12 +03:00
pipistrello 7d9222a134 port changed, network added 2025-02-18 23:33:46 +03:00
pipistrello 93268a762f initial 2025-02-18 23:23:40 +03:00
pipistrello 5ddec70043 image version and default language 2025-02-18 22:21:04 +03:00
pipistrello 95a7926f2a test 2025-02-18 22:12:14 +03:00
pipistrello 72442e8695 inio/minio:RELEASE.2024-03-21T23-13-43Z 2025-02-18 17:15:46 +03:00
pipistrello 1c76e74a7d syntax 2025-02-18 17:04:03 +03:00
pipistrello 968b72e499 version: "3.8" 2025-02-18 16:58:56 +03:00
pipistrello ff82c1c651 removed azure variables 2025-02-18 16:37:01 +03:00
pipistrello 7800ffaae4 removed "version" 2025-02-18 16:35:29 +03:00
pipistrello 7907c6c185 changed image and locked on minio and redis versions 2025-02-18 14:30:30 +03:00
pipistrello e97fa94d3a logo size changed to 92x92 2025-02-18 13:29:34 +03:00
pipistrello c25d86163f logo changed 2025-02-18 13:27:28 +03:00
pipistrello c08c7b5437 logo size changed 2025-02-18 13:22:51 +03:00
pipistrello 757cc61200 close port 8080 2025-02-18 10:01:10 +03:00
pipistrello 529de2acc6 changed url to logo on start page 2025-02-18 08:56:33 +03:00
pipistrello e8e9afceb9 logo 2025-02-18 08:55:34 +03:00
pipistrello 7f727c9677 logo added 2025-02-18 08:53:41 +03:00
pipistrello 44973cb8b7 отмена проверки 2025-02-13 17:30:45 +03:00
pipistrello de6ec6e4f3 проверка 2025-02-13 17:30:21 +03:00
pipistrello 5a589f2ef6 open port 8080 2025-02-11 15:47:09 +03:00
29 changed files with 2329 additions and 23 deletions
Vendored
BIN
View File
Binary file not shown.
+1
View File
@@ -1,2 +1,3 @@
# docker-infrastructure
test
+14
View File
@@ -0,0 +1,14 @@
services:
caddy:
image: caddy:latest
container_name: caddy
networks:
- reverseproxy-nw
volumes:
- /mnt/containers/caddy/container-data:/srv:Z
- /mnt/containers/caddy/Caddyfile:/etc/caddy/Caddyfile:Z
restart: unless-stopped
networks:
reverseproxy-nw:
external: true
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

+2 -1
View File
@@ -2,11 +2,12 @@ version: "3"
services:
server:
image: gitea/gitea:latest
image: gitea/gitea:1.20.4
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
- LANG=ru-RU
restart: always
volumes:
- /mnt/containers/gitea/container-data/data:/data:Z
+187
View File
@@ -0,0 +1,187 @@
# Internal logging stack
Portainer Git stack for `outline` (`10.0.0.6`). It replaces only the logging
part of the manual `mktxp-stack`:
- `loki` stores syslog in the persistent host path
`/mnt/containers/logging/loki-data`;
- `syslog-ng` accepts and normalizes the fleet's mixed/raw syslog formats;
- `alloy` replaces Promtail and sends normalized RFC5424 to Loki;
- `grafana` provides the MikroTik Loki dashboard and a Telemt fleet dashboard
backed by the internal DEPOT Zabbix server.
The retired stack's `mktxp`, Prometheus, and Promtail services are not part of
this stack. syslog-ng remains because real DEPOT RouterOS traffic includes raw
messages that Alloy's strict RFC3164 parser rejects.
## Portainer settings
- Repository: `https://git.it-depot.ru/depot/docker-infrastructure`
- Branch: `master`
- Compose path: `logging/docker-compose.yaml`
- Required environment variables:
- `GRAFANA_ADMIN_PASSWORD`
- `ZABBIX_API_TOKEN` — token for a read-only Zabbix API user; it is passed
into Grafana's provisioned datasource and must not be committed.
Do not deploy the new stack before completing the cutover below: the current
containers still own names `loki` and `grafana` and host ports 3000, 3100, 514,
and 601.
## Host files
The Git-backed compose file intentionally bind-mounts stable host paths.
Before deployment, stage and verify every tracked runtime file with:
```bash
sudo logging/stage-host-files.sh
sudo logging/stage-host-files.sh --check
```
The script copies only non-secret configuration and dashboard files. Portainer
still supplies `GRAFANA_ADMIN_PASSWORD` and `ZABBIX_API_TOKEN` out of band.
The resulting layout is:
```text
/mnt/containers/logging/
├── alloy-config/config.alloy
├── alloy-data/
├── grafana-config/
│ ├── dashboards/mikrotik-loki-logs.json
│ ├── dashboards/telemt-proxy-fleet.json
│ └── provisioning/
│ ├── dashboards/dashboards.yaml
│ └── datasources/{loki,zabbix}.yaml
├── grafana-data/
├── loki-config/config.yaml
├── loki-data/
└── syslog-ng-config/syslog-ng.conf
```
SELinux is enforcing. The compose mounts use `:Z`; do not remove those flags.
The persistent data directories should be owned by the container users:
Loki `10001:10001`, Grafana `472:0`, and Alloy `0:0`.
## Cutover
The live Loki history is inside the old container at `/tmp/loki`. Do not merge
a newer WAL over an older rescue WAL: the resulting non-contiguous segment
sequence makes Loki fail with `segments are not sequential`. Instead, move the
seed aside and copy the stopped container's complete data directory as one
generation:
```bash
cd /mnt/containers/mktxp/mktxp-stack
# Record a last pre-cutover query and stop all writers cleanly.
curl -fsS http://127.0.0.1:3100/ready
docker compose stop
# Preserve the seed separately; never overlay WAL generations.
mv /mnt/containers/logging/loki-data \
/mnt/containers/logging/loki-data-rescue-seed-2026-07-30
docker cp -a loki:/tmp/loki /mnt/containers/logging/loki-data
chown -R 10001:10001 /mnt/containers/logging/loki-data
# Removes containers and the old network, but NOT the old named Grafana and
# Prometheus volumes. Do not add --volumes.
docker compose down
```
Now deploy the Portainer Git stack. Expected interruption is the time between
`docker compose stop` and the new stack becoming ready.
## Verification
```bash
docker ps --filter name=loki --filter name=alloy --filter name=grafana
curl -fsS http://127.0.0.1:3100/ready
curl -fsS http://127.0.0.1:3000/api/health
ss -lnup | grep ':514'
ss -lntp | grep -E ':(601|3000|3100)\b'
```
Confirm both history and new ingestion:
```bash
START=$(date -u -d '24 hours ago' +%s%N)
curl -fsSG http://127.0.0.1:3100/loki/api/v1/query_range \
--data-urlencode 'query={job="syslog"}' \
--data-urlencode "start=$START" \
--data-urlencode 'limit=1'
logger --server 127.0.0.1 --udp --port 514 \
--rfc3164 --tag depot-cutover-test 'alloy ingestion test'
```
In Grafana, the provisioned **Network / Mikrotik Loki Logs** dashboard should
list existing `routerboard` values and show both pre-cutover and post-cutover
entries.
## Telemt / Zabbix monitoring
The Zabbix server is `10.0.0.11` internally. The DEPOT router at `10.0.0.1`
publishes TCP `185.108.4.158:10051` only for the four proxy-host egress
addresses, allowing Zabbix Agent 2 active checks without exposing the trapper
to the whole internet.
Create the following Zabbix hosts. The technical **Host name** must match the
Agent 2 `Hostname`; Grafana selects the **Visible name** shown below.
| Client | Zabbix Host name | Visible name |
|---|---|---|
| 00-xserver | `00-xserver-fedora-xxx` | `00-xserver-fedora-xxx` |
| 02-tekhnohim | `Fedora Kirochnaya` | `02-tekhnohim-docker` |
| 11-nevafud | `11-nevafud-fedora` | `11-nevafud-fedora` |
| 19-nutrilent | `19-nutrilent-docker` | `19-nutrilent-docker` |
Import `zabbix-template-telemt-active.yaml`, link **Telemt proxy by active
agent** to all four hosts, and ensure each host is in the `Linux servers`
group. All four send active checks to `185.108.4.158` and have source-restricted
passive Agent 2 interfaces on TCP `10050`. Client 02's existing local Zabbix
server continues to perform its original passive Linux checks independently.
The matching host-side collector is in `zabbix-agent/`. It enters only the
Telemt container network namespace for the control API, discards links and
secrets, caches the active-IP list and Prometheus values, and exposes
read-only Agent 2 keys. The active-IP list retains one day of history; the
numeric count and other counters retain 31 days.
After redeploying Grafana with a valid `ZABBIX_API_TOKEN`, verify:
```bash
docker exec grafana grafana cli plugins ls
curl -fsS http://127.0.0.1:3000/api/health
```
The provisioned **Network / Telegram proxy fleet** dashboard selects one of
the four visible host names above and mirrors the Telemt section of the
client-02 dashboard: current IP count, active/total connections, IP list,
traffic, and uptime.
## Rollback
Remove the new Portainer stack, then recreate the old stack with its Loki data
bound back into `/tmp/loki`:
```bash
cd /mnt/containers/mktxp/mktxp-stack
cp docker-compose.yaml docker-compose.rollback.yaml
```
Add this second volume to the `loki` service in
`docker-compose.rollback.yaml`:
```yaml
- /mnt/containers/logging/loki-data:/tmp/loki:Z
```
Then run:
```bash
docker compose -f docker-compose.rollback.yaml up -d
curl -fsS http://127.0.0.1:3100/ready
```
Do not restore the old Loki without that bind mount: its original writable
layer is deleted when the old stack is taken down.
+52
View File
@@ -0,0 +1,52 @@
// Replaces Promtail in the old syslog-ng -> Promtail -> Loki path.
//
// DEPOT's fleet is not uniformly parseable as RFC3164: some RouterOS senders
// emit raw messages without a PRI/header. syslog-ng therefore keeps listening
// on the public stack ports and normalizes every message to RFC5424 before
// forwarding it here on the private stack network.
loki.relabel "syslog" {
forward_to = []
// Preserve the label used by the existing history and MikroTik dashboard.
rule {
source_labels = ["__syslog_message_hostname"]
target_label = "routerboard"
}
rule {
source_labels = ["__syslog_message_severity"]
target_label = "severity"
}
rule {
source_labels = ["__syslog_message_facility"]
target_label = "facility"
}
rule {
source_labels = ["__syslog_connection_ip_address"]
target_label = "source_ip"
}
}
loki.source.syslog "normalized_syslog" {
listener {
address = "0.0.0.0:1514"
protocol = "tcp"
syslog_format = "rfc5424"
labels = {
job = "syslog",
transport = "syslog-ng",
}
}
relabel_rules = loki.relabel.syslog.rules
forward_to = [loki.write.default.receiver]
}
loki.write "default" {
endpoint {
url = "http://loki:3100/loki/api/v1/push"
}
}
+84
View File
@@ -0,0 +1,84 @@
services:
loki:
# This pin and the TSDB v13 on-disk format were validated on Fedora 44 in
# the 02-tekhnohim logging stack. Do not replace it with :latest during
# the data migration.
image: grafana/loki:3.7.2
container_name: loki
command: -config.file=/etc/loki/config.yaml
restart: unless-stopped
volumes:
- /mnt/containers/logging/loki-config/config.yaml:/etc/loki/config.yaml:ro,Z
- /mnt/containers/logging/loki-data:/loki:Z
ports:
# Retained for the existing operator query path.
- "3100:3100/tcp"
networks:
- logging-nw
syslog-ng:
# DEPOT's RouterOS fleet includes senders that omit the PRI/header Alloy's
# strict parser requires. Keep the proven normalizer, pinned by digest,
# and relay canonical RFC5424 to Alloy.
image: balabit/syslog-ng@sha256:ce85e1af17daf888c72267b19f7f104bf329044257564b784ff8c00ce4fc01ef
container_name: syslog-ng
command: -edv
restart: unless-stopped
depends_on:
- alloy
volumes:
- /mnt/containers/logging/syslog-ng-config/syslog-ng.conf:/etc/syslog-ng/syslog-ng.conf:ro,Z
ports:
# Existing fleet target: 185.108.4.158:514/udp.
- "514:514/udp"
# Preserve the old stack's TCP syslog endpoint.
- "601:601/tcp"
networks:
- logging-nw
alloy:
# Replaces Promtail. syslog-ng normalizes the mixed/raw fleet input into
# RFC5424 before sending it to Alloy on the private stack network.
image: grafana/alloy:v1.16.1
container_name: alloy
command:
- run
- --server.http.listen-addr=0.0.0.0:12345
- --storage.path=/var/lib/alloy/data
- /etc/alloy/config.alloy
restart: unless-stopped
depends_on:
- loki
volumes:
- /mnt/containers/logging/alloy-config/config.alloy:/etc/alloy/config.alloy:ro,Z
- /mnt/containers/logging/alloy-data:/var/lib/alloy/data:Z
networks:
- logging-nw
grafana:
image: grafana/grafana:13.1.0
container_name: grafana
restart: unless-stopped
depends_on:
- loki
environment:
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD}
GF_USERS_ALLOW_SIGN_UP: "false"
# Install the same Zabbix datasource version used by client 02.
GF_PLUGINS_PREINSTALL_SYNC: alexanderzobnin-zabbix-app@6.5.0
# Used only by the provisioned Zabbix datasource; set as a Portainer
# secret/environment value and never commit the token.
ZABBIX_API_TOKEN: ${ZABBIX_API_TOKEN}
volumes:
- /mnt/containers/logging/grafana-data:/var/lib/grafana:Z
- /mnt/containers/logging/grafana-config/provisioning/datasources:/etc/grafana/provisioning/datasources:ro,Z
- /mnt/containers/logging/grafana-config/provisioning/dashboards:/etc/grafana/provisioning/dashboards:ro,Z
- /mnt/containers/logging/grafana-config/dashboards:/var/lib/grafana/dashboards:ro,Z
ports:
# Retained for the current LAN/operator access path.
- "3000:3000/tcp"
networks:
- logging-nw
networks:
logging-nw:
@@ -0,0 +1,545 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "datasource",
"uid": "grafana"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"description": "Mikrotik Loki Logs",
"editable": true,
"fiscalYearStartMonth": 0,
"gnetId": 17139,
"graphTooltip": 0,
"id": 3,
"links": [
{
"asDropdown": false,
"icon": "external link",
"includeVars": false,
"keepTime": false,
"tags": [
"mikrotik",
"mktxp"
],
"targetBlank": false,
"title": "MKTXP Exporter",
"tooltip": "",
"type": "dashboards",
"url": ""
},
{
"asDropdown": true,
"icon": "external link",
"keepTime": false,
"tags": [
"system"
],
"title": "System Overview",
"type": "dashboards"
}
],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"description": "",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "semi-dark-orange",
"value": null
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 9,
"x": 0,
"y": 0
},
"id": 4,
"interval": "$smooth",
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "center",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"sum"
],
"fields": "",
"values": false
},
"text": {},
"textMode": "auto"
},
"pluginVersion": "9.3.2",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "count_over_time({job=\"syslog\", routerboard=\"$routerboard\"} [$__interval] |~\"(?i)$topics\" |~\"(?i)$searchable_pattern\" !~\"(?i)$exclude\")",
"legendFormat": "{{host}}",
"queryType": "range",
"refId": "A"
}
],
"title": "Log Counts By Topic",
"transformations": [],
"type": "stat"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 30,
"gradientMode": "opacity",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "smooth",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": true,
"stacking": {
"group": "A",
"mode": "normal"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 15,
"x": 9,
"y": 0
},
"id": 3,
"interval": "$smooth",
"options": {
"legend": {
"calcs": [
"mean",
"sum"
],
"displayMode": "table",
"placement": "right",
"showLegend": true
},
"tooltip": {
"mode": "none",
"sort": "none"
}
},
"pluginVersion": "8.1.2",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "count_over_time({job=\"syslog\", routerboard=\"$routerboard\"} [$__interval] |regexp \"(?P<prefix>\\\\w+)\\\\: \" |~\"(?i)$topics\" |~\"(?i)$searchable_pattern\" !~\"(?i)$exclude\")",
"legendFormat": "{{prefix}}",
"queryType": "range",
"refId": "A"
}
],
"title": "Log Counts By Topic Over Time",
"transformations": [],
"type": "timeseries"
},
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"description": "",
"gridPos": {
"h": 23,
"w": 24,
"x": 0,
"y": 7
},
"id": 5,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": false,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"pluginVersion": "7.3.6",
"targets": [
{
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"editorMode": "code",
"expr": "{job=\"syslog\", routerboard=\"$routerboard\"} |~\"(?i)$topics\" |~\"(?i)$searchable_pattern\" !~\"(?i)$exclude\"",
"legendFormat": "",
"queryType": "range",
"refId": "A"
}
],
"title": "Logs Lines By Topic",
"type": "logs"
}
],
"refresh": "5s",
"schemaVersion": 37,
"style": "dark",
"tags": [
"mikrotik",
"loki"
],
"templating": {
"list": [
{
"current": {
"selected": false,
"text": "MKT-GT",
"value": "MKT-GT"
},
"datasource": {
"type": "loki",
"uid": "P8E80F9AEF21F6940"
},
"definition": "",
"hide": 0,
"includeAll": false,
"label": "Routerboard",
"multi": false,
"name": "routerboard",
"options": [],
"query": {
"label": "routerboard",
"refId": "LokiVariableQueryEditor-VariableQuery",
"stream": "",
"type": 1
},
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"type": "query"
},
{
"current": {
"selected": true,
"text": [
"All"
],
"value": [
"$__all"
]
},
"hide": 0,
"includeAll": true,
"label": "Topics",
"multi": true,
"name": "topics",
"options": [
{
"selected": true,
"text": "All",
"value": "$__all"
},
{
"selected": false,
"text": "account",
"value": "account"
},
{
"selected": false,
"text": "caps",
"value": "caps"
},
{
"selected": false,
"text": "critical",
"value": "critical"
},
{
"selected": false,
"text": "error",
"value": "error"
},
{
"selected": false,
"text": "firewall",
"value": "firewall"
},
{
"selected": false,
"text": "info",
"value": "info"
},
{
"selected": false,
"text": "warning",
"value": "warning"
},
{
"selected": false,
"text": "wireless",
"value": "wireless"
},
{
"selected": false,
"text": "dns",
"value": "dns"
},
{
"selected": false,
"text": "health",
"value": "health"
},
{
"selected": false,
"text": "dhcp",
"value": "dhcp"
},
{
"selected": false,
"text": "interface",
"value": "interface"
},
{
"selected": false,
"text": "ipsec",
"value": "ipsec"
},
{
"selected": false,
"text": "l2tp",
"value": "l2tp"
},
{
"selected": false,
"text": "ppp",
"value": "ppp"
},
{
"selected": false,
"text": "raw",
"value": "raw"
},
{
"selected": false,
"text": "ssh",
"value": "ssh"
},
{
"selected": false,
"text": "system",
"value": "system"
},
{
"selected": false,
"text": "ups",
"value": "ups"
}
],
"query": "account,caps,critical,error,firewall,info,warning,wireless,dns,health,dhcp,interface,ipsec,l2tp,ppp,raw,ssh,system,ups",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": true,
"text": "",
"value": ""
},
"description": "Search (case insensitive)",
"hide": 0,
"label": "Search",
"name": "searchable_pattern",
"options": [
{
"selected": true,
"text": "",
"value": ""
}
],
"query": "",
"skipUrlSync": false,
"type": "textbox"
},
{
"current": {
"selected": false,
"text": "None",
"value": "None"
},
"description": "Exclude pattern (case-insensitive, None includes everything)",
"hide": 0,
"includeAll": false,
"label": "Exclude",
"multi": false,
"name": "exclude",
"options": [
{
"selected": true,
"text": "None",
"value": "None"
}
],
"query": "None,",
"queryValue": "None",
"skipUrlSync": false,
"type": "custom"
},
{
"current": {
"selected": false,
"text": "5m",
"value": "5m"
},
"hide": 0,
"includeAll": false,
"label": "Smooth",
"multi": false,
"name": "smooth",
"options": [
{
"selected": false,
"text": "30s",
"value": "30s"
},
{
"selected": false,
"text": "1m",
"value": "1m"
},
{
"selected": false,
"text": "2m",
"value": "2m"
},
{
"selected": true,
"text": "5m",
"value": "5m"
},
{
"selected": false,
"text": "10m",
"value": "10m"
},
{
"selected": false,
"text": "15m",
"value": "15m"
},
{
"selected": false,
"text": "30m",
"value": "30m"
},
{
"selected": false,
"text": "1h",
"value": "1h"
},
{
"selected": false,
"text": "2h",
"value": "2h"
}
],
"query": "30s,1m,2m,5m,10m,15m,30m,1h,2h",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
}
]
},
"time": {
"from": "now-12h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Mikrotik Loki Logs",
"uid": "awslix6doiakp-mkt-loki",
"version": 1,
"weekStart": ""
}
@@ -0,0 +1,841 @@
{
"uid": "telemt-proxy-fleet",
"title": "Telegram proxy fleet",
"tags": [
"proxy",
"telemt",
"zabbix",
"fleet"
],
"schemaVersion": 39,
"version": 1,
"editable": true,
"refresh": "30s",
"time": {
"from": "now-6h",
"to": "now"
},
"timezone": "",
"templating": {
"list": [
{
"current": {
"selected": true,
"text": "00-xserver-fedora-xxx",
"value": "00-xserver-fedora-xxx"
},
"hide": 0,
"includeAll": false,
"label": "Proxy host",
"multi": false,
"name": "proxy_host",
"options": [
{
"selected": true,
"text": "00-xserver-fedora-xxx",
"value": "00-xserver-fedora-xxx"
},
{
"selected": false,
"text": "11-nevafud-fedora",
"value": "11-nevafud-fedora"
},
{
"selected": false,
"text": "19-nutrilent-docker",
"value": "19-nutrilent-docker"
},
{
"selected": false,
"text": "02-tekhnohim-docker",
"value": "02-tekhnohim-docker"
}
],
"query": "00-xserver-fedora-xxx,11-nevafud-fedora,19-nutrilent-docker,02-tekhnohim-docker",
"queryValue": "",
"skipUrlSync": false,
"type": "custom"
}
]
},
"annotations": {
"list": []
},
"panels": [
{
"type": "row",
"title": "Telegram MTProto (:1080) — Telemt",
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 0
},
"panels": []
},
{
"id": 20,
"type": "stat",
"title": "Уникальных пользователей сейчас (IP)",
"description": "Текущее число уникальных активных клиентских IP для Telemt user secret `tekhnohim`. Это наиболее близкая доступная метрика к числу подключённых пользователей: несколько клиентов за одним NAT считаются как один IP, а один пользователь с нескольких внешних IP — как несколько.",
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"gridPos": {
"h": 5,
"w": 10,
"x": 0,
"y": 1
},
"options": {
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"colorMode": "background",
"graphMode": "area",
"textMode": "value_and_name",
"justifyMode": "center",
"wideLayout": true
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"unit": "short",
"decimals": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "dark-gray",
"value": null
},
{
"color": "green",
"value": 1
}
]
}
},
"overrides": []
},
"targets": [
{
"application": {
"filter": ""
},
"countTriggers": true,
"countTriggersBy": "",
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"evaltype": "0",
"functions": [],
"group": {
"filter": "Linux servers"
},
"host": {
"filter": "$proxy_host"
},
"item": {
"filter": "/^Telemt: Active IP address count$/"
},
"itemTag": {
"filter": ""
},
"macro": {
"filter": ""
},
"minSeverity": 3,
"mode": 0,
"options": {
"count": false,
"disableDataAlignment": false,
"showDisabledItems": false,
"skipEmptyValues": false,
"useTrends": "default",
"useZabbixValueMapping": false
},
"proxy": {
"filter": ""
},
"queryType": "0",
"refId": "A",
"resultFormat": "time_series",
"schema": 12,
"table": {
"skipEmptyValues": false
},
"tags": {
"filter": ""
},
"textFilter": "",
"trigger": {
"filter": ""
}
}
]
},
{
"id": 21,
"type": "stat",
"title": "Активных соединений",
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"gridPos": {
"h": 5,
"w": 7,
"x": 10,
"y": 1
},
"options": {
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"colorMode": "value",
"graphMode": "area",
"textMode": "value_and_name",
"justifyMode": "center"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "fixed",
"fixedColor": "blue"
},
"unit": "short",
"decimals": 0
},
"overrides": []
},
"targets": [
{
"application": {
"filter": ""
},
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"functions": [],
"group": {
"filter": "Linux servers"
},
"host": {
"filter": "$proxy_host"
},
"item": {
"filter": "/^Telemt: Active connections$/"
},
"itemTag": {
"filter": ""
},
"mode": 0,
"options": {
"count": false,
"disableDataAlignment": false,
"showDisabledItems": false,
"skipEmptyValues": false,
"useTrends": "default",
"useZabbixValueMapping": false
},
"queryType": "0",
"refId": "A",
"resultFormat": "time_series",
"schema": 12
}
]
},
{
"id": 22,
"type": "stat",
"title": "Всего подключений",
"description": "Накопительный счётчик подключений user secret `tekhnohim` с момента запуска Telemt.",
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"gridPos": {
"h": 5,
"w": 7,
"x": 17,
"y": 1
},
"options": {
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"colorMode": "value",
"graphMode": "area",
"textMode": "value_and_name",
"justifyMode": "center"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "fixed",
"fixedColor": "purple"
},
"unit": "short",
"decimals": 0
},
"overrides": []
},
"targets": [
{
"application": {
"filter": ""
},
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"functions": [],
"group": {
"filter": "Linux servers"
},
"host": {
"filter": "$proxy_host"
},
"item": {
"filter": "/^Telemt: Total connections$/"
},
"itemTag": {
"filter": ""
},
"mode": 0,
"options": {
"count": false,
"disableDataAlignment": false,
"showDisabledItems": false,
"skipEmptyValues": false,
"useTrends": "default",
"useZabbixValueMapping": false
},
"queryType": "0",
"refId": "A",
"resultFormat": "time_series",
"schema": 12
}
]
},
{
"id": 28,
"type": "table",
"title": "Текущие активные IP-адреса Telemt",
"description": "Последний снимок активных IP-адресов из Zabbix item telemt.active_ips.list. Обновляется каждые 30 секунд.",
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"gridPos": {
"h": 6,
"w": 24,
"x": 0,
"y": 6
},
"fieldConfig": {
"defaults": {
"custom": {
"align": "left",
"filterable": false
}
},
"overrides": []
},
"options": {
"cellHeight": "auto",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"showHeader": true,
"sortBy": []
},
"transformations": [
{
"id": "organize",
"options": {
"excludeByName": {
"Host": true,
"Item": true,
"Key": true
},
"renameByName": {
"Last value": "Активные подключения (пользователь | IP)"
}
}
}
],
"targets": [
{
"application": {
"filter": ""
},
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"functions": [],
"group": {
"filter": "Linux servers"
},
"host": {
"filter": "$proxy_host"
},
"item": {
"filter": "/^Telemt: Active IP addresses$/"
},
"itemTag": {
"filter": ""
},
"mode": 0,
"options": {
"count": false,
"disableDataAlignment": false,
"showDisabledItems": false,
"skipEmptyValues": true,
"useTrends": "default",
"useZabbixValueMapping": false
},
"queryType": "2",
"refId": "A",
"resultFormat": "table",
"schema": 12,
"textFilter": "",
"useCaptureGroups": false
}
]
},
{
"id": 23,
"type": "timeseries",
"title": "Пользователи и соединения",
"description": "Текущее число уникальных активных IP и параллельных Telemt-соединений.",
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 12
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"drawStyle": "line",
"fillOpacity": 15,
"lineInterpolation": "stepAfter",
"lineWidth": 2,
"pointSize": 3,
"showPoints": "never",
"spanNulls": true,
"stacking": {
"group": "A",
"mode": "none"
}
},
"unit": "short",
"decimals": 0
},
"overrides": []
},
"options": {
"legend": {
"calcs": [
"lastNotNull",
"max"
],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "multi",
"sort": "desc"
}
},
"targets": [
{
"application": {
"filter": ""
},
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"functions": [],
"group": {
"filter": "Linux servers"
},
"host": {
"filter": "$proxy_host"
},
"item": {
"filter": "/^Telemt: (Active IP address count|Active connections)$/"
},
"itemTag": {
"filter": ""
},
"mode": 0,
"options": {
"count": false,
"disableDataAlignment": false,
"showDisabledItems": false,
"skipEmptyValues": false,
"useTrends": "default",
"useZabbixValueMapping": false
},
"queryType": "0",
"refId": "A",
"resultFormat": "time_series",
"schema": 12
}
]
},
{
"id": 24,
"type": "timeseries",
"title": "Трафик Telemt (накопительно)",
"description": "Накопительные байтовые счётчики Telemt по user secret `tekhnohim`; сбрасываются при перезапуске сервиса.",
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 12
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"drawStyle": "line",
"fillOpacity": 15,
"lineInterpolation": "linear",
"lineWidth": 2,
"pointSize": 3,
"showPoints": "never",
"spanNulls": true,
"stacking": {
"group": "A",
"mode": "none"
}
},
"unit": "bytes"
},
"overrides": []
},
"options": {
"legend": {
"calcs": [
"lastNotNull",
"max"
],
"displayMode": "table",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "multi",
"sort": "desc"
}
},
"targets": [
{
"application": {
"filter": ""
},
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"functions": [],
"group": {
"filter": "Linux servers"
},
"host": {
"filter": "$proxy_host"
},
"item": {
"filter": "/^Telemt: Bytes (received from|sent to) clients$/"
},
"itemTag": {
"filter": ""
},
"mode": 0,
"options": {
"count": false,
"disableDataAlignment": false,
"showDisabledItems": false,
"skipEmptyValues": false,
"useTrends": "default",
"useZabbixValueMapping": false
},
"queryType": "0",
"refId": "A",
"resultFormat": "time_series",
"schema": 12
}
]
},
{
"id": 25,
"type": "stat",
"title": "Аптайм Telemt",
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"gridPos": {
"h": 4,
"w": 8,
"x": 0,
"y": 20
},
"options": {
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"colorMode": "value",
"graphMode": "none",
"textMode": "value_and_name",
"justifyMode": "center"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "fixed",
"fixedColor": "green"
},
"unit": "s"
},
"overrides": []
},
"targets": [
{
"application": {
"filter": ""
},
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"functions": [],
"group": {
"filter": "Linux servers"
},
"host": {
"filter": "$proxy_host"
},
"item": {
"filter": "/^Telemt: Uptime$/"
},
"itemTag": {
"filter": ""
},
"mode": 0,
"options": {
"count": false,
"disableDataAlignment": false,
"showDisabledItems": false,
"skipEmptyValues": false,
"useTrends": "default",
"useZabbixValueMapping": false
},
"queryType": "0",
"refId": "A",
"resultFormat": "time_series",
"schema": 12
}
]
},
{
"id": 26,
"type": "stat",
"title": "Получено от клиентов",
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"gridPos": {
"h": 4,
"w": 8,
"x": 8,
"y": 20
},
"options": {
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"colorMode": "value",
"graphMode": "none",
"textMode": "value_and_name",
"justifyMode": "center"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "fixed",
"fixedColor": "semi-dark-blue"
},
"unit": "bytes"
},
"overrides": []
},
"targets": [
{
"application": {
"filter": ""
},
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"functions": [],
"group": {
"filter": "Linux servers"
},
"host": {
"filter": "$proxy_host"
},
"item": {
"filter": "/^Telemt: Bytes received from clients$/"
},
"itemTag": {
"filter": ""
},
"mode": 0,
"options": {
"count": false,
"disableDataAlignment": false,
"showDisabledItems": false,
"skipEmptyValues": false,
"useTrends": "default",
"useZabbixValueMapping": false
},
"queryType": "0",
"refId": "A",
"resultFormat": "time_series",
"schema": 12
}
]
},
{
"id": 27,
"type": "stat",
"title": "Отправлено клиентам",
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"gridPos": {
"h": 4,
"w": 8,
"x": 16,
"y": 20
},
"options": {
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"colorMode": "value",
"graphMode": "none",
"textMode": "value_and_name",
"justifyMode": "center"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "fixed",
"fixedColor": "semi-dark-purple"
},
"unit": "bytes"
},
"overrides": []
},
"targets": [
{
"application": {
"filter": ""
},
"datasource": {
"type": "alexanderzobnin-zabbix-datasource",
"uid": "zabbix-depot"
},
"functions": [],
"group": {
"filter": "Linux servers"
},
"host": {
"filter": "$proxy_host"
},
"item": {
"filter": "/^Telemt: Bytes sent to clients$/"
},
"itemTag": {
"filter": ""
},
"mode": 0,
"options": {
"count": false,
"disableDataAlignment": false,
"showDisabledItems": false,
"skipEmptyValues": false,
"useTrends": "default",
"useZabbixValueMapping": false
},
"queryType": "0",
"refId": "A",
"resultFormat": "time_series",
"schema": 12
}
]
}
]
}
@@ -0,0 +1,13 @@
apiVersion: 1
providers:
- name: logging-dashboards
orgId: 1
folder: Network
type: file
disableDeletion: false
updateIntervalSeconds: 30
allowUiUpdates: false
options:
path: /var/lib/grafana/dashboards
foldersFromFilesStructure: false
@@ -0,0 +1,10 @@
apiVersion: 1
datasources:
- name: Loki
uid: P8E80F9AEF21F6940
type: loki
access: proxy
url: http://loki:3100
isDefault: true
editable: false
@@ -0,0 +1,22 @@
apiVersion: 1
datasources:
- name: Zabbix
uid: zabbix-depot
type: alexanderzobnin-zabbix-datasource
access: proxy
url: http://10.0.0.11/api_jsonrpc.php
editable: false
jsonData:
authType: token
cacheTTL: 1h
dbConnectionEnable: false
disableDataAlignment: false
disableReadOnlyUsersAck: true
queryTimeout: 60
timeout: 30
trends: true
trendsFrom: 7d
trendsRange: 4d
secureJsonData:
apiToken: ${ZABBIX_API_TOKEN}
+56
View File
@@ -0,0 +1,56 @@
auth_enabled: false
server:
http_listen_address: 0.0.0.0
http_listen_port: 3100
grpc_listen_address: 0.0.0.0
grpc_listen_port: 9096
log_level: info
common:
instance_addr: 127.0.0.1
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1
ring:
kvstore:
store: inmemory
schema_config:
configs:
# Keep the old stack's schema start and TSDB v13 format so its existing
# /tmp/loki data can be mounted at /loki without conversion.
- from: 2020-05-15
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
limits_config:
reject_old_samples: true
reject_old_samples_max_age: 168h
retention_period: 8760h
max_query_series: 5000
split_queries_by_interval: 24h
max_query_parallelism: 16
query_scheduler:
max_outstanding_requests_per_tenant: 2048
compactor:
working_directory: /loki/compactor
compaction_interval: 10m
retention_enabled: true
retention_delete_delay: 2h
delete_request_store: filesystem
ruler:
storage:
type: local
local:
directory: /loki/rules
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env bash
set -euo pipefail
mode="stage"
if [[ "${1:-}" == "--check" ]]; then
mode="check"
shift
fi
target_root="${1:-/mnt/containers/logging}"
source_root="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
mappings=(
"docker-compose.yaml:docker-compose.yaml"
"alloy-config.alloy:alloy-config/config.alloy"
"loki-config.yaml:loki-config/config.yaml"
"syslog-ng.conf:syslog-ng-config/syslog-ng.conf"
"grafana-provisioning/dashboards/dashboards.yaml:grafana-config/provisioning/dashboards/dashboards.yaml"
"grafana-provisioning/datasources/loki.yaml:grafana-config/provisioning/datasources/loki.yaml"
"grafana-provisioning/datasources/zabbix.yaml:grafana-config/provisioning/datasources/zabbix.yaml"
"grafana-dashboards/mikrotik-loki-logs.json:grafana-config/dashboards/mikrotik-loki-logs.json"
"grafana-dashboards/telemt-proxy-fleet.json:grafana-config/dashboards/telemt-proxy-fleet.json"
)
if [[ "${mode}" == "stage" ]]; then
install -d -m 0755 \
"${target_root}/alloy-config" \
"${target_root}/loki-config" \
"${target_root}/syslog-ng-config" \
"${target_root}/grafana-config/provisioning/dashboards" \
"${target_root}/grafana-config/provisioning/datasources" \
"${target_root}/grafana-config/dashboards"
install -d -o 0 -g 0 -m 0755 "${target_root}/alloy-data"
install -d -o 472 -g 0 -m 0755 "${target_root}/grafana-data"
install -d -o 10001 -g 10001 -m 0755 "${target_root}/loki-data"
fi
failed=0
for mapping in "${mappings[@]}"; do
source_file="${source_root}/${mapping%%:*}"
target_file="${target_root}/${mapping#*:}"
if [[ "${mode}" == "stage" ]]; then
install -o root -g root -m 0644 "${source_file}" "${target_file}"
fi
if cmp -s "${source_file}" "${target_file}"; then
printf 'OK %s\n' "${target_file}"
else
printf 'DIFF %s\n' "${target_file}" >&2
failed=1
fi
done
exit "${failed}"
+30
View File
@@ -0,0 +1,30 @@
@version: 3.29
@include "scl.conf"
source s_local {
internal();
};
# default-network-drivers accepts the mixed/raw formats used by the DEPOT
# fleet on the standard UDP/TCP syslog listeners.
source s_network {
default-network-drivers();
};
# Alloy's syslog receiver accepts one explicit format per listener. Normalize
# every accepted input to RFC5424 before relaying it over the private network.
template t_alloy_rfc5424 {
template("<${PRI}>1 ${ISODATE} ${HOST} ${PROGRAM} ${PID} ${MSGID} - ${MSG}\n");
};
destination d_alloy {
syslog("alloy" transport("tcp") port("1514")
template(t_alloy_rfc5424)
);
};
log {
source(s_local);
source(s_network);
destination(d_alloy);
};
+8
View File
@@ -0,0 +1,8 @@
# Cached by zabbix-telemt-collector.service; contains no proxy links or secrets.
UserParameter=telemt.active_ips.list,cat /var/lib/zabbix/telemt-active-ips.txt
UserParameter=telemt.active_ips.count,/usr/local/libexec/zabbix-telemt-value active_ips_count
UserParameter=telemt.connections.current,/usr/local/libexec/zabbix-telemt-value connections_current
UserParameter=telemt.connections.total,/usr/local/libexec/zabbix-telemt-value connections_total
UserParameter=telemt.bytes.received,/usr/local/libexec/zabbix-telemt-value bytes_received
UserParameter=telemt.bytes.sent,/usr/local/libexec/zabbix-telemt-value bytes_sent
UserParameter=telemt.uptime,/usr/local/libexec/zabbix-telemt-value uptime
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/bash
set -euo pipefail
container_name="ts-lan-telemt"
output_dir="/var/lib/zabbix"
json_target="${output_dir}/telemt-active-ips.json"
text_target="${output_dir}/telemt-active-ips.txt"
metrics_target="${output_dir}/telemt-metrics.prom"
install -d -o root -g zabbix -m 0750 "${output_dir}"
container_pid="$(docker inspect --format '{{.State.Pid}}' "${container_name}")"
if [[ -z "${container_pid}" || "${container_pid}" == "0" ]]; then
exit 1
fi
json_tmp="$(mktemp "${output_dir}/.telemt-active-ips.json.XXXXXX")"
text_tmp="$(mktemp "${output_dir}/.telemt-active-ips.txt.XXXXXX")"
metrics_tmp="$(mktemp "${output_dir}/.telemt-metrics.prom.XXXXXX")"
trap 'rm -f "${json_tmp}" "${text_tmp}" "${metrics_tmp}"' EXIT
# The API response also contains proxy links and secrets. Filter it in-memory
# and persist only the username and current active IP address list.
nsenter -t "${container_pid}" -n \
curl --fail --silent --show-error --max-time 5 \
http://127.0.0.1:9091/v1/users |
jq --compact-output '{
users: [
.data[]
| {
username,
active_unique_ips: (.active_unique_ips_list // [])
}
]
}' > "${json_tmp}"
{
active_count="$(jq '[.users[].active_unique_ips[]] | unique | length' "${json_tmp}")"
printf 'Active IP addresses: %s\n' "${active_count}"
jq --raw-output '
[
.users[] as $user
| $user.active_unique_ips[]
| "\($user.username) | \(.)"
]
| if length == 0 then ["No active IP addresses"] else . end
| .[]
' "${json_tmp}"
} > "${text_tmp}"
# Cache Prometheus output from inside Telemt's network namespace. This avoids
# depending on the host-published metrics port or its source allowlist. Zabbix
# active checks read the cache, so the central server still needs no route to
# the private Docker host.
nsenter -t "${container_pid}" -n \
curl --fail --silent --show-error --max-time 5 \
http://127.0.0.1:9090/metrics > "${metrics_tmp}"
chown root:zabbix "${json_tmp}" "${text_tmp}" "${metrics_tmp}"
chmod 0640 "${json_tmp}" "${text_tmp}" "${metrics_tmp}"
mv -f "${json_tmp}" "${json_target}"
mv -f "${text_tmp}" "${text_target}"
mv -f "${metrics_tmp}" "${metrics_target}"
@@ -0,0 +1,12 @@
[Unit]
Description=Collect sanitized Telemt data for Zabbix
After=docker.service
Requires=docker.service
[Service]
Type=oneshot
ExecStart=/usr/local/libexec/zabbix-telemt-collector
User=root
Group=root
PrivateTmp=true
NoNewPrivileges=true
@@ -0,0 +1,12 @@
[Unit]
Description=Refresh sanitized Telemt data for Zabbix
[Timer]
OnBootSec=30s
OnUnitActiveSec=30s
AccuracySec=2s
Unit=zabbix-telemt-collector.service
Persistent=true
[Install]
WantedBy=timers.target
+30
View File
@@ -0,0 +1,30 @@
#!/usr/bin/bash
set -euo pipefail
json_file="/var/lib/zabbix/telemt-active-ips.json"
metrics_file="/var/lib/zabbix/telemt-metrics.prom"
case "${1:-}" in
active_ips_count)
jq '[.users[].active_unique_ips[]] | unique | length' "${json_file}"
;;
connections_current)
awk '$1 ~ /^telemt_user_connections_current\{/ {sum += $2} END {print sum + 0}' "${metrics_file}"
;;
connections_total)
awk '$1 ~ /^telemt_user_connections_total\{/ {sum += $2} END {print sum + 0}' "${metrics_file}"
;;
bytes_received)
awk '$1 ~ /^telemt_user_octets_from_client\{/ {sum += $2} END {printf "%.0f\n", sum + 0}' "${metrics_file}"
;;
bytes_sent)
awk '$1 ~ /^telemt_user_octets_to_client\{/ {sum += $2} END {printf "%.0f\n", sum + 0}' "${metrics_file}"
;;
uptime)
awk '$1 == "telemt_uptime_seconds" {printf "%.0f\n", $2; found=1} END {if (!found) exit 1}' "${metrics_file}"
;;
*)
printf 'unsupported Telemt value: %s\n' "${1:-}" >&2
exit 2
;;
esac
@@ -0,0 +1,94 @@
zabbix_export:
version: '7.0'
template_groups:
- uuid: a571c0d144b14fd4a87a9d9b2aa9fcd6
name: Templates/Applications
templates:
- uuid: 1d617f451f8640089f9ac33d62865e72
template: 'Telemt proxy by active agent'
name: 'Telemt proxy by active agent'
description: |
Telemt metrics cached locally by zabbix-telemt-collector.timer.
Designed for hosts behind NAT; every item is a Zabbix agent active check.
groups:
- name: Templates/Applications
items:
- uuid: e383ca45b2c047519f30665999cfc02e
name: 'Telemt: Active IP address count'
type: ZABBIX_ACTIVE
key: telemt.active_ips.count
delay: 30s
history: 31d
trends: 365d
value_type: UNSIGNED
tags:
- tag: component
value: telemt
- uuid: 5a29849443d5473884246d049a2dd79f
name: 'Telemt: Active IP addresses'
type: ZABBIX_ACTIVE
key: telemt.active_ips.list
delay: 30s
history: 1d
value_type: TEXT
tags:
- tag: component
value: telemt
- uuid: 465288678a084f8c84f56c2cffc0dcda
name: 'Telemt: Active connections'
type: ZABBIX_ACTIVE
key: telemt.connections.current
delay: 30s
history: 31d
trends: 365d
value_type: UNSIGNED
tags:
- tag: component
value: telemt
- uuid: dddf99d04abb459f8890eff46b948c4b
name: 'Telemt: Total connections'
type: ZABBIX_ACTIVE
key: telemt.connections.total
delay: 30s
history: 31d
trends: 365d
value_type: UNSIGNED
tags:
- tag: component
value: telemt
- uuid: 03e3a3671d744efaa65d4328d8d4035f
name: 'Telemt: Bytes received from clients'
type: ZABBIX_ACTIVE
key: telemt.bytes.received
delay: 30s
history: 31d
trends: 365d
value_type: UNSIGNED
units: B
tags:
- tag: component
value: telemt
- uuid: 97679bf1d06b47b0acf8f33f1253d114
name: 'Telemt: Bytes sent to clients'
type: ZABBIX_ACTIVE
key: telemt.bytes.sent
delay: 30s
history: 31d
trends: 365d
value_type: UNSIGNED
units: B
tags:
- tag: component
value: telemt
- uuid: b554b83a21ca46638c753e803870661f
name: 'Telemt: Uptime'
type: ZABBIX_ACTIVE
key: telemt.uptime
delay: 30s
history: 31d
trends: 365d
value_type: UNSIGNED
units: uptime
tags:
- tag: component
value: telemt
+23
View File
@@ -0,0 +1,23 @@
location / {
proxy_pass http://10.0.0.10:8001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
allow 10.0.0.0/24;
allow 192.168.0.0/24;
allow 172.16.0.0/12;
deny all;
}
location /api/ {
proxy_pass http://10.0.0.10:8002/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
allow 10.0.0.0/24;
allow 192.168.0.0/24;
allow 172.16.0.0/12;
deny all;
}
+23
View File
@@ -0,0 +1,23 @@
location / {
proxy_pass http://10.0.0.10:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
allow 10.0.0.0/24;
allow 192.168.0.0/24;
allow 172.16.0.0/12;
deny all;
}
location /api/ {
proxy_pass http://10.0.0.10:6661/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
allow 10.0.0.0/24;
allow 192.168.0.0/24;
allow 172.16.0.0/12;
deny all;
}
+25
View File
@@ -0,0 +1,25 @@
location /ws {
proxy_pass http://10.0.0.10:8002/ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
allow 10.0.0.0/24;
allow 192.168.0.0/24;
allow 172.16.0.0/12;
deny all;
}
location /ws {
proxy_pass http://10.0.0.10:8002/ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
+17 -17
View File
@@ -1,14 +1,14 @@
version: "2"
version: "3.8"
services:
outline_redis:
image: redis
image: redis:7-alpine
restart: always
container_name: outline_redis
networks:
- outline-internal
outline_postgres:
image: postgres:13
image: postgres:13-alpine
restart: always
container_name: outline_postgres
environment:
@@ -21,7 +21,7 @@ services:
- /mnt/containers/outline/container-data/db:/var/lib/postgresql/data:Z
outline_minio:
image: minio/minio
image: minio/minio:RELEASE.2021-10-27T16-29-42Z
restart: always
container_name: outline_minio
volumes:
@@ -38,11 +38,11 @@ services:
command: "server /data --console-address :9001"
outline:
image: outlinewiki/outline
image: flameshikari/outline-ru:latest
user: root
restart: always
container_name: outline
command: sh -c "yarn db:migrate --env=production-ssl-disabled && yarn start --env=production-ssl-disabled"
command: sh -c "node build/server/index.js"
depends_on:
- outline_postgres
- outline_redis
@@ -55,26 +55,26 @@ services:
- REDIS_URL=redis://outline_redis:6379
- URL=${WIKI_URL}
- PORT=443
- DEFAULT_LANGUAGE=ru_RU
- AWS_ACCESS_KEY_ID=minio
- AWS_REGION=us-east-1
- AWS_SECRET_ACCESS_KEY=${MINIO_ROOT_PASSWORD}
- AWS_S3_UPLOAD_BUCKET_URL=${WIKIDATA_URL}
- AWS_S3_UPLOAD_BUCKET_NAME=outline
- AWS_S3_UPLOAD_MAX_SIZE=26214400
- FILE_STORAGE_UPLOAD_MAX_SIZE=86214400
- AWS_S3_FORCE_PATH_STYLE=true
- AWS_S3_ACL=private
- OIDC_CLIENT_ID=outline
- OIDC_CLIENT_SECRET=${AUTH_CLIENT_SECRET}
- OIDC_AUTH_URI=${AUTH_URL}/auth/realms/master/protocol/openid-connect/auth
- OIDC_TOKEN_URI=${AUTH_URL}/auth/realms/master/protocol/openid-connect/token
- OIDC_USERINFO_URI=${AUTH_URL}/auth/realms/master/protocol/openid-connect/userinfo
- OIDC_USERNAME_CLAIM=email
- OIDC_DISPLAY_NAME="Keycloak - AD"
- OIDC_SCOPES=email
- AZURE_CLIENT_ID=${AZURE_CLIENT_ID}
- AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET}
- AZURE_RESOURCE_APP_ID=${AZURE_RESOURCE_APP_ID}
- TEAM_LOGO=http://it-depot.ru/site/templates/assets/images/logo.jpg
- AZURE_TENANT_ID=${AZURE_TENANT_ID}
- TEAM_LOGO=https://git.it-depot.ru/depot/docker-infrastructure/raw/commit/c25d86163f0911daa9b9109e753289087cd97b5e/depot_logo.png
- SMTP_HOST=mail.loopa.site
- SMTP_PORT=587
- SMTP_SECURE=false
- SMTP_USERNAME=konskaya@za.loopa.site
- SMTP_PASSWORD=${SMTP_PASSWORD}
- SMTP_FROM_EMAIL=DEPOT WIKI <konskaya@za.loopa.site>
- SMTP_REPLY_EMAIL=konskaya@za.loopa.site
# ports:
# 443:443
networks:
+57
View File
@@ -0,0 +1,57 @@
---
username: oxidized
password: T9ufDgNpTR4jBc
model: routeros
resolve_dns: true
interval: 3600
use_syslog: false
debug: false
threads: 30
timeout: 20
retries: 3
prompt: !ruby/regexp /^([\w.@-]+[#>]\s?)$/
rest: 0.0.0.0:8888
next_adds_job: false
vars:
auth_metods: "publickey"
ssh_keys: ["/home/oxidized/.ssh/id_dsa", "/home/oxidized/.ssh/id_ed25519"]
ssh_no_keepalive: true
verify_host_key: never
groups: {}
models: {}
pid: "/home/oxidized/.config/oxidized/pid"
crash:
directory: "/home/oxidized/.config/oxidized/crashes"
hostnames: false
stats:
history_size: 10
input:
default: ssh, telnet
debug: false
ssh:
secure: false
ftp:
passive: true
utf8_encoded: true
output:
default: git
git:
user: oxidized
email: info@it-depot.ru
repo: "/home/oxidized/.git/default.git"
source:
default: csv
csv:
file: "/home/oxidized/.config/oxidized/router.db"
delimiter: !ruby/regexp /:/
map:
name: 0
model: 1
ip: 2
username: 3
password: 4
gpg: false
model_map:
juniper: junos
cisco: ios
mikrotik: routeros
+5 -5
View File
@@ -4,15 +4,15 @@ services:
image: oxidized/oxidized:latest
container_name: oxidized
privileged: true
environment:
CONFIG_RELOAD_INTERVAL: 600
# ports:
# - 8888:8888
volumes:
- /mnt/containers/oxidized/container-data/data:/root/.config/oxidized:Z
- /mnt/containers/oxidized/container-data/repo:/root/.git:Z
- /mnt/containers/oxidized/container-data/ssh:/root/.ssh:Z
- /mnt/containers/oxidized_remake/container-data/:/home/oxidized:Z
networks:
- reverseproxy-nw
- reverseproxy-nw
networks:
reverseproxy-nw:
reverseproxy-nw:
external: true
+47
View File
@@ -0,0 +1,47 @@
services:
ss-client:
image: shadowsocks/shadowsocks-libev:latest
container_name: ss-client
command: ss-local
-s ${OUTLINE_SERVER_IP}
-p ${OUTLINE_SERVER_PORT}
-k ${OUTLINE_SERVER_ACCESS_KEY}
-m chacha20-ietf-poly1305
-l 1080
-b 0.0.0.0
networks:
- proxy_network
restart: unless-stopped
sysctls:
- net.ipv6.conf.all.disable_ipv6=1
- net.ipv6.conf.default.disable_ipv6=1
- net.ipv6.conf.lo.disable_ipv6=1
socks-proxy:
image: serjs/go-socks5-proxy:v0.0.1
container_name: socks-proxy
ports:
- "1081:1080"
environment:
- PROXY_USER=${PROXY_USER}
- PROXY_PASSWORD=${PROXY_PASSWORD}
- SOCKS5_HOST=ss-client
- SOCKS5_PORT=1080
- PROXY_NEED_AUTH=true
- ENABLE_IPV6=false
networks:
- proxy_network
restart: unless-stopped
sysctls:
- net.ipv6.conf.all.disable_ipv6=1
- net.ipv6.conf.default.disable_ipv6=1
- net.ipv6.conf.lo.disable_ipv6=1
depends_on:
- ss-client
networks:
proxy_network:
external: true
enable_ipv6: false
driver_opts:
com.docker.network.enable_ipv6: "false"