第12章:网络文件传输与共享
本章探讨在网络上的机器之间分发和共享文件的选项。我们将先介绍一些除已了解的 scp 和 sftp 工具之外的文件复制方法,然后讨论真正的文件共享——即将一台机器上的目录挂载到另一台机器上。
由于有如此多种分发和共享文件的方式,下面列出各场景及其对应的解决方案:
| 场景 | 解决方案 |
|---|---|
| 将 Linux 机器上的一个文件或目录临时提供给其他机器访问 | Python SimpleHTTPServer(第 12.1 节) |
| 跨机器分发(复制)文件,尤其是定期执行 | rsync(第 12.2 节) |
| 定期将 Linux 机器上的文件共享给 Windows 机器 | Samba(第 12.4 节) |
| 在 Linux 机器上挂载 Windows 共享 | CIFS(第 12.4 节) |
| 在 Linux 机器之间以最少设置实现小型共享 | SSHFS(第 12.5 节) |
| 从 NAS 或其他服务器挂载较大的文件系统到可信本地网络 | NFS(第 12.6 节) |
| 将云存储挂载到 Linux 机器 | 各种基于 FUSE 的文件系统(第 12.7 节) |
请注意,这里没有涉及多地点多用户的大规模共享。虽然并非不可能,但此类解决方案通常需要大量工作,且不在本书讨论范围之内。我们将在本章末尾讨论其原因。
与本书其他许多章节不同,本章最后部分并非高级内容。事实上,你可能从中获益最多的部分恰恰是最“理论化”的部分。第 12.3 节和第 12.8 节将帮助你理解为什么这里会列出如此多的选项。
12.1 快速复制
假设你想将 Linux 机器上的一个(或多个)文件复制到个人网络上的另一台机器,且不在意复回或其他高级功能——你只想快速将文件传输过去。用 Python 有一种便捷的方式。只需进入包含这些文件的目录,执行:
$ python -m SimpleHTTPServer这会启动一个基本的 Web 服务器,使当前目录可供网络上的任何浏览器访问。默认情况下,它运行在 8000 端口;因此,如果你运行此命令的机器地址为 10.1.2.4,则在目标系统上打开浏览器访问 http://10.1.2.4:8000 即可获取所需内容。
WARNING
此方法假定你的本地网络是安全的。不要在公共网络或任何你不信任的网络环境中这样做。
12.2 rsync
当你需要复制的不止一两个文件时,可以考虑使用需要在目标端有服务器支持的工具。例如,只要远程目标端支持 SSH 和 SCP 服务器(Windows 和 macOS 均提供该支持),就可以使用 scp -r 将整个目录结构复制到另一个位置。我们已在第 10 章见过此选项:
$ scp -r directory user@remote_host[:dest_dir]这种方法能完成任务,但不够灵活。特别是,传输完成后,远程主机上的目录可能不是源目录的精确副本。如果远程机器上已存在该目录且包含一些无关文件,这些文件在传输后仍然保留。
如果你预期会定期执行此类操作(尤其计划自动化此过程),则应使用专用的同步工具,它还能执行分析和验证。在 Linux 上,rsync 是标准同步工具,性能出色,并提供许多有用的传输方式。本节将介绍一些基本的 rsync 操作模式及其特性。
12.2.1 rsync 入门
要使 rsync 在两台主机之间正常工作,必须在源端和目标端都安装 rsync 程序,并且需要一种从一台机器访问另一台机器的方式。传输文件最简单的方法是使用远程 shell 账户,假设你希望通过 SSH 访问来传输文件。但请记住,rsync 即使在单台机器上的不同位置之间(如从一个文件系统到另一个文件系统)复制文件和目录也很方便。
从表面上看,rsync 命令与 scp 差别不大。事实上,你可以使用相同的参数运行 rsync。例如,要将一组文件复制到远程主机 host 上的家目录,输入:
$ rsync file1 file2 ... host:在任何当代系统上,rsync 都假定你使用 SSH 连接到远程主机。
注意以下错误消息:
rsync: 未找到 rsync: connection unexpectedly closed (0 bytes read so far) rsync error: error in rsync protocol data stream (code 12) at io.c(165)
这条信息表明你的远程 shell 在其系统上找不到 rsync。如果 rsync 在远程系统上但不在该系统的用户命令路径中,请使用 --rsync-path=path 手动指定其位置。
如果两台主机上的用户名不同,则在命令参数中的远程主机名前加上 user@,其中 user 是你远程主机上的用户名:
$ rsync file1 file2 ... user@host:除非提供额外选项,否则 rsync 只复制文件。实际上,如果仅使用上述描述的选项,并将目录 dir 作为参数,你会看到以下信息:
skipping directory dir
要传输整个目录层次结构(包括符号链接、权限、模式和设备),请使用 -a 选项。此外,如果要复制到远程主机上除家目录以外的其他目录,请在远程主机名后写上目标目录名,如下所示:
$ rsync -a dir host:dest_dir复制目录可能有些棘手,因此如果不确定传输会有什么结果,请使用 -nv 选项组合。-n 选项指示 rsync 以“试运行”模式运行——即运行一次模拟而不实际复制任何文件。-v 选项用于详细模式,显示有关传输及所涉及文件的详细信息:
$ rsync -nva dir host:dest_dir输出类似这样:
building file list ... done
ml/nftrans/nftrans.html
[more files]
wrote 2183 bytes read 24 bytes 401.27 bytes/sec
12.2.2 生成目录结构的精确副本
默认情况下,rsync 在复制文件和目录时不考虑目标目录之前的已有内容。例如,如果你将包含文件 a 和 b 的目录 d 传输到一台已有文件 d/c 的机器上,则传输后目标端将包含 d/a、d/b 和 d/c。要生成源目录的精确副本,必须删除目标目录中源目录不存在的文件(本例中的 d/c)。使用 --delete 选项:
$ rsync -a --delete dir host:dest_dirWARNING
此操作可能很危险,因此请花时间检查目标目录,看是否有任何你可能无意删除的内容。记住,如果对传输没有把握,请使用
-nv选项执行试运行,以便确切知道rsync何时要删除文件。
12.2.3 使用尾部斜杠
在 rsync 命令行中将目录指定为源时需特别小心。考虑我们到目前为止使用的基本命令:
$ rsync -a dir host:dest_dir传输完成后,远程 host 上的 dest_dir 内部会包含目录 dir。图 12-1 展示了 rsync 通常如何处理包含文件 a 和 b 的目录 dir。
graph LR subgraph 源 dir1[dir] dir1 --- a1[a] dir1 --- b1[b] end subgraph 目标(传输前) dest_before[dest_dir] end rsync1["rsync -a dir host:dest_dir"] subgraph 目标(传输后) dest_after[dest_dir] dest_after --- dir2[dir] dir2 --- a2[a] dir2 --- b2[b] end
图 12-1:普通 rsync 复制
但是,在源名称后添加斜杠(/)会显著改变行为:
$ rsync -a dir/ host:dest_dir这里,rsync 将 dir 内的所有内容复制到远程 host 的 dest_dir 中,而不会在目标端实际创建 dir 目录。因此,可以将 dir/ 的传输视为类似于本地文件系统上 cp dir/* dest_dir 的操作。
例如,假设你有一个包含文件 a 和 b 的目录 dir(即 dir/a 和 dir/b)。运行尾部斜杠版本的命令将其传输到远程主机 host 上的 dest_dir 目录:
$ rsync -a dir/ host:dest_dir传输完成后,dest_dir 包含 a 和 b 的副本,但不包含 dir。然而,如果你省略了 dir 后的尾部斜杠,dest_dir 将得到 dir 的副本,其中包含 a 和 b。因此,传输结果在远程主机上会得到名为 dest_dir/dir/a 和 dest_dir/dir/b 的文件和目录。图 12-2 展示了在使用尾部斜杠时,rsync 如何处理图 12-1 中的目录结构。
graph LR subgraph 源 dir1[dir] dir1 --- a1[a] dir1 --- b1[b] end subgraph 目标(传输前) dest_before[dest_dir] end rsync2["rsync -a dir/ host:dest_dir"] subgraph 目标(传输后) dest_after[dest_dir] dest_after --- a2[a] dest_after --- b2[b] end
图 12-2:rsync 中尾部斜杠的效果
将文件和目录传输到远程主机时,意外地在路径后添加 / 通常只是一个小麻烦;你可以登录远程主机,添加 dir 目录,然后将所有传输过来的项目放回 dir 中。不幸的是,如果将尾部斜杠与 --delete 选项结合使用,则可能造成更大的灾难;请格外小心,因为这样很容易误删不相关的文件。
WARNING
出于这个潜在风险,请警惕你 shell 的自动文件名补全功能。许多 shell 在你按 TAB 键后会在补全的目录名后自动添加尾部斜杠。
12.2.4 排除文件和目录
rsync 的一个重要功能是在传输操作中排除文件和目录。例如,假设你想将本地名为 src 的目录传输到 host,但希望排除所有名为 .git 的内容。可以这样做:
$ rsync -a --exclude=.git src host:注意,此命令会排除所有名为 .git 的文件和目录,因为 --exclude 接受的是模式,而不是绝对文件名。要排除某个特定项目,请指定以 / 开头的绝对路径,如下所示:
$ rsync -a --exclude=/src/.git src host:NOTE
此命令中
/src/.git的第一个/不是系统根目录,而是传输的基目录。
以下是关于排除模式的一些额外提示:
- 你可以使用任意多个
--exclude参数。 - 如果反复使用相同的模式,请将它们放在一个纯文本文件中(每行一个模式),然后使用
--exclude-from=file。 - 要排除名为
item的目录但保留同名的文件,请使用尾部斜杠:--exclude=item/。 - 排除模式基于完整的文件或目录名称组件,可以包含简单的通配符。例如,
t*s匹配this,但不匹配ethers。 - 如果你排除了某个文件或目录,但发现模式过于严格,可以使用
--include来专门包含另一个文件或目录。
注意: 本章节内容对应原书第 316–321 页,为第 12 章第 1 部分。后续部分将涵盖 Samba、SSHFS、NFS 等章节。
12.2.5 检查传输、添加保护措施和使用详细模式
为了加快操作速度,rsync 使用快速检查来判断传输源上的文件是否已存在于目标端。该检查结合了文件大小和最后修改日期。第一次将整个目录层次结构传输到远程主机时,rsync 发现目标端不存在任何文件,因此会传输所有内容。使用 rsync -n 测试传输可以验证这一点。
运行一次 rsync 后,再次使用 rsync -v 运行。这次你应该会看到传输列表中没有文件出现,因为文件集在两端都存在,且修改日期相同。
当源端的文件与目标端的文件不完全相同时,rsync 会传输源文件并覆盖远程端存在的任何文件。但默认行为可能不够完善,因为你可能需要额外的保证来确认文件确实相同后才跳过传输,或者你可能想添加一些额外的保护措施。以下是一些有用的选项:
--checksum(缩写:-c):计算文件的校验和(大多为唯一签名)以判断它们是否相同。此选项在传输期间会消耗少量 I/O 和 CPU 资源,但如果你处理的是敏感数据或大小经常一致的文件,这是必需的。--ignore-existing:不覆盖目标端已存在的文件。--backup(缩写:-b):不覆盖目标端已存在的文件,而是在传输新文件前,通过向这些现有文件名添加~后缀来重命名它们。--suffix=s:将与--backup配合使用的后缀从~改为s。--update(缩写:-u):不覆盖目标端上日期晚于源端对应文件的任何文件。
如果没有特殊选项,rsync 会静默运行,仅在出现问题时产生输出。然而,你可以使用 rsync -v 获得详细模式,或使用 rsync -vv 获得更多细节(你可以添加任意多个 v 选项,但两个可能已足够)。要在传输后获得全面摘要,请使用 rsync --stats。
12.2.6 压缩数据
许多用户喜欢将 -z 选项与 -a 结合使用,在传输前压缩数据:
$ rsync -az dir host:dest_dir压缩可以在某些情况下提高性能,例如当你通过慢速连接(如缓慢的上行链路)上传大量数据时,或者当两台主机之间的延迟较高时。然而,在快速的局域网上,两台终端机器可能因压缩和解压缩数据所需的 CPU 时间而受限,因此未压缩的传输可能更快。
12.2.7 限制带宽
当向远程主机上传大量数据时,很容易堵塞互联网连接的上行链路。即使在此类传输期间你不会使用(通常较大的)下行链路容量,但如果让 rsync 以最快速度运行,你的连接仍然会显得很慢,因为传出的 TCP 数据包(如 HTTP 请求)必须与传输竞争上行链路的带宽。
为了解决这个问题,使用 --bwlimit 为你的上行链路留出一点喘息空间。例如,要将带宽限制为 100,000 Kbps,可以这样做:
$ rsync --bwlimit=100000 -a dir host:dest_dir12.2.8 将文件传输到你的计算机
rsync 命令不仅用于将文件从本地机器复制到远程主机。你也可以通过将远程主机和远程源路径作为命令行上的第一个参数,将文件从远程机器传输到本地主机。例如,要将远程系统上的 src_dir 传输到本地主机上的 dest_dir,运行以下命令:
$ rsync -a host:src_dir dest_dirNOTE
如前所述,你可以使用
rsync在本地机器上复制目录;只需在两个参数中都省略host:。
12.2.9 进一步的 rsync 主题
每当你需要复制大量文件时,rsync 应该是你首先想到的工具之一。在批处理模式下运行 rsync 对于将同一组文件复制到多个主机特别有用,因为它可以加速长时间传输,并在中断时恢复。
你还会发现 rsync 对于制作备份非常有用。例如,你可以将互联网存储(如 Amazon S3)挂载到 Linux 系统,然后使用 rsync --delete 定期将文件系统与网络存储同步,从而实现非常有效的备份系统。
rsync 的命令行选项远不止这里描述的这些。如需粗略概览,运行 rsync --help。更详细的信息可以在 rsync(1) 手册页以及 rsync 主页(https://rsync.samba.org/)中找到。
12.3 文件共享简介
你的 Linux 机器可能并非网络中孤立的设备,当网络中有多台机器时,几乎总有在它们之间共享文件的理由。在本章的剩余部分,我们将首先探讨 Windows 和 macOS 机器之间的文件共享,了解 Linux 如何适应与完全陌生的环境交互。为了在 Linux 机器之间共享文件或从网络附加存储(NAS)设备访问文件,我们最后会讨论使用 SSHFS 和网络文件系统(NFS)作为客户端。
12.3.1 文件共享的使用与性能
在使用任何类型的文件共享系统时,你需要问自己一个问题:为什么要这样做?在传统的基于 Unix 的网络中,有两个主要原因:便利性和缺乏本地存储。一个用户可以登录到网络上的多台机器中的任何一台,每台机器都能访问该用户的主目录。将存储集中在少量集中式服务器上,比购买和维护每台机器的本地存储要经济得多。
这种模式的优点被一个多年未变的主要缺点所掩盖:网络存储性能通常比本地存储差。某些类型的数据访问是可以接受的;例如,当代硬件和网络在从服务器向媒体播放器流式传输视频和音频数据时没有问题,部分原因是数据访问模式非常可预测。从大文件或流传输数据的服务器可以高效地预加载和缓冲数据,因为它知道客户端很可能会按顺序访问数据。
然而,如果你进行更复杂的操作或同时访问许多不同的文件,你会发现 CPU 更多时候是在等待网络。延迟是主要原因之一。延迟是指从任何随机(任意)网络文件访问中接收数据所需的时间。在向客户端发送任何数据之前,服务器必须接受并解密请求,然后定位并加载数据。前几步通常是最慢的,并且几乎每次新的文件访问都要执行。
故事的寓意是,当你开始考虑网络文件共享时,问问自己为什么要这样做。如果是为了大量不需要频繁随机访问的数据,你可能不会遇到问题。但例如,如果你正在编辑视频或开发任何规模较大的软件系统,你会希望将所有文件保留在本地存储上。
12.3.2 文件共享安全
传统上,文件共享协议中的安全性并未被视为高优先级。这会对如何以及在哪里实施文件共享产生影响。如果你有任何理由怀疑共享文件的机器之间的网络安全,那么你的配置中需要考虑授权/认证和加密。良好的授权和认证意味着只有拥有正确凭据的主体才能访问文件(并且服务器是其声称的身份),而加密则确保没有人能够在数据传输到目标的过程中窃取文件数据。
最容易配置的文件共享选项通常最不安全,而且不幸的是,没有标准化的方法来保护这些类型的访问。然而,如果你愿意花功夫连接正确的组件,诸如 stunnel、[IPSec]] 和 VPN 之类的工具可以保护基本文件共享协议之下的各个层。
12.4 使用 Samba 共享文件
如果你有运行 Windows 的机器,你可能希望使用标准的 Windows 网络协议——服务器消息块(SMB)——允许这些 Windows 机器访问你的 Linux 系统的文件和打印机。macOS 也支持 SMB 文件共享,但你也可以使用第 12.5 节描述的 SSHFS。
Unix 的标准文件共享软件套件称为 Samba。Samba 不仅允许网络上的 Windows 计算机访问你的 Linux 系统,反过来也同样有效:你可以通过 Samba 客户端软件从 Linux 机器上打印并访问 Windows 服务器上的文件。
要设置 Samba 服务器,请执行以下步骤:
- 创建
smb.conf文件。 - 向
smb.conf添加文件共享节。 - 向
smb.conf添加打印机共享节。 - 启动 Samba 守护进程
nmbd和smbd。
当您从发行版软件包安装 Samba 时,系统应使用一些合理的服务器默认值来执行这些步骤。然而,它可能无法确定您希望在 Linux 机器上向客户端提供哪些特定的共享(资源)。
NOTE
本章对 Samba 的讨论并非旨在全面;它仅限于让单子网上的 Windows 机器能够通过“网上邻居”浏览器看到一台独立的 Linux 机器。Samba 的配置方式数不胜数,因为访问控制和网络拓扑的可能性非常多。有关如何配置大型服务器的详尽细节,请参阅《Using Samba》第 3 版(Gerald Carter、Jay Ts 和 Robert Eckstein 著,O’Reilly,2007 年),这是一本更全面的指南,并访问 Samba 网站(https://samba.org/)。
12.4.1 服务器配置
中央 Samba 配置文件是 smb.conf,大多数发行版将其放置在 etc 目录中,例如 /etc/samba。但是,你可能需要搜寻此文件,因为它也可能位于 lib 目录中,例如 /usr/local/samba/lib。
smb.conf 的文件格式类似于您在其他地方见过的 XDG 风格(例如 systemd 配置格式),并分解为多个用方括号表示的节,例如 [global] 和 [printers]。smb.conf 中的 [global] 节包含适用于整个服务器和所有共享的通用选项。这些选项主要涉及网络配置和访问控制。以下示例 [global] 节展示了如何设置服务器名称、描述和工作组:
[global]
# 服务器名称
netbios name = name
# 服务器描述
server string = My server via Samba
# 工作组
workgroup = MYNETWORK这些参数的作用如下:
netbios name:服务器名称。如果省略此参数,Samba 将使用 Unix 主机名。NetBIOS 是 SMB 主机常用来相互通信的一个 API。server string:服务器的简短描述。默认值为 Samba 版本号。workgroup:Windows 工作组名称。如果你在 Windows 域中,请将此参数设置为你的域名。
12.4.2 服务器访问控制
你可以在 smb.conf 文件中添加选项,以限制能够访问 Samba 服务器的机器和用户。以下是可以在 [global] 部分以及控制各个共享的部分(如本章后续所述)中设置的众多选项中的一部分:
interfaces:设置此选项可使 Samba 监听(接受连接)指定的网络或接口。例如:interfaces = 10.23.2.0/255.255.255.0 interfaces = enp0s31f6bind interfaces only:当使用interfaces参数时,将此选项设置为yes,可将访问限制为仅通过那些接口可以直接到达的机器。valid users:设置此选项以允许指定用户访问。例如:valid users = jruser, billguest ok:将此参数设置为true可使共享对网络上的匿名用户可用。仅在确信网络为私有网络时才这样做。browseable:设置此选项可使共享在网络浏览器中可见。如果对某些共享将此参数设置为no,您仍然可以访问这些共享,但需要知道它们的确切名称。
12.4.3 密码
通常,您应仅允许通过密码认证访问 Samba 服务器。不幸的是,Unix 的基本密码系统与 Windows 不同,因此除非您指定明文网络密码或通过 Windows 域服务器认证密码,否则必须设置备选密码系统。本节演示如何使用适用于小型网络的 Samba 简易数据库(TDB)后端来设置备选密码系统。
首先,在 smb.conf 文件的 [global] 部分使用以下条目定义 Samba 密码数据库的特征:
# 使用 tdb 使 Samba 启用加密密码
security = user
passdb backend = tdbsam
obey pam restrictions = yes
smb passwd file = /etc/samba/passwd_smb这些行允许您使用 smbpasswd 命令操作 Samba 密码数据库。obey pam restrictions 参数确保任何使用 smbpasswd 命令更改密码的用户都必须遵守 PAM(可插拔认证模块,详见第 7 章)对常规密码更改所施加的任何规则。对于 passdb backend 参数,您可以选择在冒号后指定 TDB 文件的路径名——例如 tdbsam:/etc/samba/private/passwd.tdb。
NOTE
如果您有权访问 Windows 域,可以将
security = domain设置为使用域的认证系统,从而无需密码数据库。但是,要让域用户访问运行 Samba 的机器,每个域用户必须在该机器上有一个同名的本地账户。
添加和删除用户
要授予 Windows 用户访问 Samba 服务器的权限,首先需要使用 smbpasswd -a 命令将该用户添加到密码数据库:
# smbpasswd -a usernamesmbpasswd 命令的 username 参数必须是您 Linux 系统上的有效用户名。
像常规的 passwd 程序一样,smbpasswd 会要求您两次输入新的 SMB 用户密码。密码通过必要的安全检查后,smbpasswd 会确认已创建新用户。
要删除用户,使用 smbpasswd 的 -x 选项:
# smbpasswd -x username要仅临时停用用户,使用 -d 选项;稍后可使用 -e 选项重新启用用户:
# smbpasswd -d username
# smbpasswd -e username更改密码
超级用户可以使用 smbpasswd(不带除用户名以外的选项或关键字)来更改 Samba 密码:
# smbpasswd username然而,如果 Samba 服务器正在运行,任何用户都可以通过单独在命令行上输入 smbpasswd 来更改自己的 Samba 密码。
最后,有一个配置中的地方需要特别留意。如果在 smb.conf 文件中看到这样一行,请小心:
unix password sync = yes这一行会导致 smbpasswd 在更改 Samba 密码的同时,也更改用户的常规密码。结果可能非常令人困惑,尤其是当用户将其 Samba 密码更改为不同于其 Linux 密码的内容时,他们会发现自己无法再登录 Linux 系统。某些发行版默认在其 Samba 服务器软件包中设置了此参数!
12.4.4 手动启动服务器
通常,如果您通过发行版的软件包安装了 Samba,则无需担心启动服务器。通过 systemctl --type=service 检查列表即可确认。但是,如果您是从源代码安装的,请使用以下参数运行 nmbd 和 smbd,其中 smb_config_file 是 smb.conf 文件的完整路径:
# nmbd -D -s smb_config_file
# smbd -D -s smb_config_filenmbd 守护进程是一个 NetBIOS 名称服务器,而 smbd 则负责处理共享请求。-D 选项指定守护进程模式。如果在 smbd 运行时修改了 smb.conf 文件,可以通过 HUP 信号通知守护进程这些更改,不过让 systemd 来管理服务器几乎总是更好的选择,在这种情况下,您可以让 systemctl 为您完成这项工作。
12.4.5 诊断和日志文件
如果 Samba 服务器启动时出现问题,命令行上会显示错误消息。但是,运行时诊断消息会写入 log.nmbd 和 log.smbd 日志文件,这些文件通常位于 /var/log 目录下,例如 /var/log/samba。您还会在那里找到其他日志文件,例如每个单独客户端的日志。
12.4.6 文件共享配置
要将目录导出给 SMB 客户端(即与客户端共享目录),请在 smb.conf 文件中添加如下所示的部分,其中 label 是您想给共享起的名称(例如 mydocuments),path 是完整目录路径:
[label]
path = path
comment = share description
guest ok = no
writable = yes
printable = no以下参数在目录共享中很有用:
guest ok:设置为yes允许对共享进行来宾访问。public参数是同义词。writable:设置为yes或true会将共享标记为可读写。不要允许来宾访问可读写共享。printable:显然,在目录共享上,此参数必须设置为no或false。veto files:此参数阻止导出与给定模式匹配的任何文件。必须将每个模式放在斜杠之间(使其看起来像/pattern/)。此示例禁止了目标文件以及任何名为bin的文件或目录:veto files = /*.o/bin/
12.4.7 用户主目录
如果要将用户主目录导出给用户,可以在 smb.conf 文件中添加一个名为 [homes] 的部分。该部分应如下所示:
[homes]
comment = home directories
browseable = no
writable = yes默认情况下,Samba 会读取登录用户的 /etc/passwd 条目来确定其 [homes] 的主目录。但是,如果您不希望 Samba 遵循此行为(即希望将 Windows 主目录放在与常规 Linux 主目录不同的位置),可以在 path 参数中使用 %S 替换。例如,将用户的 [homes] 目录切换到 /u/user 的方法如下:
path = /u/%SSamba 会将当前用户名替换为 %S。
12.4.8 打印机共享
可以通过在 smb.conf 文件中添加 [printers] 部分,将打印机导出给 Windows 客户端。以下是使用 CUPS(标准 Unix 打印系统)时该部分的样子:
[printers]
comment = Printers
browseable = yes
printing = CUPS
path = cups
printable = yes
writable = no要使用 printing = CUPS 参数,您的 Samba 安装必须已配置并链接到 CUPS 库。
NOTE
根据您的配置,您可能希望允许来宾访问打印机(使用
guest ok = yes选项),而不是向每个需要访问打印机的人提供 Samba 密码或账户。例如,通过防火墙规则很容易将打印机访问限制到单个子网。
12.4.9 Samba 客户端
Samba 客户端程序 smbclient 可以打印和访问远程 Windows 共享。当您需要与不提供 Unix 友好通信方式的 Windows 服务器交互时,此程序非常有用。
要开始使用 smbclient,请使用 -L 选项从名为 SERVER 的远程服务器获取共享列表:
$ smbclient -L -U username SERVER如果您的 Linux 用户名与您在 SERVER 上的用户名相同,则无需 -U username。
运行此命令后,smbclient 会要求输入密码。要以来宾身份尝试访问共享,请按 ENTER;否则,请输入您在 SERVER 上的密码。成功后,您将得到类似以下内容的共享列表:
Sharename Type Comment
--------- ---- -------
Software Disk Software distribution
Scratch Disk Scratch space
IPC$ IPC IPC Service
ADMIN$ IPC IPC Service
Printer1 Printer Printer in room 231A
Printer2 Printer Printer in basement
使用 Type 字段帮助理解每个共享,只需关注 Disk 和 Printer 共享即可(IPC 共享用于远程管理)。此列表包含两个磁盘共享和两个打印机共享。使用 Sharename 列中的名称来访问每个共享。
以客户端方式访问文件
如果只需要偶尔访问磁盘共享中的文件,请使用以下命令(同样,如果您的 Linux 用户名与服务器上的用户名匹配,可以省略 -U username):
$ smbclient -U username '\\SERVER\sharename'成功后,您将看到类似以下提示,表示现在可以传输文件:
smb: \>
在这种文件传输模式下,smbclient 类似于 Unix 的 ftp,您可以运行以下命令:
get file:将文件从远程服务器复制到本地当前目录。put file:将文件从本地机器复制到远程服务器。cd dir:将远程服务器上的目录更改为dir。lcd localdir:将本地当前目录更改为localdir。pwd:打印远程服务器上的当前目录,包括服务器和共享名称。!command:在本地主机上运行command。两个特别方便的命令是!pwd和!ls,用于确定本地的目录和文件状态。help:显示完整的命令列表。
使用 CIFS 文件系统
如果您希望更方便地访问 Windows 服务器上的文件,可以使用 mount 直接将共享附加到系统。命令语法如下(注意使用 SERVER:sharename 而不是通常的 \\SERVER\sharename 格式):
# mount -t cifs SERVER:sharename mountpoint -o user=username,pass=password要像这样使用 mount,您的系统上必须安装了通用 Internet 文件系统(CIFS)工具。大多数发行版将这些工具作为单独的软件包提供。
第12章:网络文件传输与共享
12.5 SSHFS
在介绍了 Windows 文件共享系统之后,本节将讨论 Linux 系统之间的文件共享。对于不太复杂的场景,一个便捷的选择是 SSHFS。它本质上是一个用户空间文件系统,通过打开 SSH 连接,将远程主机上的文件以挂载点的形式呈现到本地机器上。大多数发行版默认不安装它,因此你可能需要安装对应发行版的 SSHFS 软件包。
在命令行中使用 SSHFS 的语法,从表面上看与你之前见过的 SSH 命令类似。当然,你需要提供(远程主机上的)共享目录以及期望的挂载点:
$ sshfs username@host:dir mountpoint与 SSH 类似,如果本地用户名与远程主机上的用户名相同,可以省略 username@;如果只想挂载远程主机上的家目录,还可以省略 :dir。该命令会在必要时提示输入远程主机的密码。
由于这是一个用户空间文件系统,如果你以普通用户身份运行,则必须使用 fusermount 来卸载它:
$ fusermount -u mountpoint超级用户也可以使用 umount 来卸载这类文件系统。为了确保所有权和安全性的一致性,这类文件系统通常最好以普通用户身份挂载。
SSHFS 具有以下优点:
- 设置简单。远程主机上唯一的要求是启用了 SFTP,而大多数 SSH 服务器默认已启用。
- 不依赖任何特定的网络配置。只要能建立 SSH 连接,SSHFS 就能工作,无论它是在安全的本地网络还是不安全的远程网络上。
SSHFS 的缺点包括:
- 性能较差。加密、转换和传输过程带来大量开销(但可能没有你想象的那么糟糕)。
- 多用户场景受限。
如果你觉得 SSHFS 可能适合你,绝对值得一试,因为它设置起来非常方便。
12.6 NFS
在 Unix 系统之间进行文件共享时,最常用的传统系统之一是 NFS。NFS 有多种不同版本,适用于不同场景。你可以通过 TCP 和 UDP 提供 NFS 服务,并拥有大量的认证和加密选项(不幸的是,默认情况下极少启用)。由于选项众多,NFS 可能是一个很大的话题,因此我们只进行最基本的介绍。
要使用 NFS 挂载远程服务器上的目录,可以使用与挂载 CIFS 目录基本相同的语法:
# mount -t nfs server:directory mountpoint从技术上讲,你不需要 -t nfs 选项,因为 mount 命令应该会自动识别,但你可能需要查阅 nfs(5) 手册页中的选项说明。你会看到多种不同的安全选项,通过 sec 选项指定。许多小型封闭网络的管理员使用基于主机的访问控制。更复杂的方法,例如基于 Kerberos 的认证,需要在系统的其他部分进行额外配置。
当你发现自己对网络文件系统的使用越来越多时,建议设置自动挂载器(automounter),这样你的系统只会在你实际尝试使用这些文件系统时才挂载它们,以避免启动时出现依赖问题。传统的自动挂载工具叫 automount,还有一个较新的版本叫 amd,但现在这些功能大多已被 systemd 中的 automount 单元类型所取代。
NFS 服务器
设置 NFS 服务器以便与其他 Linux 机器共享文件,比配置客户端更复杂。你需要运行服务器守护进程(mountd 和 nfsd),并设置 /etc/exports 文件来反映你正在共享的目录。然而,我们不会深入介绍 NFS 服务器,主要原因是通过购买 NAS 设备来处理网络存储共享通常更加方便。许多这样的设备基于 Linux,因此它们自然支持 NFS 服务器。厂商通过提供自己的管理工具来增加 NAS 设备的价值,减轻了诸如设置 RAID 配置和云备份等繁琐任务的痛苦。
12.7 云存储
说到云备份,另一种网络文件存储选项是云存储,例如 AWS S3 或 Google Cloud Storage。这些系统的性能不如本地网络存储,但它们提供了两个显著优势:你永远不需要维护它们,也不必担心备份问题。
除了所有云存储提供商都提供的 Web(及编程)界面之外,还有多种方法可以将大多数云存储挂载到 Linux 系统上。与我们目前为止看到的大多数文件系统不同,这些几乎都是通过 FUSE(用户空间文件系统)接口实现的。对于一些流行的云存储提供商(如 S3),甚至有多种选择。这是合理的,因为 FUSE 处理程序本质上就是一个用户空间守护进程,充当数据源和内核之间的中介。
本书不涉及设置云存储客户端的具体细节,因为每个客户端都不同。
12.8 网络文件共享现状
至此,你可能会觉得有关 NFS 和文件共享的讨论似乎有些不完整——也许确实如此,但这也仅仅是因为文件共享系统本身就不完整。我们在第 12.3.1 节和 12.3.2 节中讨论了性能和安全性问题。特别是,NFS 的基础安全级别相当低,需要大量的额外工作才能改进。CIFS 系统在这方面稍好一些,因为必要的加密层已内置于当代软件中。然而,性能限制并不容易克服,更不用说当系统暂时无法访问其网络存储时,性能可能会变得多么糟糕。
为解决这个问题,已经有过多次尝试。其中或许最广泛的是 Andrew 文件系统(AFS),它最初设计于 20 世纪 80 年代,专门围绕这些问题的解决方案而构建。那么,为什么不是每个人都使用 AFS 或类似系统呢?
这个问题没有单一的答案,但很大程度上归结于部分设计中缺乏灵活性。例如,其安全机制需要 Kerberos 认证系统。尽管 Kerberos 是普遍可用的,但它从未成为 Unix 系统的标配,并且需要相当多的工作来设置和维护(你需要为其设置一个服务器)。
对于大型机构来说,满足 Kerberos 等要求不是问题。这正是 AFS 得以蓬勃发展的环境:大学和金融机构是 AFS 的大用户。但对于小型用户来说,不这样做显然更简单,他们更倾向于选择像 NFS 或 CIFS 共享这样简单的方案。这种限制甚至延伸到 Windows;从 Windows 2000 开始,微软在其服务器产品中将 Kerberos 作为默认认证方式,但小型网络通常不会采用包含此类服务器的 Windows 域。
除了认证前提之外,还存在由更技术性的原因引起的问题。许多网络文件系统客户端传统上是内核代码,NFS 尤为典型。不幸的是,网络文件系统的需求足够复杂,以至于问题开始出现。仅仅认证这一项就不应该放在内核中。内核客户端实现还严重限制了网络文件系统潜在开发者群体的规模,从而阻碍了整个系统的发展。在某些情况下,客户端代码位于用户空间,但底层总有一些内核定制。
目前,在 Linux/Unix 世界中,我们发现自己缺乏一种真正标准的网络文件共享方式(至少在你不是大型站点、或者不愿意投入相当多工作的情况下是如此)。然而,这种情况不一定会一直持续下去。
当云存储提供商开始提供服务时,很明显传统的网络文件共享形式并不适用。在云端,访问方法构建在诸如 TLS 等安全机制之上,使得无需设置像 Kerberos 这样大型系统就能访问存储。正如前一节所述,有许多通过 FUSE 访问云存储的选项。我们不再依赖内核来处理客户端的任何部分;任何类型的认证、加密或处理都可以轻松地在用户空间中完成。
所有这些都意味着,未来很可能出现一些文件共享设计,在安全性以及文件名转换等其他领域融入更多灵活性。
注意:本章涉及相关图像,分别位于第 341 页(图像 2327、2321、2325、2317、2323、2316、2320、2315、2319)。由于文本未提供图像的具体内容,此处仅保留引用。