first commit
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Template anonymisé — synchronisation chiffrée vers pCloud
|
||||
# Copier en pcloud-sync.sh, adapter les chemins, ne jamais commiter le fichier réel
|
||||
# ni les identifiants (à stocker via un gestionnaire de secrets / variables d'environnement,
|
||||
# jamais en dur dans ce script).
|
||||
#
|
||||
# Pré-requis : rclone configuré avec un remote pCloud chiffré (crypt) nommé "pcloud-crypt"
|
||||
# Doc rclone crypt : https://rclone.org/crypt/
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SOURCE_DIR="/mnt/data-pool/sensitive"
|
||||
REMOTE_NAME="pcloud-crypt"
|
||||
REMOTE_PATH="backup/data-pool"
|
||||
LOG_FILE="/var/log/pcloud-sync.log"
|
||||
|
||||
timestamp() {
|
||||
date "+%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
|
||||
echo "$(timestamp) - Début de la synchronisation" >> "$LOG_FILE"
|
||||
|
||||
rclone sync "$SOURCE_DIR" "${REMOTE_NAME}:${REMOTE_PATH}" \
|
||||
--backup-dir "${REMOTE_NAME}:${REMOTE_PATH}-versions/$(date +%Y%m%d)" \
|
||||
--log-file "$LOG_FILE" \
|
||||
--log-level INFO \
|
||||
--transfers 4 \
|
||||
--checkers 8
|
||||
|
||||
echo "$(timestamp) - Synchronisation terminée" >> "$LOG_FILE"
|
||||
|
||||
# Note : l'option --backup-dir conserve une copie des fichiers modifiés/supprimés
|
||||
# côté distant, datée du jour, pour limiter l'impact d'une synchronisation
|
||||
# après compromission ou chiffrement local malveillant.
|
||||
@@ -0,0 +1,21 @@
|
||||
# Template anonymisé — config Cloudflare Tunnel
|
||||
# Copier en config.yml, remplacer les valeurs, ne jamais commiter le fichier réel ni le credentials-file.
|
||||
|
||||
tunnel: __REPLACE_WITH_TUNNEL_ID__
|
||||
credentials-file: /etc/cloudflared/__REPLACE_WITH_TUNNEL_ID__.json
|
||||
|
||||
ingress:
|
||||
- hostname: cloud.__REPLACE_WITH_DOMAIN__
|
||||
service: http://nginx-proxy-manager:80
|
||||
|
||||
- hostname: media.__REPLACE_WITH_DOMAIN__
|
||||
service: http://nginx-proxy-manager:80
|
||||
|
||||
- hostname: vault.__REPLACE_WITH_DOMAIN__
|
||||
service: http://nginx-proxy-manager:80
|
||||
|
||||
- hostname: auth.__REPLACE_WITH_DOMAIN__
|
||||
service: http://nginx-proxy-manager:80
|
||||
|
||||
# Règle de repli obligatoire en fin de fichier
|
||||
- service: http_status:404
|
||||
@@ -0,0 +1,129 @@
|
||||
# Template anonymisé — à adapter, ne JAMAIS commiter de vraies valeurs
|
||||
# Copier ce fichier en docker-compose.yml et remplacer les variables avant usage.
|
||||
|
||||
version: "3.9"
|
||||
|
||||
networks:
|
||||
proxy-net:
|
||||
external: true
|
||||
internal-net:
|
||||
internal: true
|
||||
|
||||
services:
|
||||
|
||||
nginx-proxy-manager:
|
||||
image: jc21/nginx-proxy-manager:latest
|
||||
container_name: nginx-proxy-manager
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "81:81" # interface d'admin, à exposer uniquement via le tunnel
|
||||
volumes:
|
||||
- ./npm/data:/data
|
||||
- ./npm/letsencrypt:/etc/letsencrypt
|
||||
networks:
|
||||
- proxy-net
|
||||
|
||||
cloudflared:
|
||||
image: cloudflare/cloudflared:latest
|
||||
container_name: cloudflared
|
||||
restart: unless-stopped
|
||||
command: tunnel run
|
||||
environment:
|
||||
- TUNNEL_TOKEN=__REPLACE_WITH_SECRET__ # à stocker dans un .env, jamais en clair ici
|
||||
networks:
|
||||
- proxy-net
|
||||
|
||||
authentik-server:
|
||||
image: ghcr.io/goauthentik/server:latest
|
||||
container_name: authentik-server
|
||||
restart: unless-stopped
|
||||
command: server
|
||||
environment:
|
||||
AUTHENTIK_SECRET_KEY: __REPLACE_WITH_SECRET__
|
||||
AUTHENTIK_POSTGRESQL__HOST: authentik-db
|
||||
AUTHENTIK_POSTGRESQL__PASSWORD: __REPLACE_WITH_SECRET__
|
||||
AUTHENTIK_REDIS__HOST: authentik-redis
|
||||
depends_on:
|
||||
- authentik-db
|
||||
- authentik-redis
|
||||
networks:
|
||||
- proxy-net
|
||||
- internal-net
|
||||
|
||||
authentik-db:
|
||||
image: postgres:16-alpine
|
||||
container_name: authentik-db
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_PASSWORD: __REPLACE_WITH_SECRET__
|
||||
POSTGRES_USER: authentik
|
||||
POSTGRES_DB: authentik
|
||||
volumes:
|
||||
- ./authentik/database:/var/lib/postgresql/data
|
||||
networks:
|
||||
- internal-net
|
||||
|
||||
authentik-redis:
|
||||
image: redis:alpine
|
||||
container_name: authentik-redis
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- internal-net
|
||||
|
||||
vaultwarden:
|
||||
image: vaultwarden/server:latest
|
||||
container_name: vaultwarden
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
DOMAIN: "https://__REPLACE_WITH_SUBDOMAIN__"
|
||||
SIGNUPS_ALLOWED: "false"
|
||||
volumes:
|
||||
- ./vaultwarden/data:/data
|
||||
networks:
|
||||
- proxy-net
|
||||
|
||||
nextcloud:
|
||||
image: nextcloud:latest
|
||||
container_name: nextcloud
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /mnt/data-pool/nextcloud:/var/www/html
|
||||
networks:
|
||||
- proxy-net
|
||||
- internal-net
|
||||
|
||||
jellyfin:
|
||||
image: jellyfin/jellyfin:latest
|
||||
container_name: jellyfin
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /mnt/media-pool/library:/media
|
||||
- ./jellyfin/config:/config
|
||||
networks:
|
||||
- proxy-net
|
||||
|
||||
gluetun:
|
||||
image: qmcgaw/gluetun:latest
|
||||
container_name: gluetun
|
||||
restart: unless-stopped
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
environment:
|
||||
VPN_SERVICE_PROVIDER: __REPLACE_WITH_PROVIDER__
|
||||
VPN_TYPE: wireguard
|
||||
WIREGUARD_PRIVATE_KEY: __REPLACE_WITH_SECRET__
|
||||
networks:
|
||||
- internal-net
|
||||
|
||||
deluge:
|
||||
image: linuxserver/deluge:latest
|
||||
container_name: deluge
|
||||
restart: unless-stopped
|
||||
network_mode: "service:gluetun"
|
||||
depends_on:
|
||||
- gluetun
|
||||
volumes:
|
||||
- /mnt/media-pool/downloads:/downloads
|
||||
- ./deluge/config:/config
|
||||
@@ -0,0 +1,29 @@
|
||||
# 🌐 Nginx Proxy Manager — bonnes pratiques appliquées
|
||||
|
||||
> Aucune capture d'écran ni configuration réelle n'est versionnée ici (l'admin NPM contient les certificats et les hosts internes). Ce fichier documente les règles suivies.
|
||||
|
||||
## Principes
|
||||
|
||||
- Un **proxy host** par service, jamais de service exposé directement sans passer par NPM.
|
||||
- Forçage SSL systématique (`Force SSL` + `HTTP/2`) sur chaque host.
|
||||
- Certificats Let's Encrypt en wildcard sur le domaine principal, renouvellement automatique.
|
||||
- Pas d'exposition de l'interface d'administration NPM (port 81) en dehors du tunnel Cloudflare + Authentik forward-auth.
|
||||
|
||||
## Convention de nommage des sous-domaines
|
||||
|
||||
| Sous-domaine | Service |
|
||||
| ------------------------- | -------------------- |
|
||||
| `cloud.example.com` | Nextcloud |
|
||||
| `media.example.com` | Jellyfin |
|
||||
| `photos.example.com` | Immich |
|
||||
| `vault.example.com` | Vaultwarden |
|
||||
| `auth.example.com` | Authentik |
|
||||
| `git.example.com` | Gitea |
|
||||
|
||||
## Forward-auth (Authentik)
|
||||
|
||||
Pour les services ne gérant pas nativement le SSO, un bloc de configuration personnalisée NPM redirige les requêtes non authentifiées vers Authentik (`outpost` en mode proxy), qui valide la session avant de relayer la requête vers le service interne.
|
||||
|
||||
## Journalisation
|
||||
|
||||
Les access logs et error logs de NPM sont conservés localement avec rotation, pour permettre une analyse en cas de comportement suspect (tentatives d'accès répétées, scans, etc.).
|
||||
Reference in New Issue
Block a user