This commit is contained in:
n.kisl 2024-01-30 16:46:58 +05:00
parent 0a57d305b2
commit 896e9c6b31
15 changed files with 7080 additions and 0 deletions

View File

@ -0,0 +1,8 @@
route:
receiver: 'alertmanager-bot'
receivers:
- name: 'alertmanager-bot'
webhook_configs:
- send_resolved: true
url: 'http://alertmanager-bot:8080'

62
config/caddy/Caddyfile Normal file
View File

@ -0,0 +1,62 @@
{
acme_dns cloudflare d7fWGzIMmzGfgGddSSzG8OtjpCTFLy4YcQS88-Co
}
*.es-ukrtb.ru, es-ukrtb.ru {
@main host es-ukrtb.ru
handle @main {
root * /srv/www
encode gzip
file_server
}
@mail host mail.es-ukrtb.ru
handle @mail {
reverse_proxy https://mail:443 {
transport http {
tls_insecure_skip_verify
}
}
}
@nextcloud host cloud.es-ukrtb.ru
handle @nextcloud {
reverse_proxy node-nextcloud:80
}
@git host git.es-ukrtb.ru
handle @git {
reverse_proxy gitea:3000
}
@ip host ip.es-ukrtb.ru
handle @ip {
templates
header Content-Type text/plain
respond "{{.RemoteIP}}"
}
# @pf {
# host pf.es.ukrtb.ru
# remote_ip 192.168.0.0/16 10.0.0.0/8 127.0.0.0/8 172.16.0.0/12
# }
# handle @pf {
# reverse_proxy 172.16.0.1:8080
# }
@prometheus host prometheus.es-ukrtb.ru
handle @prometheus {
reverse_proxy prometheus:9090
}
@grafana host grafana.es-ukrtb.ru
handle @grafana {
reverse_proxy grafana:3000
}
@exporter host exporter.es-ukrtb.ru
handle @exporter {
reverse_proxy exporter:9100
}
@alertmanager host alertmanager.es-ukrtb.ru
handle @alertmanager {
reverse_proxy alertmanager:8080
}
}

View File

@ -0,0 +1,12 @@
apiVersion: 1
providers:
- name: 'Prometheus'
orgId: 1
folder: ''
type: file
disableDeletion: false
editable: true
allowUiUpdates: true
options:
path: /etc/grafana/provisioning/dashboards

View File

