|
|
@@ -7,19 +7,18 @@
|
|
|
# Credits: Maks Usmanov (skamasle), Jaap Marcus (jaapmarcus) and contributors:
|
|
|
# Thanks to <https://github.com/Skamasle/sk_da_importer/graphs/contributors>
|
|
|
|
|
|
-# This script is provided whitout any warranty
|
|
|
+# This script is provided without any warranty
|
|
|
# Run at your own risk
|
|
|
# Version 0.1
|
|
|
# This script restore backups from DA to Hestiacp
|
|
|
|
|
|
# shellcheck source=/usr/local/hestia/func/main.sh
|
|
|
-source $HESTIA/func/main.sh
|
|
|
+source "$HESTIA"/func/main.sh
|
|
|
# shellcheck source=/etc/hestiacp/hestia.conf
|
|
|
source /etc/hestiacp/hestia.conf
|
|
|
# load config file
|
|
|
source_conf "$HESTIA/conf/hestia.conf"
|
|
|
|
|
|
-# Check required binaries
|
|
|
if [ ! -e /usr/bin/rsync ] || [ ! -e /usr/bin/file ]; then
|
|
|
echo "#######################################"
|
|
|
echo "rsync not installed, try install it"
|
|
|
@@ -32,10 +31,11 @@ if [ ! -e /usr/bin/rsync ] || [ ! -e /usr/bin/file ]; then
|
|
|
fi
|
|
|
exit 3
|
|
|
fi
|
|
|
-
|
|
|
# Put this to 0 if you want use bash -x to debug it
|
|
|
debug=1
|
|
|
hestia_package=default
|
|
|
+letsencrypt_enable=0
|
|
|
+addusertext="IMPORTED"
|
|
|
tmp_dir='tmp_dir_da_backup'
|
|
|
time=$(echo "$time_n_date" | cut -f 1 -d \ )
|
|
|
date=$(echo "$time_n_date" | cut -f 2 -d \ )
|
|
|
@@ -56,6 +56,12 @@ delete_tmp() {
|
|
|
rm -rf /backup/${tmp_dir}
|
|
|
}
|
|
|
|
|
|
+# URL decoding function
|
|
|
+urldecode() {
|
|
|
+ local url_encoded="${1//+/ }"
|
|
|
+ printf '%b' "${url_encoded//%/\\x}"
|
|
|
+}
|
|
|
+
|
|
|
tput setaf 3
|
|
|
echo "#######################################"
|
|
|
echo "# START WITH IMPORT "
|
|
|
@@ -138,13 +144,13 @@ else
|
|
|
exit 3
|
|
|
fi
|
|
|
|
|
|
-cd /backup/${tmp_dir}/
|
|
|
+cd /backup/${tmp_dir}/ || exit
|
|
|
main_dir=$(pwd)
|
|
|
echo "Access tmp directory $main_dir"
|
|
|
directadmin_user=$(grep username backup/user.conf | cut -d "=" -f 2)
|
|
|
directadmin_usermail=$(grep email backup/user.conf | cut -d "=" -f 2 | grep @)
|
|
|
echo "Get User: $directadmin_user"
|
|
|
-if [ -z $directadmin_usermail ]; then
|
|
|
+if [ -z "$directadmin_usermail" ]; then
|
|
|
directadmin_usermail=$(grep domain backup/user.conf | cut -d "=" -f 2 | head -n 1)
|
|
|
fi
|
|
|
|
|
|
@@ -156,7 +162,7 @@ fi
|
|
|
|
|
|
echo "Generate random password for $directadmin_user and create Hestiacp Account ..."
|
|
|
new_password=$(generate_password)
|
|
|
-$BIN/v-add-user $directadmin_user $new_password $directadmin_usermail $hestia_package
|
|
|
+"$BIN"/v-add-user "$directadmin_user" "$new_password" "$directadmin_usermail" $hestia_package $addusertext
|
|
|
if [ "$?" -ne 0 ]; then
|
|
|
tput setaf 1
|
|
|
echo "Error: Unable to create user"
|
|
|
@@ -184,32 +190,33 @@ function run_da_db() {
|
|
|
for da_db in $da_db_list; do
|
|
|
|
|
|
database_name=${da_db::-5}
|
|
|
- grep -w $database_name server_dbs
|
|
|
+ grep -w "$database_name" server_dbs
|
|
|
if [ $? == "1" ]; then
|
|
|
if [ -e "backup/${database_name}.sql" ]; then
|
|
|
|
|
|
#Get the database name
|
|
|
- db=$(grep db_collation backup/${da_db} | tr '&' '\n ' | grep SCHEMA_NAME | cut -d "=" -f 2)
|
|
|
+ db=$(grep db_collation backup/"${da_db}" | tr '&' '\n ' | grep SCHEMA_NAME | cut -d "=" -f 2)
|
|
|
|
|
|
tput setaf 2
|
|
|
echo " Create and restore ${db} "
|
|
|
tput sgr0
|
|
|
mysql -e "CREATE DATABASE $db"
|
|
|
- mysql ${db} < backup/${db}.sql
|
|
|
+ mysql "${db}" < backup/"${db}".sql
|
|
|
#Get all the users of the database
|
|
|
while IFS= read -r line; do
|
|
|
|
|
|
- selectdb_line=$(echo $line | grep passwd)
|
|
|
+ selectdb_line=$(echo "$line" | grep passwd)
|
|
|
if [ ! -z "$selectdb_line" ]; then
|
|
|
|
|
|
- db_user=$(echo $selectdb_line | tr '&' '\n ' | grep ${directadmin_user} | cut -d "=" -f 1)
|
|
|
- md5=$(echo $selectdb_line | tr '&' '\n ' | grep passwd | cut -d "=" -f 2)
|
|
|
+ db_user=$(echo "$selectdb_line" | tr '&' '\n ' | grep "${directadmin_user}" | cut -d "=" -f 1)
|
|
|
+ encoded_md5=$(echo "$selectdb_line" | tr '&' '\n ' | grep passwd | cut -d "=" -f 2)
|
|
|
+ md5=$(urldecode "$encoded_md5")
|
|
|
|
|
|
echo "DB: $db"
|
|
|
echo "udb: $db_user"
|
|
|
echo "Password: ${md5}"
|
|
|
|
|
|
- echo "DB='$db' DBUSER='$db_user' MD5='$md5' HOST='localhost' TYPE='mysql' CHARSET='UTF8' U_DISK='0' SUSPENDED='no' TIME='$time' DATE='$data'" >> /usr/local/hestia/data/users/$directadmin_user/db.conf
|
|
|
+ echo "DB='$db' DBUSER='$db_user' MD5='$md5' HOST='localhost' TYPE='mysql' CHARSET='UTF8' U_DISK='0' SUSPENDED='no' TIME='$time' DATE='$date'" >> /usr/local/hestia/data/users/"$directadmin_user"/db.conf
|
|
|
fi
|
|
|
|
|
|
done < "backup/${da_db}"
|
|
|
@@ -218,11 +225,11 @@ function run_da_db() {
|
|
|
tput setaf 2
|
|
|
echo "Rebuild databases files for $directadmin_user"
|
|
|
tput sgr0
|
|
|
- $BIN/v-rebuild-databases $directadmin_user
|
|
|
+ "$BIN"/v-rebuild-databases "$directadmin_user"
|
|
|
fi
|
|
|
else
|
|
|
tput setaf 1
|
|
|
- echo "Error: Cant restore database $db alredy exists in mysql server"
|
|
|
+ echo "Error: Cant restore database $db already exists in mysql server"
|
|
|
tput sgr0
|
|
|
fi
|
|
|
done
|
|
|
@@ -250,39 +257,39 @@ for directadmin_domain in $directadmin_domain_list; do
|
|
|
tput setaf 2
|
|
|
echo "Add $directadmin_domain if not exists"
|
|
|
tput sgr0
|
|
|
- $BIN/v-add-domain ${directadmin_user} $directadmin_domain
|
|
|
+ "$BIN"/v-add-domain "${directadmin_user}" "$directadmin_domain"
|
|
|
if [ $? -ne 0 ]; then
|
|
|
tput setaf 4
|
|
|
echo "Domain $directadmin_domain already added in some account, skip..."
|
|
|
tput sgr0
|
|
|
- elif [ -d /home/${directadmin_user}/web/${directadmin_domain} ]; then
|
|
|
+ elif [ -d /home/"${directadmin_user}"/web/"${directadmin_domain}" ]; then
|
|
|
echo "Domain $directadmin_domain added, restoring files"
|
|
|
- echo $directadmin_domain >> restored_domains
|
|
|
- rm -f /home/$directadmin_user/web/$directadmin_domain/public_html/index.html
|
|
|
- rm -f /home/$directadmin_user/web/$directadmin_domain/public_html/robots.txt
|
|
|
+ echo "$directadmin_domain" >> restored_domains
|
|
|
+ rm -f /home/"$directadmin_user"/web/"$directadmin_domain"/public_html/index.html
|
|
|
+ rm -f /home/"$directadmin_user"/web/"$directadmin_domain"/public_html/robots.txt
|
|
|
|
|
|
public_sync_count=0
|
|
|
- rsync -av domains/${directadmin_domain}/public_html/ /home/$directadmin_user/web/$directadmin_domain/public_html 2>&1 \
|
|
|
+ rsync -av domains/"${directadmin_domain}"/public_html/ /home/"$directadmin_user"/web/"$directadmin_domain"/public_html 2>&1 \
|
|
|
| while read file_dm; do
|
|
|
public_sync_count=$(($public_sync_count + 1))
|
|
|
echo -en "-- $public_sync_count restored files\r"
|
|
|
done
|
|
|
|
|
|
- chown ${directadmin_user}:${directadmin_user} -R /home/${directadmin_user}/web/${directadmin_domain}/public_html
|
|
|
- chmod 751 /home/${directadmin_user}/web/${directadmin_domain}/public_html
|
|
|
+ chown "${directadmin_user}":"${directadmin_user}" -R /home/"${directadmin_user}"/web/"${directadmin_domain}"/public_html
|
|
|
+ chmod 751 /home/"${directadmin_user}"/web/"${directadmin_domain}"/public_html
|
|
|
|
|
|
if [[ -L "domains/${directadmin_domain}/private_html" && -d "domains/${directadmin_domain}/private_html" ]]; then
|
|
|
echo "private_html is a symlink to public_html so we don't need to copy it."
|
|
|
else
|
|
|
private_sync_count=0
|
|
|
|
|
|
- rsync -av domains/${directadmin_domain}/private_html/ /home/$directadmin_user/web/$directadmin_domain/private 2>&1 \
|
|
|
+ rsync -av domains/"${directadmin_domain}"/private_html/ /home/"$directadmin_user"/web/"$directadmin_domain"/private 2>&1 \
|
|
|
| while read file_dm; do
|
|
|
private_sync_count=$(($private_sync_count + 1))
|
|
|
echo -en "-- $private_sync_count restored files\r"
|
|
|
done
|
|
|
- chown ${directadmin_user}:${directadmin_user} -R /home/${directadmin_user}/web/${directadmin_domain}/private
|
|
|
- chmod 751 /home/${directadmin_user}/web/${directadmin_domain}/private
|
|
|
+ chown "${directadmin_user}":"${directadmin_user}" -R /home/"${directadmin_user}"/web/"${directadmin_domain}"/private
|
|
|
+ chmod 751 /home/"${directadmin_user}"/web/"${directadmin_domain}"/private
|
|
|
fi
|
|
|
else
|
|
|
echo "Ups.. cant restore or add domain: $directadmin_domain"
|
|
|
@@ -300,8 +307,8 @@ echo "Start restoring mails"
|
|
|
tput sgr0
|
|
|
function da_restore_imap_pass() {
|
|
|
#DirectAdmin passw is SHA512-CRYPT
|
|
|
- da_orig_pass=$(grep -w $1 backup/$2/email/passwd | tr ':' ' ' | cut -d " " -f2)
|
|
|
- echo ${da_orig_pass}
|
|
|
+ da_orig_pass=$(grep -w "$1" backup/"$2"/email/passwd | tr ':' ' ' | cut -d " " -f2)
|
|
|
+ echo "${da_orig_pass}"
|
|
|
USER_DATA=$HESTIA/data/users/${3}/
|
|
|
update_object_value "mail/${2}" 'ACCOUNT' "${1}" '$MD5' "{SHA512-CRYPT}$da_orig_pass"
|
|
|
echo "Password for $1@$2 restored"
|
|
|
@@ -309,32 +316,136 @@ function da_restore_imap_pass() {
|
|
|
echo cat restored_domains
|
|
|
if [ -e restored_domains ]; then
|
|
|
cat restored_domains | while read da_mail_domain; do
|
|
|
- if [ "$(ls -A imap/${da_mail_domain}/)" ]; then
|
|
|
+ if [ "$(ls -A imap/"${da_mail_domain}"/)" ]; then
|
|
|
tput setaf 2
|
|
|
echo "Found Imap for ${da_mail_domain}"
|
|
|
tput sgr0
|
|
|
- ls -1 imap/${da_mail_domain}/ | while read da_imap; do
|
|
|
+ ls -1 imap/"${da_mail_domain}"/ | while read da_imap; do
|
|
|
tmp_pass=$(generate_password)
|
|
|
- $BIN/v-add-mail-account $directadmin_user $da_mail_domain $da_imap tmp_pass
|
|
|
+ "$BIN"/v-add-mail-account "$directadmin_user" "$da_mail_domain" "$da_imap" "$tmp_pass"
|
|
|
if [ "$debug" != 0 ]; then
|
|
|
- rsync -av imap/${da_mail_domain}/${da_imap}/Maildir/ /home/${directadmin_user}/mail/${da_mail_domain}/${da_imap} 2>&1 \
|
|
|
+ rsync -av imap/"${da_mail_domain}"/"${da_imap}"/Maildir/ /home/"${directadmin_user}"/mail/"${da_mail_domain}"/"${da_imap}" 2>&1 \
|
|
|
| while read backup_file_dm; do
|
|
|
sk_sync=$((sk_sync + 1))
|
|
|
echo -en "-- $sk_sync restored files\r"
|
|
|
done
|
|
|
echo " "
|
|
|
else
|
|
|
- rsync imap/${da_mail_domain}/${da_imap}/Maildir/ /home/${directadmin_user}/mail/${da_mail_domain}/${da_imap}
|
|
|
+ rsync imap/"${da_mail_domain}"/"${da_imap}"/Maildir/ /home/"${directadmin_user}"/mail/"${da_mail_domain}"/"${da_imap}"
|
|
|
fi
|
|
|
- chown ${directadmin_user}:mail -R /home/${directadmin_user}/mail/${da_mail_domain}/${da_imap}
|
|
|
- find /home/$directadmin_user/mail/$da_mail_domain -type f -name 'dovecot*' -delete
|
|
|
- da_restore_imap_pass $da_imap $da_mail_domain $directadmin_user
|
|
|
+ chown "${directadmin_user}":mail -R /home/"${directadmin_user}"/mail/"${da_mail_domain}"/"${da_imap}"
|
|
|
+ find /home/"$directadmin_user"/mail/"$da_mail_domain" -type f -name 'dovecot*' -delete
|
|
|
+ da_restore_imap_pass "$da_imap" "$da_mail_domain" "$directadmin_user"
|
|
|
done
|
|
|
|
|
|
- $BIN/v-rebuild-mail-domain $directadmin_user $da_mail_domain
|
|
|
+ "$BIN"/v-rebuild-mail-domain "$directadmin_user" "$da_mail_domain"
|
|
|
fi
|
|
|
done
|
|
|
fi
|
|
|
+
|
|
|
+tput setaf 3
|
|
|
+echo "#######################################"
|
|
|
+echo "# CRON JOBS "
|
|
|
+echo "#######################################"
|
|
|
+tput sgr0
|
|
|
+
|
|
|
+# Restore cron jobs
|
|
|
+if [ -f "backup/crontab.conf" ]; then
|
|
|
+ while IFS= read -r cron_line; do
|
|
|
+ # Skip empty lines and comments
|
|
|
+ [[ -z "$cron_line" || "$cron_line" =~ ^#.*$ ]] && continue
|
|
|
+
|
|
|
+ # Check if the line is an environment variable
|
|
|
+ if [[ "$cron_line" =~ ^[A-Z]+= ]]; then
|
|
|
+ # Export environment variable
|
|
|
+ # echo "Setting environment variable: $cron_line"
|
|
|
+ export "$cron_line"
|
|
|
+ continue
|
|
|
+ fi
|
|
|
+
|
|
|
+ # Remove the cron job identifier and extract cron job details
|
|
|
+ if [[ "$cron_line" =~ ^[0-9]+= ]]; then
|
|
|
+ cron_line=${cron_line#*=}
|
|
|
+ fi
|
|
|
+
|
|
|
+ # Extract cron job details (handle cases where command contains spaces)
|
|
|
+ IFS=' ' read -r min hour day month wday command <<< "$cron_line"
|
|
|
+
|
|
|
+ # Ensure it is a valid cron job line (i.e., min, hour, day, month, wday should be numeric or valid cron symbols)
|
|
|
+ if ! [[ "$min" =~ ^[\*0-9,-/]+$ && "$hour" =~ ^[\*0-9,-/]+$ && "$day" =~ ^[\*0-9,-/]+$ && "$month" =~ ^[\*0-9,-/]+$ && "$wday" =~ ^[\*0-9,-/]+$ ]]; then
|
|
|
+ echo "Invalid cron job format: $cron_line"
|
|
|
+ continue
|
|
|
+ fi
|
|
|
+
|
|
|
+ # Reconstruct the command part
|
|
|
+ command="${cron_line#"${min}" "${hour}" "${day}" "${month}" "${wday}" }"
|
|
|
+
|
|
|
+ echo "Adding cron job for user $directadmin_user: $cron_line"
|
|
|
+ "$BIN"/v-add-cron-job "$directadmin_user" "$min" "$hour" "$day" "$month" "$wday" "$command"
|
|
|
+ done < "backup/crontab.conf"
|
|
|
+else
|
|
|
+ echo "No cron jobs found to restore."
|
|
|
+fi
|
|
|
+
|
|
|
+tput setaf 3
|
|
|
+echo "#######################################"
|
|
|
+echo "# DOMAIN ALIASES "
|
|
|
+echo "#######################################"
|
|
|
+tput sgr0
|
|
|
+
|
|
|
+# Restore domain aliases
|
|
|
+domain_base_dir="backup"
|
|
|
+
|
|
|
+if [ -d "$domain_base_dir" ]; then
|
|
|
+ for domain_subdir in "$domain_base_dir"/*/; do
|
|
|
+ domain_pointers_file="$domain_subdir/domain.pointers"
|
|
|
+ if [ -f "$domain_pointers_file" ]; then
|
|
|
+ while IFS= read -r pointer_line; do
|
|
|
+ # Skip empty lines and comments
|
|
|
+ [[ -z "$pointer_line" || "$pointer_line" =~ ^#.*$ ]] && continue
|
|
|
+
|
|
|
+ # Extract alias and type
|
|
|
+ alias_domain=$(echo "$pointer_line" | cut -d'=' -f1)
|
|
|
+ alias_type=$(echo "$pointer_line" | awk -F'type=' '{print $2}')
|
|
|
+
|
|
|
+ if [[ "$alias_type" == "alias" || "$alias_type" == "pointer" ]]; then
|
|
|
+ domain_name=$(basename "$domain_subdir")
|
|
|
+ echo "Adding domain alias $alias_domain for user $directadmin_user on domain $domain_name"
|
|
|
+ "$BIN"/v-add-web-domain-alias "$directadmin_user" "$domain_name" "$alias_domain" no
|
|
|
+ else
|
|
|
+ echo "Skipping non-alias type for $alias_domain: $alias_type"
|
|
|
+ fi
|
|
|
+ done < "$domain_pointers_file"
|
|
|
+ fi
|
|
|
+ done
|
|
|
+else
|
|
|
+ echo "No domain directories found to restore."
|
|
|
+fi
|
|
|
+
|
|
|
+tput setaf 3
|
|
|
+echo "#######################################"
|
|
|
+echo "# ENABLE LETSENCRYPT "
|
|
|
+echo "#######################################"
|
|
|
+tput sgr0
|
|
|
+
|
|
|
+# Enable Let's Encrypt for each domain
|
|
|
+if [ "$letsencrypt_enable" = 1 ]; then
|
|
|
+ for directadmin_domain in $directadmin_domain_list; do
|
|
|
+ echo "Enabling Let's Encrypt for $directadmin_domain"
|
|
|
+ letsencrypt_output=$("$BIN"/v-add-letsencrypt-domain "$directadmin_user" "$directadmin_domain" '' yes 2>&1)
|
|
|
+ echo "$letsencrypt_output"
|
|
|
+ if echo "$letsencrypt_output" | grep -q "Error: mail domain"; then
|
|
|
+ echo "Error with Let's Encrypt: $letsencrypt_output"
|
|
|
+ echo "Retrying Let's Encrypt without mail domain for $directadmin_domain"
|
|
|
+ "$BIN"/v-add-letsencrypt-domain "$directadmin_user" "$directadmin_domain" '' no
|
|
|
+ else
|
|
|
+ echo "Let's Encrypt enabled for $directadmin_domain"
|
|
|
+ fi
|
|
|
+ done
|
|
|
+else
|
|
|
+ echo "Let's Encrypt is not enabled for any domain."
|
|
|
+fi
|
|
|
+
|
|
|
delete_tmp
|
|
|
tput sgr0
|
|
|
tput setaf 2
|