网络文件共享(5)之使用samba构建跨平台网络文件系统

网络文件共享(5)之使用samba构建跨平台网络文件系统

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:

介绍

下面内容整理自:

Samba 是在 Linux 和 UNIX 系统上实现 SMB 协议的一个免费软件,由服务器及客户端程序构成。SMB(Server Messages Block,信息服务块)是一种在局域网上共享文件和打印机的一种通信协议,它为局域网内的不同计算机之间提供文件及打印机等资源的共享服务。SMB 协议是客户机/服务器型协议,客户机通过该协议可以访问服务器上的共享文件系统、打印机及其他资源。通过设置“NetBIOS over TCP/IP”使得 Samba 不但能与局域网络主机分享资源,还能与全世界的电脑分享资源。

NETBIOS 协议是由 IBM 公司开发,主要用于数十台计算机的小型局域网。该协议是一种在局域网上的程序可以使用的应用程序编程接口(API),为程序提供了请求低级服务的统一的命令集,作用是为了给局域网提供网络以及其他特殊功能。系统可以利用 WINS 服务、广播及 Lmhost 文件等多种模式将 NetBIOS 名——特指基于 NETBIOS 协议获得计算机名称——解析为相应 IP 地址,实现信息通讯,所以在局域网内部使用 NetBIOS 协议可以方便地实现消息通信及资源的共享。因为它占用系统资源少、传输效率高,所以几乎所有的局域网都是在 NetBIOS 协议的基础上工作的。NetBIOS 是 Network Basic Input/Output System 的简称,一般指用于局域网通信的一套 API,是 Windows 基于主机名(最长 15 个字符)实现互相通信的机制。

历史溯源

在早期网络世界当中,档案数据在不同主机之间的传输大多是使用 FTP 这个好用的服务器软件来进行传送。不过,使用 FTP 传输档案却有个小小的问题,那就是您无法直接修改主机上面的档案数据!也就是说您想要更改 Linux 主机上的某个档案时,必需要由 Server 端将该档案下载到 Client 端后才能修改,也因此该档案在 Server 与 Client 端都会存在。这个时候,万一如果有一天您修改了某个档案,却忘记将数据上传回主机,那么等过了一阵子之后,如何知道那个档案才是最新的?!
既然有这样的问题,可不可以在 Client 端的机器上面直接取用 Server 上面的档案,如果可以在 Client 端直接进行 Server 端档案的存取,那么在 Client 端就不需要存在该档案数据,也就是说,只要有 Server 上面的档案资料存在就可以!有没有这样的档案系统(File System)?很高兴的是, NetworkFile System, NFS 就是这样的档案系统之一!我只要在 Client 端将 Server所提供分享的目录挂载进来,那么在 Client 的机器上面就可以直接取用 Server上的档案数据,而且,该数据就像 Client 端上面的分区一般!而除了可以让 Unix Like 的机器互相分享档案的 NFS 服务器之外,在微软(Microsoft)面也有类似的档案系统,那就是 CommonInternet File System, CIFS 这个咚咚啦!CIFS 最简单的实现就是目前常见的『网上邻居』。Windows 系统的计算机可以透过桌面上『网上邻居』来分享别人所提供的档案数据。不过,NFS 仅能让 Unix 机器沟通, CIFS 只能让 Windows 机器沟通。伤脑筋,那么有没有让Windows 与 Unix-Like 这两个不同的平台相互分享档案数据的档案系统?
1991 年一个名叫 Andrew Tridgwell 的大学生就有这样的困扰,他手上有三部机器,分别是跑 DOS 的个人计算机、DEC 公司的 Digital Unix 系统以及 Sun 的 Unix 系统。在当时,DEC 公司有发展出一套称为 PATHWORKS 的软件,这套软件可以用来分享 DEC 的 Unix 与个人计算机的 DOS 这两个操作系统的档案数据,可惜让 Tridgwell 觉得较困扰的是,Sun 的 Unix 无法藉由这个软件来达到数据分享的目的。这个时候 Tridgwell 就想说:『咦!既然这两部系统可以相互沟通,没道理 Sun 就必需这么苦命吧?可不可以将这两部系统的运作原理找出来,然后让 Sun 这部机器也能够分享档案数据呢?』,为了解决这样的的问题,这老兄就自行写了个程序去侦测当 DOS 与 DEC 的 Unix 系统在进行数据分享传送时所使用到的通讯协议信息,然后将这些重要的信息撷取下来,并且基于上述所找到的通讯协议而开发出 ServerMessage Block (SMB) 这个档案系统,而就是这套 SMB 软件能够让 Unix 与 DOS 互相的分享数据!(注:再次的强调一次,在 Unix Like 上面可以分享档案数据的 file system 是 NFS,那么在 Windows 上面使用的『网络邻居』所使用的档案系统则称为 Common Internet File System, CIFS)。
因此 Tridgwell 就去申请了 SMBServer(Server Message Block 的简写)这个名字来做为他撰写的这个软件的商标,可惜的是,因为 SMB 是没有意义的文字,因此没有办法达成注册。既然如此的话,那么能不能在字典里面找到相关的字词可以做为商标来注册呢?翻了老半天,呵呵!这个 Samba 刚好含有 SMB ,又是热情有劲的拉丁舞蹈的名称,不如就用这个名字来做为商标好了。如此,这成为我们今天所使用的 Samba 的名称由来。

