Linux工作原理12网络文件传输和共享

12网络文件传输和共享

本章将介绍在网络上的计算机之间分发和共享文件的方法。首先,我们将介绍一些复制文件的方法,而不是你已经见过的 scp 和 sftp 实用程序。然后,我们将讨论真正的文件共享,即把一台机器上的目录附加到另一台机器上。
因为分发和共享文件的方法有很多,所以这里列出了一些情况和相应的解决方案。这里没有涉及在多个地点与众多用户之间进行大规模共享的问题。尽管并非不可能,但这种解决方案通常需要大量的工作,不在本书的讨论范围之内。在本章的最后,我们将讨论为什么会出现这种情况。
与本书的许多其他章节不同,本章的最后一部分并非高级材料。事实上,最有价值的章节是最 “理论化 ”的章节。第 12.3 节和第 12.8 节将帮助你理解为什么这里首先列出了这么多选项。

12.1 快速复制(SimpleHTTPServer)

假设你想把一个(或多个)文件从你的 Linux 机器复制到个人网络上的另一台机器上,而且你并不关心复制回来或任何花哨的东西--你只想快速地把文件拿到那里。使用 Python 有一种方便的方法。只需转到包含文件的目录,然后运行

python -m SimpleHTTPServer

这将启动一个基本的网络服务器,使网络上的任何浏览器都能访问当前目录。默认情况下,它运行在 8000 端口上,因此,如果运行此程序的机器地址是 10.1.2.4,将目标系统上的浏览器指向 http://10.1.2.4:8000,就能获取所需内容。

本方法假定本地网络是安全的。请勿在公共网络或任何其他您不信任的网络环境中执行此操作。

12.2 rsync

当你想复制的不仅仅是一两个文件时,可以使用需要目的地服务器支持的工具。例如,你可以用 scp -r 将整个目录结构复制到另一个地方,前提是远程目的地必须支持 SSH 和 SCP 服务器(Windows 和 macOS 都支持)。我们已经在第 10 章中看到过这个选项:

$ scp -r directory user@remote_host[:dest_dir]

这种方法可以完成工作,但不是很灵活。特别是,传输完成后,远程主机可能没有目录的精确副本。如果远程机器上已经存在目录,并且其中包含一些无关文件,那么这些文件在传输后仍会存在。
如果你希望经常做这类事情(尤其是如果你计划自动执行该过程),你应该使用一个专门的同步系统,它还可以执行分析和验证。在 Linux 上,rsync 是标准的同步器,性能良好,并提供多种有用的传输方式。在本节中,我们将介绍一些基本的 rsync 操作模式,并了解它的一些特殊性。

12.2.1 rsync 入门

要让 rsync 在两台主机间运行,你必须在源主机和目标主机上都安装 rsync 程序,还需要一种从另一台机器访问其中一台机器的方法。传输文件最简单的方法是使用远程 shell 账户,我们假设你想使用 SSH 访问来传输文件。不过,请记住,即使是在一台机器上的不同位置之间复制文件和目录,比如从一个文件系统复制到另一个文件系统,rsync 也能派上用场。
从表面上看,rsync 命令与 scp 并无太大区别。事实上,你可以使用相同的参数运行 rsync。例如,要将一组文件复制到主机上的主目录,请输入

$ rsync file1 file2 ... host:

在任何当代系统上,rsync 都假定你使用 SSH 连接到远程主机。

rsync not found
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 的文件的机器上,那么 rsync 之后,目标目录将包含 d/a、d/b 和 d/c。
要制作源目录的精确副本,必须删除目标目录中不存在于源目录的文件,例如本例中的 d/c。请使用 --delete 选项来实现这一目的:

$ rsync -a --delete dir host:dest_dir

此操作可能很危险,因此请花时间检查目标目录,看看是否有任何内容会被无意中删除。记住,如果对传输没有把握,可以使用 -nv 选项进行模拟运行,这样就能准确知道 rsync 要删除文件的时间。