@ -0,0 +1,12 @@
apiVersion: 1
providers:
- name: 'Prometheus'
orgId: 1
folder: ''
type: file
disableDeletion: false
editable: true
allowUiUpdates: true
options:
path: /etc/grafana/provisioning/dashboards

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,398 @@
{
"id": null,
"title": "Nginx",
"description": "Nginx exporter metrics",
"tags": [
"nginx"
],
"style": "dark",
"timezone": "browser",
"editable": true,
"hideControls": false,
"sharedCrosshair": true,
"rows": [
{
"collapse": false,
"editable": true,
"height": "250px",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": "Prometheus",
"decimals": 2,
"editable": true,
"error": false,
"fill": 1,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 3,
"isNew": true,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": true,
"min": true,
"rightSide": true,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "sum(irate(nginx_connections_processed_total{stage=\"any\"}[5m])) by (stage)",
"hide": false,
"interval": "",
"intervalFactor": 10,
"legendFormat": "requests",
"metric": "",
"refId": "B",
"step": 10
}
],
"timeFrom": null,
"timeShift": null,
"title": "Requests/sec",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": 0,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": "Prometheus",
"decimals": 2,
"editable": true,
"error": false,
"fill": 1,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 2,
"isNew": true,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": true,
"min": true,
"rightSide": true,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "sum(nginx_connections_current) by (state)",
"interval": "",
"intervalFactor": 2,
"legendFormat": "{{state}}",
"metric": "",
"refId": "A",
"step": 2
}
],
"timeFrom": null,
"timeShift": null,
"title": "Connections",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": 0,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
},
{
"aliasColors": {},
"bars": false,
"datasource": "Prometheus",
"decimals": 2,
"editable": true,
"error": false,
"fill": 1,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 1,
"isNew": true,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": true,
"min": true,
"rightSide": true,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "sum(irate(nginx_connections_processed_total{stage!=\"any\"}[5m])) by (stage)",
"hide": false,
"interval": "",
"intervalFactor": 10,
"legendFormat": "{{stage}}",
"metric": "",
"refId": "B",
"step": 10
}
],
"timeFrom": null,
"timeShift": null,
"title": "Connections rate",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": 0,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"title": "Nginx exporter metrics"
},
{
"collapse": false,
"editable": true,
"height": "250px",
"panels": [
{
"aliasColors": {},
"bars": false,
"datasource": null,
"editable": true,
"error": false,
"fill": 1,
"grid": {
"threshold1": null,
"threshold1Color": "rgba(216, 200, 27, 0.27)",
"threshold2": null,
"threshold2Color": "rgba(234, 112, 112, 0.22)"
},
"id": 4,
"isNew": true,
"legend": {
"alignAsTable": true,
"avg": true,
"current": true,
"max": true,
"min": true,
"rightSide": true,
"show": true,
"total": false,
"values": true
},
"lines": true,
"linewidth": 2,
"links": [],
"nullPointMode": "connected",
"percentage": false,
"pointradius": 5,
"points": false,
"renderer": "flot",
"seriesOverrides": [],
"span": 12,
"stack": false,
"steppedLine": false,
"targets": [
{
"expr": "sum(rate(container_cpu_usage_seconds_total{name=~\"nginx\"}[5m])) / count(node_cpu_seconds_total{mode=\"system\"}) * 100",
"intervalFactor": 2,
"legendFormat": "nginx",
"refId": "A",
"step": 2
}
],
"timeFrom": null,
"timeShift": null,
"title": "CPU usage",
"tooltip": {
"msResolution": false,
"shared": true,
"sort": 0,
"value_type": "cumulative"
},
"type": "graph",
"xaxis": {
"show": true
},
"yaxes": [
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
},
{
"format": "short",
"label": null,
"logBase": 1,
"max": null,
"min": null,
"show": true
}
]
}
],
"title": "Nginx container metrics"
}
],
"time": {
"from": "now-15m",
"to": "now"
},
"timepicker": {
"refresh_intervals": [
"5s",
"10s",
"30s",
"1m",
"5m",
"15m",
"30m",
"1h",
"2h",
"1d"
],
"time_options": [
"5m",
"15m",
"1h",
"6h",
"12h",
"24h",
"2d",
"7d",
"30d"
]
},
"templating": {
"list": []
},
"annotations": {
"list": []
},
"refresh": "10s",
"schemaVersion": 12,
"version": 9,
"links": [],
"gnetId": null
}

View File

@ -0,0 +1,11 @@
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
orgId: 1
url: http://prometheus:9090
basicAuth: false
isDefault: true
editable: true

View File

@ -0,0 +1,30 @@
groups:
- name: example
rules:
- alert: service_down
expr: up == 0
for: 30s
labels:
severity: page
annotations:
summary: "Instance {{ $labels.instance }} down"
description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 30 seconds."
- alert: high_load
expr: node_load1 > 0.8
for: 30s
labels:
severity: page
annotations:
summary: "Instance {{ $labels.instance }} under high load"
description: "{{ $labels.instance }} of job {{ $labels.job }} is under high load."
- alert: site_down
expr: probe_success < 1
for: 30s
labels:
severity: page
annotations:
summary: "Site Down: {{$labels.instance}}"
description: "Site Down: {{$labels.instance}} for more than 30 seconds"

View File

@ -0,0 +1,15 @@
scrape_configs:
- job_name: node
scrape_interval: 5s
static_configs:
- targets: ['exporter:9100']
rule_files:
- 'alert.rules'
alerting:
alertmanagers:
- scheme: http
static_configs:
- targets:
- "alertmanager:9093"

BIN
data/caddy/www/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

62
data/caddy/www/index.html Normal file
View File