组成部分

Samba 软件的主要组成部分有:

  • smbd:这是 samba 的 SMB 服务器。它使用 SMB 协议与客户连接,完成事实上的用户认证、权限管理和文件共享任务。
  • nmbd:提供 NetBIOS 名字服务的守护进程,可以帮助客户定位服务器和域,如同 Windows NT 上的 WINS 服务器。
  • smb.conf:是 samba 的配置文件,在 FreeBSD 中被放在 /usr/local/etc 目录中。
  • swat:是一个 Samba 专用的 WWW 服务器,用于通过客户浏览器配置 Samba,提供了对 Samba 的图形配置界面。
  • smbclient:是一个简单的 SMB 客户程序,用于访问其他 SMB 计算机共享的文件或打印资源,例如 Windows95 或 NT 计算机,它的操作和 ftp 类似。
  • smbprint:是一个 shell 脚本,使用 smbclient 向 Windows 计算机上共享出的打印机上发送要打印的文档。
  • nmblookup:用于查询 NetBIOS 名字的命令行工具。

Samba 服务启动后端口占用情况如下:

  • nmbd 进程占用 137/udp、138/udp 提供 NETBIOS 支持;
  • smbd 进程占用 139/tcp、445/tcp 提供 CIFS 支持;

使用 RPM 安装 Samba 服务时至少需要安装如下套件:

  • samba:这个套件主要包含了 Samba 的主要 daemon 档案(smbd 及 nmbd)、 Samba 的文件档(document)、以及其它与 Samba 相关的 logrotate 设定文件及开机预设选项档案等;
  • samba-common:这个套件则主要提供了 Samba 的主要设定档(smb.conf)、 smb.conf 语法检验的测试程序(testparm)等等;
  • samba-client:这个套件则提供了当 Linux 做为 Samba Client 端时,所需要的工具指令;

不过,在 Mandrake 9.1 当中,则将 samba 这个套件又分为 samba-serversamba-doc 两个套件,所以在 MDK 9.1 则有四个套件需要安装:samba-serversamba-docsamba-commonsamba-client

配置文件