12.2.3 使用尾部斜线

在 rsync 命令行中指定一个目录作为源文件时要特别小心。请看我们目前使用的基本命令

$ rsync -a dir host:dest_dir

完成后,dest_dir 中的目录 dir 就会出现在 host 上。图 12-1 显示了 rsync 通常如何处理包含 a 和 b 文件的目录的示例。

图 12-1:正常的 rsync 复制
不过,在源名称后添加斜线 (/) 会明显改变行为:

$ rsync -a dir/ host:dest_dir

在这里,rsync 会将 dir 中的所有内容复制到主机上的 dest_dir,而不会在目标主机上创建 dir。因此,可以将 dir/ 的传输视为类似于本地文件系统上 cp dir/* dest_dir 的操作。
例如,假设有一个包含 a 和 b 文件(dir/a 和 dir/b)的目录 dir。运行该命令的跟踪斜线版本,将它们传输到主机上的 dest_dir 目录:

$ rsync -a dir/ host:dest_dir

传输完成后,dest_dir 包含 a 和 b 的副本,但不包括 dir。但是,如果省略了 /on dir 的尾部,dest_dir 就会得到一个包含 a 和 b 的 dir 副本。传输的结果是,远程主机上会有名为 dest_dir/dir/a 和 dest_dir/dir/b 的文件和目录。图 12-2 展示了 rsync 在使用尾部斜线时如何处理图 12-1 中的目录结构。

在向远程主机传输文件和目录时,如果不小心在路径后添加了 /,通常只会造成麻烦;你可以前往远程主机,添加 dir 目录,然后将所有传输的项目放回 dir 中。不幸的是,当你将尾部的 / 与 --delete 选项结合使用时,可能会造成更大的灾难;一定要格外小心,因为这样很容易删除不相关的文件。

图 12-2: rsync 中尾部斜线的影响

请警惕 shell 的文件名自动补全功能。许多 shell 会在您按下 TAB 键后,在完成的目录名上添加斜线。

12.2.4 排除文件和目录

rsync 的一个重要功能是可以将文件和目录排除在传输操作之外。例如,你想将名为 src 的本地目录传输到主机,但又想排除任何名为 .git 的文件。你可以这样做

$ rsync -a --exclude=.git src host:

请注意,这条命令会排除所有名为 .git 的文件和目录,因为 --exclude 使用的是模式,而不是绝对文件名。要排除某个特定项目,请指定以 / 开头的绝对路径,如图所示:

$ rsync -a --exclude=/src/.git src host:

该命令中 /src/.git 的第一个 / 不是系统根目录,而是传输的基本目录。

这里还有一些关于如何排除模式的提示:

  • 你可以使用任意多个 --exclude 参数。
  • 如果重复使用相同的模式,可将其放在纯文本文件中(每行一个模式),然后使用 --exclude-from=file 。
  • 若要排除名为 item 的目录,但包含该名称的文件,请使用尾部斜线:--exclude=item/。
  • 排除模式基于完整的文件或目录名称组件,并可包含简单的球状通配符(通配符)。例如,t*s 与此匹配,但不匹配ether。
  • 如果排除了某个目录或文件名,但发现自己的模式限制性太强,可以使用 --include 来特别包括另一个文件或目录。

12.2.5 检查传输、添加保护措施和使用核查模式

为加快运行速度,rsync 使用快速检查来确定传输源上的任何文件是否已在目标上。检查使用文件大小和最后修改日期的组合。第一次将整个目录层次结构传输到远程主机时,rsync 会发现目的地没有任何文件已经存在,并传输所有文件。使用 rsync -n 测试传输过程可以验证这一点。
运行一次 rsync 后,使用 rsync -v 再运行一次。这一次,你会发现传输列表中没有文件显示,因为文件集在两端都存在,且修改日期相同。
当源端的文件与目标端的文件不一致时,rsync 会传输源文件并覆盖远程端存在的任何文件。不过,默认行为可能不够充分,因为在传输过程中跳过文件之前,你可能需要额外的保证,即文件确实是相同的,或者你可能想要添加一些额外的保护措施。下面是一些很有用的选项:

  • --校验和(缩写:-c)计算文件的校验和(主要是唯一签名),看它们是否相同。在传输过程中,该选项会消耗少量 I/O 和 CPU 资源,但如果你处理的是敏感数据或文件大小通常一致的文件,则必须使用该选项。
  • --忽略已存在文件 不删除目标端已存在的文件。
  • -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 尽可能快地运行,连接速度还是会显得很慢,因为 HTTP 请求等外发 TCP 数据包将不得不与传输数据争夺上行链路的带宽。
要解决这个问题,可以使用 --bwlimit 给上行链路一点喘息空间。例如,要将带宽限制在 100,000Kbps 以下,可以这样做

$ rsync --bwlimit=100000 -a dir host:dest_dir

12.2.8 向电脑传输文件

rsync 命令不仅可以将文件从本地机器复制到远程主机。通过将远程主机和远程源路径作为命令行的第一个参数,你也可以将文件从远程机器传输到本地主机。例如,要将远程系统上的 src_dir 传输到本地主机上的 dest_dir,请运行此命令:

$ rsync -a host:src_dir dest_dir

如前所述,您也可以使用 rsync 复制本地机器上的目录,只需在两个参数中省略 host:即可。

12.2.9 更多 rsync 主题

每当需要复制大量文件时,rsync 都会是最先想到的实用工具之一。在批处理模式下运行 rsync 对将同一组文件复制到多个主机特别有用,因为它能加快长时间传输的速度,并能在传输中断时恢复。

你还会发现 rsync 在备份时非常有用。例如,你可以将互联网存储(如亚马逊的 S3)连接到 Linux 系统,然后使用 rsync --delete 定期将文件系统与网络存储同步,从而实现一个非常有效的备份系统。
除了这里介绍的命令行选项,还有很多其他命令行选项。运行 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 机器使用标准的 Windows 网络协议服务器消息块(SMB)访问 Linux 系统的文件和打印机。
Unix 的标准文件共享软件套件称为 Samba。Samba 不仅能让网络中的 Windows 计算机访问你的 Linux 系统,还能反过来使用:你可以通过 Samba 客户端软件从 Linux 机器打印和访问 Windows 服务器上的文件。
要设置 Samba 服务器,请执行以下操作:

  • 创建一个 smb.conf 文件。
  • 在 smb.conf 文件中添加文件共享部分。
  • 在 smb.conf 中添加打印机共享部分。
  • 启动 Samba 守护进程 nmbd 和 smbd。

从发行版软件包安装 Samba 时,系统会使用服务器的一些合理默认值执行这些步骤。不过,它可能无法确定你希望将 Linux 机器上的哪些特定共享(资源)提供给客户端。

本章对 Samba 的讨论并不全面;它仅限于让单个子网中的 Windows 机器通过 Windows 网络位置浏览器看到一台独立的 Linux 机器。配置 Samba 的方法不胜枚举,因为访问控制和网络拓扑结构有多种可能性。有关如何配置大型服务器的详细内容,请参阅 Gerald Carter、Jay Ts 和 Robert Eckstein 合著的《Using Samba》(第 3 版)(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]
# server name
netbios name = name
# server description
server string = My server via Samba
# workgroup
workgroup = MYNETWORK

这些参数的作用如下:

  • netbios name 服务器名称。如果省略此参数,Samba 将使用 Unix 主机名。NetBIOS 是 SMB 主机之间经常使用的 API。
  • server string 服务器的简短描述。默认为 Samba 版本号。
  • 工作组 Windows 工作组名称。如果在 Windows 域中,请将此参数设置为域的名称。

12.4.2 服务器访问控制

可以在 smb.conf 文件中添加选项,限制哪些机器和用户可以访问 Samba 服务器。以下是可以在 [global] 部分和控制单个共享的部分(如本章后面所述)中设置的众多选项中的几个:
接口 设置此项可让 Samba 在指定的网络或接口上监听(接受连接)。例如

interfaces = 10.23.2.0/255.255.255.0
interfaces = enp0s31f6
  • bind interfaces only:将此项设置为 “是”,以便将访问权限限制在只能通过这些接口直接访问的机器上。
  • valid users 设置此项以允许指定用户访问。例如
valid users = jruser, bill
  • guest ok 将此参数设置为 true 可让网络上的匿名用户访问共享。只有在确定网络是私有的情况下才可这样做。
  • browseable 设置此项可让网络浏览器查看共享。如果将任何共享的此参数设置为 “否”,则仍可访问 Samba 服务器上的共享,但需要知道共享的确切名称才能访问它们。

12.4.3 密码

一般来说,只有通过密码验证才能访问 Samba 服务器。不幸的是,Unix 的基本密码系统与 Windows 的不同,因此除非指定明文网络密码或使用 Windows 域服务器验证密码,否则必须设置其他密码系统。本节将向你展示如何使用 Samba 的 Trivial Database (TDB) 后端设置一个适合小型网络的替代密码系统。
首先,在 smb.conf [global] 部分使用以下条目定义 Samba 密码数据库的特性:

# use the tdb for Samba to enable encrypted passwords
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 后端参数,可以选择在冒号后指定 TDB 文件的路径名,例如,tdbsam:/etc/samba/private/passwd.tdb。

如果可以访问 Windows 域,则可以设置安全性 = 域,使 Samba 使用域的身份验证系统,而无需密码数据库。不过,为了让域用户访问运行 Samba 的计算机,每个域用户都必须在该计算机上拥有具有相同用户名的本地帐户。

  • 添加和删除用户
    要让 Windows 用户访问 Samba 服务器,首先需要使用 smbpasswd -a 命令将用户添加到密码数据库:
# smbpasswd -a username

smbpasswd 命令的用户名参数必须是 Linux 系统中的有效用户名。
与普通系统的 passwd 程序一样,smbpasswd 会要求你输入两次新 SMB 用户的密码。密码通过必要的安全检查后,smbpasswd 会确认已创建新用户。
要删除用户,请使用 smbpasswd 的 -x 选项:

# smbpasswd -x username

要暂时停用用户,可使用 -d 选项;之后可使用 -e 选项重新启用用户:

# smbpasswd -d username
# smbpasswd -e username
  • 更改密码

可以超级用户身份更改 Samba 密码,方法是使用 smbpasswd,除用户名外无其他选项或关键字:

# 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_file

nmbd 守护进程是一个 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 这里的 “是 ”或 “true ”设置将共享标记为读写。不允许访客访问读写共享。
  • printable 显然,在目录共享中,该参数必须设置为 “否 ”或 “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/passwdentry 来确定 [homes] 的主目录。不过,如果不想让 Samba 遵循这一行为(即希望将 Windows home 目录放在与常规 Linux home 目录不同的位置),可以在路径参数中使用 %S 替换。例如,下面是切换用户的

path = /u/%S

Samba 将当前用户名替换为 %S。

参考资料

12.4.8 共享打印机

通过在 smb.conf 文件中添加 [printers] 部分,可以将打印机导出到 Windows 客户端。下面是使用标准 Unix 打印系统 CUPS 时该部分的外观:

[printers]
comment = Printers
browseable = yes
printing = CUPS
path = cups
printable = yes
writable = no

要使用打印 = CUPS 参数,您的 Samba 安装必须针对 CUPS 库进行配置和链接。
注意
根据您的配置,您可能还希望使用 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

使用 “类型 ”字段帮助你理解每个共享,只需注意磁盘和打印机共享(IPCshares 用于远程管理)。该列表中有两个磁盘共享和两个打印机共享。使用 Sharenamecolumn 中的名称访问每个共享。

12.4.9.1以客户端身份访问文件

如果只需要临时访问磁盘共享中的文件,请使用以下命令(同样,如果你的 Linux 用户名与服务器上的用户名一致,可以省略 -U 用户名):

$ smbclient -U username "\\SERVER\sharename

成功后,你会得到如下提示,表明你现在可以传输文件了:

smb: \>

在这种文件传输模式下,smbclient 类似于 Unix 的 ftp,你可以运行这些命令:

  • get file 从远程服务器拷贝文件到当前本地目录。
  • put file 将本地机器上的文件复制到远程服务器上。
  • cd dir 将远程服务器上的目录更改为 dir。
  • lcd localdir 将当前本地目录更改为 localdir。
  • pwd 打印远程服务器上的当前目录,包括服务器和共享名称。
  • !command 在本地主机上运行命令。两个特别方便的命令是 !pwd 和 !ls ,用于确定本地端的目录和文件状态。
  • help 显示完整的命令列表。

12.4.9.2使用 CIFS 文件系统

如果想更方便地访问 Windows 服务器上的文件,可以使用挂载直接将共享附加到系统上。命令语法如下(注意使用 SERVER:sharename 而非正常的 \SERVER\sharename 格式):

# mount -t cifs SERVER:sharename mountpoint -o user=username,pass=password

要像这样使用挂载,系统上必须安装通用互联网文件系统(CIFS)实用程序。大多数发行版都将其作为一个单独的软件包提供。

12.4.10 Ubuntu搭建samba实例:

$ sudo apt install samba
$ sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.backup
$ sudo nano /etc/samba/smb.conf
[ShareName]
   path = /path/to/shared/folder
   read only = no
   browsable = yes
$ sudo systemctl restart smbd
$ sudo smbpasswd -a username

参考:https://reintech.io/blog/installing-configuring-samba-ubuntu-22

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 服务器都默认启用 SFTP。
  • 它不依赖于任何特定的网络配置。只要能打开 SSH 连接,SSHFS 就能正常工作,无论连接是在安全的本地网络还是不安全的远程网络上。

SSHFS 的缺点是

  • 性能下降。加密、转换和传输的开销很大(但可能没有你想象的那么糟糕)。
  • 多用户设置受到限制。

如果你认为 SSHFS 可能适合你,那就绝对值得一试,因为它的设置非常简单。

12.6 NFS

NFS 是 Unix 系统中最常用的传统文件共享系统之一,有许多不同版本的 NFS 可用于不同场景。您可以通过 TCP 和 UDP 为 NFS 提供服务,并有大量的身份验证和加密选项(遗憾的是,默认情况下启用的选项很少)。由于选项众多,NFS 可能是一个很大的话题,因此我们将只做最基本的介绍。
要使用 NFS 在服务器上挂载远程目录,请使用与挂载 CIFS 目录相同的基本语法:

# mount -t nfs server:directory mountpoint

从技术上讲,你并不需要 -t nfs 选项,因为 mountshould 会帮你解决这个问题,但你可能需要研究一下 nfs(5) 手册页面中的选项。使用 sec 选项,你可以找到几种不同的安全选项。许多小型封闭网络的管理员使用基于主机的访问控制。更复杂的方法,如基于 Kerberos 的身份验证,需要在系统的其他部分进行额外配置。
当你发现通过网络更多地使用文件系统时,请设置自动计数器,使系统只在你实际尝试使用文件系统时才挂载它们,以防止出现启动时的依赖性问题。传统的自动挂载工具名为 automount,还有一个更新的版本名为 amd,但其中大部分功能现已被 systemd 中的自动挂载单元类型所取代。

  • NFS 服务器
    设置 NFS 服务器向其他 Linux 机器共享文件要比配置客户端复杂得多。你需要运行服务器守护进程(mountd 和 nfsd),并设置 /etc/exports 文件以反映你要共享的目录。不过,我们不会介绍 NFS 服务器,主要是因为通过网络共享存储通常要方便得多,只需购买一台 NAS 设备来代为处理即可。许多此类设备都基于 Linux,因此自然会支持 NFS 服务器。供应商通过提供自己的管理工具为 NAS 设备增添价值,以减轻设置 RAID 配置和云备份等繁琐任务的痛苦。

12.7 云存储

说到云备份,另一种网络文件存储方式是云存储,如 AWS S3 或 Google Cloud Storage。这些系统没有本地网络存储的性能,但却有两个显著优势:你永远不必维护它们,也不必担心备份问题。
除了所有云存储提供商都提供的网络(和编程)接口外,还有一些方法可以在 Linux 系统上挂载大多数类型的云存储。与我们目前看到的大多数文件系统不同,这些系统几乎都是以 FUSE(用户空间文件系统)接口的形式实现的。对于一些流行的云存储提供商,如 S3,甚至有多种选择。这是有道理的,因为 FUSE 处理程序只不过是一个用户空间守护进程,充当数据源和内核之间的中介。

本书不涉及设置云存储客户端的具体细节,因为每个客户端都不尽相同。

12.8 网络文件共享的现状

说到这里,你可能会觉得对 NFS 和一般文件共享的讨论似乎有些不完整--也许是这样,但这只是文件共享系统本身的问题。我们在第 12.3.1 和 12.3.2 节中讨论了性能和安全问题。特别是,NFS 的基本安全级别很低,需要大量额外工作才能提高。CIFS 系统在这方面略胜一筹,因为必要的加密层已内置于当代软件中。然而,性能限制并不容易克服,更不用说当系统暂时无法访问其网络存储时会有多么糟糕的表现了。
为解决这一问题,人们进行了多次尝试。其中最广泛的可能是安德鲁文件系统(AFS),该系统最初设计于 20 世纪 80 年代,就是围绕解决这些问题而建立的。那么,为什么不是每个人都使用 AFS 或类似的系统呢?
这个问题没有统一的答案,但很大程度上是因为设计的某些部分缺乏灵活性。例如,安全机制要求使用 Kerberos 验证系统。尽管该系统普遍可用,但它从未成为 Unix 系统的标准配置,而且需要大量的设置和维护工作(你必须为它设置一个服务器)。
对于大型机构来说,满足 Kerberos 等要求不成问题。这正是 AFS 蓬勃发展的环境;大学和金融机构是 AFS 的大本营。但对于小用户来说,不这样做更简单,他们更喜欢 NFS 或 CIFS 共享等更简单的选项。这种限制甚至延伸到了 Windows;从 Windows 2000 开始,微软改用 Kerberos 作为其服务器产品的默认身份验证,但小型网络并不倾向于使用这种服务器的 Windows 域。

除了身份验证这一先决条件外,还有一个源于更多技术原因的问题。传统上,许多网络文件系统客户端都是内核代码,尤其是 NFS。不幸的是,网络文件系统的要求足够复杂,因此问题开始出现。仅仅是身份验证在内核中就没有用武之地。内核客户端的实现也严重限制了网络文件系统潜在的开发人员基础,阻碍了整个系统的发展。在某些情况下,客户端代码位于用户空间,但其下层总是有某种内核定制。
目前,我们发现在 Linux/Unix 世界中还没有一种真正标准的网络文件共享方式(至少如果你不是一个大型网站,或者你不愿意投入大量的工作)。不过,情况并不一定总是如此。
当提供商开始提供云存储服务时,传统的网络文件共享形式显然已经不适用了。在云中,访问方法建立在 TLS 等安全机制之上,无需建立 Kerberos 等大型系统即可访问存储。正如前文所述,通过 FUSE 访问云存储有很多选择。客户端的任何部分都不再依赖内核;任何类型的身份验证、加密或处理都可以在用户空间轻松完成。
所有这些都意味着,未来的文件共享设计很可能会在安全性和文件名翻译等其他方面融入更多灵活性。

posted @ 2024-07-28 07:31  磁石空杯  阅读(38)  评论(0编辑  收藏  举报