mirror of
https://github.com/guezoloic/serverconfig.git
synced 2026-03-28 18:03:49 +00:00
feat: rework entire repo structure
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.env
|
||||||
33
Dockerfile
Normal file
33
Dockerfile
Normal file
@@ -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"]
|
||||||
@@ -1,32 +1,34 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
source /usr/local/bin/libs/common.sh
|
# DISK MONITORING & INSTALLATION SCRIPT
|
||||||
source /etc/serverconfig/.env
|
# 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
|
INSTALLED=$1
|
||||||
if [[ "--install" == $INSTALLED ]]; then
|
if [[ "--install" == $INSTALLED ]]; then
|
||||||
info_print "\n\
|
log_info "disk-monitor Installation"
|
||||||
==================================================\n\
|
|
||||||
disk-monitor Installation\n\
|
|
||||||
--------------------------------------------------"
|
|
||||||
if ! command -v crontab >/dev/null 2>&1; then
|
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
|
exit 1
|
||||||
fi
|
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
|
crontab -l | grep -F "$CRON_JOB" > /dev/null 2>&1
|
||||||
if ! crontab -l | grep -Fq "$CRON_JOB"; then
|
if ! crontab -l | grep -Fq "$CRON_JOB"; then
|
||||||
(crontab -l 2>/dev/null; echo "$CRON_JOB") | crontab -
|
(crontab -l 2>/dev/null; echo "$CRON_JOB") | crontab -
|
||||||
info_print "Cron job added." $SUCCESS_FLAG
|
log_success "Cron job added."
|
||||||
fi
|
fi
|
||||||
exit 0;
|
exit 0;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
source /usr/local/bin/libs/notifications.sh
|
|
||||||
|
|
||||||
usage=80
|
usage=80
|
||||||
|
|
||||||
send_notification "$(
|
send_notification "$(
|
||||||
df -h / | grep / | awk -v max="$usage" '{
|
df -h / | grep / | awk -v max="$usage" '{
|
||||||
usage = $5;
|
usage = $5;
|
||||||
20
docker-compose.sh
Normal file
20
docker-compose.sh
Normal file
@@ -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
|
||||||
@@ -69,9 +69,9 @@ services:
|
|||||||
DOCKER_HOST: tcp://socket-rw:2375 # Uses RW proxy to pause containers during backup
|
DOCKER_HOST: tcp://socket-rw:2375 # Uses RW proxy to pause containers during backup
|
||||||
volumes:
|
volumes:
|
||||||
- wireguard-data:/backup/wireguard:ro
|
- wireguard-data:/backup/wireguard:ro
|
||||||
- ./synapse:/backup/synapse:ro
|
- ./data/synapse:/backup/synapse:ro
|
||||||
- ssl-data:/backup/ssl:ro
|
- ssl-data:/backup/ssl:ro
|
||||||
- ./backup:/archive
|
- ./data/backup:/archive
|
||||||
networks:
|
networks:
|
||||||
- socket-rw-bridge
|
- socket-rw-bridge
|
||||||
- web-network
|
- web-network
|
||||||
@@ -89,8 +89,8 @@ services:
|
|||||||
- ENABLE_IPV6=true
|
- ENABLE_IPV6=true
|
||||||
volumes:
|
volumes:
|
||||||
- ssl-data:/etc/nginx/certs:ro
|
- ssl-data:/etc/nginx/certs:ro
|
||||||
- ./nginx/default_html:/usr/share/nginx/html
|
- ./data/nginx/default_html:/usr/share/nginx/html
|
||||||
- ./nginx/vhost.d:/etc/nginx/vhost.d
|
- ./data/nginx/vhost.d:/etc/nginx/vhost.d
|
||||||
labels:
|
labels:
|
||||||
- "docker-volume-backup.stop-during-backup=true" # Ensure consistency during backup
|
- "docker-volume-backup.stop-during-backup=true" # Ensure consistency during backup
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -110,9 +110,9 @@ services:
|
|||||||
- DOCKER_HOST=tcp://socket-rw:2375 # Needs RW to restart Nginx after renewal
|
- DOCKER_HOST=tcp://socket-rw:2375 # Needs RW to restart Nginx after renewal
|
||||||
volumes:
|
volumes:
|
||||||
- ssl-data:/etc/nginx/certs
|
- ssl-data:/etc/nginx/certs
|
||||||
- ./nginx/vhost.d:/etc/nginx/vhost.d
|
- ./data/nginx/vhost.d:/etc/nginx/vhost.d
|
||||||
- ./nginx/default_html:/usr/share/nginx/html
|
- ./data/nginx/default_html:/usr/share/nginx/html
|
||||||
- ./nginx/acme_config:/etc/acme.sh
|
- ./data/nginx/acme_config:/etc/acme.sh
|
||||||
labels:
|
labels:
|
||||||
- "docker-volume-backup.stop-during-backup=true"
|
- "docker-volume-backup.stop-during-backup=true"
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -132,7 +132,7 @@ services:
|
|||||||
# - LETSENCRYPT_HOST=${HOSTNAME}, www.${HOSTNAME}
|
# - LETSENCRYPT_HOST=${HOSTNAME}, www.${HOSTNAME}
|
||||||
# - LETSENCRYPT_EMAIL=${EMAIL}
|
# - LETSENCRYPT_EMAIL=${EMAIL}
|
||||||
# volumes:
|
# volumes:
|
||||||
# - ./data:/usr/share/nginx/html/data
|
# - /data/public:/usr/share/nginx/html/data
|
||||||
# networks:
|
# networks:
|
||||||
# - web-network
|
# - web-network
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ services:
|
|||||||
container_name: synapse
|
container_name: synapse
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- ./synapse:/data
|
- ./data/synapse:/data
|
||||||
environment:
|
environment:
|
||||||
- SYNAPSE_CONFIG_PATH=/data/homeserver.yaml
|
- SYNAPSE_CONFIG_PATH=/data/homeserver.yaml
|
||||||
- VIRTUAL_HOST=msg.${HOSTNAME}
|
- VIRTUAL_HOST=msg.${HOSTNAME}
|
||||||
@@ -210,7 +210,7 @@ services:
|
|||||||
- GITEA__server__ROOT_URL=https://git.${HOSTNAME}/
|
- GITEA__server__ROOT_URL=https://git.${HOSTNAME}/
|
||||||
- DISABLE_REGISTRATION=true # Private instance security
|
- DISABLE_REGISTRATION=true # Private instance security
|
||||||
volumes:
|
volumes:
|
||||||
- ./gitea:/data
|
- ./data/gitea:/data
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
ports:
|
ports:
|
||||||
- "222:22" # SSH port mapping for Git operations
|
- "222:22" # SSH port mapping for Git operations
|
||||||
@@ -227,7 +227,7 @@ services:
|
|||||||
- LETSENCRYPT_HOST=mirror.${HOSTNAME}
|
- LETSENCRYPT_HOST=mirror.${HOSTNAME}
|
||||||
- LETSENCRYPT_EMAIL=${EMAIL}
|
- LETSENCRYPT_EMAIL=${EMAIL}
|
||||||
- VIRTUAL_PORT=4321
|
- VIRTUAL_PORT=4321
|
||||||
- BETTER_AUTH_SECRET=${MIRROR_AUTH_SECRET}
|
- BETTER_AUTH_SECRET=${GITHUB_AUTH_SECRET}
|
||||||
volumes:
|
volumes:
|
||||||
- gitea-mirror-data:/app/data
|
- gitea-mirror-data:/app/data
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
50
install.sh
50
install.sh
@@ -1,32 +1,17 @@
|
|||||||
#!/bin/bash
|
#!/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"
|
# set -euo pipefail
|
||||||
readonly PROJECT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|
||||||
|
|
||||||
readonly REQ=("curl" "docker")
|
ENV_LIST=(
|
||||||
|
"EMAIL" "HOSTNAME"
|
||||||
readonly ENV_FILE="${PROJECT_DIR}/.env"
|
"TELEGRAM_TOKEN" "TELEGRAM_CHAT_ID"
|
||||||
|
"AWS" "ENDPOINT" "AWS_ACCESS_KEY_ID" "AWS_SECRET_ACCESS_KEY"
|
||||||
readonly GREEN='\033[0;32m'
|
"GITHUB_AUTH_SECRET"
|
||||||
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 check_root() {
|
function check_root() {
|
||||||
if [[ $EUID -ne 0 ]]; then
|
if [[ $EUID -ne 0 ]]; then
|
||||||
@@ -49,8 +34,13 @@ function check_dependencies() {
|
|||||||
|
|
||||||
function install_scripts() {
|
function install_scripts() {
|
||||||
log_info "Installing scripts..."
|
log_info "Installing scripts..."
|
||||||
for script in "$SCRIPT_FILE"/*.sh; do
|
for script in "$PROJECT_DIR"/*.sh; do
|
||||||
[ -e "$script" ] || continue
|
[ -e "$script" ] || continue
|
||||||
|
|
||||||
|
if [[ "$script" == "$(realpath "$0")" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
log_info "Configuring $(basename "$script")..."
|
log_info "Configuring $(basename "$script")..."
|
||||||
if ! bash "$script" --install; then
|
if ! bash "$script" --install; then
|
||||||
log_error "Hook failed for $script"
|
log_error "Hook failed for $script"
|
||||||
@@ -68,9 +58,17 @@ function main() {
|
|||||||
log_info "Creating directories and files..."
|
log_info "Creating directories and files..."
|
||||||
touch "$ENV_FILE"
|
touch "$ENV_FILE"
|
||||||
|
|
||||||
|
for env in "${ENV_LIST[@]}"; do
|
||||||
|
read -sp "Enter value for $env: " value
|
||||||
|
echo
|
||||||
|
env_variable "$env" "$value"
|
||||||
|
done
|
||||||
|
|
||||||
install_scripts
|
install_scripts
|
||||||
|
|
||||||
log_success "Installation Complete"
|
log_success "Installation Complete"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||||
main "$@"
|
main "$@"
|
||||||
|
fi
|
||||||
105
libs/common.sh
105
libs/common.sh
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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"
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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 "<b>🚨 Login Event 🚨</b>\nUser <code>%s</code> logged in from <code>%s</code> at <i>%s</i>." "$PAM_USER" "$PAM_RHOST" "$(date)")
|
|
||||||
;;
|
|
||||||
close_session)
|
|
||||||
PAYLOAD=$(printf "<b>🚨 Logout Event 🚨</b>\nUser <code>%s</code> logged out from <code>%s</code> at <i>%s</i>." "$PAM_USER" "$PAM_RHOST" "$(date)")
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -n "$PAYLOAD" ] ; then
|
|
||||||
send_notification "$PAYLOAD"
|
|
||||||
fi
|
|
||||||
40
sshd-login.sh
Normal file
40
sshd-login.sh
Normal file
@@ -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 "<b>🚨 Login Event 🚨</b>\nUser <code>%s</code> logged in from <code>%s</code> at <i>%s</i>." "$PAM_USER" "$PAM_RHOST" "$(date)")
|
||||||
|
;;
|
||||||
|
close_session)
|
||||||
|
PAYLOAD=$(printf "<b>🚨 Logout Event 🚨</b>\nUser <code>%s</code> logged out from <code>%s</code> at <i>%s</i>." "$PAM_USER" "$PAM_RHOST" "$(date)")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -n "$PAYLOAD" ]; then
|
||||||
|
send_notification "$PAYLOAD"
|
||||||
|
fi
|
||||||
70
utils.sh
Normal file
70
utils.sh
Normal file
@@ -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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user