Add update_dyndns.sh, extend menu and fix crontab/loop issues

This commit is contained in:
2026-01-31 20:20:03 +01:00
parent 18557c66dc
commit 61e3ba54b5
3 changed files with 368 additions and 2 deletions

View File

@@ -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
View 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

View File

@@ -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