From 83fced881ac5496256eb95192af30e285b80e701 Mon Sep 17 00:00:00 2001 From: monlor Date: Fri, 18 Oct 2024 20:07:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Supports=20backup=20file?= =?UTF-8?q?=20encryption=20and=20decryption?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webdav-backup/Dockerfile | 4 ++-- webdav-backup/README.md | 8 +++++++- webdav-backup/entrypoint.sh | 28 +++++++++++++++++++++++++++- webdav-backup/restore.sh | 24 +++++++++++++++++++----- 4 files changed, 55 insertions(+), 9 deletions(-) diff --git a/webdav-backup/Dockerfile b/webdav-backup/Dockerfile index 38101f7..2d69d93 100644 --- a/webdav-backup/Dockerfile +++ b/webdav-backup/Dockerfile @@ -1,10 +1,10 @@ FROM alpine:latest LABEL MAINTAINER me@monlor.com -LABEL VERSION 1.1.0 +LABEL VERSION 1.1.1 # 安装必要的工具 -RUN apk add --no-cache bash curl tar gzip && mkdir -p /data +RUN apk add --no-cache bash curl tar gzip openssl && mkdir -p /data # 复制脚本到容器 COPY --chmod=755 *.sh / diff --git a/webdav-backup/README.md b/webdav-backup/README.md index 642b17c..1dadc62 100644 --- a/webdav-backup/README.md +++ b/webdav-backup/README.md @@ -1,6 +1,6 @@ # WebDAV备份工具 -这个工具可以定期将指定的目录备份到WebDAV服务器,并提供恢复功能。 +这个工具可以定期将指定的目录备份到WebDAV服务器,并提供恢复功能。支持文件加密和解密。 ## 功能 @@ -11,6 +11,7 @@ - 从WebDAV服务器恢复指定的备份文件 - 支持 Telegram 通知(启动时和备份失败时) - 可自定义备份任务名称 +- 支持备份文件加密和解密 ## 使用方法 @@ -21,6 +22,7 @@ docker run -d \ -e WEBDAV_URL="https://your-webdav-server.com/backup" \ -e WEBDAV_USERNAME="your_username" \ -e WEBDAV_PASSWORD="your_password" \ + -e ENCRYPTION_PASSWORD="your_encryption_password" \ -v /path/to/data:/data \ monlor/webdav-backup ``` @@ -61,6 +63,7 @@ docker exec -it /bin/bash - `BACKUP_SPLIT_SIZE`: 备份文件拆分大小(可选)。格式为数字后跟可选的单位后缀(b, k, m, g, t)。例如:100M, 1G, 500K。如果不设置,备份文件将不会被拆分。 - `TELEGRAM_BOT_TOKEN`: Telegram Bot 的 token(可选) - `TELEGRAM_CHAT_ID`: 接收 Telegram 通知的聊天 ID(可选) +- `ENCRYPTION_PASSWORD`: 用于加密备份文件的密码(可选)。如果设置了此变量,备份文件将被加密。 ## 注意事项 @@ -73,6 +76,9 @@ docker exec -it /bin/bash - 如果配置了 Telegram 通知,只有在备份失败时才会发送额外的通知 - 当使用 `BACKUP_SPLIT_SIZE` 时,备份文件会被拆分成多个部分,并创建一个同名的 .txt 文件列表 - 恢复时,可以使用 .tar.gz 文件名(未拆分)或 .tar.gz.txt 文件名(拆分文件列表) +- 如果设置了 `ENCRYPTION_PASSWORD`,备份文件将被加密。确保在恢复时使用相同的密码。 +- 加密后的文件名保持不变,这意味着在WebDAV服务器上看到的文件名与未加密时相同。 +- 在恢复加密的备份时,必须提供正确的 `ENCRYPTION_PASSWORD`,否则恢复将失败。 ## 贡献 diff --git a/webdav-backup/entrypoint.sh b/webdav-backup/entrypoint.sh index 92a9717..eb74d84 100644 --- a/webdav-backup/entrypoint.sh +++ b/webdav-backup/entrypoint.sh @@ -15,6 +15,15 @@ else echo "Telegram 通知未启用" fi +# 检查加密相关环境变量 +if [ -n "$ENCRYPTION_PASSWORD" ]; then + ENCRYPTION_ENABLED=true + echo "备份加密已启用" +else + ENCRYPTION_ENABLED=false + echo "备份加密未启用" +fi + # 添加发送 Telegram 消息的函数 send_telegram_message() { if [ "$TELEGRAM_ENABLED" = true ]; then @@ -70,10 +79,27 @@ else echo "文件不拆分" fi -# 添加上传文件的函数 +# 修改加密文件的函数 +encrypt_file() { + local input_file="$1" + local output_file="$1" # 保持输出文件名与输入文件名相同 + + if [ "$ENCRYPTION_ENABLED" = true ]; then + echo "正在加密文件: ${input_file}" + openssl enc -aes-256-cbc -salt -in "$input_file" -out "${input_file}.tmp" -k "$ENCRYPTION_PASSWORD" + mv "${input_file}.tmp" "$output_file" + fi +} + +# 修改上传文件的函数 upload_file() { local file="$1" local remote_path="$2" + + if [ "$ENCRYPTION_ENABLED" = true ]; then + encrypt_file "$file" + fi + HTTP_CODE=$(curl -#L -u "${WEBDAV_USERNAME}:${WEBDAV_PASSWORD}" \ -T "$file" \ "${WEBDAV_URL}${WEBDAV_PATH}/${remote_path}" \ diff --git a/webdav-backup/restore.sh b/webdav-backup/restore.sh index fe6f220..f571e11 100644 --- a/webdav-backup/restore.sh +++ b/webdav-backup/restore.sh @@ -12,6 +12,15 @@ BACKUP_DIRS="${BACKUP_DIRS}" # 临时目录用于下载备份文件 TEMP_DIR=$(mktemp -d) +# 检查加密密码 +if [ -n "$ENCRYPTION_PASSWORD" ]; then + ENCRYPTION_ENABLED=true + echo "备份解密已启用" +else + ENCRYPTION_ENABLED=false + echo "备份解密未启用" +fi + # 函数:从用户输入获取备份文件名 get_backup_filename() { read -p "请输入要恢复的备份文件名(格式:backup_YYYYMMDD_HHMMSS.tar.gz 或 backup_YYYYMMDD_HHMMSS.tar.gz.txt): " BACKUP_FILE @@ -31,8 +40,8 @@ construct_backup_path() { BACKUP_PATH="${WEBDAV_URL}${WEBDAV_PATH}/${year}/${month}/${day}/${filename}" } -# 函数:从 WebDAV 下载备份文件 -download_backup() { +# 函数:从 WebDAV 下载并解密备份文件 +download_and_decrypt_backup() { local backup_path="$1" local output_file="$2" echo "正在从 WebDAV 下载文件: $backup_path" @@ -42,6 +51,11 @@ download_backup() { if [ "$HTTP_CODE" = "200" ]; then echo "文件下载成功。" + if [ "$ENCRYPTION_ENABLED" = true ]; then + echo "正在解密文件..." + openssl enc -d -aes-256-cbc -in "$output_file" -out "${output_file}.tmp" -k "$ENCRYPTION_PASSWORD" + mv "${output_file}.tmp" "$output_file" + fi else echo "错误:文件下载失败。HTTP 状态码: ${HTTP_CODE}" return 1 @@ -78,7 +92,7 @@ construct_backup_path "$BACKUP_FILE" if [[ $BACKUP_FILE == *.txt ]]; then # 下载备份列表文件 BACKUP_LIST_FILE="${TEMP_DIR}/${BACKUP_FILE}" - if ! download_backup "$BACKUP_PATH" "$BACKUP_LIST_FILE"; then + if ! download_and_decrypt_backup "$BACKUP_PATH" "$BACKUP_LIST_FILE"; then echo "错误:无法下载备份列表文件。" rm -rf "$TEMP_DIR" exit 1 @@ -89,7 +103,7 @@ if [[ $BACKUP_FILE == *.txt ]]; then file_url="${BACKUP_PATH%/*}/${file_name}" output_file="${TEMP_DIR}/${file_name}" - if ! download_backup "$file_url" "$output_file"; then + if ! download_and_decrypt_backup "$file_url" "$output_file"; then echo "错误:无法下载文件 $file_name" rm -rf "$TEMP_DIR" exit 1 @@ -105,7 +119,7 @@ if [[ $BACKUP_FILE == *.txt ]]; then BACKUP_FILE="${BACKUP_FILE%.txt}" else # 直接下载单个备份文件 - if ! download_backup "$BACKUP_PATH" "${TEMP_DIR}/${BACKUP_FILE}"; then + if ! download_and_decrypt_backup "$BACKUP_PATH" "${TEMP_DIR}/${BACKUP_FILE}"; then echo "错误:无法下载备份文件。" rm -rf "$TEMP_DIR" exit 1