在较早期的版本中, Samba 的配置文件都直接放置在 /etc 底下,后来的版本则将配置文件通通放置到 /etc/samba 底下去了(有的 distribution 放在 /etc/smb 有的则是 /etc/samba.d,请使用 locate 搜寻!)。在 /etc/samba 底下的几个重要的配置文件有: 

  • /etc/samba/smb.conf:这个就是 Samba 最主要的设定档了!在较为简单的设定当中,这也是唯一的一个配置文件!此外,这个档案本身就含有相当丰富的说明,所以,在设定之前,好好的详细的观看一下这个档案吧!这个设定档主要的设定分为两部份,分别是[global] 这个设定主机功能的项目,以及接下来的每个分享出去的目录的属性设定。

  • /etc/samba/lmhosts:这个配置文件的主要目的在对应 NetBIOS name 与该主机名称的 IP ,事实上,他有点像是 /etc/hosts 的功能!只不过这个 lmhosts 对应的主机名称是 NetBIOS name 喔!不要跟 /etc/hosts 搞混了!由于目前 Samba 的功能越来越强大,所以通常只要您一启动 Samba 时,他就能自己捉到 LAN 里面的相关计算机的 NetBIOS name 对应 IP 的信息,因此,这个档案通常可以不用设定了。

  • /etc/samba/smbpasswd:这个配置文件默认并不存在。它是 Samba 预设的使用者密码对应表。当设定的 Samba 服务器是较为严密的,需要使用者输入账号与密码后才能登入的状态时,使用者的密码预设就是放置在这里( 当然啰,您可以自行在 smb.conf 里面设定密码放置的地方及密码文件名,不过,我们这里都以默认的状态来说明) 。比较需要注意的是,这个档案因为包含了使用者的密码,所以,当然权限方面要较为注意啦!这个档案的拥有者需要是 root ,且权限设定为 600 才行。

执行文件

Samba 的执行文件一般来说,做为 Samba Server 的执行档有 testparmsmbdnmbdsmbpasswd,至于做为 Samba Client 的执行档主要则是:smbclient。 

  • smbd(CIFS 协议支持) 与 nmbd(对客户端提供 NetBIOS 名称解析服务):这两个执行档是那两个主要的 daemons ,每次启动 Samba 都会使用到的两个执行档。
  • testparm:当设定完成了 smb.conf 这个主要配置文件之后,而想要查看一下 Samba 的所有设定参数与 smb.conf 的设定项目是否正确时,就需要使用这个 testparm 来查看(test parameters 的简写)!所以,每次在修改完 smb.conf 之后,请务必要使用 testparm 查看看是否有设定错误。
  • smbpasswd:如果 Samba 设定的较为严格,需要规定使用者的账号与密码,那么那个密码档案的建立就需要使用 smbpasswd 来建置才可以,所以这个指令与建立 Samba 的密码有关。 
  • smbclient:当 Linux 主机想要藉由『网络上的芳邻』的功能来查看别台计算机所分享出来的目录与装置时,就可以使用 smbclient 来查看啦!这个指令也可以使用在 Samba 主机上面,用来查看是否设定成功。

相关目录

这部份需要较为注意的应该算是 Samba 的『登录档』。因为近来,利用『网络上的芳邻』来进行破坏的病毒是越来越多!也有越来越多的搞怪者会以网络上的芳邻的相关漏洞进行入侵的伎俩,所以,了解一下登录档放置的地点,并且加以分析,可以得到不小的监测。 

  • /usr/share/doc/samba:包含 Samba 的所有相关的技术手册。也就是说,当安装好 Samba 之后,系统就已经含有相当丰富而完整的 Samba 使用手册。
  • /var/log/samba:Samba 预设的登录文件放置目录。如果 Samba 老是设定不起来,又或者怀疑被人家以 port 137~139 入侵的话,就到这里来观察。
    /usr/share/samba/codepages:放置各个语言的支持格式。举例来说,想让 Samba 支持中文,那么就需要 codepage.950 这个档案的支持。在 smb.conf 里面设定即可。

使用 Windows 做服务端

这里使用 Windows 作为 Samba 服务端在 Windows 中共享一个文件夹让 Linux 主机能够通过 Samba 客户端访问,这里我以 Win10 + CentOS 6.5 为例。

Windows 主机设定

1、开启 Windows 上的 SMB 共享支持:

image.png

2、这里 Samba 共享我们使用基于系统用户认证,这里我们新建一个专门用于访问 Samba 共享的文件系统的用户 sambauser1

image.png

这里给了 sambauser1 用户读写权限。

3、新建一个文件夹名为 win_share 的文件夹作为共享目录,右键 -> 属性 -> 共享:

image.png

CentOS 主机设定

1、安装 Samba 的客户端组件:

$ yum install samba-client -y

