Wprowadzenie modularności i kompleksowa rozbudowa skryptu (v2.0)
1 Przeprowadzono gruntowną refaktoryzację i rozbudowę skryptu, przekształcając go w modularne i w pełni funkcjonalne narzędzie do
zarządzania cyklem życia serwera.
2
3 Kluczowe zmiany w tej wersji (v2.0):
4
5 - **Modularna architektura**: Skrypt obsługuje teraz komendy (np. `install`, `uninstall`, `deploy_monitoring`), co pozwala na
elastyczne zarządzanie poszczególnymi komponentami bez potrzeby uruchamiania całości.
6
7 - **Idempotentność**: Wszystkie operacje sprawdzają stan systemu przed wykonaniem, co gwarantuje bezpieczeństwo i
przewidywalność przy wielokrotnym uruchamianiu.
8
9 - **Separacja konfiguracji**: Konfiguracje usług (Docker Compose, Prometheus itp.) zostały przeniesione do folderu `templates/`,
oddzielając logikę skryptu od danych konfiguracyjnych.
10
11 - **Nowe moduły opcjonalne**: Dodano możliwość łatwej instalacji i konfiguracji:
12 - `Fail2ban` dla dodatkowego bezpieczeństwa.
13 - Bazy danych `PostgreSQL`.
14 - Systemu agregacji logów `Loki`.
15 - Systemu kopii zapasowych `Restic`.
16
17 - **Ulepszone logowanie i bezpieczeństwo**: Skrypt weryfikuje kompatybilność OS, a wszystkie jego działania są logowane do pliku
`/var/log/autoscript.log`.
18
19 - **Funkcja `uninstall`**: Dodano możliwość czystego i bezpiecznego usunięcia wszystkich komponentów wdrożonych przez skrypt.
20
21 - **Aktualizacja dokumentacji**: `README.md` i `CHANGELOG.md` zostały w pełni zaktualizowane, aby odzwierciedlać nową
funkcjonalność.
22
23 Ta wersja stanowi kamień milowy w rozwoju projektu, czyniąc go potężnym i niezawodnym narzędziem dla administratorów.
This commit is contained in:
parent
2d3dac11dd
commit
ee90c4b52d
13 changed files with 454 additions and 137 deletions
26
CHANGELOG.md
26
CHANGELOG.md
|
|
@ -1,6 +1,30 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 2025-08-03
|
## 2025-08-03 (v2.0)
|
||||||
|
|
||||||
|
### Dodano
|
||||||
|
|
||||||
|
- **Modularność Skryptu**: Wprowadzono obsługę komend (`install`, `deploy_traefik`, `deploy_monitoring`, `uninstall`), co pozwala na uruchamianie tylko wybranych części skryptu.
|
||||||
|
- **Idempotentność**: Skrypt sprawdza stan systemu (np. czy użytkownik istnieje) przed wykonaniem akcji, co pozwala na jego bezpieczne wielokrotne uruchamianie.
|
||||||
|
- **Weryfikacja Systemu**: Skrypt weryfikuje, czy jest uruchamiany na kompatybilnej dystrybucji (Debian/Ubuntu).
|
||||||
|
- **Ulepszone Logowanie**: Wszystkie operacje są logowane do pliku `/var/log/autoscript.log`.
|
||||||
|
- **Funkcja `uninstall`**: Dodano możliwość bezpiecznego odinstalowania wszystkich komponentów wdrożonych przez skrypt.
|
||||||
|
- **Szablony Konfiguracji**: Konfiguracje usług (Traefik, Prometheus) zostały przeniesione do zewnętrznych plików w folderze `templates/`.
|
||||||
|
- **Opcjonalne Moduły** (konfigurowalne w `autoscript.conf`):
|
||||||
|
- **Fail2ban**: Dodatkowa warstwa ochrony przed atakami brute-force.
|
||||||
|
- **PostgreSQL**: Możliwość wdrożenia bazy danych.
|
||||||
|
- **Loki**: Centralne zbieranie logów z kontenerów Docker.
|
||||||
|
- **Restic Backups**: Integracja z systemem kopii zapasowych (wymaga ręcznej konfiguracji po stronie dostawcy chmury).
|
||||||
|
|
||||||
|
### Zmieniono
|
||||||
|
|
||||||
|
- **Struktura Projektu**: Dodano folder `templates` na pliki konfiguracyjne.
|
||||||
|
- **Plik Konfiguracyjny**: `autoscript.conf.example` został rozbudowany o nowe opcje dla modułów opcjonalnych.
|
||||||
|
- **Dokumentacja**: `README.md` zostało całkowicie przepisane, aby odzwierciedlać nową, modularną strukturę i wszystkie nowe funkcje.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2025-08-03 (v1.1)
|
||||||
|
|
||||||
### Dodano
|
### Dodano
|
||||||
|
|
||||||
|
|
|
||||||
190
README.md
190
README.md
|
|
@ -1,129 +1,81 @@
|
||||||
# AutoScript - Zautomatyzowana Konfiguracja Serwera
|
# AutoScript v2 - Zautomatyzowana Konfiguracja i Zarządzanie Serwerem
|
||||||
|
|
||||||
## 1. Przegląd
|
## 1. Przegląd
|
||||||
|
|
||||||
Ten projekt zawiera kompleksowy skrypt `start.sh`, który automatyzuje proces konfiguracji i zabezpieczania nowego serwera opartego na systemie Debian (lub jego pochodnych, jak Ubuntu). Skrypt instaluje niezbędne oprogramowanie, wzmacnia zabezpieczenia systemu (hardening) i wdraża środowisko aplikacyjne oparte na kontenerach Docker.
|
AutoScript to potężne narzędzie do automatyzacji pełnego cyklu życia serwera opartego o system Debian/Ubuntu. Skrypt przekształca "surowy" serwer w gotowe do pracy, zabezpieczone i monitorowane środowisko produkcyjne. Dzięki modularnej budowie, możesz używać go zarówno do wstępnej konfiguracji, jak i do późniejszego zarządzania poszczególnymi komponentami.
|
||||||
|
|
||||||
Jest to idealne rozwiązanie do szybkiego przygotowania serwera deweloperskiego lub produkcyjnego, z gotowym do użycia reverse proxy (Traefik) oraz pełnym stosem monitoringu (Prometheus, Grafana).
|
|
||||||
|
|
||||||
## 2. Główne Funkcje
|
## 2. Główne Funkcje
|
||||||
|
|
||||||
- **Automatyzacja:** Uruchom jeden skrypt, aby w pełni przygotować serwer.
|
- **Modularność**: Uruchamiaj tylko te części skryptu, których potrzebujesz (`install`, `deploy_monitoring`, `uninstall` itp.).
|
||||||
- **Zabezpieczenia (Hardening):**
|
- **Automatyzacja i Idempotentność**: Skrypt można bezpiecznie uruchamiać wielokrotnie - zawsze doprowadzi system do pożądanego stanu.
|
||||||
- Konfiguracja firewalla `UFW`.
|
- **Hardening (Wzmacnianie Zabezpieczeń)**: Kompleksowe zabezpieczenie serwera, w tym firewall, niestandardowy port SSH, blokada roota, uwierzytelnianie kluczem, `CrowdSec` i opcjonalnie `Fail2ban`.
|
||||||
- Wzmocnienie zabezpieczeń SSH (zmiana portu, blokada logowania roota, autoryzacja kluczem).
|
- **Środowisko Docker**: Wdrożenie Dockera z Traefikiem jako reverse proxy i automatycznymi certyfikatami SSL.
|
||||||
- Tworzenie dedykowanego użytkownika `admin` z uprawnieniami `sudo` i weryfikacją dwuetapową (TOTP).
|
- **Monitoring i Alerty**: Pełny stos monitoringu (Prometheus, Grafana, Alertmanager) z prekonfigurowanymi regułami.
|
||||||
- Instalacja i konfiguracja `CrowdSec` (system zapobiegania włamaniom).
|
- **Zarządzanie Sekretami**: Bezpieczne przechowywanie haseł i kluczy API dzięki `sops`.
|
||||||
- Wdrożenie podstawowych zabezpieczeń jądra systemu.
|
- **Funkcje Opcjonalne**: Możliwość łatwego doinstalowania bazy danych PostgreSQL, systemu logów Loki czy kopii zapasowych Restic.
|
||||||
- **Środowisko Docker:**
|
- **Czysta Deinstalacja**: Możliwość wycofania wszystkich zmian za pomocą jednej komendy.
|
||||||
- Instalacja i konfiguracja Docker Engine z najlepszymi praktykami (m.in. `userns-remap`).
|
|
||||||
- Wdrożenie `Traefik` jako reverse proxy z automatycznym generowaniem certyfikatów SSL/TLS od Let's Encrypt (przy użyciu Cloudflare DNS).
|
|
||||||
- **Monitoring i Alerty:**
|
|
||||||
- Wdrożenie `Prometheus` do zbierania metryk.
|
|
||||||
- Wdrożenie `Grafana` do wizualizacji danych z gotową konfiguracją.
|
|
||||||
- Wdrożenie `Alertmanager` do wysyłania powiadomień o anomaliach (e-mailem).
|
|
||||||
- Wdrożenie eksporterów metryk (`node-exporter`, `cAdvisor`, `blackbox-exporter`).
|
|
||||||
- **Zarządzanie Sekretami:**
|
|
||||||
- Bezpieczne zarządzanie hasłami i kluczami API przy użyciu `sops` i `age`, bez przechowywania ich w formie jawnego tekstu.
|
|
||||||
|
|
||||||
## 3. Wymagania Wstępne
|
## 3. Struktura Projektu
|
||||||
|
|
||||||
Zanim uruchomisz skrypt, upewnij się, że posiadasz:
|
|
||||||
|
|
||||||
1. **Nowy serwer** z systemem operacyjnym Debian lub Ubuntu.
|
|
||||||
2. **Dostęp do konta `root`** na tym serwerze.
|
|
||||||
3. **Domenę internetową** zarządzaną przez **Cloudflare**.
|
|
||||||
4. **Klucz API Cloudflare** z uprawnieniami do edycji strefy DNS (`DNS:Edit`).
|
|
||||||
5. **Publiczny klucz SSH** (np. zawartość pliku `~/.ssh/id_ed25519.pub`).
|
|
||||||
|
|
||||||
## 4. Konfiguracja
|
|
||||||
|
|
||||||
Konfiguracja skryptu odbywa się w całości poprzez plik `autoscript.conf`.
|
|
||||||
|
|
||||||
1. **Utwórz plik konfiguracyjny:**
|
|
||||||
Skopiuj szablon `autoscript.conf.example` do nowego pliku o nazwie `autoscript.conf`.
|
|
||||||
```bash
|
|
||||||
cp autoscript.conf.example autoscript.conf
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Wypełnij plik `autoscript.conf`:**
|
|
||||||
Otwórz plik `autoscript.conf` w edytorze tekstu i uzupełnij wszystkie zmienne zgodnie z komentarzami. Szczególną uwagę zwróć na sekcje `WYMAGANE`.
|
|
||||||
|
|
||||||
- `PUBLIC_KEY`: Twój publiczny klucz SSH.
|
|
||||||
- `CF_DNS_API_TOKEN`: Twój token API od Cloudflare.
|
|
||||||
- `PRIMARY_DOMAIN`: Twoja główna domena.
|
|
||||||
- `ADMIN_EMAIL`: Twój adres e-mail.
|
|
||||||
- ...i inne ustawienia, takie jak dane do serwera SMTP czy wersje oprogramowania.
|
|
||||||
|
|
||||||
## 5. Użycie
|
|
||||||
|
|
||||||
1. Sklonuj to repozytorium na swój serwer.
|
|
||||||
2. Przejdź do folderu projektu: `cd autoscript`.
|
|
||||||
3. Utwórz i wypełnij plik konfiguracyjny `autoscript.conf` (zgodnie z punktem 4).
|
|
||||||
4. Uruchom skrypt z uprawnieniami `root`.
|
|
||||||
```bash
|
|
||||||
sudo ./start.sh
|
|
||||||
```
|
|
||||||
5. Skrypt automatycznie wczyta konfigurację z pliku i rozpocznie instalację.
|
|
||||||
|
|
||||||
## 6. Co robić po zakończeniu skryptu?
|
|
||||||
|
|
||||||
Po pomyślnym wykonaniu skryptu, twoje środowisko jest gotowe, ale musisz wiedzieć o kilku ważnych zmianach:
|
|
||||||
|
|
||||||
1. **Nowy Port SSH:** Port SSH został zmieniony na losowy numer z zakresu 10000-65535. **Znajdziesz go w pliku `/root/ssh_port.txt`**.
|
|
||||||
```bash
|
|
||||||
# Zaloguj się na serwerze jako root i wykonaj:
|
|
||||||
cat /root/ssh_port.txt
|
|
||||||
```
|
|
||||||
2. **Logowanie na serwer:**
|
|
||||||
- Logowanie na konto `root` jest **zablokowane**.
|
|
||||||
- Możesz zalogować się tylko jako użytkownik `admin` przy użyciu podanego klucza SSH i nowego portu.
|
|
||||||
```bash
|
|
||||||
ssh admin@<IP_SERWERA> -p <NOWY_PORT_SSH>
|
|
||||||
```
|
|
||||||
3. **Konfiguracja Weryfikacji Dwuetapowej (TOTP):**
|
|
||||||
- Przy pierwszej próbie użycia `sudo` przez użytkownika `admin` (np. `sudo ls /root`), zostaniesz poproszony o skonfigurowanie TOTP.
|
|
||||||
- W terminalu wyświetli się **kod QR**. Zeskanuj go aplikacją do uwierzytelniania (np. Google Authenticator, Authy).
|
|
||||||
- Zapisz wyświetlone kody zapasowe w bezpiecznym miejscu!
|
|
||||||
4. **Dostęp do Usług:**
|
|
||||||
Wdrożone usługi będą dostępne pod subdomenami Twojej `PRIMARY_DOMAIN`:
|
|
||||||
- **Prometheus:** `https://prometheus.twojadomena.pl`
|
|
||||||
- **Grafana:** `https://grafana.twojadomena.pl`
|
|
||||||
- **Alertmanager:** `https://alertmanager.twojadomena.pl`
|
|
||||||
- **Traefik Dashboard:** Domyślnie nie jest publicznie dostępny. Aby go udostępnić, musiałbyś dodać odpowiednią regułę routingu w plikach konfiguracyjnych Traefik.
|
|
||||||
|
|
||||||
5. **Hasła i Sekrety:**
|
|
||||||
- Hasło administratora Grafany jest generowane automatycznie.
|
|
||||||
- Wszystkie sekrety są zaszyfrowane w folderze `/opt/services/` przy użyciu `sops`. Aby je odczytać lub edytować, musisz użyć `sops` bezpośrednio na serwerze, np.:
|
|
||||||
```bash
|
|
||||||
# To polecenie odszyfruje i wyświetli plik w edytorze
|
|
||||||
sudo sops /opt/services/monitoring/secrets/monitoring.env.sops
|
|
||||||
```
|
|
||||||
|
|
||||||
## 7. Szczegółowy Opis Działania Skryptu
|
|
||||||
|
|
||||||
Skrypt `start.sh` składa się z szeregu funkcji, które są wywoływane po kolei.
|
|
||||||
|
|
||||||
- `ensure_root`: Sprawdza, czy skrypt jest uruchamiany z uprawnieniami `root`.
|
|
||||||
- `install_node_and_gemini`: Instaluje Node.js oraz Gemini CLI.
|
|
||||||
- `install_base_tools`: Instaluje podstawowe pakiety systemowe, takie jak `ufw` (firewall), `jq` (przetwarzanie JSON), `sops` (zarządzanie sekretami), `age` (szyfrowanie), `aide` (monitorowanie integralności plików) oraz `CrowdSec` (ochrona przed atakami).
|
|
||||||
- `bootstrap_sops`: Inicjalizuje konfigurację `sops` z kluczem `age`, który będzie używany do szyfrowania wszystkich sekretów.
|
|
||||||
- `create_admin_user`: Tworzy nowego użytkownika `admin`, dodaje go do grupy `sudo`, konfiguruje logowanie za pomocą klucza SSH i wymusza użycie weryfikacji dwuetapowej (TOTP) przy użyciu `sudo`.
|
|
||||||
- `harden_ssh`: Zabezpiecza serwer SSH: generuje nowe klucze hosta, blokuje logowanie na konto `root` i za pomocą hasła, zmienia domyślny port na losowy i ogranicza dostęp tylko do autoryzowanych grup.
|
|
||||||
- `configure_firewall`: Konfiguruje zaporę sieciową `UFW`, otwierając tylko niezbędne porty (nowy port SSH, HTTP, HTTPS, poczta, etc.) i blokując resztę. Dodaje również reguły chroniące kontenery Docker.
|
|
||||||
- `system_baseline`: Wprowadza zmiany w konfiguracji jądra systemowego w celu poprawy bezpieczeństwa i wydajności. Konfiguruje trwałe logi `journald` oraz automatyczne aktualizacje (`unattended-upgrades`).
|
|
||||||
- `install_docker`: Instaluje silnik Docker oraz wtyczkę `docker-compose`. Konfiguruje go zgodnie z zaleceniami bezpieczeństwa, m.in. włączając izolację przestrzeni nazw użytkowników (`userns-remap`).
|
|
||||||
- `prepare_secrets`: Przygotowuje wszystkie potrzebne sekrety (token Cloudflare, hasło do Grafany, hasło do SMTP) i szyfruje je za pomocą `sops`, aby nie były przechowywane na dysku jako jawny tekst.
|
|
||||||
- `deploy_traefik`: Wdraża kontener z Traefikiem. Konfiguruje go do obsługi ruchu HTTP/HTTPS, automatycznego przekierowywania na HTTPS oraz zamawiania certyfikatów SSL od Let's Encrypt.
|
|
||||||
- `deploy_monitoring`: Wdraża pełny stos monitoringu, w tym:
|
|
||||||
- **Prometheus:** do zbierania danych.
|
|
||||||
- **Grafana:** do ich wizualizacji.
|
|
||||||
- **Alertmanager:** do wysyłania alertów.
|
|
||||||
- **Exportery:** `node-exporter` (metryki systemu), `cAdvisor` (metryki kontenerów), `blackbox-exporter` (monitorowanie dostępności stron).
|
|
||||||
|
|
||||||
## 8. Plik `.gitattributes`
|
|
||||||
|
|
||||||
```
|
```
|
||||||
* text=auto
|
autoscript/
|
||||||
|
├── templates/ # Szablony plików konfiguracyjnych
|
||||||
|
│ ├── monitoring/
|
||||||
|
│ └── traefik/
|
||||||
|
├── autoscript.conf.example # Przykład pliku konfiguracyjnego
|
||||||
|
├── CHANGELOG.md # Dziennik zmian
|
||||||
|
├── README.md # Ta dokumentacja
|
||||||
|
└── start.sh # Główny skrypt wykonawczy
|
||||||
```
|
```
|
||||||
Ta linia w pliku `.gitattributes` jest ważna dla spójności projektu. Nakazuje ona systemowi Git automatyczne zarządzanie znakami końca linii w plikach tekstowych. Dzięki temu unikniesz problemów, jeśli będziesz pracować nad projektem na różnych systemach operacyjnych (np. Windows i Linux), które używają różnych standardów dla końca linii.
|
|
||||||
|
## 4. Użycie
|
||||||
|
|
||||||
|
### Krok 1: Konfiguracja
|
||||||
|
|
||||||
|
1. Sklonuj repozytorium na serwer: `git clone ...`
|
||||||
|
2. Przejdź do folderu: `cd autoscript`
|
||||||
|
3. Stwórz plik konfiguracyjny z szablonu: `cp autoscript.conf.example autoscript.conf`
|
||||||
|
4. Otwórz `autoscript.conf` i **dokładnie wypełnij wszystkie zmienne**, zwłaszcza te w sekcji `WYMAGANE`.
|
||||||
|
|
||||||
|
### Krok 2: Uruchomienie Skryptu
|
||||||
|
|
||||||
|
Skryptem zarządza się za pomocą komend. Wszystkie komendy należy wykonywać z uprawnieniami `root` (np. `sudo ./start.sh <komenda>`).
|
||||||
|
|
||||||
|
**Główne Komendy:**
|
||||||
|
|
||||||
|
- `sudo ./start.sh install`
|
||||||
|
**Pełna, pierwsza instalacja.** Wykonuje wszystkie niezbędne kroki: instaluje pakiety, konfiguruje zabezpieczenia, wdraża Dockera, Traefika i stos monitoringu. Uruchom tę komendę na nowym serwerze.
|
||||||
|
|
||||||
|
- `sudo ./start.sh uninstall`
|
||||||
|
**Pełna deinstalacja.** Zatrzymuje i usuwa wszystkie usługi, kontenery, wolumeny, a także odinstalowuje pakiety i wycofuje zmiany konfiguracyjne. **Używaj z ostrożnością!**
|
||||||
|
|
||||||
|
**Komendy do Zarządzania Modułami:**
|
||||||
|
|
||||||
|
Możesz zarządzać poszczególnymi częściami systemu niezależnie.
|
||||||
|
|
||||||
|
- `sudo ./start.sh deploy_traefik`
|
||||||
|
- `sudo ./start.sh deploy_monitoring`
|
||||||
|
- `sudo ./start.sh deploy_database` (jeśli włączone w konfigu)
|
||||||
|
|
||||||
|
**Komendy Pomocnicze:**
|
||||||
|
|
||||||
|
- `sudo ./start.sh reboot` - Bezpieczny restart serwera.
|
||||||
|
- `sudo ./start.sh update` - Aktualizacja pakietów systemowych.
|
||||||
|
|
||||||
|
## 5. Opis Modułów Opcjonalnych
|
||||||
|
|
||||||
|
Możesz włączyć je w pliku `autoscript.conf`.
|
||||||
|
|
||||||
|
- **Fail2ban**: Dodatkowa ochrona, która analizuje logi i blokuje adresy IP wykazujące złośliwą aktywność (np. próby logowania brute-force).
|
||||||
|
- **PostgreSQL**: Wdraża kontener z popularną bazą danych. Hasło jest zarządzane przez `sops`.
|
||||||
|
- **Loki**: System do agregacji logów z Twoich kontenerów. Umożliwia ich wygodne przeszukiwanie w Grafanie.
|
||||||
|
- **Restic Backup**: Instaluje i konfiguruje `restic` do tworzenia regularnych, szyfrowanych kopii zapasowych do chmury (np. AWS S3, Backblaze B2). **Wymaga dodatkowej konfiguracji po stronie dostawcy chmury!**
|
||||||
|
|
||||||
|
## 6. Co robić po instalacji?
|
||||||
|
|
||||||
|
Po zakończeniu komendy `install`:
|
||||||
|
|
||||||
|
1. **Nowy Port SSH:** Został zmieniony na losowy. Znajdziesz go w pliku `/root/ssh_port.txt`.
|
||||||
|
2. **Logowanie**: Logowanie na `root` jest zablokowane. Użyj użytkownika `admin` z Twoim kluczem SSH i nowym portem: `ssh admin@<IP> -p <PORT>`.
|
||||||
|
3. **TOTP (2FA)**: Przy pierwszym użyciu `sudo` zostaniesz poproszony o skonfigurowanie aplikacji do uwierzytelniania (np. Google Authenticator).
|
||||||
|
4. **Dostęp do usług**: Usługi będą dostępne pod subdomenami Twojej domeny (np. `https://grafana.twojadomena.pl`).
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
# Konfiguracja AutoScript
|
# Konfiguracja AutoScript v2
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
#
|
#
|
||||||
# Instrukcja:
|
# Instrukcja:
|
||||||
|
|
@ -40,22 +40,10 @@ TIMEZONE='Europe/Warsaw'
|
||||||
# -------------------------------------------------------------------
|
# -------------------------------------------------------------------
|
||||||
# USTAWIENIA POWIADOMIEŃ (SMTP)
|
# USTAWIENIA POWIADOMIEŃ (SMTP)
|
||||||
# -------------------------------------------------------------------
|
# -------------------------------------------------------------------
|
||||||
# Ta sekcja konfiguruje serwer e-mail do wysyłania alertów z monitoringu.
|
|
||||||
|
|
||||||
# Adres hosta i port serwera SMTP.
|
|
||||||
# Przykład: ALERT_SMTP_HOST='smtp.example.com:587'
|
|
||||||
ALERT_SMTP_HOST='mail.drap.ovh:587'
|
ALERT_SMTP_HOST='mail.drap.ovh:587'
|
||||||
|
|
||||||
# Nazwa użytkownika do logowania SMTP.
|
|
||||||
# Przykład: ALERT_SMTP_USER='alerts@example.com'
|
|
||||||
ALERT_SMTP_USER='alerts@drap.ovh'
|
ALERT_SMTP_USER='alerts@drap.ovh'
|
||||||
|
ALERT_SMTP_PASS='' # Pozostaw puste, aby wygenerować losowe
|
||||||
# Hasło do logowania SMTP.
|
|
||||||
# Jeśli pozostawisz puste, zostanie wygenerowane losowe i zapisane bezpiecznie w sops.
|
|
||||||
ALERT_SMTP_PASS=''
|
|
||||||
|
|
||||||
# Adres e-mail, z którego będą wysyłane alerty (pole 'From').
|
|
||||||
# Przykład: ALERT_SMTP_FROM='server-alerts@example.com'
|
|
||||||
ALERT_SMTP_FROM='alerts@drap.ovh'
|
ALERT_SMTP_FROM='alerts@drap.ovh'
|
||||||
|
|
||||||
# -------------------------------------------------------------------
|
# -------------------------------------------------------------------
|
||||||
|
|
@ -66,11 +54,53 @@ ALERT_SMTP_FROM='alerts@drap.ovh'
|
||||||
# Jeśli pozostawisz puste, zostanie wygenerowane losowe i zapisane bezpiecznie w sops.
|
# Jeśli pozostawisz puste, zostanie wygenerowane losowe i zapisane bezpiecznie w sops.
|
||||||
GRAFANA_ADMIN_PASSWORD=''
|
GRAFANA_ADMIN_PASSWORD=''
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------
|
||||||
|
# MODUŁY OPCJONALNE (włącz/wyłącz za pomocą true/false)
|
||||||
|
# -------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Czy instalować i konfigurować Fail2ban jako dodatkową warstwę ochrony?
|
||||||
|
INSTALL_FAIL2BAN=true
|
||||||
|
|
||||||
|
# Czy wdrażać bazę danych PostgreSQL?
|
||||||
|
INSTALL_DATABASE=false
|
||||||
|
|
||||||
|
# Czy wdrażać Loki do centralnego zbierania logów z kontenerów?
|
||||||
|
INSTALL_LOKI=false
|
||||||
|
|
||||||
|
# Czy konfigurować system kopii zapasowych Restic?
|
||||||
|
# UWAGA: Wymaga ręcznego uzupełnienia danych repozytorium!
|
||||||
|
INSTALL_BACKUP=false
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------
|
||||||
|
# KONFIGURACJA BAZY DANYCH (jeśli INSTALL_DATABASE=true)
|
||||||
|
# -------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Hasło dla użytkownika 'postgres'. Zostanie zapisane w sops.
|
||||||
|
# Jeśli pozostawisz puste, zostanie wygenerowane losowe.
|
||||||
|
POSTGRES_PASSWORD=''
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------
|
||||||
|
# KONFIGURACJA KOPII ZAPASOWYCH (jeśli INSTALL_BACKUP=true)
|
||||||
|
# -------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Pełna ścieżka do repozytorium Restic (np. s3:s3.amazonaws.com/my-bucket)
|
||||||
|
BACKUP_REPO=''
|
||||||
|
|
||||||
|
# Hasło do repozytorium Restic. Zostanie zapisane w sops.
|
||||||
|
BACKUP_PASSWORD=''
|
||||||
|
|
||||||
|
# Dane dostępowe do Twojego dostawcy chmury (np. AWS S3)
|
||||||
|
# Zostaną zapisane w sops.
|
||||||
|
AWS_ACCESS_KEY_ID=''
|
||||||
|
AWS_SECRET_ACCESS_KEY=''
|
||||||
|
|
||||||
|
# Harmonogram tworzenia kopii zapasowych (format cron)
|
||||||
|
# Poniższy przykład oznacza "codziennie o 3:30 w nocy"
|
||||||
|
BACKUP_CRON_SCHEDULE='30 3 * * *'
|
||||||
|
|
||||||
# -------------------------------------------------------------------
|
# -------------------------------------------------------------------
|
||||||
# WERSJE OBRAZÓW DOCKER
|
# WERSJE OBRAZÓW DOCKER
|
||||||
# -------------------------------------------------------------------
|
# -------------------------------------------------------------------
|
||||||
# Dobrą praktyką jest używanie konkretnych wersji oprogramowania dla stabilności.
|
|
||||||
# Używaj 'latest' z rozwagą.
|
|
||||||
|
|
||||||
TRAEFIK_VER='v3.0'
|
TRAEFIK_VER='v3.0'
|
||||||
PROMETHEUS_VER='latest'
|
PROMETHEUS_VER='latest'
|
||||||
|
|
@ -79,3 +109,6 @@ CADVISOR_VER='latest'
|
||||||
BLACKBOX_VER='latest'
|
BLACKBOX_VER='latest'
|
||||||
GRAFANA_VER='latest'
|
GRAFANA_VER='latest'
|
||||||
ALERTMANAGER_VER='latest'
|
ALERTMANAGER_VER='latest'
|
||||||
|
POSTGRES_VER='16'
|
||||||
|
LOKI_VER='latest'
|
||||||
|
PROMTAIL_VER='latest'
|
||||||
17
templates/monitoring/alertmanager.yml
Normal file
17
templates/monitoring/alertmanager.yml
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
global:
|
||||||
|
smtp_smarthost: '$ALERT_SMTP_HOST'
|
||||||
|
smtp_from: '$ALERT_SMTP_FROM'
|
||||||
|
smtp_auth_username: '$ALERT_SMTP_USER'
|
||||||
|
smtp_auth_password_file: '/etc/alertmanager/secrets/smtp_pass'
|
||||||
|
route:
|
||||||
|
group_by: ['alertname']
|
||||||
|
group_wait: 10s
|
||||||
|
group_interval: 10s
|
||||||
|
repeat_interval: 1h
|
||||||
|
receiver: 'email'
|
||||||
|
receivers:
|
||||||
|
- name: 'email'
|
||||||
|
email_configs:
|
||||||
|
- to: '$ADMIN_EMAIL'
|
||||||
|
subject: 'Alert: {{ "{{" }} .GroupLabels.alertname {{ "}}" }}'
|
||||||
|
send_resolved: true
|
||||||
30
templates/monitoring/alerts.yml
Normal file
30
templates/monitoring/alerts.yml
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
groups:
|
||||||
|
- name: general.rules
|
||||||
|
rules:
|
||||||
|
- alert: InstanceDown
|
||||||
|
expr: up == 0
|
||||||
|
for: 2m
|
||||||
|
labels: { severity: critical }
|
||||||
|
annotations:
|
||||||
|
summary: "Instance {{ $labels.instance }} down"
|
||||||
|
description: "{{ $labels.instance }} of job {{ $labels.job }} down >2m"
|
||||||
|
- alert: HighCPUUsage
|
||||||
|
expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m]))*100) > 80
|
||||||
|
for: 5m
|
||||||
|
labels: { severity: warning }
|
||||||
|
annotations: { summary: "High CPU {{ $labels.instance }}" }
|
||||||
|
- alert: HighMemoryUsage
|
||||||
|
expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes)/node_memory_MemTotal_bytes*100 > 90
|
||||||
|
for: 5m
|
||||||
|
labels: { severity: warning }
|
||||||
|
annotations: { summary: "High memory {{ $labels.instance }}" }
|
||||||
|
- alert: DiskSpaceLow
|
||||||
|
expr: (node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"}/node_filesystem_size_bytes) < 0.1
|
||||||
|
for: 10m
|
||||||
|
labels: { severity: warning }
|
||||||
|
annotations: { summary: "Low disk {{ $labels.instance }}" }
|
||||||
|
- alert: CertificateExpiration
|
||||||
|
expr: probe_ssl_earliest_cert_expiry - time() < 604800
|
||||||
|
for: 0m
|
||||||
|
labels: { severity: warning }
|
||||||
|
annotations: { summary: "Cert expires soon {{ $labels.instance }}" }
|
||||||
10
templates/monitoring/blackbox.yml
Normal file
10
templates/monitoring/blackbox.yml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
modules:
|
||||||
|
http_2xx:
|
||||||
|
prober: http
|
||||||
|
timeout: 5s
|
||||||
|
http:
|
||||||
|
valid_http_versions: ["HTTP/1.1","HTTP/2.0"]
|
||||||
|
valid_status_codes: [200,301,302]
|
||||||
|
method: GET
|
||||||
|
follow_redirects: true
|
||||||
|
tls_config: { insecure_skip_verify: false }
|
||||||
140
templates/monitoring/docker-compose.yml
Normal file
140
templates/monitoring/docker-compose.yml
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
networks:
|
||||||
|
monitoring:
|
||||||
|
traefik_proxy:
|
||||||
|
external: true
|
||||||
|
services:
|
||||||
|
prometheus:
|
||||||
|
image: prom/prometheus:${PROMETHEUS_VER}
|
||||||
|
container_name: prometheus
|
||||||
|
restart: unless-stopped
|
||||||
|
networks: [monitoring, traefik_proxy]
|
||||||
|
volumes:
|
||||||
|
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
|
||||||
|
- ./prometheus/rules:/etc/prometheus/rules:ro
|
||||||
|
- prometheus_data:/prometheus
|
||||||
|
command:
|
||||||
|
- --config.file=/etc/prometheus/prometheus.yml
|
||||||
|
- --storage.tsdb.path=/prometheus
|
||||||
|
- --storage.tsdb.retention.time=30d
|
||||||
|
- --web.enable-lifecycle
|
||||||
|
- --web.external-url=https://prometheus.${PRIMARY_DOMAIN}
|
||||||
|
security_opt: [no-new-privileges:true]
|
||||||
|
read_only: true
|
||||||
|
tmpfs: ["/tmp:size=64m"]
|
||||||
|
cap_drop: [ALL]
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD","wget","-qO-","http://localhost:9090/-/healthy"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.prom.rule=Host(`prometheus.${PRIMARY_DOMAIN}`)
|
||||||
|
- traefik.http.routers.prom.entrypoints=websecure
|
||||||
|
- traefik.http.routers.prom.tls.certresolver=le-dns
|
||||||
|
- traefik.http.routers.prom.middlewares=security-headers@file
|
||||||
|
|
||||||
|
node-exporter:
|
||||||
|
image: prom/node-exporter:${NODE_EXPORTER_VER}
|
||||||
|
container_name: node-exporter
|
||||||
|
restart: unless-stopped
|
||||||
|
networks: [monitoring]
|
||||||
|
pid: host
|
||||||
|
volumes:
|
||||||
|
- /proc:/host/proc:ro
|
||||||
|
- /sys:/host/sys:ro
|
||||||
|
- /:/rootfs:ro
|
||||||
|
command:
|
||||||
|
- --path.procfs=/host/proc
|
||||||
|
- --path.rootfs=/rootfs
|
||||||
|
- --path.sysfs=/host/sys
|
||||||
|
- --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)
|
||||||
|
security_opt: [no-new-privileges:true]
|
||||||
|
read_only: true
|
||||||
|
cap_drop: [ALL]
|
||||||
|
|
||||||
|
cadvisor:
|
||||||
|
image: gcr.io/cadvisor/cadvisor:${CADVISOR_VER}
|
||||||
|
container_name: cadvisor
|
||||||
|
restart: unless-stopped
|
||||||
|
networks: [monitoring]
|
||||||
|
volumes:
|
||||||
|
- /:/rootfs:ro
|
||||||
|
- /var/run:/var/run:rw
|
||||||
|
- /sys:/sys:ro
|
||||||
|
- /var/lib/docker:/var/lib/docker:ro
|
||||||
|
privileged: true
|
||||||
|
devices: ["/dev/kmsg:/dev/kmsg"]
|
||||||
|
|
||||||
|
blackbox-exporter:
|
||||||
|
image: prom/blackbox-exporter:${BLACKBOX_VER}
|
||||||
|
container_name: blackbox-exporter
|
||||||
|
restart: unless-stopped
|
||||||
|
networks: [monitoring]
|
||||||
|
volumes:
|
||||||
|
- ./blackbox/blackbox.yml:/etc/blackbox_exporter/config.yml:ro
|
||||||
|
security_opt: [no-new-privileges:true]
|
||||||
|
read_only: true
|
||||||
|
tmpfs: ["/tmp:size=64m"]
|
||||||
|
cap_drop: [ALL]
|
||||||
|
|
||||||
|
alertmanager:
|
||||||
|
image: prom/alertmanager:${ALERTMANAGER_VER}
|
||||||
|
container_name: alertmanager
|
||||||
|
restart: unless-stopped
|
||||||
|
networks: [monitoring, traefik_proxy]
|
||||||
|
volumes:
|
||||||
|
- ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
|
||||||
|
- alertmanager_data:/alertmanager
|
||||||
|
- ${ALERT_SMTP_PASS_PATH}:/etc/alertmanager/secrets/smtp_pass:ro
|
||||||
|
command:
|
||||||
|
- --config.file=/etc/alertmanager/alertmanager.yml
|
||||||
|
- --storage.path=/alertmanager
|
||||||
|
- --web.external-url=https://alertmanager.${PRIMARY_DOMAIN}
|
||||||
|
security_opt: [no-new-privileges:true]
|
||||||
|
read_only: true
|
||||||
|
tmpfs: ["/tmp:size=64m"]
|
||||||
|
cap_drop: [ALL]
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD","wget","-qO-","http://localhost:9093/-/healthy"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.alert.rule=Host(`alertmanager.${PRIMARY_DOMAIN}`)
|
||||||
|
- traefik.http.routers.alert.entrypoints=websecure
|
||||||
|
- traefik.http.routers.alert.tls.certresolver=le-dns
|
||||||
|
- traefik.http.routers.alert.middlewares=security-headers@file
|
||||||
|
|
||||||
|
grafana:
|
||||||
|
image: grafana/grafana:${GRAFANA_VER}
|
||||||
|
container_name: grafana
|
||||||
|
user: "472"
|
||||||
|
restart: unless-stopped
|
||||||
|
networks: [monitoring, traefik_proxy]
|
||||||
|
volumes:
|
||||||
|
- grafana_data:/var/lib/grafana
|
||||||
|
- ./grafana/provisioning:/etc/grafana/provisioning:ro
|
||||||
|
environment:
|
||||||
|
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD}
|
||||||
|
GF_USERS_ALLOW_SIGN_UP: "false"
|
||||||
|
GF_SERVER_ROOT_URL: https://grafana.${PRIMARY_DOMAIN}
|
||||||
|
security_opt: [no-new-privileges:true]
|
||||||
|
cap_drop: [ALL]
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD","wget","-qO-","http://localhost:3000/api/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
labels:
|
||||||
|
- traefik.enable=true
|
||||||
|
- traefik.http.routers.grafana.rule=Host(`grafana.${PRIMARY_DOMAIN}`)
|
||||||
|
- traefik.http.routers.grafana.entrypoints=websecure
|
||||||
|
- traefik.http.routers.grafana.tls.certresolver=le-dns
|
||||||
|
- traefik.http.routers.grafana.middlewares=security-headers@file
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
prometheus_data:
|
||||||
|
grafana_data:
|
||||||
|
alertmanager_data:
|
||||||
8
templates/monitoring/prometheus-datasource.yml
Normal file
8
templates/monitoring/prometheus-datasource.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
apiVersion: 1
|
||||||
|
datasources:
|
||||||
|
- name: Prometheus
|
||||||
|
type: prometheus
|
||||||
|
access: proxy
|
||||||
|
url: http://prometheus:9090
|
||||||
|
isDefault: true
|
||||||
|
editable: false
|
||||||
35
templates/monitoring/prometheus.yml
Normal file
35
templates/monitoring/prometheus.yml
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
global:
|
||||||
|
scrape_interval: 15s
|
||||||
|
evaluation_interval: 15s
|
||||||
|
rule_files:
|
||||||
|
- "/etc/prometheus/rules/*.yml"
|
||||||
|
alerting:
|
||||||
|
alertmanagers:
|
||||||
|
- static_configs: [{ targets: ['alertmanager:9093'] }]
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: prometheus
|
||||||
|
static_configs: [{ targets: ['localhost:9090'] }]
|
||||||
|
- job_name: node-exporter
|
||||||
|
static_configs: [{ targets: ['node-exporter:9100'] }]
|
||||||
|
- job_name: cadvisor
|
||||||
|
static_configs: [{ targets: ['cadvisor:8080'] }]
|
||||||
|
- job_name: traefik
|
||||||
|
static_configs: [{ targets: ['traefik:8080'] }]
|
||||||
|
- job_name: blackbox
|
||||||
|
metrics_path: /probe
|
||||||
|
params: { module: [http_2xx] }
|
||||||
|
static_configs:
|
||||||
|
- targets:
|
||||||
|
- https://forum.yeswas.pl
|
||||||
|
- https://social.ovh
|
||||||
|
- https://rss.social.ovh
|
||||||
|
- https://pawelorzech.pl
|
||||||
|
- https://dash.orzech.me
|
||||||
|
- https://run.orzech.me
|
||||||
|
relabel_configs:
|
||||||
|
- source_labels: [__address__]
|
||||||
|
target_label: __param_target
|
||||||
|
- source_labels: [__param_target]
|
||||||
|
target_label: instance
|
||||||
|
- target_label: __address__
|
||||||
|
replacement: blackbox-exporter:9115
|
||||||
27
templates/traefik/docker-compose.yml
Normal file
27
templates/traefik/docker-compose.yml
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
services:
|
||||||
|
traefik:
|
||||||
|
image: traefik:${TRAEFIK_VER}
|
||||||
|
container_name: traefik
|
||||||
|
restart: unless-stopped
|
||||||
|
networks: [traefik_proxy]
|
||||||
|
ports: ["80:80","443:443"]
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
- ./config/traefik.yml:/etc/traefik/traefik.yml:ro
|
||||||
|
- ./dynamic:/etc/traefik/dynamic:ro
|
||||||
|
- ./data/acme.json:/acme/acme.json
|
||||||
|
environment:
|
||||||
|
CF_DNS_API_TOKEN: ${CF_DNS_API_TOKEN}
|
||||||
|
security_opt: [no-new-privileges:true]
|
||||||
|
read_only: true
|
||||||
|
tmpfs: ["/tmp:size=64m"]
|
||||||
|
cap_drop: [ALL]
|
||||||
|
cap_add: [NET_BIND_SERVICE]
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD","wget","--no-verbose","--tries=1","--spider","http://localhost:8080/ping"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
networks:
|
||||||
|
traefik_proxy:
|
||||||
|
external: true
|
||||||
14
templates/traefik/middlewares.yml
Normal file
14
templates/traefik/middlewares.yml
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
http:
|
||||||
|
middlewares:
|
||||||
|
security-headers:
|
||||||
|
headers:
|
||||||
|
stsSeconds: 63072000
|
||||||
|
stsIncludeSubdomains: true
|
||||||
|
stsPreload: true
|
||||||
|
contentTypeNosniff: true
|
||||||
|
referrerPolicy: "strict-origin-when-cross-origin"
|
||||||
|
frameDeny: true
|
||||||
|
browserXssFilter: true
|
||||||
|
gzip: { compress: {} }
|
||||||
|
rate-limit:
|
||||||
|
rateLimit: { burst: 100, average: 50 }
|
||||||
5
templates/traefik/tls.yml
Normal file
5
templates/traefik/tls.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
tls:
|
||||||
|
options:
|
||||||
|
default:
|
||||||
|
minVersion: VersionTLS12
|
||||||
|
sniStrict: true
|
||||||
22
templates/traefik/traefik.yml
Normal file
22
templates/traefik/traefik.yml
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
api: { dashboard: true }
|
||||||
|
ping: {}
|
||||||
|
entryPoints:
|
||||||
|
web:
|
||||||
|
address: ":80"
|
||||||
|
http: { redirections: { entryPoint: { to: websecure, scheme: https } } }
|
||||||
|
websecure:
|
||||||
|
address: ":443"
|
||||||
|
providers:
|
||||||
|
file: { directory: "/etc/traefik/dynamic", watch: true }
|
||||||
|
docker:
|
||||||
|
exposedByDefault: false
|
||||||
|
network: traefik_proxy
|
||||||
|
certificatesResolvers:
|
||||||
|
le-dns:
|
||||||
|
acme:
|
||||||
|
email: ${ADMIN_EMAIL}
|
||||||
|
storage: /acme/acme.json
|
||||||
|
dnsChallenge: { provider: cloudflare, delayBeforeCheck: 0 }
|
||||||
|
metrics: { prometheus: { addEntryPointsLabels: true, addServicesLabels: true } }
|
||||||
|
log: { level: INFO, format: json }
|
||||||
|
accessLog: { format: json }
|
||||||
Loading…
Reference in a new issue