想在群晖上给重要数据做自动化冷备份,自带的USB Copy套件可以做到插入移动硬盘后自动开始备份,完成后自动弹出。但这里的弹出只是软件层面的umount,移动硬盘实际还是联机状态,磁盘还是在转,风险在于

  • 勒索病毒会加密所有挂载的硬盘内的数据,同一台机器内数据备份再多份也无法避免
  • 移动硬盘长时间工作影响寿命
  • 电网故障容易造成硬盘损坏
  • USB Copy无法自动重新挂载移动硬盘

想得到的效果

  • 定时打开USB口电源,挂载移动硬盘,开启备份任务
  • 备份完成后自动关闭USB口电源

需要的设备

软件层面无法做到物理层面关闭USB口电源,github上找到了uhubctl这个项目,对于支持的USB HUB,可以物理关闭电源。买到了个支持列表里的HUB,联想Thinkplus 4X90W86497,3口USB3.0+VGA接口

USB Copy套件内备份

  • USB Copy的任务里勾选上“插入USB/SD存储设备时,立即复制数据”和 “复制完成后退出USB/CD存储设备”
  • 在群晖内新建一个定时任务,root权限自动运行如下脚本/volume1/HDD1/usbpower.sh poweron 根据自己的情况修改usb端口
#!/bin/ash

#Author: akbwe, https://akbwe.com/posts/auto-turnoff-usb-power-after-backup-on-synology/
check() {
	if [ -e /dev/usb1 ]; then
		echo "usb device still in use"
	else
		sleep 5
		poweroff
		echo "usb poweroff on $(TZ=Asia/Singapore date)" >> /tmp/usbpower.log
	fi
}

poweroff() {
	synowebapi --exec api=SYNO.Core.ExternalDevice.Storage.USB method=eject dev_id=usb1
	if  mount | grep /dev/usb > /dev/null; then
		echo "usb device still in use"
		exit 1
	fi
	#让移动硬盘进入待机状态,磁盘停转,否则kernel 5.10的bug会自动恢复USB供电,且运行状态的硬盘直接断电容易造成损坏
	echo 0 > "/sys/bus/usb/devices/2-2.3/authorized"
	echo 0 > "/sys/bus/usb/devices/2-2:1.0/authorized"
	sleep 5
	uhubctl -a off -r50
	#取消检查备份是否完成的任务
	sed -i /usbpower.sh/s/^/#/ /etc/crontab
}

poweron() {
	uhubctl -a on
	#通电后禁用然后启用一次USB口,否则系统无法自动挂载设备
	echo 0 > "/sys/bus/usb/devices/2-2/authorized"
	sleep 1
	echo 1 > "/sys/bus/usb/devices/2-2/authorized"
	#备份开始后每分钟检查一次备份是否完成
	sed -i /usbpower.sh/s/#//g /etc/crontab
}

case "$1" in
	check)
		check;;
	poweroff)
		poweroff;;
	poweron)
		poweron;;
	*)
		echo "command: check/poweroff/poweron"
esac

exit 0
  • vi /etc/crontab 新加入一条定时任务,每分钟自动运行。作用是检查备份任务是否已经完成,如果已经完成,USB口关闭电源后此项定时任务会被自动注释掉
*       *       *       *       *       root    /volume1/HDD1/usbpower.sh check

Hyper Backup内备份

  • 在群晖内新建一个定时任务,root权限自动运行如下脚本/volume1/HDD1/usbpower.sh poweron 根据自己的情况修改usb端口
#!/bin/ash

#Author: akbwe, https://akbwe.com/posts/auto-turnoff-usb-power-after-backup-on-synology/
#设置hyper backup任务id,可ssh运行synoschedtask --get命令查看
taskid=1

check() {
	#检查备份是否结束
	if ps aux | grep -v "grep" | grep "img_backup -B  -k $taskid"; then
		echo "hyper backup running now"
	else
		sleep 10
		#等待10秒再检查一次以防万一
		if ps aux | grep -v "grep" | grep "img_backup -B  -k $taskid"; then
			echo "hyper backup running now"
		else
			echo "hyper backup finished"
			poweroff
		fi
	fi
}

poweroff() {
	synowebapi --exec api=SYNO.Core.ExternalDevice.Storage.USB method=eject dev_id=usb1
	sleep 5
	if  mount | grep /dev/usb > /dev/null; then
		echo "usb device still in use"
		exit 1
	fi
	#让移动硬盘进入待机状态,磁盘停转,否则kernel 5.10的bug会自动恢复USB供电,且运行状态的硬盘直接断电容易造成损坏
	echo 0 > "/sys/bus/usb/devices/2-2.3/authorized"
	echo 0 > "/sys/bus/usb/devices/2-2:1.0/authorized"
	sleep 5
	uhubctl -a off -r50
	#取消检查备份是否完成的任务
	sed -i /usbpower.sh/s/^/#/ /etc/crontab
}