@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="ru"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Корпоративная защита</title>
<link rel="stylesheet" href="styles.css">
<link rel="icon" href="/favicon.png" type="image/x-icon">
</head>
<body>
<main>
<div class="container">
<div class="gradient-cards">
<div class="card">
<div class="container-card bg-green-box">
<a href="https://git.es-ukrtb.ru">
<span class="link"></span>
</a>
<p class="card-title">Gitea</p>
<p class="card-description">Локальная git система для репозиториев.</p>
</div>
</div>
<div class="card">
<div class="container-card bg-white-box">
<a href="https://mail.es-ukrtb.ru">
<span class="link"></span>
</a>
<p class="card-title">Mail</p>
<p class="card-description">Почтовый сервер для работы.</p>
</div>
</div>
<div class="card">
<div class="container-card bg-yellow-box">
<a href="https://cloud.es-ukrtb.ru">
<span class="link"></span>
</a>
<p class="card-title">Cloud</p>
<p class="card-description">Nextcloud облако для файлов.</p>
</div>
</div>
<div class="card">
<div class="container-card bg-blue-box">
<a href="https://grafana.es-ukrtb.ru">
<span class="link"></span>
</a>
<p class="card-title">Graphana</p>
<p class="card-description">Мониторинг для сервисов.</p>
</div>
</div>
</div>
</div>
</main>
<footer>
© 2023 Кафедра Информационной Безопасности
</footer>
</body></html>

183
data/caddy/www/styles.css Normal file
View File