2、使用 Samba 客户端(smbclient)查看 Windows 主机共享的文件系统,语法格式为 smbclient -L <服务端主机地址或主机名> -U <服务端主机的系统用户名>,这里我的 Windows 主机的地址为 192.168.3.16,所以访问命令如下:

$ smbclient -L 192.168.3.16 -U sambauser1
Enter sambauser1's password: 
Domain=[DESKTOP-OAUFJ7A] OS=[Windows 10 Pro 17763] Server=[Windows 10 Pro 6.3]

        Sharename       Type      Comment
        ---------       ----      -------
        ADMIN$          Disk      远程管理
        C$              Disk      默认共享
        IPC$            IPC       远程 IPC
        win_share       Disk      
session request to 192.168.3.16 failed (Called name not present)
session request to 192 failed (Called name not present)
session request to *SMBSERVER failed (Called name not present)
NetBIOS over TCP disabled -- no workgroup available

可以看到共享的 win_share 文件系统。

交互式访问

这里的交互式访问指的是类似 ftp 命令提示符下的访问操作。

1、使用 smbclient 访问 Windows 主机共享的 win_share,语法格式为 smbclient <文件系统的 UNC 地址> -U <服务端主机的系统用户名>,访问命令如下:

$ smbclient //192.168.3.16/win_share -U sambauser1
Enter sambauser1's password: 
Domain=[DESKTOP-OAUFJ7A] OS=[Windows 10 Pro 17763] Server=[Windows 10 Pro 6.3]
smb: \> 

2、可以看到访问成功后进入到 smb 的命令提示符下,其中的操作和 ftp 的命令提示符下的操作类似,使用 help 子命令可以查看可以使用的子命令:

smb: \> help
?              allinfo        altname        archive        blocksize      
cancel         case_sensitive cd             chmod          chown          
close          del            dir            du             echo           
exit           get            getfacl        geteas         hardlink       
help           history        iosize         lcd            link           
lock           lowercase      ls             l              mask           
md             mget           mkdir          more           mput           
newer          open           posix          posix_encrypt  posix_open     
posix_mkdir    posix_rmdir    posix_unlink   print          prompt         
put            pwd            q              queue          quit           
readlink       rd             recurse        reget          rename         
reput          rm             rmdir          showacls       setea          
setmode        stat           symlink        tar            tarmode        
timeout        translate      unlock         volume         vuid           
wdel           logon          listconnect    showconnect    ..             
!              
smb: \> 

3、上传 /etc/fstab

smb: \> put fstab 
putting file fstab as \fstab (252.3 kb/s) (average 252.3 kb/s)
smb: \> 

4、在 Windows 主机中查看 win_share 目录:

image.png

上传的文件在 Windows 主机中能查看到,说明交互式访问操作成功。

挂载访问

这里的挂载访问指得是类似挂载、访问 NFS 文件系统的操作。

要挂载 Samba 共享的文件系统也是使用 mount 命令,使用格式如下:

mount -t cifs <share_dir> <mount_point> -o user=<username>,password=<password>
    share_dir:Samba 服务主机上共享的 UNC 格式的文件夹路径;
    mount_point:挂载到本机的挂载点;
    username:Samba 服务主机上的系统用户名;
    password:系统用户密码;

1、挂载 Windows 主机上共享的 win_share 文件系统到 /share/samba

$ mount -t cifs //192.168.3.16/win_share /share/samba/ -o user=sambauser1,password=zze.xyz

2、查看 /share/smaba 目录:

$ ls /share/samba/
fstab

可以看到刚刚上传的 fstab 文件。

3、在 /share/smaba 目录下创建名为 1.txt 的文件:

$ cd /share/samba/ && touch 1.txt

4、返回 Windows 主机查看 win_share 目录:

image.png

挂载目录中创建的文件在 Windows 主机中能够查看到,说明挂载访问操作成功。

使用 CentOS 做服务端

Samba 的用户

在 Linux 中 Samba 的用户认证都是基于系统用户实现:

  • 其账号就是系统用户名;
  • 其密码是 Samba 自己维护的密码;