poweron() {
	uhubctl -a on
	#通电后禁用然后启用一次USB口,否则系统无法自动挂载设备
	echo 0 > "/sys/bus/usb/devices/2-2/authorized"
	sleep 1
	echo 1 > "/sys/bus/usb/devices/2-2/authorized"
	#等待10秒自动挂载完成后开始备份
	sleep 10
	/var/packages/HyperBackup/target/bin/dsmbackup --backup $taskid
	#备份开始后每分钟检查一次备份是否完成
	sed -i /usbpower.sh/s/#//g /etc/crontab
}

case "$1" in
	check)
		check;;
	poweroff)
		poweroff;;
	poweron)
		poweron;;
	*)
		echo "command: check/poweroff/poweron"
esac

exit 0
  • vi /etc/crontab 新加入一条定时任务,每分钟自动运行。作用是检查备份任务是否已经完成,如果已经完成,USB口关闭电源后此项定时任务会被自动注释掉
*       *       *       *       *       root    /volume1/HDD1/usbpower.sh check

同时使用Hyper Backup和USB Copy自动备份

同时进行两个任务的话硬盘会受不了,所以先进行Hyper Backup备份,完成后再继续使用USB Copy备份,然后自动关闭USB口电源

  • USB Copy的任务需要关闭插入硬盘自动开始备份的选项,同时打开备份完成后弹出硬盘
  • 在群晖内新建一个定时任务,root权限自动运行如下脚本/volume1/HDD1/usbpower.sh poweron 根据自己的情况修改usb端口
#!/bin/ash

#Author: akbwe, https://akbwe.com/posts/auto-turnoff-usb-power-after-backup-on-synology/

#设置任务id,可ssh运行synoschedtask --get命令查看
hyper_taskid=1
usbcopy_taskid=1

check_hyper() {
	#检查Hyper Backup备份是否结束
	if ps aux | grep -v "grep" | grep "img_backup -B  -k $hyper_taskid"; then
		echo "hyper backup running now"
	else
		echo "hyper backup finished"
		#Hyper Back结束后开始USB Copy备份
		/var/packages/USBCopy/target/bin/usb-copy-notifier --execute-task $usbcopy_taskid
		#停止检查Hyper Backup进程,开始检查USB Backup进程
		sed -i /check_hyper/s/^/#/ /etc/crontab
		sed -i /check_usbcopy/s/#//g /etc/crontab
	fi
}

check_usbcopy() {
	if  mount | grep /dev/usb > /dev/null; then
		echo "usb device still in use"
	else
		sleep 5
		#结束备份任务,关闭USB口电源
		poweroff

	fi
}

poweroff() {
	synowebapi --exec api=SYNO.Core.ExternalDevice.Storage.USB method=eject dev_id=usb1
	sleep 5
	if  mount | grep /dev/usb > /dev/null; then
		echo "usb device still in use"
		exit 1
	fi
	#让移动硬盘进入待机状态,磁盘停转,否则kernel 5.10的bug会自动恢复USB供电,且运行状态的硬盘直接断电容易造成损坏
	echo 0 > "/sys/bus/usb/devices/2-2.3/authorized"
	echo 0 > "/sys/bus/usb/devices/2-2:1.0/authorized"
	sleep 5
	uhubctl -a off -r50
	echo "usb poweroff on $(TZ=Asia/Singapore date)" >> /tmp/usbpower.log
	
	#取消所有检查备份是否完成的任务
	sed -i /usbpower.sh/s/^/#/ /etc/crontab
}

poweron() {
	uhubctl -a on
	#通电后禁用然后启用一次USB口,否则系统无法自动挂载设备
	echo 0 > "/sys/bus/usb/devices/2-2/authorized"
	sleep 1
	echo 1 > "/sys/bus/usb/devices/2-2/authorized"
	#等待10秒自动挂载完成后开始Hyper Backup备份
	sleep 10
	/var/packages/HyperBackup/target/bin/dsmbackup --backup $hyper_taskid
	#Hyper Backup备份开始后每分钟检查一次备份是否完成
	sed -i /check_hyper/s/#//g /etc/crontab
}

case "$1" in
	check_usbcopy)
		check_usbcopy;;
	check_hyper)
		check_hyper;;
	poweroff)
		poweroff;;
	poweron)
		poweron;;
	*)
		echo "command: check_hyper/check_hyper/poweroff/poweron"
esac

exit 0
  • vi /etc/crontab 新加入两条定时任务,每分钟自动运行。作用是检查备份任务是否已经完成,如果已经完成,USB口关闭电源后此项定时任务会被自动注释掉
#*      *       *       *       *       root    /volume1/HDD1/usbpower.sh check_usbcopy
#*  	* 	* 	*  	*   root    /volume1/HDD1/usbpower.sh check_hyper