Add update_dyndns.sh, extend menu and fix crontab/loop issues
This commit is contained in:
@@ -55,3 +55,11 @@ create on 20-3-2025 by Désiré Werner Menrath
|
||||
- All scripts updated to use gettext
|
||||
- Replaced Traefik-Crowdsec-Stack updater with own authelia-watcher-manager which works
|
||||
together with the docker project lxtools/authelia-watcher
|
||||
|
||||
### Added / Fixed
|
||||
01-02-2026
|
||||
|
||||
- install.sh: Fixed crontab installation (now uses sudo/root) to ensure iptables permissions
|
||||
- clidmanager.sh: Fixed menu navigation loop by using 'exec' for submenu return
|
||||
- update_dyndns.sh: Added script for DynDNS protection and iptables management
|
||||
- clidmanager.sh: Extended menu with Authelia Watcher Manager options
|
||||
|
||||
358
clidmanager.sh
Normal file
358
clidmanager.sh
Normal file
@@ -0,0 +1,358 @@
|
||||
#!/bin/bash
|
||||
|
||||
# clidmanager simple management a docker container
|
||||
# Author: Désiré Werner Menrath
|
||||
# Email: polunga40@unity-mail.de
|
||||
# Use without warranty!
|
||||
|
||||
# 1 = 1. Year, 09 = Month of the Year, 2924 = Day and Year of the Year
|
||||
|
||||
NORMAL='\033[0m'
|
||||
GREEN='\033[1;32m'
|
||||
RED='\033[31;1;42m'
|
||||
YELLOW='\033[1;33m'
|
||||
LBLUE='\033[1;34m'
|
||||
ZYAN='\033[30;1;36m'
|
||||
|
||||
export TEXTDOMAIN=clidmanager
|
||||
export TEXTDOMAINDIR="/usr/share/locale"
|
||||
|
||||
# Translations for header variables
|
||||
version_num="v. 2.01.3126"
|
||||
version=$(printf "${GREEN}%s${LBLUE}" "$version_num")
|
||||
cmname=$(printf "${YELLOW}%s${LBLUE}" "containermanager")
|
||||
info=$(echo -e "${GREEN}$(gettext "Enter 'dw' in terminal to go directly")")
|
||||
info2=$(echo -e "${GREEN}$(gettext "to the docker directory.")${NORMAL}")
|
||||
|
||||
one=$(echo -e $YELLOW"1"$LBLUE)
|
||||
two=$(echo -e $YELLOW"2"$LBLUE)
|
||||
three=$(echo -e $YELLOW"3"$LBLUE)
|
||||
four=$(echo -e $YELLOW"4"$LBLUE)
|
||||
five=$(echo -e $YELLOW"5"$LBLUE)
|
||||
six=$(echo -e $YELLOW"6"$LBLUE)
|
||||
seven=$(echo -e $YELLOW"7"$LBLUE)
|
||||
eight=$(echo -e $YELLOW"8"$LBLUE)
|
||||
|
||||
list_dir_with_numbers() {
|
||||
unset dcname
|
||||
array=($(ls))
|
||||
typeset -i i=0 max=${#array[*]}
|
||||
while (( i < max )); do
|
||||
echo -e $LBLUE[$YELLOW$i$LBLUE] $LBLUE"${array[$i]}"$NORMAL
|
||||
i=i+1
|
||||
done
|
||||
|
||||
while read -p "$(gettext "Enter folder number: ")" entrynumber; do
|
||||
if [[ "$entrynumber" =~ ^[0-9]+$ && "$entrynumber" -lt "$i" ]]; then
|
||||
dcname=${array[entrynumber]}
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
newdir() {
|
||||
clear
|
||||
echo
|
||||
echo -e $BLUE"$(gettext "If a name is entered here,\nit creates a folder in /opt/containers/.")"$NORMAL
|
||||
echo
|
||||
echo -e $GREEN"$(gettext "Attention, please specify only one folder here!")"$NORMAL
|
||||
read -p "$(gettext "Enter container name: ")" dcname
|
||||
sudo mkdir -p /opt/containers/$dcname
|
||||
while [ -z $dcname ]
|
||||
do
|
||||
echo -e $GREEN"$(gettext "Oops, no folder name was entered...")"$NORMAL
|
||||
echo
|
||||
read -p "$(gettext "Enter container name: ")" dcname
|
||||
sudo mkdir -p /opt/containers/$dcname
|
||||
done
|
||||
if [ -d /opt/containers/$dcname ]
|
||||
then
|
||||
clear
|
||||
echo
|
||||
echo -e $GREEN"$(gettext "Folder")"$BLUE ${dcname} $GREEN"$(gettext "was successfully created.")"$NORMAL
|
||||
echo
|
||||
echo "$(gettext "Should additional folders be created in the created folder?")"
|
||||
echo "$(gettext "Press y and Enter for more folders. Press Enter to return to the program.")"
|
||||
read -p "" response
|
||||
if [ "$response" == "y" ]
|
||||
then
|
||||
clear
|
||||
echo -e $GREEN"$(gettext "Example for 2 additional folders in the created folder:")"
|
||||
echo
|
||||
echo -e $BLUE"data config"$NORMAL
|
||||
echo
|
||||
echo -e $GREEN"$(gettext "More than 2 folders can be specified here,")"$NORMAL
|
||||
read -p "$(gettext "Enter folder names: ")" subfolders
|
||||
for item in ${subfolders[*]}
|
||||
do
|
||||
sudo mkdir -p /opt/containers/$dcname/$item
|
||||
done
|
||||
while [ -z $item ]
|
||||
do
|
||||
echo -e $GREEN"$(gettext "Oops, no further folders were specified...")"
|
||||
echo -e $GREEN"$(gettext "Please try again")"$NORMAL
|
||||
read -p "$(gettext "Enter folder names: ")" subfolders
|
||||
for item in ${subfolders[*]}
|
||||
do
|
||||
sudo mkdir -p /opt/containers/$dcname/$item
|
||||
done
|
||||
done
|
||||
clear
|
||||
echo -e $GREEN"$(gettext "Folder ...")$BLUE"
|
||||
echo
|
||||
ls -x /opt/containers/$dcname/
|
||||
echo
|
||||
echo -e $GREEN"$(gettext "were created.")"
|
||||
echo
|
||||
read -p "$(gettext "Continue with Enter.")"
|
||||
sudo clidmanager
|
||||
else
|
||||
sudo clidmanager
|
||||
fi
|
||||
else
|
||||
echo -e $RED"$(gettext "An error occurred...\nPlease check the path to see if the folder exists.")"$NORMAL
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
list_containers() {
|
||||
|
||||
clear
|
||||
echo -e $ZYAN
|
||||
docker ps --format 'table {{.Names}}\t{{.Status}}'
|
||||
echo -e $NORMAL
|
||||
}
|
||||
|
||||
# dcname = Docker Container Name
|
||||
|
||||
log() {
|
||||
|
||||
unset dcname
|
||||
clear
|
||||
echo -e ""$NORMAL
|
||||
echo -e $BLUE" -----$(gettext "Docker Compose Logs")-----"$NORMAL
|
||||
echo -e $GREEN"$(gettext "Below you see a list of containers")"$NORMAL
|
||||
echo -e ""$ZYAN
|
||||
cd /opt/containers/ && list_dir_with_numbers
|
||||
cd $dcname && docker compose logs
|
||||
}
|
||||
|
||||
# dcstart = docker compose start
|
||||
|
||||
dcstart() {
|
||||
|
||||
unset dcname
|
||||
clear
|
||||
echo -e ""$NORMAL
|
||||
echo -e $BLUE"$(gettext "Here the specified container is recreated when the yml file changes.")"
|
||||
echo -e "$(gettext "And for a new container, it is downloaded and started.")"$NORMAL
|
||||
echo
|
||||
echo -e $BLUE" -----$(gettext "Docker Compose start")-----"
|
||||
echo -e $GREEN"$(gettext "Below you see a list of containers")"$NORMAL
|
||||
echo -e ""$ZYAN
|
||||
cd /opt/containers/ && list_dir_with_numbers
|
||||
cd $dcname && docker compose up -d
|
||||
|
||||
}
|
||||
|
||||
edit_yml() {
|
||||
|
||||
unset dcname
|
||||
clear
|
||||
echo -e ""$NORMAL
|
||||
echo -e $BLUE" -----$(gettext "yml File edit")-----"
|
||||
echo -e $GREEN"$(gettext "Below you see a list of containers")"$NORMAL
|
||||
echo -e ""$ZYAN
|
||||
cd /opt/containers/ && list_dir_with_numbers
|
||||
cd $dcname && nano docker-compose.yml
|
||||
sudo clidmanager
|
||||
}
|
||||
|
||||
all_stop() {
|
||||
|
||||
docker stop $(docker ps -a -q)
|
||||
}
|
||||
|
||||
all_start() {
|
||||
|
||||
docker start $(docker ps -a -q)
|
||||
}
|
||||
|
||||
watcher_management() {
|
||||
# Find container name dynamically via label
|
||||
REAL_CONTAINER_NAME=$(docker ps --filter "label=service=authelia-watcher" --format "{{.Names}}")
|
||||
|
||||
if [ -z "$REAL_CONTAINER_NAME" ]; then
|
||||
clear
|
||||
echo -e "${RED}$(gettext "Error: Watcher container not found!")${NORMAL}"
|
||||
echo -e "$(gettext "Make sure the label 'service=authelia-watcher' is set.")"
|
||||
read -p "$(gettext "Press Enter to exit...")"
|
||||
clear
|
||||
return
|
||||
fi
|
||||
|
||||
ENV_PATH="/opt/containers/authelia-watcher/config/.env"
|
||||
|
||||
# Initial .env is not exist
|
||||
if [ ! -f "$ENV_PATH" ]; then
|
||||
{
|
||||
echo "MY_DOMAIN=\"\""
|
||||
echo "CHECK_INTERVAL=300"
|
||||
echo "SEND_WELCOME_NOTIFICATION=1"
|
||||
echo "SEND_WATCHER_START_NOTIFICATION=1"
|
||||
} > "$ENV_PATH"
|
||||
else
|
||||
# Ensure rows before write
|
||||
for var in MY_DOMAIN CHECK_INTERVAL SEND_WELCOME_NOTIFICATION SEND_WATCHER_START_NOTIFICATION; do
|
||||
grep -q "^$var=" "$ENV_PATH" || echo "$var=" >> "$ENV_PATH"
|
||||
done
|
||||
# Set standard value when empty
|
||||
sed -i 's/^CHECK_INTERVAL=$/CHECK_INTERVAL=300/' "$ENV_PATH"
|
||||
fi
|
||||
|
||||
while true; do
|
||||
clear
|
||||
echo -e "${LBLUE}--- Authelia Watcher: Management & Config ---${NORMAL}"
|
||||
echo -e "$(gettext "Found Container:") ${GREEN}$REAL_CONTAINER_NAME${NORMAL}"
|
||||
echo "======================================================"
|
||||
echo -e "[$one] $(gettext "View active bans (iptables)")"
|
||||
echo -e "[$two] $(gettext "Manually unban an IP")"
|
||||
echo -e "[$three] $(gettext "Whitelist Management (DynDNS/Static)")"
|
||||
echo -e "[$four] $(gettext "Edit JSON Configuration")"
|
||||
echo -e "[$five] $(gettext "DynDNS & Notification Settings")"
|
||||
echo -e "[$six] $(gettext "View Watcher Logs")"
|
||||
echo -e "[$seven] $(gettext "Back to Main Menu")"
|
||||
echo "======================================================"
|
||||
read -n 1 -s -r -p "$(gettext "Select an option: ")" wopt
|
||||
|
||||
WHITELIST_PATH="/opt/containers/authelia-watcher/config/whitelist.txt"
|
||||
BLACKLIST_PATH="/opt/containers/authelia-watcher/config/blacklist.txt"
|
||||
|
||||
case $wopt in
|
||||
1)
|
||||
clear
|
||||
(echo "$(gettext "ACTIVE BANS (iptables):")"; echo "---------------------------"; \
|
||||
iptables -L INPUT -n --line-numbers | grep DROP) | less
|
||||
;;
|
||||
2)
|
||||
echo -e "\n"
|
||||
read -p "$(gettext "Enter IP address to unban: ")" IP_TO_UNBAN
|
||||
if [ -n "$IP_TO_UNBAN" ]; then
|
||||
while iptables -L INPUT -n | grep -q "$IP_TO_UNBAN"; do
|
||||
iptables -D INPUT -s "$IP_TO_UNBAN" -j DROP 2>/dev/null
|
||||
done
|
||||
[ -f "$BLACKLIST_PATH" ] && sed -i "/^$IP_TO_UNBAN$/d" "$BLACKLIST_PATH"
|
||||
printf "\n${GREEN}$(gettext "IP %s has been successfully removed from firewall and blacklist.")${NORMAL}\n" "$IP_TO_UNBAN"
|
||||
read -p "$(gettext "Press Enter...")"
|
||||
fi
|
||||
;;
|
||||
3)
|
||||
clear
|
||||
echo -e "${LBLUE}--- $(gettext "Whitelist Management") ---${NORMAL}"
|
||||
echo "1) $(gettext "Add IP to Whitelist")"
|
||||
echo "2) $(gettext "Remove IP from Whitelist")"
|
||||
echo "3) $(gettext "Show Whitelist")"
|
||||
read -n 1 -s -r -p "$(gettext "Option: ")" wl_opt
|
||||
echo -e "\n"
|
||||
case $wl_opt in
|
||||
1)
|
||||
read -p "$(gettext "Enter IP to whitelist: ")" NEW_WL
|
||||
if [ -n "$NEW_WL" ]; then
|
||||
if ! grep -Fxq "$NEW_WL" "$WHITELIST_PATH" 2>/dev/null; then
|
||||
echo "$NEW_WL" >> "$WHITELIST_PATH"
|
||||
# Sofort entbannen, falls vorhanden
|
||||
while iptables -L INPUT -n | grep -q "$NEW_WL"; do
|
||||
iptables -D INPUT -s "$NEW_WL" -j DROP 2>/dev/null
|
||||
done
|
||||
sed -i "/^$NEW_WL$/d" "$BLACKLIST_PATH" 2>/dev/null
|
||||
printf "${GREEN}$(gettext "✅ IP %s added to whitelist and unbanned.")${NORMAL}\n" "$NEW_WL"
|
||||
else
|
||||
echo "$(gettext "IP already in whitelist.")"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
read -p "$(gettext "Enter IP to remove: ")" RM_WL
|
||||
[ -n "$RM_WL" ] && sed -i "/^$RM_WL$/d" "$WHITELIST_PATH"
|
||||
printf "${RED}$(gettext "❌ IP %s removed from whitelist.")${NORMAL}\n" "$RM_WL"
|
||||
;;
|
||||
3)
|
||||
echo "$(gettext "Current Whitelist:")"
|
||||
[ -s "$WHITELIST_PATH" ] && cat "$WHITELIST_PATH" || echo "$(gettext "Whitelist is empty.")"
|
||||
;;
|
||||
esac
|
||||
read -p "$(gettext "Press Enter...")"
|
||||
;;
|
||||
4)
|
||||
nano /opt/containers/authelia-watcher/config/watcher-config.json
|
||||
docker restart "$REAL_CONTAINER_NAME"
|
||||
;;
|
||||
5)
|
||||
echo -e "\n\n--- $(gettext "DynDNS & Notification Settings") ---"
|
||||
echo -e "$(gettext "Current Domain:") ${GREEN}${MY_DOMAIN:-N/A}${NORMAL}"
|
||||
echo -e "$(gettext "Current Interval:") ${GREEN}${CHECK_INTERVAL}${NORMAL}s"
|
||||
|
||||
read -p "$(gettext "New Domain (Leave empty to skip): ")" NEW_DOM
|
||||
read -p "$(gettext "New Interval (seconds, default 300): ")" NEW_INT
|
||||
read -p "$(gettext "Send Welcome Notification? (1=Yes, 0=No): ")" NEW_WELCOME
|
||||
read -p "$(gettext "Send Container Start Notification? (1=Yes, 0=No): ")" NEW_START
|
||||
|
||||
# Domain Update
|
||||
[ -n "$NEW_DOM" ] && sed -i "s|^MY_DOMAIN=.*|MY_DOMAIN=\"$NEW_DOM\"|" "$ENV_PATH"
|
||||
|
||||
# Interval Update
|
||||
[ -n "$NEW_INT" ] && sed -i "s/^CHECK_INTERVAL=.*/CHECK_INTERVAL=$NEW_INT/" "$ENV_PATH"
|
||||
|
||||
# Welcome Notification Update
|
||||
[ -n "$NEW_WELCOME" ] && sed -i "s/^SEND_WELCOME_NOTIFICATION=.*/SEND_WELCOME_NOTIFICATION=$NEW_WELCOME/" "$ENV_PATH"
|
||||
|
||||
# Watcher Start Notification Update
|
||||
[ -n "$NEW_START" ] && sed -i "s/^SEND_WATCHER_START_NOTIFICATION=.*/SEND_WATCHER_START_NOTIFICATION=$NEW_START/" "$ENV_PATH"
|
||||
|
||||
echo -e "${GREEN}$(gettext "Settings saved.")${NORMAL}"
|
||||
sleep 2 ;;
|
||||
6)
|
||||
docker logs -f --tail 50 "$REAL_CONTAINER_NAME"
|
||||
;;
|
||||
7)
|
||||
exec sudo clidmanager # Back to main menu
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
clear
|
||||
echo -e $LBLUE""
|
||||
main_menu() {
|
||||
while true; do
|
||||
clear
|
||||
echo -e "$version | $cmname |"
|
||||
echo "======================================="
|
||||
echo -e "[$one] $(gettext "Create new container folder")"
|
||||
echo -e "[$two] $(gettext "Edit/Create yml file")"
|
||||
echo -e "[$three] $(gettext "Start/Restart container")"
|
||||
echo -e "[$four] $(gettext "View logs")"
|
||||
echo -e "[$five] $(gettext "Stop all containers")"
|
||||
echo -e "[$six] $(gettext "Start all containers")"
|
||||
echo -e "[$seven] $(gettext "Authelia Watcher Manager")"
|
||||
echo -e "[$eight] $(gettext "Show running containers")"
|
||||
echo "======================================="
|
||||
echo "$info"
|
||||
echo "$info2"
|
||||
read -n 1 -s -r -p "$(gettext "Choose 1-8: ")" entry
|
||||
|
||||
case $entry in
|
||||
1) newdir; exit ;;
|
||||
2) edit_yml; exit ;;
|
||||
3) dcstart; exit ;;
|
||||
4) log; exit ;;
|
||||
5) all_stop; exit ;;
|
||||
6) all_start; exit ;;
|
||||
7) watcher_management; exit ;;
|
||||
8) list_containers; exit ;;
|
||||
*) clear; exit ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
main_menu
|
||||
@@ -90,7 +90,7 @@ install() {
|
||||
echo "$(gettext "User added to Docker group... 100%")"
|
||||
# Create cronjob
|
||||
CRON_ENTRY="@reboot /usr/local/bin/update_dyndns.sh > /dev/null 2>&1 &"
|
||||
(crontab -l 2>/dev/null | grep -Fq "$CRON_ENTRY") || ( (crontab -l 2>/dev/null; echo "$CRON_ENTRY") | crontab - )
|
||||
(sudo crontab -l 2>/dev/null | grep -Fq "$CRON_ENTRY") || ( (sudo crontab -l 2>/dev/null; echo "$CRON_ENTRY") | sudo crontab - )
|
||||
echo "$(gettext "Cronjob for DynDNS protection created.")"
|
||||
echo
|
||||
echo "$(gettext "At the next login you can call clidmanager")"
|
||||
@@ -131,7 +131,7 @@ remove() {
|
||||
echo "$(gettext "clidmanager and update_dyndns.sh completely removed.... 100%")"
|
||||
sleep 0.5
|
||||
echo
|
||||
crontab -l 2>/dev/null | grep -v "update_dyndns.sh" | crontab -
|
||||
sudo crontab -l 2>/dev/null | grep -v "update_dyndns.sh" | sudo crontab -
|
||||
echo "$(gettext "Cronjob removed.")"
|
||||
read -p "$(gettext "Press Enter to exit...")"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user