运维日记009 - 认识Linux上的桑巴舞——Samba

什么是Samaba?

在现代的办公局域网络中,大部分的工作站使用的是Windows系统,而这类机器没有使用NFS Server访问Linux主机的能力。Windows系统之间使用Microsoft和IBM合作开发的SMB(Server Message Block)协议来进行文件或打印机等设备之间的共享。而Samba就是Linux专为SMB而设计的服务器系统,这样Windows工作站与Linux工作站就可以方便的沟通起来。

为什么要取Samba这个怪名字呢?原来,Samba这套系统是一个名叫Andrew Tridgell的博士生通过逆向工程分析SMB通信协议而开发出来的。软件开发出来以后,Andrew Tridgell为这套系统注册商标,一开始申请用SMBServer作为商标。但是,因为SMB是没有意义的文字,所以无法注册为商标。这位老兄开始翻开字典,就像给孩子取名字一样苦苦查找,突然发现Samba刚好含有SMB,又是一个热情有劲的拉丁舞的的名称,所以就用这个名字作为了商标。

自从有了Samba,微软表示很不满意,因为Samba使得Linux的工作站可以无缝的融入到Windows工作组中,并分走了Windows的奶油和蛋糕嘛!所以微软一直通过各自方式试图阻挠Samba。直到2007年,微软在欧盟的反垄断案中败诉,然后被强制要求向Samba公开他们的网络控制协议,这件事情之后,微软才开始慢慢学习和Samba接触。在2011年微软甚至还向Samba社区提交了一段补丁代码。Samba 团队的 Chris Hertel 在文章中写道:“在过去的年月里,收到来自微软的补丁代码是一件无法想象的事情,但是时代已经变了,战争也该结束。对于软件专利我仍然持否定态度,因为它阻止了软件的创新。但是现在,在为建立一个更强大的社区和提高SMB的互操作性的战斗前线上,微软和我们并肩作战。“

安装Samba

假如你还不知晓自己的系统内是否已经安装了Samba,可以通过如下命令获知:

# smbd -V
Version 3.6.9-164.el6

如果像上面那样可以顺利的看到版本信息,则表示Samba已经安装好了。否则,你还需用安装Samba相关套件。

在RHEL6中,Samba服务的包组是CIFS file server。CIFS即网络文件共享系统(Common Internet File System),就是通过SMB协议而构成的网络文件系统。现在我们来安装它:

# yum groupinstall "CIFS file server"

Samba主要是由两个服务程序构成:

  • smbd
    负责验证用户身份,提供文件与打印机的共享服务。
  • nmbd
    提供WINS(Windows Internet Name Service)服务,也就是查询Windows主机名称所对应的IP地址服务。这相当于SMB局域网上的DNS服务。

配置Samba

在RHEL6下安装好Samba后,主配置文件位置在/etc/samba/smb.conf。虽然有system-config-samba这样的图形化配置工具,但功能有限,Redhat仍然建议用户通过手动编辑配置文件的方式配置Samba。smb.conf文件比较长,我们先来看开头一段:

[global]

# ----------------------- Network Related Options -------------------------
#
# workgroup = NT-Domain-Name or Workgroup-Name, eg: MIDEARTH
#
# server string is the equivalent of the NT Description field
#
# netbios name can be used to specify a server name not tied to the hostname
#
# Interfaces lets you configure Samba to use multiple interfaces
# If you have multiple network interfaces then you can list the ones
# you want to listen on (never omit localhost)
#
# Hosts Allow/Hosts Deny lets you restrict who can connect, and you can
# specifiy it as a per share option as well
#
        workgroup = MSHOME
        server string = Samba Server Version %v

        netbios name = RH6_Samba_111

;       interfaces = lo eth0 192.168.12.2/24 192.168.13.2/24 
        hosts allow = 127. 192.168.1.

整个smb.conf是由多个区段(section)构成的。上面列出了global段定义关于整体的参数,比如工作组名称、NetBIOS主机名、监听的网卡等等。从这段配置文件可见,smb.conf的注释相当详细,所以只要读注释基本就能够了解每个配置参数的作用了。在我上面的配置中:

