commit 43796b2c3c3ffda6354cca626dbf32ac1f0acfdc Author: Frogg Date: Wed May 6 10:49:27 2026 +0000 First commit with basis files diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d18538c --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +# Ignorer les fichiers par défaut de Debian/Ubuntu +bash_completion.sh +vte-2.91.sh +vte.csh +#01-locale-fix.sh + +# Ignorer les backups et fichiers temporaires +*~ +*.bak +*.swp +*.save diff --git a/01-locale-fix.sh b/01-locale-fix.sh new file mode 100644 index 0000000..e3c8733 --- /dev/null +++ b/01-locale-fix.sh @@ -0,0 +1,2 @@ +# Make sure the locale variables are set to valid values. +eval $(/usr/bin/locale-check C.UTF-8) diff --git a/777-welcome.sh b/777-welcome.sh new file mode 100755 index 0000000..28e58ba --- /dev/null +++ b/777-welcome.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +# NETTOYAGE + +clear + +# INC +. /etc/profile.d/inc/colors.sh +. /etc/profile.d/inc/vars.sh + +# LINUX TOOL +. /etc/profile.d/inc/tool.sh + +################ +### SHORTCUT ### +################ + +#F_DAT="${WHITE}$(date +"%A, %e %B %Y, %r")${NC}" +F_DAT="${WHITE}$(LC_TIME=fr_FR.UTF-8 date +"%A, %e %B %Y, %r")${NC}" +F_IPS="${YELLOW}IP Addresses.: ${WHITE}${IP}" +F_UPT="${YELLOW}Uptime.......: ${WHITE}${UPTIME}" +F_MEM="${YELLOW}Memory.......: ${WHITE}${MEMUSED} / ${MEMTOTAL} Go" +F_LOD="${YELLOW}Load Averages: ${WHITE}${ONE}, ${FIVE}, ${FIFTEEN} (1, 5, 15 min)" +F_VER="${WHITE} ${VERSION}" +F_BAR_MEM="${YELLOW}Memory.......: $(draw_bar $M_PCT ${V1})" +F_BAR_DSK="${YELLOW}Disk Usage...: $(draw_bar $D_PCT ${J1})" +F_USR="${YELLOW}Nb acc user..: ${WHITE}${NBUSERS}" + +###################### +### CUSTOM MESSAGE ### +###################### + +echo -e "${CYAN} ==[ You are connected to ${WHITE}$FULLNAME${CYAN} ]== +${GREEN} _ __ _ +${GREEN} ((-)).--.((-)) ${F_DAT} +${GREEN} / '' \\ ${F_VER} +${GREEN} ( \______/ ) +${GREEN} \ ( ) / ${F_IPS} +${GREEN} / /~~~~~~~~\ \ ${F_UPT} +${GREEN} /~~\/ / \ \/~~\ ${F_MEM} +${GREEN}( ( ( ) ) ) ${F_LOD} +${GREEN} \ \ \ \ / / / / ${F_BAR_MEM} +${GREEN} _\ \/ \.______./ \/ /_ ${F_BAR_DSK} +${GREEN} ___/ /\__________/\ \___ ${F_USR}" + +################# +### WARNINGS ### +################# + +. /etc/profile.d/inc/warnings.sh + + echo -e "${GREEN}======================================================================${NONE}" + +################# +### SERVICES ### +################# + +. /etc/profile.d/inc/services.sh + +############## +### INFOS ### +############## + +. /etc/profile.d/inc/infos.sh + +##################### +### BASH DISPLAY ### +##################### + +. /etc/profile.d/inc/ps1.sh + +################## +### SEND MAIL ### +################## + +. /etc/profile.d/inc/mail_connect.sh diff --git a/inc/colors.sh b/inc/colors.sh new file mode 100644 index 0000000..5a9ccc1 --- /dev/null +++ b/inc/colors.sh @@ -0,0 +1,18 @@ + +# SETTING CUSTOM COLOR +NONE="\e[0m" +WHITE="\e[1;37m" +GREEN="\e[1;32m" +RED="\e[0;32;31m" +YELLOW="\e[1;33m" +BLUE="\e[34m" +CYAN="\e[36m" +LIGHT_GREEN="\e[1;32m" +LIGHT_RED="\e[1;31m" + +R1="\e[38;5;196m" # Rouge alerte +G1="\e[38;5;240m" # Gris +V1="\e[38;5;82m" # Vert +J1="\e[38;5;220m" # Or +NC="\e[0m" # Reset + diff --git a/inc/infos.sh b/inc/infos.sh new file mode 100644 index 0000000..f24f0f2 --- /dev/null +++ b/inc/infos.sh @@ -0,0 +1,6 @@ +# Infos +echo "" +echo -e "${YELLOW}You can use the commands ${WHITE}cmd ${YELLOW}or ${WHITE}conf ${YELLOW}for more information...${NONE}" +echo "" + + diff --git a/inc/mail_connect.sh b/inc/mail_connect.sh new file mode 100755 index 0000000..9c85bd4 --- /dev/null +++ b/inc/mail_connect.sh @@ -0,0 +1,79 @@ +#!/bin/bash + +################ +### LOG MAIL ### +################ + +env > /tmp/env_login.txt + +USERIP=$(echo ${SSH_CONNECTION%% *}) + +# On ne check la géo que si l'IP n'est pas locale (RFC1918) +if [[ $USERIP =~ ^192\.168\. || $USERIP =~ ^10\. || $USERIP =~ ^172\. ]]; then + LOC_INFO="Local Network (LAN)" +else + # On récupère tout en un seul appel JSON pour économiser l'API et éviter les erreurs + GEO=$(curl -s ipinfo.io/$USERIP/json) + CITY=$(echo "$GEO" | grep '"city"' | cut -d'"' -f4) + COUNTRY=$(echo "$GEO" | grep '"country"' | cut -d'"' -f4) + ORG=$(echo "$GEO" | grep '"org"' | cut -d'"' -f4) + LOC_INFO="$CITY, $COUNTRY (ISP: $ORG)" +fi + + +# Détection du backend mail (une seule fois) +if command -v mail >/dev/null 2>&1; then + MAIL_BACKEND="mail" + +elif command -v sendmail >/dev/null 2>&1; then + MAIL_BACKEND="sendmail" + +elif command -v msmtp >/dev/null 2>&1; then + MAIL_BACKEND="msmtp" + +else + echo "ERROR: No mail system available" >&2 + MAIL_BACKEND="none" +fi + + +send_mail() { + local to="$1" + local subject="$2" + local body="$3" + + case "$MAIL_BACKEND" in + mail) + echo "$body" | mail -v -s "$subject" "$to" + ;; + + sendmail) + { + echo "To: $to" + echo "Subject: $subject" + echo "" + echo "$body" + } | sendmail -t + ;; + + msmtp) + { + echo "To: $to" + echo "Subject: $subject" + echo "" + echo "$body" + } | msmtp "$to" + ;; + + *) + echo "No mail backend available" >&2 + return 1 + ;; + esac +} + + +SUBJECT="[INFO] $USER connected on $FULLNAME" +BODY="$USER connected on $FULLNAME from $USERIP - $LOC_INFO" + +send_mail "$ADMIN_MAIL" "$SUBJECT" "$BODY" diff --git a/inc/ps1.sh b/inc/ps1.sh new file mode 100644 index 0000000..da7ae5a --- /dev/null +++ b/inc/ps1.sh @@ -0,0 +1,44 @@ +# Shortucts for server config info +alias cmd='bash /etc/profile.d/info/cmd' +alias conf='bash /etc/profile.d/info/conf' +alias welcome='bash /etc/profile.d/custom.sh' +# Shortcuts basics +alias cls='clear' +alias ll='ls -lah' +alias lh='ls -lisah' +alias ..='cd ..' +alias ...='cd ../..' +alias home='welcome && cd ~' +alias ffs='find / \( -path /proc -o -path /sys -o -path /dev -o -path /run \) -prune -o -type f -iname' +alias ff='sudo find / \( -path /proc -o -path /sys -o -path /dev -o -path /run \) -prune -o -type f -name' +#Shortcuts APT +update='sudo apt update && sudo apt upgrade -y' +install='sudo apt install' +remove='sudo apt remove' +#Shortcuts debug +alias func='declare -F' +alias grep='grep --color=auto' +alias egrep='egrep --color=auto' +alias fgrep='fgrep --color=auto' +alias ports='netstat -tulanp' +alias psg='ps aux | grep -i' +alias top='htop' +alias cpu='top -o %CPU' +alias mem='top -o %MEM' +alias hdd='ncdu' +#Shortcut network +alias myip='curl ifconfig.me' +alias localip='ip a' +#Shortcut Apache +alias web-restart='systemctl restart apache2' +alias web-err='tail -fn 100 /var/log/apache2/error.log' +alias web-log='tail -fn 100 /var/log/apache2/access.log /var/log/apache2/error.log' + + +# Frogg version +#PS1='${debian_chroot:+($debian_chroot)}\[\033[01;34m\][\[\033[01;91m\]\u\[\033[01;34m\]@\[\033[01;91m\]\h\[\033[01;34m\]]\[\033[01;34m\] \w\[\033[01;37m\] >' +# Github https://gist.github.com/justintv/168835 +#PS1='\[\033[0;32m\]\[\033[0m\033[0;32m\]\u\[\033[0;36m\] @ \w\[\033[0;32m\]\n$(git branch 2>/dev/null | grep "^*" | colrm 1 2)\[\033[0;32m\]└─\[\033[0m\033[0;32m\] \$\[\033[0m\033[0;32m\]\[\033[0m\] ' + +# Mixed version +PS1='${debian_chroot:+($debian_chroot)}\[\033[01;34m\][\[\033[01;91m\]\u\[\033[01;34m\]@\[\033[01;91m\]\h\[\033[01;34m\]]\[\033[01;34m\] \w\[\033[01;37m\] \n$(git branch --show-current 2>/dev/null)\[\033[0;32m\]└─\[\033[0m\033[0;32m\] \$\[\033[0m\033[0;32m\]\[\033[0m\] ' diff --git a/inc/services.sh b/inc/services.sh new file mode 100755 index 0000000..236d222 --- /dev/null +++ b/inc/services.sh @@ -0,0 +1,173 @@ +#!/bin/bash + +status_text() +{ + local type="$1" + local msg="$2" + + case "$type" in + ok|success) + echo "${GREEN}✅ ${msg}${NC}" + ;; + warn|warning) + echo "${YELLOW}⚡ ${msg}${NC}" + ;; + error|err) + echo "${RED}❌ ${msg}${NC}" + ;; + *) + echo "${msg}" + ;; + esac +} + +format_line() +{ + local label="$1" + local status="$2" + local width=16 + + local len=${#label} + local dots="" + local i + + while [ "$len" -lt "$width" ]; do + dots="${dots}." + len=$((len + 1)) + done + + printf "%s%s: %b\n" "$label" "$dots" "$status" +} + + +check_service() +{ + local svc="$1" + local label="$2" + local status + + if ! command -v systemctl >/dev/null 2>&1; then + status=$(status_text error "systemctl indisponible") + format_line "$label" "$status" + return + fi + + if sudo -n systemctl is-active --quiet "$svc" 2>/dev/null; then + status=$(status_text success "actif") + + elif sudo -n systemctl status "$svc" >/dev/null 2>&1; then + status=$(status_text error "arrêté") + + else + status=$(status_text error "non installé") + fi + + format_line "$label" "$status" +} + + +get_systemd_status() +{ + local failed_output failed_count status + + # On capture la sortie ET on vérifie si la commande réussit + # 2>/dev/null est crucial ici pour ne pas polluer l'affichage + if failed_output=$(systemctl --failed --no-legend --no-pager 2>/dev/null); then + # La commande a fonctionné, on compte les lignes vides ou non + failed_count=$(echo "$failed_output" | grep -c '[^[:space:]]') + + if [ "$failed_count" -gt 0 ]; then + status=$(status_text error "État critique (${failed_count} problème(s))") + else + status=$(status_text success "système OK") + fi + else + # La commande a échoué (probablement un problème de sudo/permissions) + status=$(status_text warning "Erreur accès (relancer avec sudo)") + fi + + format_line "Systemd" "$status" +} + + +get_fail2ban_status() +{ + local banned status jails count total=0 + + if ! command -v fail2ban-client >/dev/null 2>&1; then + status=$(status_text error "non installé") + format_line "Fail2Ban" "$status" + return + fi + + if ! fail2ban-client ping >/dev/null 2>&1; then + status=$(status_text error "service indisponible") + format_line "Fail2Ban" "$status" + return + fi + + jails=$(fail2ban-client status 2>/dev/null | sed -n 's/.*Jail list:\s*//p' | tr ',' ' ') + + for jail in $jails; do + count=$(fail2ban-client status "$jail" 2>/dev/null | awk '/Currently banned/ {print $NF}') + total=$((total + ${count:-0})) + done + + status=$(status_text success "actif (${total} IPs bannies)") + format_line "Fail2Ban" "$status" +} + +get_apparmor_status() +{ + local enforce status + + if [ ! -d /sys/kernel/security/apparmor ]; then + status=$(status_text error "non disponible") + format_line "AppArmor" "$status" + return + fi + + enforce=$(aa-status 2>/dev/null | awk '/profiles are in enforce mode/ {print $1}') + + if [ -z "$enforce" ] || [ "$enforce" -eq 0 ]; then + status=$(status_text error "aucun profil renforcé") + else + status=$(status_text success "${enforce} profils renforcés") + fi + + format_line "AppArmor" "$status" +} + +get_ufw_status() +{ + local status rules raw + + if ! command -v ufw >/dev/null 2>&1; then + status=$(status_text error "non installé") + format_line "Firewall (UFW)" "$status" + return + fi + + raw=$(ufw status 2>/dev/null | head -n 1) + + if echo "$raw" | grep -q "active"; then + rules=$(ufw status 2>/dev/null | grep -cE "ALLOW|DENY") + status=$(status_text success "actif (${rules} règles)") + else + status=$(status_text error "inactif") + fi + + format_line "Firewall (UFW)" "$status" +} + + +# ---- DISPLAY + +echo -e $(get_systemd_status) +echo -e $(get_fail2ban_status) +echo -e $(get_apparmor_status) +echo -e $(get_ufw_status) + +echo -e $(check_service "zabbix-server" "Zabbix Server") +echo -e $(check_service "mysql" "MySQL") +echo -e $(check_service "apache2" "Apache Web") diff --git a/inc/tool.sh b/inc/tool.sh new file mode 100644 index 0000000..74ad904 --- /dev/null +++ b/inc/tool.sh @@ -0,0 +1,27 @@ +disable_ipv6() +{ + local status + + # Vérification des droits root + if [ "$EUID" -ne 0 ]; then + status=$(status_text error "Droits root requis pour modifier sysctl") + format_line "IPv6" "$status" + return 1 + fi + + # Application des paramètres sysctl + # On cible 'all', 'default' et 'lo' (loopback) + sysctl -w net.ipv6.conf.all.disable_ipv6=1 >/dev/null + sysctl -w net.ipv6.conf.default.disable_ipv6=1 >/dev/null + sysctl -w net.ipv6.conf.lo.disable_ipv6=1 >/dev/null + + # Rendre les changements persistants après redémarrage + cat < /etc/sysctl.d/99-disable-ipv6.conf +net.ipv6.conf.all.disable_ipv6 = 1 +net.ipv6.conf.default.disable_ipv6 = 1 +net.ipv6.conf.lo.disable_ipv6 = 1 +EOF + + status=$(status_text success "IPv6 désactivé avec succès") + format_line "IPv6" "$status" +} diff --git a/inc/vars.sh b/inc/vars.sh new file mode 100644 index 0000000..96c2e53 --- /dev/null +++ b/inc/vars.sh @@ -0,0 +1,75 @@ +#################### +### PREPARE VARS ### +#################### + +FULLNAME=$(hostname).$(hostname --domain) +USERIP=$(echo ${SSH_CONNECTION%% *}) +LOC=$(curl -s ipinfo.io/$USERIP/city) +COUNTRY=$(curl -s ipinfo.io/$USERIP/country) +ISP=$(curl -s ipinfo.io/$USERIP/org) + +# --- RÉCUPÉRATION DES DATAS --- +# RAM +M_INFO=$(free -m | awk '/Mem:/ { printf "%d %d", $2, $3 }') +read -r M_TOT M_USE <<< "$M_INFO" +M_PCT=$((M_USE * 100 / M_TOT)) + +# DISQUE (Sur la partition racine /) +D_PCT=$(df / | awk 'NR==2 {print $5}' | sed 's/%//') + +# --- LA FONCTION DE DESSIN --- +# Usage: draw_bar +draw_bar() { + local pct=$1 + local color=$2 + local size=30 + local filled=$((pct * size / 100)) + local empty=$((size - filled)) + + printf "[" + echo -ne "${color}" + for i in $(seq 1 $filled); do echo -ne "■"; done + echo -ne "${G1}" + for i in $(seq 1 $empty); do echo -ne "·"; done + echo -ne "${NC}] ${pct}%" +} + + +# GET UPTIME +upSeconds="$(/usr/bin/cut -d. -f1 /proc/uptime)" +secs=$((${upSeconds}%60)) +mins=$((${upSeconds}/60%60)) +hours=$((${upSeconds}/3600%24)) +days=$((${upSeconds}/86400)) +UPTIME=`printf "%d days, %02dhours %02dmin %02dsec" "$days" "$hours" "$mins" "$secs"` + +# GET IP +IP=`hostname -I` + +# GET MEMORY +MEMTOTAL=`awk '/MemTotal/ { printf "%.3f \n", $2/1024/1024 }' /proc/meminfo` +MEMFREE=`awk '/MemFree/ { printf "%.3f \n", $2/1024/1024 }' /proc/meminfo` +MEMUSED=`awk "BEGIN {print ${MEMTOTAL}-${MEMFREE}; exit}"` + +#GET LOAD +read ONE FIVE FIFTEEN REST < /proc/loadavg + +# GET LINUX VERSION +if [ -z "$DISTRIB_DESCRIPTION" ] && [ -x /usr/bin/lsb_release ]; then + # Fall back to using the very slow lsb_release utility + DISTRIB_DESCRIPTION=$(lsb_release -s -d) +fi +re='(.*\()(.*)(\).*)' +if [[ $DISTRIB_DESCRIPTION =~ $re ]]; then + DISTRIB_DESCRIPTION=$(printf "%s%s%s%s%s" "${BASH_REMATCH[1]}" "${YELLOW}" "${BASH_REMATCH[2]}" "${NONE}" "${BASH_REMATCH[3]}") +fi +VERSION=`echo -e $DISTRIB_DESCRIPTION` + +#VERSION=`echo -e $DISTRIB_DESCRIPTION "(kernel "$(uname -r)")\n"` + +#SYSTEM NAME +SYSTEMNAME=$(cat /etc/os-release) + +# USERS +NBUSERS=$(awk -F: '$3 >= 1000 && $7 !~ /(nologin|false)/ {count++} END {print count+1}' /etc/passwd) +#NBCONN=$(who | wc -l) diff --git a/inc/warnings.sh b/inc/warnings.sh new file mode 100644 index 0000000..a68cd1b --- /dev/null +++ b/inc/warnings.sh @@ -0,0 +1,41 @@ +# Alertes de sécurité (Échec login) +FAILED=$(journalctl _SYSTEMD_UNIT=ssh.service --since "24 hours ago" | grep -c "Failed password") +if [ $FAILED -gt 0 ]; then + echo -e "${GREEN}======================================================================${NONE}" + echo -e " ${R1}⚡ ATTENTION : ${FAILED} tentatives de connexion SSH échouées ces dernières 24h !${NONE}" +fi + +OTHER_USERS=$(who | wc -l) +if [ "$OTHER_USERS" -gt 1 ]; then + echo -e "${GREEN}======================================================================${NONE}" + echo -e " ${R1}⚡ Attention :${NC} Il y a actuellement $(($OTHER_USERS - 1)) autre(s) session(s) active(s).${NC}" + echo -e "${R1} ╔════════════════════════════════════════════════╗" +printf " ║ %-10s %-10s %-8s %-15s ║\n" "USER" "DATE" "HEURE" "IP" + echo " ╠════════════════════════════════════════════════╣" + +who | awk '{ + user=$1 + + # Cas avec IP (dernier champ contient des parenthèses) + if ($NF ~ /^\(.*\)$/) { + ip=$NF + gsub(/[()]/,"",ip) + + time=$(NF-1) + date=$(NF-2) + } else { + ip="console locale" + + time=$NF + date=$(NF-1) + } + + printf " ║ %-10s %-10s %-8s %-15s ║\n", user, date, time, ip +}' + + echo -e " ╚════════════════════════════════════════════════╝${NC}" +fi + + + + diff --git a/info/cmd b/info/cmd new file mode 100644 index 0000000..3b46f50 --- /dev/null +++ b/info/cmd @@ -0,0 +1,31 @@ +!/bin/sh + +# INCLUDE COLORS +. /etc/profile.d/inc/colors.sh + +clear + +echo -e " +${CYAN}[ APACHE ] +${YELLOW}Restart apache..........: ${WHITE}apache2ctl restart +${CYAN}[ MAIL ] +${YELLOW}Sending a mail..........: ${WHITE}echo "Subject: sendmail test" | sendmail -v admin@frogg.fr +${CYAN}[ CRON ] +${YELLOW}Edit main cron tab......: ${WHITE}crontab -e +${CYAN}[ LINUX ] +${YELLOW}Restart a service.......: ${WHITE}/etc/init.d/\${service name} restart${NONE} +${YELLOW}Add symbolic link.......: ${WHITE}ln -s \${path} \${symlink} +${YELLOW}Disk space tool.........: ${WHITE}ncdu +${YELLOW}Display journal.........: ${WHITE}journalctl -xe +${YELLOW}Display system erros....: ${WHITE}systemctl --failed + +liste des fonctions chargée dans la session ssh +declare -F + +" + +############## +### INFOS ### +############## + +. /etc/profile.d/inc/infos.sh diff --git a/info/conf b/info/conf new file mode 100644 index 0000000..21a5cd1 --- /dev/null +++ b/info/conf @@ -0,0 +1,39 @@ +#!/bin/sh + +# INCLUDE COLORS +. /etc/profile.d/inc/colors.sh + +clear + +echo -e " +${CYAN}[ WEBSITE ] +${YELLOW}Websites folder.........: ${WHITE}TODO +${CYAN}[ APACHE ] +${YELLOW}Vhost Websites includes.: ${WHITE}TODO +${CYAN}[ PHP ] +${YELLOW}Apache config...........: ${WHITE}TODO +${YELLOW}CLI config..............: ${WHITE}TODO +${CYAN}[ MYSQL ] +${YELLOW}Vhost Websites includes.: ${WHITE}TODO +${CYAN}[ MAIL ] +${YELLOW}graphical config........: ${WHITE}TODO +${CYAN}[ ZABBIX ] +${YELLOW}Zabbix agent config.....: ${WHITE}/etc/zabbix/zabbix-agent.conf +${CYAN}[ CUSTOM ] +${YELLOW}Login message...........: ${WHITE}/etc/profile.d/* +${YELLOW}SSH custom display......: ${WHITE}/root/.bashrc${NONE} +ajouter le path pour les mails +/etc/msmtprc +APP ARMOR +/etc/apparmor.d/local/ +log rotate conf +/etc/logrotate.d/ +Variable d environement +/etc/environment +" + +############## +### INFOS ### +############## + +. /etc/profile.d/inc/infos.sh