所以如果要新建一个 Samba 账号必须先创建一个用于访问 Samba 共享的文件系统的系统用户,然后将这个系统用户告知到 Samba,让 Samba 为其维护其访问密码。
为系统用户设定 Samba 访问密码的命令为 smbpasswd,其使用格式如下:

smbpasswd [option] <sys_user>
    option:常用选项
        -a:添加系统用户为 Samba 用户;
        -d:禁用指定账号;
        -e:启用指定账号;
        -x:删除指定账号;
    sys_user:系统用户名

默认情况下,访问 Samba 服务共享的文件系统的 Samba 用户的家目录会被共享出去

添加 Samba 账户

1、先添加一个系统账户:

$ useradd smbuser1

2、添加上面的系统账户为 Samba 账户:

$ smbpasswd -a smbuser1
New SMB password:
Retype new SMB password:
Added user smbuser1.

启动并测试访问

1、启动 Samba 服务:

$ service smb start; service nmb start  
Starting SMB services:                                     [  OK  ]
Starting NMB services:                                     [  OK  ]

启动 Samba 需要将 smbnmb 这两个守护进程都启动。

2、查看是否启动成功:

$ ss -tunl | egrep '(:137)|(:138)|(:139)|(:445)'
udp    UNCONN     0      0          192.168.3.255:137                   *:*     
udp    UNCONN     0      0           192.168.3.17:137                   *:*     
udp    UNCONN     0      0                      *:137                   *:*     
udp    UNCONN     0      0          192.168.3.255:138                   *:*     
udp    UNCONN     0      0           192.168.3.17:138                   *:*     
udp    UNCONN     0      0                      *:138                   *:*     
tcp    LISTEN     0      50                     *:139                   *:*     
tcp    LISTEN     0      50                    :::139                  :::*     
tcp    LISTEN     0      50                     *:445                   *:*     
tcp    LISTEN     0      50                    :::445                  :::*  

如果 Samba 服务成功启动,137、138、139、445 端口都将被占用。

3、在 Windows 中打开网络资源管理器,查看是否出现以 Linux 主机名命名的设备:

image.png

4、双击该设备,输入刚刚创建的 Samba 用户账号及密码:

image.png

也可直接在资源地址栏以 UNC 格式的地址访问 Linux 主机上的 Samba 共享的文件系统,我这里就是 \\192.168.3.17

如果验证成功将会显示以 Samba 用户名命名的文件夹:

image.png

其实该目录是 Linux 主机上 smbuser1 用户的家目录的映射,下面验证一下。

5、进入 smbuser1 目录,创建 1.txt 文件:

image.png

6、切换到 Linux 主机,查看 /home/smbuser1 目录:

$ ll /home/smbuser1/
total 0
-rwxr--r-- 1 smbuser1 smbuser1 0 Jan 31 20:36 1.txt

可以看到在 Windows 上创建的文件出现在系统用户的家目录了。

共享公共目录

在上述测试示例中可以看到,默认情况下访问 Samba 服务共享的文件系统的 Samba 用户仅能看到自己的家目录。
如果我们需要共享一个公共的、特定的目录,则需要修改 Samba 的主配置文件 /etc/samba/smb.conf
在该配置文件中的设定可分为两大类,分别为全局设定和特定共享的设定,而特定共享的设定又可分为私有家目录、打印机共享和自定义共享的设定。
看一下该配置文件,下面仅对其中重点的选项做一下注释说明:

# /etc/samba/smb.conf
# 该配置文件类似于 mysql 的配置文件,通过 [section] 的方式分块配置。
# "#" 开头的为行纯注释,";" 开头的行为可启用的选项。

# [global] 标示下方为全局设定
[global]
        # 工作域的设定,Samba 默认的工作组为 MYGROUP,Windows 默认的工作组为 WORKGROUP
        workgroup = WORKGROUP
        # 服务器的描述信息,使用 smbclient 探测时会打印到屏幕
        server string = Samba Server Version %v
        # netbios 名称,也是 Windows 主机上网络资源管理器中显示的设备名称
;       netbios name = smbserver
        # 指定监听的接口或地址
