通过SSH传输的tar加密备份的数据完整性验证方法咨询
通过SSH传输的tar加密备份的数据完整性验证方法咨询
首先得说,你的顾虑非常合理——TCP确实能保证数据包不丢失、顺序正确,但如果连接长时间中断导致传输半途而废,或者远端磁盘出问题(比如空间不足),光靠TCP的可靠性就不够了,而且你没法本地存完整备份,所以得找边传边验证的方案。下面给你几个实用的方法:
方法一:用rsync替代ssh+cat(推荐,自带断点续传+校验)
rsync本身就是为可靠传输文件设计的,支持断点续传,而且传输完成后会自动校验文件完整性。把你的管道改成这样就行:
set -o pipefail # 让管道中任何一步失败都返回错误码 tar \ --create \ ... \ --listed-incremental="${metadata_file}" \ --file - \ "${FILES_TO_BACKUP[@]}" | gpg --encrypt ... --output - | rsync -avP -e ssh --inplace - ${REMOTE_HOST}:${output_file}
关键参数解释:
-a:归档模式,保留文件权限等属性(流式传输下不影响核心功能)-v:显示详细传输信息-P:显示传输进度,同时保留中途中断的部分文件(方便断点续传)-e ssh:指定用ssh作为传输通道--inplace:直接写入目标文件,避免先存临时文件再改名(流式传输场景下必须用这个参数)-:表示从标准输入读取数据流
如果传输中途断开,重新运行这个命令即可,rsync会自动跳过已经传完的部分,不用从头再来。传输完成后,rsync会自动对比校验和,确保文件完整。
方法二:生成校验和实时对比(适合坚持用ssh+cat的场景)
如果不想换rsync,可以在本地生成加密后数据流的校验和,同时把数据传到远端,再让远端计算接收文件的校验和,最后对比两者是否一致:
set -o pipefail # 传输数据的同时,本地生成校验和,远端计算接收后的校验和 tar \ --create \ ... \ --listed-incremental="${metadata_file}" \ --file - \ "${FILES_TO_BACKUP[@]}" | gpg --encrypt ... --output - | tee >(sha256sum > /tmp/local_backup_checksum.txt) | ssh -T ${REMOTE_HOST} "cat > ${output_file}; sha256sum ${output_file} > /tmp/remote_backup_checksum.txt" # 把远端的校验和文件拉回来对比 scp ${REMOTE_HOST}:/tmp/remote_backup_checksum.txt /tmp/ if diff /tmp/local_backup_checksum.txt /tmp/remote_backup_checksum.txt > /dev/null; then echo "备份完整性验证通过!" # 清理临时校验和文件 rm /tmp/local_backup_checksum.txt ssh ${REMOTE_HOST} "rm /tmp/remote_backup_checksum.txt" else echo "备份数据存在差异,已删除远端不完整文件!" ssh ${REMOTE_HOST} "rm ${output_file}" rm /tmp/local_backup_checksum.txt /tmp/remote_backup_checksum.txt fi
说明:
tee会把数据流复制一份到本地的sha256sum进程,完全不影响正常传输到远端- 用sha256sum是因为它的碰撞概率极低,适合大文件的完整性校验
- 对比完成后记得清理临时文件,避免占用不必要的空间
额外的可靠性保障
不管用哪种方法,都建议开启set -o pipefail——默认bash管道的退出码只看最后一个命令的状态,开启这个选项后,只要管道中任何一个命令失败(比如tar打包出错、gpg加密失败、ssh连接中断),整个管道都会返回错误码,你可以根据这个提前判断传输是否异常。
另外,你提到的metadata文件,继续用校验和验证就好,比如:
# 本地生成metadata的校验和 sha256sum "${metadata_file}" > /tmp/metadata_checksum.txt # 复制到远端 scp "${metadata_file}" ${REMOTE_HOST}:${metadata_file_path} # 拉回远端的校验和对比 ssh ${REMOTE_HOST} "sha256sum ${metadata_file_path}" > /tmp/remote_metadata_checksum.txt diff /tmp/metadata_checksum.txt /tmp/remote_metadata_checksum.txt
备注:内容来源于stack exchange,提问作者Felix Schneider
相关产品推荐
相关产品推荐