@ -0,0 +1,183 @@
/* Общие стили */
body {
font-family: Arial, sans-serif;
background-color: #f0f6fd;
color: #333333;
margin: 0;
padding: 0;
}
h1, h2 {
color: #333333;
text-align: center;
}
a {
color: #004d99;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* Стили для шапки */
header {
padding: 5px;
color: #ffffff;
}
nav ul {
list-style-type: none;
margin: 0;
padding: 0;
}
nav ul li {
display: inline;
margin-right: 20px;
}
/* Стили для основного содержимого */
main {
padding: 20px;
}
section {
margin-bottom: 40px;
}
/* Стили для подвала */
footer {
padding: 5px;
text-align: left;
color: #ffffff;
width: 100%;
position: fixed;
bottom: 0;
background: linear-gradient(71deg, #080509, #1a171c, #080509);
}
.container {
width: 1200px !important;
padding: 0 !important;
margin-right: auto;
margin-left: auto;
@media screen and (min-width: 992px) and (max-width: 1439px) {
max-width: 1279px !important;
padding: 0 !important;
margin: 0 80px !important;
width: auto !important;
}
@media screen and (max-width: 991px) {
max-width: 959px !important;
margin: 0 16px !important;
padding: 0 !important;
width: auto !important;
}
}
.gradient-cards {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 32px;
padding: 30px;
@media screen and (max-width: 991px) {
grid-template-columns: 1fr;
}
}
.container-title {
text-align: center;
padding: 0 !important;
margin-bottom: 40px;
font-size: 40px;
color: #fff;
font-weight: 600;
line-height: 60px;
}
.card {
max-width: 550px;
border: 0;
width: 100%;
margin-inline: auto;
}
.container-card {
position: relative;
border: 2px solid transparent;
background: linear-gradient(71deg, #080509, #1a171c, #080509);
background-clip: padding-box;
border-radius: 45px;
padding: 40px;
img {
margin-bottom: 32px;
}
}
.bg-green-box,
.bg-white-box,
.bg-yellow-box,
.bg-blue-box {
position: relative;
}
.bg-green-box::after,
.bg-white-box::after,
.bg-yellow-box::after,
.bg-blue-box::after {
position: absolute;
top: -1px;
bottom: -1px;
left: -1px;
right: -1px;
content: "";
z-index: -1;
border-radius: 45px;
}
.bg-green-box::after {
background: linear-gradient(71deg, #0d1212, #3da077, #0d1212);
}
.bg-white-box::after {
background: linear-gradient(71deg, #121013, #b0afb0, #121013);
}
.bg-yellow-box::after {
background: linear-gradient(71deg, #110e0e, #afa220, #110e0e);
}
.bg-blue-box::after {
background: linear-gradient(71deg, #0c0a0e, #5f6fad, #0c0a0e);
}
.card-title {
font-weight: 600;
color: white;
letter-spacing: -0.02em;
line-height: 40px;
font-style: normal;
font-size: 28px;
padding-bottom: 8px;
}
.card-description {
font-weight: 600;
line-height: 32px;
color: hsla(0, 0%, 100%, 0.5);
font-size: 16px;
max-width: 470px;
}
.link {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 1;
}

164
docker compose Normal file
View File

@ -0,0 +1,164 @@
version: "3.7"
services:
caddy:
image: iarekylew00t/caddy-cloudflare:latest
restart: unless-stopped
cap_add:
- NET_ADMIN
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./config/caddy:/etc/caddy
- ./data/caddy/www:/srv/www
- ./data/caddy:/data
- ./config/caddy:/config
postgres-gitea:
image: postgres:14
restart: always
volumes:
- ./data/postgres-gitea:/bitnami/postgresql
environment:
- POSTGRES_DB=gitea
- POSTGRES_USER=gitea
- POSTGRES_PASSWORD=gitea
gitea:
image: gitea/gitea:latest
restart: always
volumes:
- ./data/gitea:/data
environment:
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=postgres-gitea:5432
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=gitea
expose:
- 3000
- 2222
node-nextcloud:
image: nextcloud:apache
environment:
- POSTGRES_HOST=postgres-nextcloud
- POSTGRES_PASSWORD=nextcloud
- POSTGRES_DB=nextcloud
- POSTGRES_USER=nextcloud
expose:
- 80
restart: always
volumes:
- ./data/nextcloud:/var/www/html
postgres-nextcloud:
image: postgres:alpine
environment:
- POSTGRES_PASSWORD=nextcloud
- POSTGRES_DB=nextcloud
- POSTGRES_USER=nextcloud
restart: always
volumes:
- ./data/postgres-nextcloud:/var/lib/postgresql/data
expose:
- 5432
mail:
container_name: mail
ports:
- 25:25
- 110:110
- 143:143
- 465:465
- 587:587
- 993:993
- 995:995
environment:
- TZ=Asia/Yekaterinburg
- HTTPS=off
expose:
- 80
volumes:
- ./data/mail:/data
tty: true
image: analogic/poste.io
prometheus:
image: prom/prometheus
container_name: prometheus
volumes:
- ./config/prometheus:/etc/prometheus
- ./data/prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--storage.tsdb.retention.time=200h'
- '--web.enable-lifecycle'
restart: unless-stopped
expose:
- 9090
grafana:
image: grafana/grafana
container_name: grafana
volumes:
- ./data/grafana:/var/lib/grafana
- ./config/grafana:/etc/grafana/provisioning
environment:
- GF_SECURITY_ADMIN_USER=${ADMIN_USER}
- GF_SECURITY_ADMIN_PASSWORD=${ADMIN_PASSWORD}
- GF_USERS_ALLOW_SIGN_UP=false
restart: unless-stopped
expose:
- 4000
exporter:
image: prom/node-exporter
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
container_name: exporter
hostname: exporter
command:
- --path.procfs=/host/proc
- --path.sysfs=/host/sys
- --collector.filesystem.ignored-mount-points
- ^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)
expose:
- 9100
restart: unless-stopped
alertmanager-bot:
command:
- --alertmanager.url=http://alertmanager:9093
- --log.level=info
- --store=bolt
- --bolt.path=/data/bot.db
- --telegram.admin=?????????
- --telegram.token=?????????
image: metalmatze/alertmanager-bot
user: root
expose:
- 8080
container_name: alertmanager-bot
hostname: alertmanager-bot
restart: unless-stopped
volumes:
- ./data/alertmanager:/data
alertmanager:
image: prom/alertmanager
user: root
expose:
- 9093
volumes:
- ./config/alertmanager/:/etc/alertmanager/
container_name: alertmanager
hostname: alertmanager
restart: unless-stopped
command:
- '--config.file=/etc/alertmanager/config.yml'
- '--storage.path=/etc/alertmanager/data'