workgroup = MSHOME,将NT域名或者工作组名称设置为MSHOME。在CIFS中,根据主机不同的功能将它们划分到不同的域或者工作组中以方便管理。域与工作组在规模和管理方式上都有所不同:工作组一般不超过20台主机,而域可以管理上千台主机;而域需要配置单独的域控制器(Domain Controller),而工作组不需要;域的管理是在Domain Controller上集中管理的,而工作组是在每台主机上单独配置的。

server string = Samba Server Version %v,是一段显示给访问者的描述信息。这里我使用了默认设置。

netbios name = RH6_Samba_111,NetBIOS主机名称。这一行把该主机在CIFS中的主机名称设置为”RH6_Samba_111“,如果注释掉该行,会使用hostname作为NetBIOS主机名称。

; interfaces = lo eth0 192.168.12.2/24 192.168.13.2/24,该行指定Samba服务监听在哪些网卡上,注释掉该行表示监听所有网卡。

hosts allow = 127. 192.168.1.,该行定义哪些网段的主机可以访问本Samba服务。这里我定义了127网段和192.168.1网段可以访问。

接下来的很多配置我们看注释就能明白,不再一一描述。下面我们看一下share区段:

#============================ Share Definitions ==============================

[homes]
        comment = Home Directories
        browseable = no
        writable = yes
;       valid users = %S
;       valid users = MYDOMAIN\%S

当SMB客户端连接到此主机时,Samba会自动以用户帐号名建立一个家目录(Home Directory)。writable = yes表示用户可以在家目录中写入文件。browseable = no表示除了用户自己可以浏览本家目录的资源外,其他用户是不可以浏览的。

再往下看到最后几行:

# A publicly accessible directory, but read only, except for people in
# the "staff" group
        [public]
;       comment = Public Stuff
        path = /data
        public = yes
;       writable = yes
        printable = no
;       write list = +staff

这里定义了本Samba服务所共享的资源。[public]为该共享资源访问点的名称;path = /data定义了共享资源的位置;public = yes规定了该目录为公开共享,即无需密码即可访问;printable = no定义了该资源不是一个打印机而是磁盘;; writable = yes注释掉该行表示该目录为只读;; write list = +staff,这里可以设定一个组,该组用户可以写入该共享目录。

这里把/data目录作为共享资源,所以我们必须事先建立好这个目录,并设置好目录的权限:

# mkdir -m 755 /data

假如你的系统开启了SELinux,则还必须修改共享目录的SELinux上下文属性。这里为了简便起见,事先关闭了SELinux,所以就无需设置了。

设定好smb.conf文件后,可以用testparm工具检验此配置文件的语法是否有错误。testparm会列出你的设定值,对于没有明确定义的参数,则会列出它们的默认值。

# testparm -v -s

不同于其他服务,Samba自己会注意smb.conf配置文件的变化,因此不必重新启动Samba来使新的配置文件生效。然而,Samba采用的策略是定期检查,因此要想使你的配置文件立刻生效,除非重启smbd daemon:

# service smb restart

Samba用户和密码

每个Samba用户必须有一个本地账号身份。你可以把一个Linux本地用户作为作为Samba用户,你也可以通过/etc/samba/smbusers文件把一些Samba的虚用户映射为本地用户账号。如:

# cat /etc/samba/smbusers 

root = administrator admin
nobody = guest pcguest smbguest

这里可以看到,系统将administrator和admin这样的虚用户映射为root本地账号,而将guest、pcguest、smbguest这样的虚用户映射为nobody本地账号。建立Samba用户和密码的方法是使用smbpasswd命令,如:

# smbpasswd -a Jimmy

即建立了一个名为Jimmy的Samba用户,当然前提是本地系统内应该有一个Jimmy用户,否则smbpasswd建立Samba用户会失败。

连接Samba服务器

我们用客户端连接一下Samba服务器,测试一下Samba服务器是否正常。在Linux中,有客户端有两种方式连接Samba服务器。

  • smbclient

我们可以安装并使用smbclient这个Samba客户端工具。

# yum install samba-client

用smbclient登陆Samba服务器,看看服务器共享了哪些资源:

$ smbclient -L //moban-c/
Enter wjm's password: 

