解放双手!使用 Shell 脚本将 VPS 数据每日自动备份到 Telegram
作为一名站长或开发者,服务器数据的安全性是我们永远不能忽视的生命线。无论是硬件故障、软件 Bug 还是恶意攻击,都可能导致我们数小时甚至数月的心血付之一炬。
传统的备份方案可能涉及另一台服务器或昂贵的商业对象存储,但今天,我将向大家分享一个极具性价比且高效的终极解决方案:将 VPS 的关键数据每日自动打包、加密,并上传到 Telegram 的无限云存储中!
💡 为什么选择 Telegram?
- 免费云存储 :Telegram 的“保存的消息”和私密频道,就是一个无限容量的个人云盘。
- 即时通知 :备份成功后,文件会立刻推送到您的客户端,让您随时掌控备份状态。
- 异地容灾 :将备份存放在与 VPS 完全隔离的第三方服务上,是最佳的容灾实践。
- 安全可靠 :配合强大的 GPG 加密,即使 Telegram 服务器数据泄露,我们的备份内容也安然无恙。
✨ 方案亮点
我们即将打造的这套自动化备份系统,是一个生产级别的解决方案,具备以下特点:
- ✅ 全自动化 :一次配置,每日通过 Cron 自动执行,无需人工干预。
- 🔐 强加密 :使用 GPG 对备份文件进行对称加密,没有密码谁也无法查看。
- 📦 完整打包 :支持同时备份多个网站目录、配置文件和 MySQL/PostgreSQL 数据库。
- 🪓 大文件支持 :自动分割超过 2GB(Telegram 非会员限制)的大文件,确保上传成功。
- 🧹 自动清理 :备份上传后自动删除本地临时文件,不占用服务器宝贵空间。
- 💡 环境兼容:完美解决在 Cron 或宝塔面板等非交互式环境中
HOME
变量缺失导致程序出错的问题。 - 📜 日志记录 :可将执行日志输出到文件,方便排查问题。
⚙️ 准备工作
在正式开始之前,我们需要确保服务器上已安装好必要的工具,并获取到关键的 Telegram 频道 ID。整个准备过程分为以下两个步骤。
1. 安装所需工具
- ① TDL (Telegram 客户端)
一个强大的 Telegram 命令行客户端,是上传文件的核心。请参照其 官方文档 完成安装和登录授权。 ② GnuPG (加密工具)
用于对备份文件进行加密,保障数据安全。# Debian/Ubuntu 系统 sudo apt update && sudo apt install -y gpg # CentOS/RHEL 系统 sudo yum install -y gnupg2
③ 数据库客户端
用于导出数据库。通常已预装,如果没有,请根据您的数据库类型安装。# MySQL/MariaDB sudo apt install -y mysql-client # PostgreSQL sudo apt install -y postgresql-client
2. 获取 Telegram 频道 ID
这是脚本用来定位备份文件存放地的关键标识。我们提供两种方法来获取它。
方法一:从网页版 URL 获取 (最推荐)
- 创建频道 :在您的任意 Telegram 客户端创建一个 私密频道 ,并确保您已加入。
- 登录网页版:在电脑浏览器中,访问并登录 Telegram 网页版:
https://web.telegram.org/a/
- 定位 ID:登录后,点击您创建的私密频道。此时,浏览器的地址栏会显示类似下方的 URL:
https://web.telegram.org/a/#-1002759598666
- 提取纯数字 ID:
- URL 中井号
#
后面的-1002759598666
是频道的完整 ID。 - 关键一步 :我们需要 去掉前面的
-100
前缀 ,只保留后面的纯数字部分。 - 例如,从
-1002759598666
中,我们提取出2759598666
。
- URL 中井号
方法二:从桌面客户端获取
- 开启实验性功能 :进入 设置 → 高级 → 实验功能 ,勾选 在资料中显示对话 ID。
- 查看并提取 ID:打开您的私密频道,进入其 资料页,会看到如
Channel ID: 2759598666
的信息。
👉 最终确认:脚本里到底填什么?
无论您使用哪种方法,请务必记住:在脚本的
TG_CHAT_ID
配置项中,仅填写那串纯数字 ,不带任何前缀或符号。正确示例:
TG_CHAT_ID="2759598666"
📜 核心脚本
这是我们整个方案的核心。首先,创建脚本文件并赋予执行权限。
# 创建脚本存放目录
sudo mkdir -p /opt/scripts
# 创建脚本文件并赋予执行权限
sudo touch /opt/scripts/backup_to_telegram.sh
sudo chmod +x /opt/scripts/backup_to_telegram.sh
然后,将下面的完整脚本内容粘贴到 /opt/scripts/backup_to_telegram.sh
文件中。
#!/bin/bash
# =================================================================
# VPS Backup to Telegram Script (with File Splitting & CRON Fix)
# Author: Your Name/Blog URL
# Version: 2.1
# Description: A robust script to backup, encrypt, split large files,
# and upload to Telegram via tdl.
# =================================================================
# !!! 关键修复:为非交互式环境(如Cron/宝塔面板)指定HOME目录 !!!
# tdl 需要 $HOME 目录来寻找其配置文件和会话数据
export HOME=/root
# --- 配置区域 START (请根据您的实际情况修改) ---
# 1. 需要备份的目录 (多个目录用空格隔开)
# 例如: BACKUP_SRC_DIRS="/var/www/my_site /etc/nginx"
BACKUP_SRC_DIRS="/var/www/html /etc/nginx/sites-available"
# 2. 数据库配置 (如果不需要备份数据库,请将 DB_USER 留空)
DB_USER="your_db_user"
DB_PASS="your_db_password"
DB_NAME="your_db_name"
DB_TYPE="mysql" # 可选 "mysql" 或 "postgres"
# 3. Telegram 配置
# 在这里填入您上一步获取到的纯数字ID
TG_CHAT_ID="YOUR_CHAT_ID"
# Telegram 单文件上传大小限制 (非会员约 1.9GB)
UPLOAD_LIMIT_BYTES=2040109465
# 4. 加密配置
# !!! 重要 !!! 请设置一个强密码用于加密备份文件
# 这个密码是您未来解密备份的唯一凭证,请务必妥善保管在安全的地方!
GPG_PASSPHRASE="A_VERY_STRONG_AND_SECRET_PASSWORD"
# 5. 临时文件和备份命名
TMP_DIR="/tmp/backup_$$" # $$ 表示当前脚本的进程ID,保证并发执行时目录唯一
BACKUP_FILENAME_PREFIX="vps_backup"
# --- 配置区域 END ---
# --- 脚本主体 (一般无需修改) ---
set -e
set -o pipefail
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
}
cleanup() {
if [ -d "$TMP_DIR" ]; then
log "正在清理临时文件..."
# 额外清理可能产生的分卷文件和临时包
rm -rf "$TMP_DIR" /tmp/${BACKUP_FILENAME_PREFIX}_*.tar.gz*
log "清理完成。"
fi
}
trap cleanup EXIT
log "备份任务开始 (V2.1 - 支持大文件分割)..."
log "创建临时工作目录: $TMP_DIR"
mkdir -p "$TMP_DIR"
log "正在备份指定的目录..."
for src_dir in $BACKUP_SRC_DIRS; do
if [ -d "$src_dir" ]; then
cp -r "$src_dir" "$TMP_DIR/"
log " - 已备份: $src_dir"
else
log " - 警告: 目录不存在,已跳过: $src_dir"
fi
done
if [ -n "$DB_USER" ]; then
log "正在备份数据库: $DB_NAME..."
DB_BACKUP_FILE="$TMP_DIR/${DB_NAME}.sql"
case "$DB_TYPE" in
mysql) mysqldump -u"$DB_USER" -p"$DB_PASS" --single-transaction --routines --triggers "$DB_NAME" > "$DB_BACKUP_FILE";;
postgres) PGPASSWORD="$DB_PASS" pg_dump -U "$DB_USER" -d "$DB_NAME" -f "$DB_BACKUP_FILE";;
*) log "错误: 不支持的数据库类型 '$DB_TYPE'。"; exit 1;;
esac
log "数据库备份完成。"
fi
TIMESTAMP=$(date '+%Y%m%d_%H%M%S')
ARCHIVE_NAME="${BACKUP_FILENAME_PREFIX}_${TIMESTAMP}.tar.gz"
ARCHIVE_PATH="/tmp/${ARCHIVE_NAME}"
log "正在打包压缩成: $ARCHIVE_PATH"
tar -zcvf "$ARCHIVE_PATH" -C "$TMP_DIR" . > /dev/null
ENCRYPTED_ARCHIVE_PATH="${ARCHIVE_PATH}.gpg"
log "正在加密备份文件: $ENCRYPTED_ARCHIVE_PATH"
gpg --symmetric --batch --yes --passphrase "$GPG_PASSPHRASE" -o "$ENCRYPTED_ARCHIVE_PATH" "$ARCHIVE_PATH"
log "检查文件大小并准备上传..."
FILE_SIZE=$(stat -c%s "$ENCRYPTED_ARCHIVE_PATH")
if [ "$FILE_SIZE" -gt "$UPLOAD_LIMIT_BYTES" ]; then
SPLIT_SIZE="1900M"
log "文件大小 ($((FILE_SIZE / 1024 / 1024)) MB) 超过限制,将分割成 ${SPLIT_SIZE} 的分卷。"
# 使用split进行分割,并生成有意义的分卷名
split -b "$SPLIT_SIZE" -d -a 2 --additional-suffix=.part "$ENCRYPTED_ARCHIVE_PATH" "${ARCHIVE_PATH}.gpg."
log "文件分割完成,开始逐个上传分卷..."
PART_COUNT=$(find /tmp -name "${ARCHIVE_NAME}.gpg.*.part" | wc -l)
CURRENT_PART=1
for part_file in $(find /tmp -name "${ARCHIVE_NAME}.gpg.*.part"); do
log "正在上传分卷 $CURRENT_PART/$PART_COUNT: $(basename "$part_file")"
tdl up -p "$part_file" -c "$TG_CHAT_ID"
log "分卷 $CURRENT_PART/$PART_COUNT 上传成功。"
rm -f "$part_file"
CURRENT_PART=$((CURRENT_PART + 1))
done
else
log "文件大小 ($((FILE_SIZE / 1024 / 1024)) MB) 未超过限制,直接上传。"
tdl up -p "$ENCRYPTED_ARCHIVE_PATH" -c "$TG_CHAT_ID"
fi
log "所有文件上传成功!"
rm -f "$ARCHIVE_PATH" "$ENCRYPTED_ARCHIVE_PATH"
log "本地的原始压缩包和加密包已删除。"
log "备份任务圆满完成!"
exit 0
🚀 部署与自动化
脚本配置完成后,我们只需三步即可实现全自动运行。
- 修改配置
使用文本编辑器(如vim
或nano
)打开/opt/scripts/backup_to_telegram.sh
,仔细修改顶部的“配置区域”,填入您自己的目录、数据库信息、Telegram 频道 ID 和 一个强壮的加密密码 。 - 手动测试
在终端执行一次脚本,确保一切正常。/opt/scripts/backup_to_telegram.sh
观察日志输出,并检查您的 Telegram 频道是否收到了备份文件。
- 设置定时任务 (Cron Job)
执行crontab -e
并添加以下一行,以设置每天凌晨 4 点执行备份:0 4 * * * /opt/scripts/backup_to_telegram.sh >> /var/log/backup_telegram.log 2>&1
命令解释 :
>> /var/log/backup_telegram.log 2>&1
会将脚本的所有输出(包括正常信息和错误信息)都追加到日志文件中,这对于日后排查问题至关重要。如果您使用 宝塔面板,可以在“计划任务”中添加一个 Shell 脚本任务,执行周期设置为每天,脚本内容填入
/opt/scripts/backup_to_telegram.sh
即可。
🔧 如何恢复备份
备份的最终目的是恢复。以下是在不同操作系统上恢复数据的指南。
在 Linux / macOS 上恢复
- 下载文件:从 Telegram 下载所有备份文件(单个
.gpg
文件或多个.partXX
文件)到同一目录。 合并文件 (如果被分割):
# 使用通配符自动按顺序合并所有part文件 cat vps_backup_*.part* > backup_merged.gpg
解密文件 :
# 提示输入密码时,输入您在脚本中设置的GPG_PASSPHRASE gpg -o backup.tar.gz -d backup_merged.gpg
- 解压文件 :
tar -zxvf backup.tar.gz
在 Windows 上恢复
- 安装工具 :下载并安装 Gpg4win 和 7-Zip。
- 合并文件 (如果被分割):在文件所在目录打开命令提示符(CMD),执行:
copy /b vps_backup_*.part* backup_merged.gpg
- 解密文件 :右键点击
.gpg
文件,选择GpgEX
或Kleopatra
相关的 "Decrypt" 选项,输入您的加密密码。 - 解压文件 :右键点击解密后得到的
.tar.gz
文件,选择7-Zip
->提取到...
。
恭喜您!现在,您已经拥有了一套强大、可靠且免费的自动化 VPS 备份方案。安心地去创造吧,数据安全已由这套系统稳稳守护!