;       interfaces = lo eth0 192.168.12.2/24 192.168.13.2/24 
        # 白名单,仅允许指定的范围的地址访问
;       hosts allow = 127. 192.168.12. 192.168.13.

        # 日志文件 %m 代指为客户端地址
        log file = /var/log/samba/log.%m
        # 日志滚动大小为 50K
        max log size = 50
        # 指定基于账号和密码访问
        security = user
        # 密码保存在 tdbsam 格式的数据库中
        passdb backend = tdbsam

...

# [homes] 标示针对每个用户家目录的设定
[homes]
        # 注释信息
        comment = Home Directories
        # 当一个用户既不是目录的属主,也不存在于目录的属组,是否仍可浏览,公共共享一个目录时需开启
        browseable = no
        # 是否可写
        writable = yes
        # 设定有效用户,%S 代指当前用户
;       valid users = %S
        # 设定指定域的用户为有效用户
;       valid users = MYDOMAIN\%S

...

如果需要指定一个特定的目录用于共享访问,则需要在 /etc/samba/smb.conf 中自定义块配置,格式如下:

# share_name 共享文件系统名称
[share_name]
# 设定共享的目录路径
path = /path/to/directory
# 注释
comment = Comment String
# 来宾是否可以访问
guest ok = {yes|no}
# 是否公开
public = {yes|no}
# 是否可写
writable = {yes|no}
# 是否只读
read only = {yes|no}
# 可写用户列表,用 "," 隔开,也可以使用 +group_name 标识一个组
write list = +group_name, user1, user2, ...

以共享 /shared 目录为例。

1、在 /etc/samba/smb.conf 添加如下配置:

[smbshare1]
        comment = My Shared Testing
        path = /shared
        read only = no
        guest ok = yes
        writable = yes

2、使用 testparm 命令检查配置文件是否正确:

$ testparm
Load smb config files from /etc/samba/smb.conf
rlimit_max: increasing rlimit_max (1024) to minimum Windows limit (16384)
Processing section "[homes]"
Processing section "[printers]"
Processing section "[smbshare1]"
Loaded services file OK.
...

3、创建文件夹并给与 smbuser1 权限:

$ mkdir /shared
$ setfacl -m u:smbuser1:rwx /shared

4、重启 Samba 服务:

$ service smb restart; service nmb restart;

5、再次在 Windows 中使用 smbuser1 用户访问 Linux 服务端:

image.png

6、可以看到新共享的 smbshare1 出现在了 Windows 的资源目录,进入该文件夹创建文件 2.txt

image.png

7、切换到 Linux 服务端查看 /shared 目录:

$ ls /shared/
2.txt

可以看到在 Windows 中创建的文件成功出现在 Linux 共享目录中,共享成功~

使用图形化工具 swat 配置 Samba

1、Samba 提供了一个 Web 可视化工具 swat 来简易配置工作,先执行下面命令安装一下:

$ yum install -y samba-swat

2、swat 本身就提供了轻量级的 web 服务,并将自身交给超级守护进程 xinetd 代为管理,因此安装完 swat 后再 /etc/xinet.d 下会生成 swat 文件,要让 swat 服务能够随 xinetd 的启动而启动需要修改 /etc/xinet.d/swat 文件中的 disable 选项为 no,如下:

service swat
{
        port            = 901
        socket_type     = stream
        wait            = no
        only_from       = 192.168.3.0/24
        user            = root
        server          = /usr/sbin/swat
        log_on_failure  += USERID
        disable         = no
}

3、启动 xinetd 服务:

$ service xinetd start
Starting xinetd:                                           [  OK  ]

4、检查 swat 服务占用的 901 端口是否处于监听状态:

$ ss -tnl | grep :901
LISTEN     0      64                       :::901                     :::*

5、使用浏览器访问 swat 服务,提示输入用户账号及密码就是系统账号及密码,我这里直接使用 root 测试:

image.png

登录成功后界面如下:

image.png

成功,接下来的配置操作试着点吧点吧就知道了的,自行摸索吧~~

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.zze.xyz/archives/linux-file-sharing5.html

Buy me a cup of coffee ☕.