Anonymous login successful
Domain=[MSHOME] OS=[Unix] Server=[Samba 3.6.9-164.el6]

        Sharename       Type      Comment
        ---------       ----      -------
        public          Disk      Public Stuff
        IPC$            IPC       IPC Service (Samba Server Version 3.6.9-164.el6)
Anonymous login successful
Domain=[MSHOME] OS=[Unix] Server=[Samba 3.6.9-164.el6]

        Server               Comment
        ---------            -------

        Workgroup            Master
        ---------            -------

L参数即list,列出Samba服务器所有共享的资源。在上面这条命令中提示输入密码时我们直接回车,即使用匿名用户登陆。这时我们只看到一个共享资源即public。下面我们使用Jimmy用户登陆一下看看:

$ smbclient -L //moban-c/ -U Jimmy
Enter Jimmy's password:

Domain=[MSHOME] OS=[Unix] Server=[Samba 3.6.9-164.el6]

        Sharename       Type      Comment
        ---------       ----      -------
        public          Disk      Public Stuff
        IPC$            IPC       IPC Service (Samba Server Version 3.6.9-164.el6)
        Jimmy           Disk      Home Directories
Domain=[MSHOME] OS=[Unix] Server=[Samba 3.6.9-164.el6]

        Server               Comment
        ---------            -------

        Workgroup            Master
        ---------            -------

在提示输入密码时,输入刚才用smbpasswd建立的Jimmy的Samba服务密码,以Jimmy用户登入Samba服务器,可以看到两个共享资源,一个为public,另一个为Jimmy的主目录。

我们可以用smbclient访问一下public这个共享资源:

$ smbclient //moban-c/public -U Jimmy
Enter Jimmy's password: 
Anonymous login successful
Domain=[MSHOME] OS=[Unix] Server=[Samba 3.6.9-164.el6]
smb: \>

smbclient支持如put、get这样的类似于FTP的命令,但这样毕竟不太方便。我们还可以使用类似CIFS的方式访问Samba服务器,这样就可以像操作本地文件一样访问Samba共享资源了。

  • CIFS

可以通过mount命令挂载远端Samba服务的共享资源:

# mount //192.168.1.111/public /mnt -o username=Jimmy
Password for Jimmy@//192.168.1.111/public:

输入Jimmy的Samba服务密码即可成功挂载,从此就像操作本地文件一样访问Samba共享资源了。

实战:Samba服务实现小组协同工作

考虑这样一个情形:小组内有Tom、Alice和Jimmy三个用户,三个用户都使用的是Windows工作站。小组配置了一台Linux服务器,并安装了Samba服务。我们在Linux服务器上共享一个目录/smbshare给三个用户使用,每个用户都可以访问并修改别人建立的文件,但是不能删除别人的文件而只能删除自己的文件。该如何实现呢?

1、create Linux local users & groups

在Linux服务器上创建Tom、Alice和Jimmy三个用户,并创建一个组,三个用户应属于同一个组:

# useradd Tom
# useradd Alice
# useradd Jimmy
# groupadd IT
# usrmod -G IT Tom
# usermod -G IT Alice
# usermod -G IT Jimmy

注意,这里并不需要给用户设置密码。因为这三个用户仅仅是通过Samba客户端访问该Linux主机的Samba服务,而并不会直接登陆到该Linux主机。

2、create the share directory & set it properly

需要创建共享文件夹/smbshare,但更重要的是设置好它的权限。因为每个用户都可以修改别人的文件,所以需要设置SGID;又因为只能删除自己的文件,不能删除别人的文件,所以需要设置Sticky位。因此该目录的权限应该为3770。

# mkdir -m 3700 /smbshare
# chgrp IT /smbshare

假如你开启了SELinux,可能还需要做如下设置:

# chcon -t samba_share_t /smbshare

3、modify the Samba configuration file

vim打开/etc/samba/smb.conf,增加以下段:

[ITshare]
        comment = IT share Stuff
        path = /smbshare
        public = no
        writable = yes
        printable = no
        write list = +IT
        browseable = yes

4、create the Samba usrs & passwords

将三个用户设置为Samba用户:

# smbpasswd -a Tom
# smbpasswd -a Alice
# smbpasswd -a Jimmy

5、restart the smbd service:

# service smb reload

or

# service smb restart

好了,Tom、Alice和Jimmy已经可以愉快的合作了。