Debian系统数据管理教程
以下是关于在 Debian 系统上管理二进制和文本数据的工具及其相关提示。
10.1. 共享,拷贝和存档
数据的安全和它的受控共享有如下几个方面。
存档文件的建立
远程存储访问
复制
跟踪修改历史
促进数据共享
防止未经授权的文件访问
检测未经授权的文件修改
这些可以通过使用工具集来实现。
存档和压缩工具
复制和同步工具
网络文件系统
移动存储媒介
安全 shell
认证体系
版本控制系统工具
哈希算法和加密工具
10.1.1. 存档和压缩工具
以下是 Debian 系统上可用的存档和压缩工具的预览。
表 10.1. 存档和压缩工具列表
软件包 | 流行度 | 大小 | 扩展名 | 命令 | 描述 |
---|---|---|---|---|---|
tar | V:902, I:999 | 3077 | .tar | tar (1) | 标准的归档工具(默认) |
cpio | V:440, I:998 | 1199 | .cpio | cpio (1) | Unix System V 风格的归档器,与 find (1) 一起使用 |
binutils | V:172, I:629 | 144 | .ar | ar (1) | 创建静态库的归档工具 |
fastjar | V:1, I:13 | 183 | .jar | fastjar (1) | Java 归档工具(类似 zip) |
pax | V:8, I:14 | 170 | .pax | pax (1) | 新的 POSIX 归档工具,介于 tar 和 cpio 之间 |
gzip | V:876, I:999 | 252 | .gz | gzip (1), zcat (1), … | GNU LZ77 压缩工具(默认) |
bzip2 | V:166, I:970 | 112 | .bz2 | bzip2 (1), bzcat (1), … | Burrows-Wheeler block-sorting 压缩工具有着比 gzip (1) 更高的压缩率 (跟 gzip 有着相似的语法但速度比它慢) |
lzma | V:1, I:16 | 149 | .lzma | lzma (1) | LZMA 压缩工具有着比 gzip (1) 更高的压缩率(不推荐) |
xz-utils | V:360, I:980 | 1203 | .xz | xz (1), xzdec (1), … | XZ 压缩工具有着比 bzip2 (1) 更高的压缩率(压缩速度慢于 gzip 但是比 bzip2 快; LZMA 压缩工具的替代品) |
zstd | V:193, I:481 | 2158 | .zstd | zstd (1), zstdcat (1), … | Zstandard 快速无损压缩工具 |
p7zip | V:20, I:463 | 8 | .7z | 7zr (1), p7zip (1) | 有着更高压缩率的 7-zip 文件归档器(LZMA 压缩) |
p7zip-full | V:110, I:480 | 12 | .7z | 7z (1), 7za (1) | 有着更高压缩率的 7-Zip 文件归档器(LZMA 压缩和其他) |
lzop | V:15, I:142 | 164 | .lzo | lzop (1) | LZO 压缩工具有着比 gzip (1) 更高的压缩和解压缩速度 (跟 gzip 有着相似的语法但压缩率比它低) |
zip | V:48, I:380 | 616 | .zip | zip (1) | InfoZip:DOS 归档器和压缩工具 |
unzip | V:105, I:771 | 379 | .zip | unzip (1) | InfoZIP:DOS 解档器和解压缩工具 |
gzipped
tar
(1) 归档器用于扩展名是 ".tgz
" 或者 ".tar.gz
" 的文件。xz-compressed
tar
(1) 归档器用于扩展名是 ".txz
" 或者 ".tar.xz
" 的文件。FOSS 工具,例如
tar
(1),中的主流压缩方法已经按如下所示的迁移:gzip
→bzip2
→xz
cp
(1),scp
(1) 和tar
(1) 工具可能并不适用于一些特殊的文件。cpio
(1) 工具的适用范围是最广的。cpio
(1) 是被设计为与find
(1) 和其它命令一起使用,适合于创建备份脚本的场景,因此,脚本的文件选择部分能够被独立测试。Libreoffice 数据文件的内部结构是 "
.jar
" 文件,它也可以使用unzip
工具来打开。事实上跨平台支持最好的存档工具是
zip
。按照“zip -rX
”的方式调用可以获得最大的兼容性。如果最大文件大小需要纳入考虑范围,请同时配合“-s
”选项使用。
10.1.2. 复制和同步工具
以下是 Debian 系统上的可用的简单复制和备份工具的预览。
表 10.2. 复制和同步工具列表
软件包 | 流行度 | 大小 | 工具 | 功能 |
---|---|---|---|---|
coreutils | V:880, I:999 | 18307 | GNU cp | 复制本地文件和目录("-a" 参数实现递归) |
openssh-client | V:866, I:996 | 4959 | scp | 复制远端文件和目录(客户端,"-r " 参数实现递归) |
openssh-server | V:730, I:814 | 1804 | sshd | 复制远端文件和目录(远程服务器) |
rsync | V:246, I:552 | 781 | 单向远程同步和备份 | |
unison | V:3, I:15 | 14 | 双向远程同步和备份 |
在复制文件的时候, rsync
(8) 比其他工具提供了更多的特性。
差分传输算法只会发送源文件与已存在的目标文件之间的差异部分
快速检查算法 (默认) 会查找大小或者最后的修改时间有变化的文件
"
--exclude
" 和 "--exclude-from
" 选项类似于tar
(1)在源目录中添加反斜杠的语法能够避免在目标文件中创建额外的目录级别。
10.1.3. 归档语法
以下是用不同的工具压缩和解压缩整个 "./source
" 目录中的内容。
GNU tar
(1):
$ tar -cvJf archive.tar.xz ./source $ tar -xvJf archive.tar.xz
或者,如下所示。
$ find ./source -xdev -print0 | tar -cvJf archive.tar.xz --null -T -
cpio
(1):
$ find ./source -xdev -print0 | cpio -ov --null > archive.cpio; xz archive.cpio $ zcat archive.cpio.xz | cpio -i
10.1.4. 复制语法
如下是用不同的工具复制整个 "./source
" 目录中的内容。
本地复制: "
./source
" 目录 → "/dest
" 目录远程复制:本地主机上的 "
./source" 目录
→ "user@host.dom
" 主机上的 "/dest
" 目录
rsync
(8):
# cd ./source; rsync -aHAXSv . /dest # cd ./source; rsync -aHAXSv . user@host.dom:/dest
你能够选择使用“源目录上的反斜杠”语法。
# rsync -aHAXSv ./source/ /dest # rsync -aHAXSv ./source/ user@host.dom:/dest
或者,如下所示。
# cd ./source; find . -print0 | rsync -aHAXSv0 --files-from=- . /dest # cd ./source; find . -print0 | rsync -aHAXSv0 --files-from=- . user@host.dom:/dest
GNU cp
(1) 和 openSSH scp
(1):
# cd ./source; cp -a . /dest # cd ./source; scp -pr . user@host.dom:/dest
GNU tar
(1):
# (cd ./source && tar cf - . ) | (cd /dest && tar xvfp - ) # (cd ./source && tar cf - . ) | ssh user@host.dom '(cd /dest && tar xvfp - )'
cpio
(1):
# cd ./source; find . -print0 | cpio -pvdm --null --sparse /dest
你能够在所有包含 ".
" 的例子里用 "foo
" 替代 ".
",这样就可以从 "./source/foo
" 目录复制文件到 "/dest/foo
" 目录。
在所有包含 ".
" 的列子里,你能够使用绝对路径 "/path/to/source/foo
" 来代替 ".
",这样可以去掉 "cd ./source;
". 如下所示,这些文件会根据工具的不同,拷贝到不同的位置。
"
/dest/foo
":rsync
(8), GNUcp
(1), 和scp
(1)"
/dest/path/to/source/foo
": GNUtar
(1), 和cpio
(1)
10.1.5. 查找文件的语法
find
(1) 被用作从归档中筛选文件也被用作拷贝命令 (参见第 10.1.3 节 “归档语法”和第 10.1.4 节 “复制语法”) 或者用于 xargs
(1) (参见第 9.4.9 节 “使用文件循环来重复一个命令”)。通过 find 的命令行参数能够使其功能得到加强。
以下是 find
(1)基本语法的总结。
find 条件参数的运算规则是从左到右。
一旦输出是确定的,那么运算就会停止。
“逻辑 OR" (由条件之间的 "
-o
" 参数指定的)优先级低于 "逻辑 AND" (由 "-a
" 参数指定或者条件之间没有任何参数)。”逻辑 NOT" (由条件前面的 "
!
" 指定) 优先级高于 “逻辑 AND”。"
-prune
" 总是返回逻辑 TRUE 并且如果这个目录是存在的,将会搜索除这个目录以外的文件。"
-name
" 选项匹配带有 shell 通配符 (参见第 1.5.6 节 “Shell 通配符”) 的文件名但也匹配带有类似 "*
" 和 "?
" 元字符的.
"。(新的 POSIX 特性)"
-regex
" 匹配整个文件路径,默认采用 emacs 风格的 BRE (参见第 1.6.2 节 “正则表达式”)。"
-size
" 根据文件大小来匹配 (值前面带有 "+
" 号匹配更大的文件,值前面带有 "-
" 号匹配更小的文件)"
-newer
" 参数匹配比参数名中指定的文件还要新的文件。"
-print0
" 参数总是返回逻辑 TRUE 并将完整文件名 (null terminated) 打印到标准输出设备上。
如下是 find
(1) 语法格式。
# find /path/to \ -xdev -regextype posix-extended \ -type f -regex ".*\.cpio|.*~" -prune -o \ -type d -regex ".*/\.git" -prune -o \ -type f -size +99M -prune -o \ -type f -newer /path/to/timestamp -print0
这些命令会执行如下动作。
查找 "
/path/to
" 下的所有文件限定全局查找的文件系统并且使用的是 ERE (参见第 1.6.2 节 “正则表达式”)
通过停止处理的方式来排除匹配 "
.*\.cpio
" 或 ".*~
" 正则表达式的文件通过停止处理的方式来排除匹配 "
.*/\.git
" 正则表达式的目录通过停止处理的方式来排除比 99MB (1048576字节单元) 更大的文件
显示文件名,满足以上搜索条件并且比 "
/path/to/timestamp
" 新的文件
请留心以上例子中的 "-prune -o
" 排除文件的习惯用法。
10.1.6. 归档媒体
为重要的数据存档寻找 存储设备 时,你应该注意它们的局限性。对于小型的个人数据备份,我使用品牌公司的 CD-R 和 DVD-R 然后把它放在阴凉、干燥、清洁的地方。(专业的一般使用磁带存档介质)
网上(主要是来源于供应商信息)可以查看存储介质的最大使用寿命。
大于100年:用墨水的无酸纸
100年:光盘存储(CD/DVD,CD/DVD-R)
30年:磁带存储(磁带,软盘)
20年:相变光盘存储(CD-RW)
这不包括由于人为导致的机械故障等等。
网上(主要来源于供应商信息)可以查看存储介质的最大的写次数。
大于250,000次:硬盘驱动器
大于10,000次:闪存
1,000次:CD/DVD-RW
1次:CD/DVD-R,纸
10.1.7. 可移动存储设备
可移动存储设备可能是以下的任何一种。
USB 闪存盘
硬盘驱动器
光盘驱动器
数码相机
数字音乐播放器
它们可以通过以下的方式来进行连接。
USB
IEEE 1394 / FireWire
PC 卡
像 GNOME 和 KDE 这样的现代桌面环境能够在 "/etc/fstab
" 文件中没有匹配条目的时候,自动挂载这些可移动设备。
udisks2
包提供了守护进程和相关的实用程序来挂载和卸载这些设备。D-bus 创建事件来触发自动处理。
PolicyKit 提供了所需的特权。
现代桌面环境下的挂载点被选为 "/media/username/disk_label
",它可以被如下所示的来定制。
FAT 格式的文件系统使用
mlabel
(1) 命令ISO9660 文件系统使用带有 "
-V
" 选项的genisoimage
(1) 命令ext2/ext3/ext4 文件系统使用带有 "
-L
" 选项的tune2fs
(1) 命令
10.1.8. 选择用于分享数据的文件系统
当你通过可移动存储设备与其他系统分享数据的时候,你应该先把它格式化为被两种操作系统都支持的通用的 文件系统。下面是文件系统的列表。
表 10.3. 典型使用场景下可移动存储设备可选择的文件系统列表
文件系统名 | 典型使用场景 |
---|---|
FAT12 | 软盘(<32MiB)上跨平台的数据分享 |
FAT16 | 在小硬盘(<2GiB)上的跨平台的数据分享 |
FAT32 | 在大硬盘(<8TiB,被 MS Windows95 OSR2 以上的操作系统所支持) 上的跨平台的数据分享 |
exFAT | 在大硬盘类设备上跨平台共享数据(<512TiB,被 WindowsXP, Mac OS X Snow Leopard 10.6.5 和 Linux 内核 5.4 版本以上的操作系统所支持) |
NTFS | 在大硬盘类设备上的跨平台共享数据 (在 MS Windows NT 和后续版本原生支持;在 Linux 上,通过使用 FUSE 的 NTFS-3G 支持。) |
ISO9660 | 在 CD-R 和 DVD+/-R 上的跨平台的静态数据分享 |
UDF | CD-R 和 DVD+/-R (新)上的增量数据写入 |
MINIX | 软盘上磁盘空间高利用率的 unix 文件数据存储 |
ext2 | 在装有老旧 linux 系统的硬盘上的数据分享 |
ext3 | 在装有老旧 linux 系统的硬盘上的数据分享 |
ext4 | 在装有较新的 linux 系统的硬盘上的数据分享 |
btrfs | 使用只读快照在装有较新的 Linux 系统的硬盘上共享数据 |
FAT 文件系统被绝大多数的现代操作系统支持,它对于通过可移动硬盘进行的数据交换是非常有用的。
当格式化像装有 FAT 文件系统的跨平台数据共享的可移动设备时,以下应该是保险的选择。
用
fdisk
(8),cfdisk
(8) 或者parted
(8) 命令(参见第 9.6.2 节 “硬盘分区配置”)把它们格式化为单个的主分区并对把它做如下标记。标记小于 2GB 的 FAT 设备为 字符"6"。
标记更大的 FAT32 设备为字符 "c"。
如下所示是用
mkfs.vfat
(8) 命令格式化主分区的。它的设备名字,例如 "
/dev/sda1
" 用于 FAT16 设备明确的选项和它的设备名,例如 "
-F 32 /dev/sda1
" 用于 FAT32 设备
当使用 FAT 或 ISO9660 文件系统分享数据时,如下是需要注意的安全事项。
用
tar
(1),或cpio
(1)命令压缩文件,目地是为了保留文件名,符号链接,原始的文件权限和文件所有者信息。用
split
(1) 命令把压缩文件分解成若干小于 2GiB的小文件,使其免受文件大小限制。加密压缩文件保护其内容免受未经授权的访问。
![]() | 注意 |
---|---|
因为 FAT 文件系统的设计,最大的文件大小为 |
10.1.9. 网络上的数据分享
当使用网络来分享数据的时候,你应该使用通用的服务。这里有一些提示。
表 10.4. 典型使用场景下可选择的网络服务列表
网络服务 | 典型使用场景描述 |
---|---|
SMB/CIFS 用 Samba 挂载网络文件系统 | 通过 “Microsoft Windows 网络” 分享文件,参见 smb.conf (5) 和 官方 Samba 3.x.x 指导和参考手册(The Official Samba 3.x.x HOWTO and Reference Guide) 或 samba-doc 软件包 |
NFS 用 Linux 内核挂载网络文件系统 | 通过 “Unix/Linux 网络" 分享文件,参见 exports (5) 和 Linux NFS-HOWTO |
HTTP 服务 | 在 web 服务器/客户端之间分享文件 |
HTTPS 服务 | 在有加密的安全套接层 (SSL) 或者安全传输层 (TLS) 的网络服务器/客户端中分享文件 |
FTP 服务 | 在 FTP 服务器/客户端之间分享文件 |
尽管对于文件分享来说,通过网络挂载文件系统和传输文件是相当方便的,但这可能是不安全的。它们的网络连接必须通过如下所示的加强安全性。
用 SSL/TLS 加密
建立 SSH 通道
建立 VPN 通道
网络之间需要有安全的防火墙
参见 第 6.5 节 “其它网络应用服务” 和 第 6.6 节 “其它网络应用客户端”。
10.2. 备份和恢复
我们都熟知计算机有时会出问题,或者由于人为的错误导致系统和数据损坏。备份和恢复操作是成功的系统管理中非常重要的一部分。可能有一天你的电脑就会出问题。
10.2.1. 备份和恢复策略
有 3 个关键的因素决定实际的备份和恢复策略。
知道要备份和恢复什么。
用户进程的 Cron 工作,文件在 "
/var/spool/cron/crontabs
" 目录,并且重启cron
(8)。参见第 9.4.14 节 “定时任务安排”来获得关于cron
(8) 和crontab
(1) 的信息。用户进程的 Systemd 计时器工作:文件在 "
~/.config/systemd/user
" 目录。参见systemd.timer
(5) 和systemd.service
(5)。用户进程的自动启动工作:文件在 "
~/.config/autostart
" 目录。参见 Desktop Application Autostart Specification。你自己创建的数据文件:在 "
~/
" 下的数据你使用的应用程序创建的数据文件:在 "
/var/
" 下的数据(除了 "/var/cache/
","/var/run/
" 和 "/var/tmp/
")系统配置文件:在 "
/etc/
” 下的数据本地程序:在 "
/usr/local/
" 或 "/opt/
" 下的数据系统安装信息:关键步骤 (分区,...) 的纯文本备忘录
验证数据结果:通过实验性的恢复操作来预先验证
知道怎样去备份和恢复。
安全的数据存储:保护其免于覆盖和系统故障
经常备份:有计划的备份
冗余备份:数据镜像
傻瓜式操作:单个简单命令备份
评估涉及的风险和成本。
使用 cron 任务或者 systemd 计时器任务来自动化调度备份工作
硬件(特别是硬盘)将会损坏
文件系统可能会损坏,里面的数据可能被丢失
对违规安全访问而言,远程存储系统不能够被信任
弱的密码保护能够被轻松的破解
文件权限系统可以被破解
敏感的身份数据,比如 "
/etc/ssh/ssh_host_*_key
", "~/.gnupg/*
", "~/.ssh/*
", "~/.local/share/keyrings/*
", "/etc/passwd
", "/etc/shadow
", "popularity-contest.conf
", "/etc/ppp/pap-secrets
", and "/etc/exim4/passwd.client
" 应当使用加密备份。[5] (参见 第 9.9 节 “数据加密提示”。)即使在信任的系统上,也不能够硬编码系统登录密码或者加密密码到任何脚本里面。(参见 第 10.3.6 节 “密码密钥环”。)
数据至少是应该在不同的磁盘分区上,最好是在不同的磁盘和机器上,来承受文件系统发生的损坏。重要数据最好存储在一个只读文件系统上。[4]
数据丢失的风险
数据非法访问的风险
数据丢失的方式及其可能性
备份所需的资源:人力,硬件,软件,…
![]() | 提示 |
---|---|
你能够用 " |
10.2.2. 实用备份套件
以下是 Debian 系统上值得注意的实用备份程序套件的列表。
表 10.5. 实用备份程序套件列表
软件包 | 流行度 | 大小 | 说明 |
---|---|---|---|
bacula-common | V:8, I:10 | 2305 | Bacula: 网络数据备份,恢复和核查-常见的支持文件 |
bacula-client | V:0, I:2 | 178 | Bacula: 网络数据备份,恢复和核查-客户端元软件包 |
bacula-console | V:0, I:3 | 112 | Bacula: 网络数据备份,恢复和核查-文本终端 |
bacula-server | I:0 | 178 | Bacula: 网络数据备份,恢复和核查-服务器端元软件包 |
amanda-common | V:0, I:2 | 9897 | Amanda: 马里兰大学开发的高级自动化网络磁盘归档器(库) |
amanda-client | V:0, I:2 | 1092 | Amanda: 马里兰大学开发的高级自动化网络磁盘归档器(客户端) |
amanda-server | V:0, I:0 | 1077 | Amanda: 马里兰大学开发的高级自动化网络磁盘归档器(服务器端) |
backuppc | V:2, I:2 | 3178 | BackupPC 是用于备份 PC 机数据(基于磁盘)的高性能的企业级工具 |
duplicity | V:30, I:50 | 1973 | (远程) 增量备份 |
deja-dup | V:28, I:44 | 4992 | duplicity 的 GUI(图形用户界面)前端 |
borgbackup | V:11, I:20 | 3301 | (远程) 去重备份 |
borgmatic | V:2, I:3 | 509 | borgbackup 备份软件的辅助软件 |
rdiff-backup | V:4, I:10 | 1203 | (远程) 增量备份 |
restic | V:2, I:6 | 21385 | (远程) 增量备份 |
backupninja | V:2, I:3 | 360 | 轻量的可扩展的 meta-backup 系统 |
flexbackup | V:0, I:0 | 243 | (远程) 增量备份 |
slbackup | V:0, I:0 | 151 | (远程) 增量备份 |
backup-manager | V:0, I:1 | 566 | 命令行备份工具 |
backup2l | V:0, I:0 | 115 | 用于可挂载媒介 (基于磁盘的) 的低维护的备份/恢复工具 |
备份工具有各自的专用的用途。
Mondo Rescue 是一个备份系统,它能够方便的从备份 CD/DVD 等设备中快速恢复整个系统,而不需要经过常规的系统安装过程。
Bacula,Amanda 和 BackupPC 是全功能的备份实用套件,主要用于联网的定期备份。
Duplicity 和 Borg 是简单的备份工具用于典型的工作站。
10.2.3. 备份技巧
对于一个个人工作站,为服务器环境设计的全功能备份套件工具也行不是最合适的。与此同时,已有的用于工作站的备份工具有一些不足。
这里有一些技巧让备份更加容易,只需用户做最小的工作。这些技巧可以同任意备份工具一起使用。
出于演示的目的,让我们假设基本用户和组名为 penguin
,创建一个备份和快照脚本例子"/usr/local/bin/bkss.sh
":
#!/bin/sh -e SRC="$1" # source data path DSTFS="$2" # backup destination filesystem path DSTSV="$3" # backup destination subvolume name DSTSS="${DSTFS}/${DSTSV}-snapshot" # snapshot destination path if [ "$(stat -f -c %T "$DSTFS")" != "btrfs" ]; then echo "E: $DESTFS needs to be formatted to btrfs" >&2 ; exit 1 fi MSGID=$(notify-send -p "bkup.sh $DSTSV" "in progress ...") if [ ! -d "$DSTFS/$DSTSV" ]; then btrfs subvolume create "$DSTFS/$DSTSV" mkdir -p "$DSTSS" fi rsync -aHxS --delete --mkpath "${SRC}/" "${DSTFS}/${DSTSV}" btrfs subvolume snapshot -r "${DSTFS}/${DSTSV}" ${DSTSS}/$(date -u --iso=min) notify-send -r "$MSGID" "bkup.sh $DSTSV" "finished!"
这里,只使用基本工具 rsync
(1)来帮助备份,存储空间使用 Btrfs 来高效利用。
10.2.3.1. GUI(图形用户界面)备份
这里是一个创建单击 GUI(图形用户界面)图标备份的例子。
准备一个 USB 存储设备用来备份。
格式化 USB 存储设备为一个分区,使用 btrfs 文件系统,卷标名为"
BKUP
"。这个 U 盘也能够加密 (参见 第 9.9.1 节 “使用 dm-crypt/LUKS 加密移动磁盘”)。把这个插入你的系统。桌面系统将自动挂载它到 "
/media/penguin/BKUP
"。执行"
sudo chown penguin:penguin /media/penguin/BKUP
",让它可以由用户写。创建如下的"
~/.local/share/applications/BKUP.desktop
"文件,按照 第 9.4.10 节 “从 GUI 启动一个程序” 里写的技术:[Desktop Entry] Name=bkss Comment=Backup and snapshot of ~/Documents Exec=/usr/local/bin/bkss.sh /home/penguin/Documents /media/penguin/BKUP Documents Type=Application
对于每一次图标单击,你的数据从"~/Documents
"备份到 USB 存储设备,并创建了一个只读快照。
10.2.3.2. 挂载事件触发的备份
这里是一个由挂载事件触发的自动备份例子。
按 第 10.2.3.1 节 “GUI(图形用户界面)备份” 的方式准备一个 USB 存储设备用于备份。
创建一个如下的 systemd 服务单元文件"
~/.config/systemd/user/back-BKUP.service
":[Unit] Description=USB Disk backup Requires=media-%u-BKUP.mount After=media-%u-BKUP.mount [Service] ExecStart=/usr/local/bin/bkss.sh %h/Documents /media/%u/BKUP Documents StandardOutput=append:%h/.cache/systemd-snap.log StandardError=append:%h/.cache/systemd-snap.log [Install] WantedBy=media-%u-BKUP.mount
用下面的方式启用这个 systemd 单元配置:
$ systemctl --user enable bkup-BKUP.service
对于每一次挂载事件,你的数据从"~/Documents
"备份到 USB 存储设备,并创建了一个只读快照。
这里,当前 systemd 在内存中的 systemd 挂载单元的名字,用户使用 "systemctl --user list-units --type=mount
" 来调用服务管理器来查询。
10.2.3.3. 时间事件触发的备份
这里是一个由时间事件触发的自动备份例子。
按 第 10.2.3.1 节 “GUI(图形用户界面)备份” 的方式准备一个 USB 存储设备用于备份。
创建一个如下的 systemd 时间单元文件"
~/.config/systemd/user/snap-Documents.timer
":[Unit] Description=Run btrfs subvolume snapshot on timer Documentation=man:btrfs(1) [Timer] OnStartupSec=30 OnUnitInactiveSec=900 [Install] WantedBy=timers.target
创建一个如下的 systemd 服务单元文件"
~/.config/systemd/user/snap-Documents.service
":[Unit] Description=Run btrfs subvolume snapshot Documentation=man:btrfs(1) [Service] Type=oneshot Nice=15 ExecStart=/usr/local/bin/bkss.sh %h/Documents /media/%u/BKUP Documents IOSchedulingClass=idle CPUSchedulingPolicy=idle StandardOutput=append:%h/.cache/systemd-snap.log StandardError=append:%h/.cache/systemd-snap.log
用下面的方式启用这个 systemd 单元配置:
$ systemctl --user enable snap-Documents.timer
对于每一次时间事件,你的数据从"~/Documents
"备份到 USB 存储设备,并创建了一个只读快照。
这里,当前 systemd 在内存中的 systemd 用户时间单元的名字,使用 "systemctl --user list-units --type=timer
" 来调用服务管理器来查询。
对于现在的桌面系统,这个 systemd 方案,比起传统的 Unix at
(1)、cron
(8) 或 anacron
方式,能够提供更精致的细粒度控制。
10.3. 数据安全基础
数据安全基础设施是数据加密,讯息摘要和签名工具的结合。
表 10.6. 数据安全基础工具列表
软件包 | 流行度 | 大小 | 命令 | 说明 |
---|---|---|---|---|
gnupg | V:554, I:906 | 885 | gpg (1) | GNU 隐私卫士 - OpenPGP 加密和签名工具 |
gpgv | V:893, I:999 | 922 | gpgv (1) | GNU 隐私卫士 - 签名验证工具 |
paperkey | V:1, I:14 | 58 | paperkey (1) | 从 OpenPGP 私钥里面,仅仅导出私密信息 |
cryptsetup | V:19, I:79 | 417 | cryptsetup (8), … | dm-crypt 块设备加密支持 LUKS 工具 |
coreutils | V:880, I:999 | 18307 | md5sum (1) | 计算与校验 MD5 讯息摘要 |
coreutils | V:880, I:999 | 18307 | sha1sum (1) | 计算与校验 SHA1 讯息摘要 |
openssl | V:841, I:995 | 2111 | openssl (1ssl) | 使用 "openssl dgst " (OpenSSL)计算信息摘要 |
libsecret-tools | V:0, I:10 | 41 | secret-tool (1) | 存储和取回密码 (CLI) |
seahorse | V:80, I:269 | 7987 | seahorse (1) | 密钥管理工具(GNOME) |
参见 第 9.9 节 “数据加密提示” 的 dm-crypt 和 fscrypt,它们通过 Linux 内核模块实现了自动数据加密架构。
10.3.1. GnuPG 密钥管理
如下是 GNU 隐私卫士 基本的密钥管理命令。
表 10.7. GNU 隐私卫士密钥管理命令的列表
命令 | 说明 |
---|---|
gpg --gen-key | 生成一副新的密钥对 |
gpg --gen-revoke my_user_ID | 生成 my_user_ID 的一份吊销证书 |
gpg --edit-key user_ID | 交互式的编辑密钥,输入 "help" 来获得帮助信息 |
gpg -o file --export | 把所有的密钥输出到文件 |
gpg --import file | 从文件导入密钥 |
gpg --send-keys user_ID | 发送 user_ID 的公钥到公钥服务器 |
gpg --recv-keys user_ID | 从公钥服务器下载 user_ID 的公钥 |
gpg --list-keys user_ID | 列出 user_ID 的所有密钥 |
gpg --list-sigs user_ID | 列出 user_ID 的签字 |
gpg --check-sigs user_ID | 检查 user_ID 密钥签字 |
gpg --fingerprint user_ID | 检查 user_ID 的指纹 |
gpg --refresh-keys | 更新本地密钥 |
信任码含义.
表 10.8. 信任码含义列表
代码 | 信任描述 |
---|---|
- | 没有所有者信任签名/没有计算 |
e | 信任计算失败 |
q | 没有足够的信息用于计算 |
n | 从不信任这个键 |
m | 最低限度的信任 |
f | 完全信任 |
u | 最终信任 |
如下命令上传我的 "1DD8D791
" 公钥到主流的公钥服务器 "hkp://keys.gnupg.net
"。
$ gpg --keyserver hkp://keys.gnupg.net --send-keys 1DD8D791
默认良好的公钥服务器在 "~/.gnupg/gpg.conf
" (旧的位置在 "~/.gnupg/options
")文件中设置,此文件包含了以下信息。
keyserver hkp://keys.gnupg.net
从钥匙服务器获取无名钥匙。
$ gpg --list-sigs --with-colons | grep '^sig.*\[User ID not found\]' |\ cut -d ':' -f 5| sort | uniq | xargs gpg --recv-keys
有一个错误在 OpenPGP 公钥服务器 (先前的版本 0.9.6),会将键中断为 2 个以上的子键。新的 gnupg
(>1.2.1-2) 软件包能够处理这些中断的子键。参见 gpg
(1) 下的 "--repair-pks-subkey-bug
" 选项.
10.3.2. 在文件上使用 GnuPG
这里有一些在文件上使用 GNU 隐私卫士 命令的例子。
表 10.9. 在文件上使用的 GNU 隐私卫士的命令列表
命令 | 说明 |
---|---|
gpg -a -s file | ASCII 封装的签名文件 file.asc |
gpg --armor --sign file | 同上 |
gpg --clearsign file | 生成明文签字信息 |
gpg --clearsign file|mail foo@example.org | 发送一份明文签字到 foo@example.org |
gpg --clearsign --not-dash-escaped patchfile | 明文签名的补丁文件 |
gpg --verify file | 验证明文文件 |
gpg -o file.sig -b file | 生成一份分离的签字 |
gpg -o file.sig --detach-sign file | 同上 |
gpg --verify file.sig file | 使用 file.sig 验证文件 |
gpg -o crypt_file.gpg -r name -e file | 公钥加密,从文件里面获取名字,生成二进制的 crypt_file.gpg |
gpg -o crypt_file.gpg --recipient name --encrypt file | 同上 |
gpg -o crypt_file.asc -a -r name -e file | 公钥加密,从文件中获取名字,生成 ASCII 封装的 crypt_file.asc |
gpg -o crypt_file.gpg -c file | 将文件对称加密到 crypt_file.gpg |
gpg -o crypt_file.gpg --symmetric file | 同上 |
gpg -o crypt_file.asc -a -c file | 对称加密,从文件到 ASCII 封装的 crypt_file.asc |
gpg -o file -d crypt_file.gpg -r name | 解密 |
gpg -o file --decrypt crypt_file.gpg | 同上 |
10.3.3. 在 Mutt 中使用 GnuPG
增加下面内容到 "~/.muttrc
",在自动启动时,避免一个慢的 GnuPG,在索引菜单中按 "S
" 来允许它使用。
macro index S ":toggle pgp_verify_sig\n" set pgp_verify_sig=no
10.3.4. 在 Vim 中使用 GnuPG
gnupg
插件可以让你对扩展名为 ".gpg
", ".asc
", 和 ".pgp
"的文件可靠的运行 GnuPG。[6]
$ sudo aptitude install vim-scripts $ echo "packadd! gnupg" >> ~/.vim/vimrc
10.3.5. MD5 校验和
md5sum
(1) 提供了制作摘要文件的一个工具,它使用 rfc1321 里的方式制作摘要文件.
$ md5sum foo bar >baz.md5 $ cat baz.md5 d3b07384d113edec49eaa6238ad5ff00 foo c157a79031e1c40f85931829bc5fc552 bar $ md5sum -c baz.md5 foo: OK bar: OK
10.3.6. 密码密钥环
在 GNOME 系统,GUI(图形用户界面)工具 seahorse
(1) 管理密码,安全的在密钥环 ~/.local/share/keyrings/*
里面保存它们。
secret-tool
(1) 能够从命令行存储密码到钥匙环。
让我们存储 LUKS/dm-crypt 加密磁盘镜像用到的密码
$ secret-tool store --label='LUKS passphrase for disk.img' LUKS my_disk.img Password: ********
这个存储的密码能够被获取并给到其它程序,比如 cryptsetup
(8)。
$ secret-tool lookup LUKS my_disk.img | \ cryptsetup open disk.img disk_img --type luks --keyring - $ sudo mount /dev/mapper/disk_img /mnt
10.4. 源代码合并工具
这里有许多源代码合并工具。如下的是我感兴趣的工具。
表 10.10. 源代码合并工具列表
软件包 | 流行度 | 大小 | 命令 | 说明 |
---|---|---|---|---|
patch | V:97, I:700 | 248 | patch (1) | 给原文件打补丁 |
vim | V:95, I:369 | 3743 | vimdiff (1) | 在 vim 中并排比较两个文件 |
imediff | V:0, I:0 | 200 | imediff (1) | 全屏交互式两路/三路合并工具 |
meld | V:7, I:30 | 3536 | meld (1) | 比较和移植文件(GTK) |
wiggle | V:0, I:0 | 175 | wiggle (1) | 应用被拒绝的补丁 |
diffutils | V:862, I:996 | 1735 | diff (1) | 逐行比较两个文件 |
diffutils | V:862, I:996 | 1735 | diff3 (1) | 逐行比较和合并三个文件 |
quilt | V:2, I:22 | 871 | quilt (1) | 管理系列补丁 |
wdiff | V:7, I:51 | 648 | wdiff (1) | 在文本文件中,显示单词的不同 |
diffstat | V:13, I:121 | 74 | diffstat (1) | 通过 diff 生成一个改变柱状图 |
patchutils | V:16, I:119 | 232 | combinediff (1) | 从两个增量补丁创建一个积累补丁 |
patchutils | V:16, I:119 | 232 | dehtmldiff (1) | 从一个 HTML 页面提取出一个 diff |
patchutils | V:16, I:119 | 232 | filterdiff (1) | 从一个 diff 文件里面提取或者排除 diff 文件 |
patchutils | V:16, I:119 | 232 | fixcvsdiff (1) | 修复由 CVS patch (1) 错误创建的 diff 文件 |
patchutils | V:16, I:119 | 232 | flipdiff (1) | 交换两个补丁的顺序 |
patchutils | V:16, I:119 | 232 | grepdiff (1) | 显示哪些文件是由匹配正则表达式的补丁修改 |
patchutils | V:16, I:119 | 232 | interdiff (1) | 显示在两个统一格式 diff 文件(基于同一个文件的两个不同 diff 文件)之间的差异 |
patchutils | V:16, I:119 | 232 | lsdiff (1) | 显示哪些文件由补丁修改 |
patchutils | V:16, I:119 | 232 | recountdiff (1) | 重新计算通用内容 diff 文件的数量和偏移 |
patchutils | V:16, I:119 | 232 | rediff (1) | 修复手工编辑 diff 文件的数量和偏移 |
patchutils | V:16, I:119 | 232 | splitdiff (1) | 隔离出增量补丁 |
patchutils | V:16, I:119 | 232 | unwrapdiff (1) | 识别已经被分词的补丁 |
dirdiff | V:0, I:1 | 167 | dirdiff (1) | 显示目录树之间的不同并移植改变 |
docdiff | V:0, I:0 | 553 | docdiff (1) | 逐词逐字地比较两个文件 |
makepatch | V:0, I:0 | 100 | makepatch (1) | 生成扩展补丁文件 |
makepatch | V:0, I:0 | 100 | applypatch (1) | 应用扩展补丁文件 |
10.4.1. 从源代码文件导出差异
下面的操作,导出两个源文件的不同,并根据文件的位置,创建通用 diff 文件"file.patch0
" 或 "file.patch1
".
$ diff -u file.old file.new > file.patch0 $ diff -u old/file new/file > file.patch1
10.4.2. 源代码文件移植更新
diff 文件(通常被叫作 patch 补丁文件),用于发送一个程序更新。通过下面的方式,接收到的部分,应用这个更新到其它文件。
$ patch -p0 file < file.patch0 $ patch -p1 file < file.patch1
10.4.3. 交互式移植
如果一个源代码,你有两个版本,你可以通过下面的方式,使用 imediff
(1) 执行两方交互式移植。
$ imediff -o file.merged file.old file.new
如果一个源代码,你有三个版本,你可以通过下面的方式,使用 imediff
(1) 执行交互式三方移植。
$ imediff -o file.merged file.yours file.base file.theirs
10.5. Git
Git 是这些天选择的用于 版本控制系统 version control system (VCS) 的工具,因为 Git 能够同时在本地和远程源代码管理上,做任何事情。
通过 Debian Salsa 服务,Debian 能够提供免费的 Git 服务。在 https://wiki.debian.org/Salsa 能找到它的说明文档。
下面是一些 Git 相关软件包。
表 10.11. git 相关包和命令列表
软件包 | 流行度 | 大小 | 命令 | 说明 |
---|---|---|---|---|
git | V:351, I:549 | 46734 | git (7) | Git 快速、可扩展、分布式的版本控制系统 |
gitk | V:5, I:33 | 1838 | gitk (1) | 有历史功能的 Git 图形仓库浏览器 |
git-gui | V:1, I:18 | 2429 | git-gui (1) | Git 图形界面(无历史功能) |
git-email | V:0, I:10 | 1087 | git-send-email (1) | 从 Git 用电子邮件发送收集到的补丁 |
git-buildpackage | V:1, I:9 | 1988 | git-buildpackage (1) | 用 Git 自动制作 Debian 包 |
dgit | V:0, I:1 | 473 | dgit (1) | Debian 档案库的 git 交互操作 |
imediff | V:0, I:0 | 200 | git-ime (1) | 交互式的分开 git 提交的辅助工具 |
stgit | V:0, I:0 | 601 | stg (1) | 封装的 git (Python) |
git-doc | I:12 | 13208 | N/A | Git 官方文档 |
gitmagic | I:0 | 721 | N/A | "Git 魔术",易于理解的 Git 手册 |
10.5.1. 配置 Git 客户端
你可以在 "~/.gitconfig
" 里面设置几个 Git 接下来需要使用的全局配置,比如说你的名字和电子邮件地址。
$ git config --global user.name "Name Surname" $ git config --global user.email yourname@example.com
你也可以按如下所示定制 Git 的默认行为。
$ git config --global init.defaultBranch main $ git config --global pull.rebase true $ git config --global push.default current
如果你习惯使用 CVS 或 Subversion 命令,你也许希望设置如下几个命令别名。
$ git config --global alias.ci "commit -a" $ git config --global alias.co checkout
你能够通过如下方式检查你的全局配置:
$ git config --global --list
10.5.2. 基本的 Git 命令
Git 操作涉及几个数据。
工作树目录保持面向用户的文件,你可以对这些文件做修改。
需要被记录的改变,必须明确的被选择并暂存到索引。这是
git add
和git rm
命令。索引保持暂存文件。
在接下来的请求之前,暂存文件将被提交到本地仓库。这个是
git commit
命令。本地仓库保持已经提交的的文件。
git pull
命令在git fetch
后执行git merge
或git rebase
命令。这里,
git merge
联合两个独立分支的历史结尾到一个点。(在没有定制的git pull
,这个是默认的,同时对上游作者发布分支到许多人时,也是好的 )这里,
git rebase
创建一个远程分支的序列历史的单个分支,跟着本地分支。(这是定制pull.rebase true
的情况,对我们其余的用途有用。)Git 记录提交数据的链接历史并在仓库里面将它们作为分支组织。
本地仓库通过
git push
命令发送数据到远程仓库。本地仓库能够通过
git fetch
和git pull
命令从远程仓库接收数据。远程仓库保持已经提交的文件。
到远程仓库的通信,使用安全的通信协议,比如 SSH 或 HTTPS。
工作树是在 .git/
目录之外的文件。在 .git/
目录里面的文件,包括索引、本地仓库数据和一些 git 配置的文本文件。
这里是主要的 Git 命令概览。
表 10.12. 主要的 Git 命令
Git 命令 | 功能 |
---|---|
git init | 创建(本地)存储库 |
git clone URL | 克隆远程存储库到本地仓库工作目录树 |
git pull origin main | 通过远程仓库 origin 更新本地 main 分支 |
git add . | 增加工作树里面的文件仅作为预先存在的索引文件 |
git add -A . | 增加工作树里面的所有文件到索引(包括已经删除的) |
git rm filename | 从工作树和索引中删除文件 |
git commit | 提交在索引中的暂存改变到本地存储库 |
git commit -a | 添加工作树里的所有的改变到索引并提交它们到本地仓库(添加 + 提交) |
git push -u origin branch_name | 使用本地 branch_name 分支更新远程仓库 origin (初始启用) |
git push origin branch_name | 使用本地 branch_name 分支更新远程仓库 origin (随后调用) |
git diff treeish1 treeish2 | 显示 treeish1 提交和 treeish2 提交的不同 |
gitk | VCS 存储库分支历史树的图形界面显示 |
10.5.3. Git 技巧
下面是一些 Git 技巧。
表 10.13. Git 技巧
Git 命令行 | 功能 |
---|---|
gitk --all | 参看完整的 Git 历史和操作,比如重置 HEAD 到另外一个提交、挑选补丁、创建标签和分支…… |
git stash | 得到一个干净的工作树,不会丢失数据 |
git remote -v | 检查远程设置 |
git branch -vv | 检查分支设置 |
git status | 显示工作树状态 |
git config -l | 列出 git 设置 |
git reset --hard HEAD; git clean -x -d -f | 反转所有工作树的改变并完全清理它们 |
git rm --cached filename | 反转由 git add filename 改变的暂存索引 |
git reflog | 获取参考日志(对从删除的分支中恢复提交有用) |
git branch new_branch_name HEAD@{6} | 从 reflog 信息创建一个新的分支 |
git remote add new_remote URL | 增加一个由 URL 指向的远程仓库 new_remote |
git remote rename origin upstream | 远程仓库的名字从 origin 重命名到 upstream |
git branch -u upstream/branch_name | 设置远程跟踪到远程仓库 upstream 和它的分支名 branch_name 。 |
git remote set-url origin https://foo/bar.git | 改变 origin 的 URL |
git remote set-url --push upstream DISABLED | 禁止推送到 upstream (编辑 .git/config 来重新启用) |
git remote update upstream | 获取 upstream 仓库中所有远程分支更新 |
git fetch upstream foo:upstream-foo | 创建本地(可能是孤立的)upstream-foo 分支,作为upstream 仓库中 foo 分支的一个拷贝 |
git checkout -b topic_branch ; git push -u topic_branch origin | 制作一个新的 topic_branch 并把它推送到 origin |
git branch -m oldname newname | 本地分支改名 |
git push -d origin branch_to_be_removed | 删除远程分支(新的方式) |
git push origin :branch_to_be_removed | 删除远程分支(老的方式) |
git checkout --orphan unconnected | 创建一个新的 unconnected 分支 |
git rebase -i origin/main | 从 origin/main 重新排序、删除、压缩提交到一个干净的分支历史 |
git reset HEAD^; git commit --amend | 压缩最后两个提交为一个 |
git checkout topic_branch ; git merge --squash topic_branch | 压缩整个 topic_branch 到一个提交 |
git fetch --unshallow --update-head-ok origin '+refs/heads/*:refs/heads/*' | 反转一个浅克隆到一个所有分支的完整克隆 |
git ime | 分开最后的提交到一系列单个逐一文件的小提交。(要求 imediff ) |
git repack -a -d; git prune | 本地仓库重新打包到一个单独的包中(这可能限制从删除分支里面恢复丢失数据等机会) |
10.5.4. Git 参考
参见下面内容。
man 手册: git(1) (
/usr/share/doc/git-doc/git.html
)Git 用户手册 (
/usr/share/doc/git-doc/user-manual.html
)git 介绍教程 (
/usr/share/doc/git-doc/gittutorial.html
)git 介绍教程:第二部 (
/usr/share/doc/git-doc/gittutorial-2.html
)GIT 每一天 20个左右的命令 (
/usr/share/doc/git-doc/giteveryday.html
)Git 魔术 (
/usr/share/doc/gitmagic/html/index.html
)
10.5.5. 其它的版本控制系统
版本控制系统(VCS )有时被认为是修订控制系统 (RCS), 或者是软件配置管理程序 (SCM)。
这里是 Debian 系统上著名的其它非 Git 的 VCS 汇总。
表 10.14. 其它版本控制系统工具列表
软件包 | 流行度 | 大小 | 工具 | VCS 类型 | 描述 |
---|---|---|---|---|---|
mercurial | V:5, I:32 | 2019 | Mercurial | 分布式 | mercurial 主要是用 Python 写的还有一部分是 C 写的 |
darcs | V:0, I:5 | 34070 | Darcs | 分布式 | 有智能代数补丁的 DVCS(慢) |
bzr | I:8 | 28 | GNU Bazaar | 分布式 | 受 tla 启发并且是用 Python 写的 DVCS (历史) |
tla | V:0, I:1 | 1022 | GNU arch | 分布式 | 主要由 Tom Lord 写的 DVCS (成为历史的) |
subversion | V:13, I:72 | 4837 | Subversion | 远程 | ”比 CVS 做的好“,远程 VCS 的新标准(历史) |
cvs | V:4, I:30 | 4753 | CVS | 远程 | 以前的远程 VCS 标准(历史) |
tkcvs | V:0, I:1 | 1498 | CVS, … | 远程 | VCS (CVS,Subversion,RCS) 存储库树的图形界面显示 |
rcs | V:2, I:13 | 564 | RCS | 本地 | "比 Unix SCCS 做的好"(历史) |
cssc | V:0, I:1 | 2044 | CSSC | 本地 | Unix SCCS 的克隆(历史) |
[4] 一个只能写一次的媒介,例如 CD/DVD-R, 能防止覆盖事故。(参见 第 9.8 节 “二进制数据” 怎样在 shell 命令行写入存储媒介。GNOME 桌面图形环境可以让你轻松的通过菜单:“位置 → CD/DVD 刻录”来实现写入操作。)
[5] 这些数据中的一些,不能够通过在系统里面输入同样的字符串来重新生成。
[6] 如果你使用 "~/.vimrc
" 代替 "~/.vim/vimrc
",请进行相应的取代。