diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2eea525
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.env
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..f09d69a
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,33 @@
+# Utilise la même base que ton serveur Scaleway
+FROM debian:12-slim
+
+# Évite les erreurs 'TERM environment variable not set' lors du 'clear'
+ENV TERM=xterm
+# Empêche les interfaces interactives pendant l'installation des paquets
+ENV DEBIAN_FRONTEND=noninteractive
+
+# Installation des dépendances
+# Note : on utilise docker.io pour avoir le binaire /usr/bin/docker
+RUN apt-get update && apt-get install -y \
+ curl \
+ cron \
+ sudo \
+ procps \
+ docker.io \
+ docker-compose \
+ && rm -rf /var/lib/apt/lists/*
+
+# Création de l'arborescence de travail
+WORKDIR /app
+
+# On copie le contenu du projet
+# Assure-toi d'être à la racine de 'serverconfig' quand tu buildes
+COPY . .
+
+# On rend les scripts exécutables
+# Utilisation de find pour être sûr de ne rater aucun script dans les sous-dossiers
+RUN find . -name "*.sh" -exec chmod +x {} +
+
+# On lance le script d'installation
+# Utilisation de la forme exec pour une meilleure gestion des signaux
+CMD ["./install.sh"]
diff --git a/scripts/disk-monitor.sh b/disk-monitor.sh
similarity index 63%
rename from scripts/disk-monitor.sh
rename to disk-monitor.sh
index 3d7ea84..1c6f493 100644
--- a/scripts/disk-monitor.sh
+++ b/disk-monitor.sh
@@ -1,32 +1,34 @@
#!/bin/bash
-source /usr/local/bin/libs/common.sh
-source /etc/serverconfig/.env
+# DISK MONITORING & INSTALLATION SCRIPT
+# This script monitors disk usage and sends notifications.
+# It can also self-install into the system crontab.
+
+PROJECT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
+readonly PROJECT_DIR 2>/dev/null
+
+source $PROJECT_DIR/utils.sh
+source $ENV_FILE
INSTALLED=$1
if [[ "--install" == $INSTALLED ]]; then
- info_print "\n\
-==================================================\n\
- disk-monitor Installation\n\
---------------------------------------------------"
+ log_info "disk-monitor Installation"
+
if ! command -v crontab >/dev/null 2>&1; then
- info_print "Error: crontab not found." $ERROR_FLAG
+ log_error "Error: crontab not found."
exit 1
fi
- CRON_JOB="0 3 * * 1 $SCRIPT_FILE/scripts/disk-monitor.sh"
+ CRON_JOB="0 3 * * 1 $PROJECT_DIR/disk-monitor.sh"
crontab -l | grep -F "$CRON_JOB" > /dev/null 2>&1
if ! crontab -l | grep -Fq "$CRON_JOB"; then
(crontab -l 2>/dev/null; echo "$CRON_JOB") | crontab -
- info_print "Cron job added." $SUCCESS_FLAG
+ log_success "Cron job added."
fi
exit 0;
fi
-source /usr/local/bin/libs/notifications.sh
-
usage=80
-
send_notification "$(
df -h / | grep / | awk -v max="$usage" '{
usage = $5;
diff --git a/docker-compose.sh b/docker-compose.sh
new file mode 100644
index 0000000..2c6a9df
--- /dev/null
+++ b/docker-compose.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+PROJECT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
+readonly PROJECT_DIR 2>/dev/null
+
+source $PROJECT_DIR/utils.sh
+source $ENV_FILE
+
+if [[ "--install" == $1 ]]; then
+ log_info "docker-compose Installation"
+ COMPOSE_FILE="$(realpath "$PROJECT_DIR/docker-compose.yml")"
+
+ if [[ -f "$COMPOSE_FILE" ]]; then
+ docker compose -f "$COMPOSE_FILE" up -d --force-recreate --remove-orphans && \
+ log_success "$COMPOSE_FILE is running.";
+
+ else log_error "no docker-compose.yml found at $PROJECT_DIR";
+ fi
+ exit 0;
+fi
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 2017cf4..bb2d381 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -69,9 +69,9 @@ services:
DOCKER_HOST: tcp://socket-rw:2375 # Uses RW proxy to pause containers during backup
volumes:
- wireguard-data:/backup/wireguard:ro
- - ./synapse:/backup/synapse:ro
+ - ./data/synapse:/backup/synapse:ro
- ssl-data:/backup/ssl:ro
- - ./backup:/archive
+ - ./data/backup:/archive
networks:
- socket-rw-bridge
- web-network
@@ -89,8 +89,8 @@ services:
- ENABLE_IPV6=true
volumes:
- ssl-data:/etc/nginx/certs:ro
- - ./nginx/default_html:/usr/share/nginx/html
- - ./nginx/vhost.d:/etc/nginx/vhost.d
+ - ./data/nginx/default_html:/usr/share/nginx/html
+ - ./data/nginx/vhost.d:/etc/nginx/vhost.d
labels:
- "docker-volume-backup.stop-during-backup=true" # Ensure consistency during backup
depends_on:
@@ -110,9 +110,9 @@ services:
- DOCKER_HOST=tcp://socket-rw:2375 # Needs RW to restart Nginx after renewal
volumes:
- ssl-data:/etc/nginx/certs
- - ./nginx/vhost.d:/etc/nginx/vhost.d
- - ./nginx/default_html:/usr/share/nginx/html
- - ./nginx/acme_config:/etc/acme.sh
+ - ./data/nginx/vhost.d:/etc/nginx/vhost.d
+ - ./data/nginx/default_html:/usr/share/nginx/html
+ - ./data/nginx/acme_config:/etc/acme.sh
labels:
- "docker-volume-backup.stop-during-backup=true"
depends_on:
@@ -132,7 +132,7 @@ services:
# - LETSENCRYPT_HOST=${HOSTNAME}, www.${HOSTNAME}
# - LETSENCRYPT_EMAIL=${EMAIL}
# volumes:
- # - ./data:/usr/share/nginx/html/data
+ # - /data/public:/usr/share/nginx/html/data
# networks:
# - web-network
@@ -186,7 +186,7 @@ services:
container_name: synapse
restart: unless-stopped
volumes:
- - ./synapse:/data
+ - ./data/synapse:/data
environment:
- SYNAPSE_CONFIG_PATH=/data/homeserver.yaml
- VIRTUAL_HOST=msg.${HOSTNAME}
@@ -210,7 +210,7 @@ services:
- GITEA__server__ROOT_URL=https://git.${HOSTNAME}/
- DISABLE_REGISTRATION=true # Private instance security
volumes:
- - ./gitea:/data
+ - ./data/gitea:/data
- /etc/localtime:/etc/localtime:ro
ports:
- "222:22" # SSH port mapping for Git operations
@@ -227,7 +227,7 @@ services:
- LETSENCRYPT_HOST=mirror.${HOSTNAME}
- LETSENCRYPT_EMAIL=${EMAIL}
- VIRTUAL_PORT=4321
- - BETTER_AUTH_SECRET=${MIRROR_AUTH_SECRET}
+ - BETTER_AUTH_SECRET=${GITHUB_AUTH_SECRET}
volumes:
- gitea-mirror-data:/app/data
networks:
diff --git a/install.sh b/install.sh
index 3267d34..1f9f0ed 100644
--- a/install.sh
+++ b/install.sh
@@ -1,32 +1,17 @@
#!/bin/bash
-set -euo pipefail
+PROJECT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
+readonly PROJECT_DIR 2>/dev/null
+source "$PROJECT_DIR/utils.sh"
-readonly PROJECT_NAME="serverconfig"
-readonly PROJECT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
+# set -euo pipefail
-readonly REQ=("curl" "docker")
-
-readonly ENV_FILE="${PROJECT_DIR}/.env"
-
-readonly GREEN='\033[0;32m'
-readonly RED='\033[0;31m'
-readonly YELLOW='\033[1;33m'
-readonly BLUE='\033[0;34m'
-readonly NC='\033[0m'
-
-DATETIME_FORMAT="%d-%m-%Y %H:%M:%S"
-
-function log() {
- local type="${1}"
- local color="${2}"
- local message="${3}"
- echo -e "${color}[$(date +"$DATETIME_FORMAT")] [${type}]${NC} ${message}"
-}
-
-function log_info() { log "INFO" "$BLUE" "$1"; }
-function log_success() { log "OK " "$GREEN" "$1"; }
-function log_error() { log "ERR " "$RED" "$1" >&2; }
+ENV_LIST=(
+ "EMAIL" "HOSTNAME"
+ "TELEGRAM_TOKEN" "TELEGRAM_CHAT_ID"
+ "AWS" "ENDPOINT" "AWS_ACCESS_KEY_ID" "AWS_SECRET_ACCESS_KEY"
+ "GITHUB_AUTH_SECRET"
+)
function check_root() {
if [[ $EUID -ne 0 ]]; then
@@ -49,8 +34,13 @@ function check_dependencies() {
function install_scripts() {
log_info "Installing scripts..."
- for script in "$SCRIPT_FILE"/*.sh; do
+ for script in "$PROJECT_DIR"/*.sh; do
[ -e "$script" ] || continue
+
+ if [[ "$script" == "$(realpath "$0")" ]]; then
+ continue
+ fi
+
log_info "Configuring $(basename "$script")..."
if ! bash "$script" --install; then
log_error "Hook failed for $script"
@@ -68,9 +58,17 @@ function main() {
log_info "Creating directories and files..."
touch "$ENV_FILE"
+ for env in "${ENV_LIST[@]}"; do
+ read -sp "Enter value for $env: " value
+ echo
+ env_variable "$env" "$value"
+ done
+
install_scripts
log_success "Installation Complete"
}
-main "$@"
\ No newline at end of file
+if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
+ main "$@"
+fi
\ No newline at end of file
diff --git a/libs/common.sh b/libs/common.sh
deleted file mode 100644
index 13edb27..0000000
--- a/libs/common.sh
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/bin/bash
-
-FILENAME="serverconfig"
-
-ETC_DIR="/etc/$FILENAME"
-ENV_FILE="$ETC_DIR/.env"
-LOG="/var/log/$FILENAME.log"
-SCRIPT_FILE="/usr/local/bin"
-
-INFO="\e[34mINFO\e[0m"
-SUCCESS="\e[32mSUCCESS\e[0m"
-WARN="\e[33mWARN\e[0m"
-ERROR="\e[31mERROR\e[0m"
-DEBUG="\e[35mDEBUG\e[0m"
-ACTION="\e[36mACTION\e[0m"
-
-INFO_FLAG=1
-WARN_FLAG=2
-ERROR_FLAG=3
-DEBUG_FLAG=4
-ACTION_FLAG=5
-SUCCESS_FLAG=6
-
-
-DATETIME_FORMAT="%d-%m-%Y %H:%M:%S"
-
-info_print() {
- local message="$1"
- local level="${2:-1}"
- local write_log="${3:-true}"
-
- case $level in
- 1|--) local level=$INFO;;
- 2) local level=$WARN;;
- 3) local level=$ERROR;;
- 4) local level=$DEBUG;;
- 5) local level=$ACTION;;
- 6) local level=$SUCCESS;;
- *);;
- esac
-
- local output="[$(date +"$DATETIME_FORMAT")] - $level: $message"
-
- if [ "$write_log" = true ]; then echo -e "$output" | tee -a "$LOG"
- else echo -e "$output"
- fi
-}
-
-create_env_variable() {
- local key="$1"
- local value="$2"
- local file="${3:-$ENV_FILE}"
- local isUpdated="${4:-true}"
-
- if [[ "$file" == '--' ]]; then
- file=$ENV_FILE
- fi
-
- if [[ -z "$value" && "$isUpdated" == true ]]; then
- if grep -q "^$key=*" "$file" 2>/dev/null; then
- info_print "$key not updated." $WARN_FLAG
- return
- else
- info_print "$key not set (empty input)." $WARN_FLAG
- return
- fi
- fi
-
- if [[ "$isUpdated" == true ]]; then
- if grep -Eq "^${key}=" "$file" 2>/dev/null; then
- read -p "$key already set, overwrite? (y/N): " yn
-
- case "$yn" in
- [Yy]*)
- sed -i "s/^$key=.*/$key=$value/" "$file"
- info_print "$key updated." $SUCCESS_FLAG
- ;;
- *)
- info_print "$key not changed." $WARN_FLAG
- ;;
- esac
- else
- echo "$key=$value" >> "$file"
- info_print "$key set." $SUCCESS_FLAG
- fi
- else
- if grep -Eq "^${key}=" "$file" 2>/dev/null; then
- sed -i "s/^$key=.*/$key=$value/" "$file"
- else
- echo "$key=$value" >> "$file"
- fi
- fi
-}
-
-create_raw_line_variable() {
- local line="$1"
- local file="$2"
-
- if grep -Fxq "$line" "$file" 2>/dev/null; then
- info_print "'$line' already defined as raw line." $WARN_FLAG
- else
- echo "$line" >> "$file"
- info_print "'$line' added as raw line." $SUCCESS_FLAG
- fi
-}
\ No newline at end of file
diff --git a/libs/notifications.sh b/libs/notifications.sh
deleted file mode 100644
index 3eaf275..0000000
--- a/libs/notifications.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-source /usr/local/bin/libs/common.sh
-source /etc/serverconfig/.env
-
-INSTALLED=$1
-
-if [[ "--install" == $INSTALLED ]]; then
- info_print "\n\
-==================================================\n\
- notifications Installation\n\
---------------------------------------------------"
-
- ENV_LIST=("TELEGRAM_TOKEN" "TELEGRAM_CHAT_ID")
-
- for env in "${ENV_LIST[@]}"; do
- read -p "Enter value for $env: " value
- create_env_variable "$env" "$value"
- done
-
- exit 0
-fi
-
-send_notification() {
- local message="$1"
- curl -X POST "https://api.telegram.org/bot$TELEGRAM_TOKEN/sendMessage" \
- -d "chat_id=$TELEGRAM_CHAT_ID" \
- -d "text=$message" \
- -d "parse_mode=HTML"
-}
\ No newline at end of file
diff --git a/scripts/docker-compose.sh b/scripts/docker-compose.sh
deleted file mode 100644
index 14e09c5..0000000
--- a/scripts/docker-compose.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-
-INSTALLED=$1
-if [[ "--install" == $INSTALLED ]]; then
- source /usr/local/bin/libs/common.sh
-
- info_print "\n\
-==================================================\n\
- docker-compose Installation\n\
---------------------------------------------------"
-
- ENV_LIST=("EMAIL" "HOSTNAME")
-
- for env in "${ENV_LIST[@]}"; do
- read -p "Enter value for $env: " value
- create_env_variable "$env" "$value"
- done
-
- source /etc/serverconfig/.env
-
- if [[ -f "$ETC_DIR/docker-compose.yml" ]]; then
- docker compose -f "$ETC_DIR/docker-compose.yml" up -d --force-recreate --remove-orphans && \
- info_print "$ETC_DIR/docker-compose.yml is running." 6;
-
- else info_print "no docker-compose.yml found at $ETC_DIR" 3;
- fi
- exit 0;
-fi
\ No newline at end of file
diff --git a/scripts/sshd-login.sh b/scripts/sshd-login.sh
deleted file mode 100644
index 0395466..0000000
--- a/scripts/sshd-login.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/bash
-
-source /usr/local/bin/libs/common.sh
-source /etc/serverconfig/.env
-
-INSTALLED=$1
-if [[ "--install" == $INSTALLED ]]; then
- info_print "\n\
-==================================================\n\
- sshd-login Installation\n\
---------------------------------------------------"
-
- login='session optional pam_exec.so /usr/local/bin/scripts/sshd-login.sh'
- file='/etc/pam.d/common-session'
-
- if [[ ! -f "$file" ]]; then
- info_print "$file doesn't found." $ERROR_FLAG
- exit 1
- fi
-
- if ! grep -Fxq "$login" "$file"; then
- echo "$login" >> "$file"
- info_print "login command added to $file." $SUCCESS_FLAG
- else
- info_print "login command already added to $file." $WARN_FLAG
- fi
- exit 0;
-fi
-
-source /usr/local/bin/libs/notifications.sh
-
-case "$PAM_TYPE" in
- open_session)
- PAYLOAD=$(printf "🚨 Login Event 🚨\nUser %s logged in from %s at %s." "$PAM_USER" "$PAM_RHOST" "$(date)")
- ;;
- close_session)
- PAYLOAD=$(printf "🚨 Logout Event 🚨\nUser %s logged out from %s at %s." "$PAM_USER" "$PAM_RHOST" "$(date)")
- ;;
-esac
-
-if [ -n "$PAYLOAD" ] ; then
- send_notification "$PAYLOAD"
-fi
\ No newline at end of file
diff --git a/sshd-login.sh b/sshd-login.sh
new file mode 100644
index 0000000..c93ad7c
--- /dev/null
+++ b/sshd-login.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+PROJECT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
+readonly PROJECT_DIR 2>/dev/null
+
+source $PROJECT_DIR/utils.sh
+
+INSTALLED=$1
+if [[ "--install" == $INSTALLED ]]; then
+ log_info "sshd-login Installation"
+
+ login="session optional pam_exec.so $PROJECT_DIR/sshd-login.sh"
+ file='/etc/pam.d/common-session'
+
+ if [[ ! -f "$file" ]]; then
+ log_error "$file doesn't found."
+ exit 1
+ fi
+
+ if ! grep -Fxq "$login" "$file"; then
+ echo "$login" >>"$file"
+ log_success "login command added to $file."
+ else
+ log_warn "login command already added to $file." $WARN_FLAG
+ fi
+ exit 0
+fi
+
+case "$PAM_TYPE" in
+open_session)
+ PAYLOAD=$(printf "🚨 Login Event 🚨\nUser %s logged in from %s at %s." "$PAM_USER" "$PAM_RHOST" "$(date)")
+ ;;
+close_session)
+ PAYLOAD=$(printf "🚨 Logout Event 🚨\nUser %s logged out from %s at %s." "$PAM_USER" "$PAM_RHOST" "$(date)")
+ ;;
+esac
+
+if [ -n "$PAYLOAD" ]; then
+ send_notification "$PAYLOAD"
+fi
diff --git a/utils.sh b/utils.sh
new file mode 100644
index 0000000..b0d9bae
--- /dev/null
+++ b/utils.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+
+# UTILITY FUNCTIONS & CONFIGURATION
+# This script acts as a library (utils.sh) for other monitoring scripts.
+# It handles logging, environment variables, and Telegram notifications.
+
+PROJECT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
+readonly PROJECT_DIR 2>/dev/null
+
+readonly PROJECT_NAME="serverconfig"
+
+readonly REQ=("curl" "docker")
+
+readonly ENV_FILE="${PROJECT_DIR}/.env"
+
+readonly GREEN='\033[0;32m'
+readonly RED='\033[0;31m'
+readonly YELLOW='\033[1;33m'
+readonly BLUE='\033[0;34m'
+readonly NC='\033[0m'
+
+DATETIME_FORMAT="%d-%m-%Y %H:%M:%S"
+
+function log() {
+ local type="${1}"
+ local color="${2}"
+ local message="${3}"
+ echo -e "${color}[$(date +"$DATETIME_FORMAT")] [${type}]${NC} ${message}"
+}
+
+function log_info() { log "INFO" "$BLUE" "$1"; }
+function log_success() { log "OK " "$GREEN" "$1"; }
+function log_error() { log "ERR " "$RED" "$1" >&2; }
+function log_warn() { log "WARN " "$YELLOW" "$1" >&2; }
+
+# USING TELEGRAM (may change later)
+function send_notification() {
+ local message="$1"
+ curl -X POST "https://api.telegram.org/bot$TELEGRAM_TOKEN/sendMessage" \
+ -d "chat_id=$TELEGRAM_CHAT_ID" \
+ -d "text=$message" \
+ -d "parse_mode=HTML"
+}
+
+function env_variable() {
+ source $ENV_FILE
+
+ local key="$1"
+ local value="$2"
+
+ if [[ -z "$value" ]]; then
+ log_warn "$key not set."
+ fi
+
+ if grep -Eq "^${key}=" "$ENV_FILE" 2>/dev/null; then
+ read -p "$key already set, overwrite? (y/N): " yn
+ case "$yn" in
+ [yY]*)
+ sed -i "s/^$key=.*/$key=$value/" "$ENV_FILE"
+ log_success "$key updated."
+ ;;
+ *)
+ log_info "$key not changed."
+ ;;
+ esac
+ else
+ echo "$key=$value" >> "$ENV_FILE"
+ log_success "$key created."
+ fi
+}
\ No newline at end of file