Ubuntu 18.04 配置Samba详解

最近在Ubuntu 18.04上配置了Samba服务,以方便和Windows,Mac跨平台文件共享。虽然通过搜索了几个网页很快就照着实现了该功能,只是觉着有些配置不彻底搞清楚就不踏实。于是本着寻根问底的精神仔细看了看它的帮助文档,整理记录一下。

官方帮助文档链接在此。先简单记录几个Samba的基本操作:

  • 所有配置在/etc/samba/smb.conf里,需要root权限修改。
  • 修改完毕需要运行 sudo service smbd restart 以重启服务使它生效。
  • 配置防火墙ufw以允许访问Samba,可以使用sudo ufw allow samba 即可打开139,445端口。

这里必须得吐槽一下命名的混乱,Samba, smb, smbd 在上面交替出现,为什么就不能统一成一个samba呢?

下面就是详细介绍smb.conf这个文件里的各项。

smb.conf文件格式

  • 文件包括块Sections和参数parameters。每个块都由方括号开始,内部是块名字,块内容持续到下一个方括号为止。每一个块里包含若干 “名称=值”对 name = value。
  • 文件是基于行进行处理的,每一行表示一个块名字,一个参数,或者一个注释。对于过长的句子可以在句尾加斜杠 \ 来表示它是上一行的继续。
  • 块和参数名字大小写不敏感。
  • name = value 定义中,只有第一个等号是重要的。它之前之后的空白都被忽略。块名字和参数名字的前,后以及中间的空格是无意义的(irrelevant)。 参数的前,后空格将被忽略,而参数中间的空格将被原样保留(retained verbatim )。
  • 以分号;或井号#开始的行是注释,都被忽略。
  • 参数的值可以是字符串(不需要引号),布尔值(yes/no, 0/1 或 true/false)。值为布尔值时对大小写不敏感,但字符串时对大小写敏感。个别参数还可以取整数值(numeric),比如 create masks.

块描述

配置文件中的每一块(除了[global]块)都描述了一个共享资源。块的名字就是共享资源的名字,块里的参数定义了各种共享属性。

有三个特殊块,[global], [homes] and [printers],我们稍后将在特殊块这一节里介绍。接下来的注释都适用于普通块。

块可以是文件共享服务,或者打印服务(客户端通过它来访问服务器上的打印服务)。

块可以指定为访客服务guest services,此时不需要密码就可以访问。一个专门的Unix guest账号被用来访问此服务。原文档里说每一个块section都是一个服务service,所以后文解释参数的时候service都可以理解为块 (Sections are either file share services (used by the client as an extension of their native file systems) or printable services (used by the client to access print services on the host running the server).)

非访客服务的块都需要密码来访问它们。

Samba server给文件夹赋的权限不会超过Linux系统赋给该文件夹的权限。

下面的示例代码块定义了一个共享文件夹/home/bar,用户对它有写权限, 通过共享名称foo来访问:

[foo]
path = /home/bar
read only = no

下面的代码块定义了一个可打印共享。此共享是只读,但是可打印。即唯一的写权限是通过调用打开,写入和关闭一个spool file。其中的guest ok 参数表明默认允许guest用户访问。

[aprinter]
path = /usr/spool/public
read only = yes
printable = yes
guest ok = yes

特殊块

[global]块

此块中的参数作用于整个server,或作为其他块中没有定义的一些参数的默认值。参见参数PARAMETERS以获取更多信息。

[homes]块

如果配置文件中有[homes]块,则会把此用户的home路径共享到此处,既可以访问当前samba用户对应的home文件夹。

[printer]块

这个用于共享打印服务,很少用到,所以不再翻译。

用户名/密码验证

有多重方法进行登陆验证。下面列出了Samba使用下面6个步骤来进行验证,如果所有步骤都验证失败,则拒绝该连接;如果某一步验证通过,后续的步骤就不再执行。

如果1个服务被标志为 “guest only = yes”  并且服务器运行在共享级安全(“security = share”), 1到5步会被略掉。

  1. 如果客户端提供的用户名/密码通过了UNIX的密码程序验证,则该连接就会用此用户名进行连接。这包括使用 \\server\service%username 来传递用户名的方法。
  2. 如果客户端以前在系统里注册了一个用户名并且现在提供了一个正确的密码,此连接将被允许。
  3. 将提供的密码和客户端的NetBIOS名称和任何以前用户的任何用户名比较,如果相符,则允许连接。
  4. 如果客户端实现在server端验证了户名/密码对,且客户端提供了有效的token,则连接有效。
  5. 如果 user = 的参数被定义,而客户端提供了一个密码,且该密码和该参数列表的某一个user相符,则可以连接。如果user= 列表里的名字前有个@,则表示整个组内的用户名。
  6. 如果服务是guest服务,一个连接会用配置里guest account=的用户名来创建,不管是否提供密码。

参数详解

一些参数是专用于[global]块的,另一些可以被所有块使用。下面参数列表中,每个参数后都跟了一个(G) 或者 (S),它们仅做为描述字符来区分,不能出现在配置文件中。

  • (G)表示该参数是专用于[global]块的;
  • (S) 表明该参数可以用于一个专门的service块

所有的S参数都可以在[global]块中指定,此时它可以作为其他块中该参数的默认值。下面的参数按照字母顺序排列。

变量替换

配置文件中很多参数的值可以用变量替代,例如选项'path=/tmp/%u'就可以翻译成'path=/tmp/john' 如果连接用户是john。

  • %U session username 用户名
  • %G primary group name of %U 组名
  • %h the Internet hostname that Samba is running on 主机名
  • %m the NetBIOS name of the client machine (very useful). 这个参数当Samba在监听端口445时无效。如果想使用它,请在[global]块里指定 smb ports = 139. 这将是Samba不再监听445端口。
  • %L the NetBIOS name of the server. This allows you to change your config based on what the client calls you. Your server can have a “dual personality”.
  • %M the Internet name of the client machine.
  • %R the selected protocol level after protocol negotiation. It can be one of CORE, COREPLUS, LANMAN1, LANMAN2 or NT1.
  • %d the process id of the current server process.进程id
  • %a The architecture of the remote machine. It currently recognizes Samba (Samba), the Linux CIFS file system (CIFSFS), OS/2, (OS2), Windows for Workgroups (WfWg), Windows 9x/ME (Win95), Windows NT (WinNT), Windows 2000 (Win2K), Windows XP (WinXP), Windows XP 64-bit(WinXP64), Windows 2003 including 2003R2 (Win2K3), and Windows Vista (Vista). Anything else will be known as UNKNOWN.
  • %I the IP address of the client machine. 客户机ip地址。
  • %i the local IP address to which a client connected.
  • %T the current date and time.
  • %D name of the domain or workgroup of the current user.
  • %w the winbind separator.
  • %$(envvar) the value of the environment variable envar.

接下来的一些替代参数只适用于某些配置参数(只用于1个连接建立后)。%S,%P, %u, %g, %H,%N,%p不再详细解释。

参数解释

提醒: 每次修改完配置文件并保存修改后,都需要重启samba服务才能生效: sudo service smbd restart. 参数有很多,下面列出一些常用的参数以及解释

  • available (S) 共享开关, 取值为yes或no。设置为no时则此共享块指定的文件夹无法访问。
  • allow hosts(S), 别名是hosts allow,见下文描述。
  • create mask (S) ,别名是create mode,用来设置客户端在server上创建新文件的权限。当文件被创建时,UNIX系统会根据DOS到UNIX的权限转换来创建1个文件权限,然后将此权限和create mask参数的值进行与AND操作来最终确定该文件的属性。该参数默认是0744, 移除了group和other这两类用户的写和执行权限。可以设置为0700来使它仅限于当前用户操作。个人 建议设置为0700.
  • direcotry, 是path的别名,更常用path,见下文描述。
  • deny hosts, 别名是hosts deny,见下文描述。
  • directory mask (S) 这个和create mask 很相似,只是用于指定客户端在server上创建的新文件夹的权限。默认值是0755, 移除了group和other这两类用户的执行权限。个人 建议设置为0700.
  • force user (S) 用来指定建立连接后的用户名。不管使用哪个用户名/密码来访问此参数所在块指定的共享文件夹,系统都用force user的值表示的用户名来操作。这样可以方便多用户来协同操作同一个文件,比如上面create mask里设定0700的文件。
  • force group(S) 用来指定建立连接后的用户所属组,这个和force user非常相似,都是身份修改或者“顶替”。注意它的值会修改force user对应的group. 举例说明,samba server 所在server上有个用户名是test,组是test。配置文件里force user = test, force group = root, 用户连接使用john/password 连接,则连接后的用户名为test,用户组为root。
  • guest account (G), 这个放在[global]块里,用来指定guest account对应的用户名。这个用户名将被用来访问所有设置为guest ok (public)的共享。连接后当前client将有和这个用户相同的访问权限。这个用户名必须存在于现在的pasword文件里(即属于linux的一个用户),但不需要有效登陆。‘ftp’经常是这个参数的一个好选择。 guest account = ftp
  • guest ok, 它的一个别名是public,用来指定是否可以访客方式访问,取值为yes或no。取值为yes时不需要用户名密码,直接输入\\ip\sectionName就可以访问了,特别注意。
  • guest only (S),等同于only guest, 取值为yes或no.如果为Yes,则该共享只允许guest访问。如果guest ok参数没有设置,则此参数无效。
  • hide dot files (S), 取值为yes或no。 是否隐藏server上名字以点.开始的文件是否显示为隐藏文件,默认为yes。
  • hosts allow(S), 别名是allow hosts,参数取值是一系列用逗号,空格或Tab分割的允许访问的主机名,可以是名字或者IP地址。如果它设置在[global] 块里,则它会作用overwrite于所有的共享块,不管某个共享块是否有对此参数的不同具体设置。默认值为空,即都可以访问。
具体举例说明:

Example 1: allow all IPs in 150.203.*.*; except one
hosts allow = 150.203. EXCEPT 150.203.6.66

Example 2: allow hosts that match the given network/netmask
hosts allow = 150.203.15.0/255.255.255.0

Example 3: allow a couple of hosts
hosts allow = lapland, arvidsjaur

Example 4: allow only hosts in NIS netgroup "foonet", but deny access from one particular host
hosts allow = @foonet
hosts deny = pirate
  • hosts deny(S), 别名是deny hosts,和allow host 用法相同,只是作用相反,参数取值是一系列用逗号,空格或Tab分割的拒绝访问的主机名,可以是名字或者IP地址。如果它设置在[global] 块里,则它会作用overwrite于所有的共享块,不管某个共享块是否有对此参数的不同具体设置。默认值为空,没有拒绝任何机器,即都可以访问。
  • invalid users (S) 指定某些用户名或某些group里的用户禁止连接。默认值为空,所有用户都可以连接。Example: invalid users = root fred admin @wheel禁止root,fred admin 以及wheel用户组里所有用户
  • lock directory (G) 指定用来设置最大连接数的lock file的保存路径。
  • max connections (S) 一个共享允许的最大连接说。默认为零,无限制。此特性需要lock file实现,所以要设置参数 lock directory (G) 来指定lock file 的路径。
  • passdb backend (G) 用来决定用户名和组信息的后端保存方式。可选值为smbpasswd, tdbsam, ldapsam
    1) smbpasswd - The default smbpasswd backend. Takes a path to the smbpasswd file as an optional argument.
    2) tdbsam - The TDB based password storage backend. Takes a path to the TDB as an optional argument (defaults to passdb.tdb in the private dir directory.
    3) ldapsam - The LDAP based passdb backend. Takes an LDAP URL as an optional argument (defaults to ldap://192.168.1.98)
Examples of use are:
passdb backend = tdbsam:/etc/samba/private/passdb.tdb 

or multi server LDAP URL with OpenLDAP library:
passdb backend = ldapsam:"ldap://ldap-1.example.com ldap://ldap-2.example.com"

or multi server LDAP URL with Netscape based LDAP library:
passdb backend = ldapsam:"ldap://ldap-1.example.com ldap-2.example.com"
  • path, 别名directory,用来指定文件共享路径。可以用%u来代指登陆用户名,path = /home/%u
  • public,等同于上文guest ok,建议设置为no以保护文件隐私。
  • read list(S) 对此共享设置只读用户列表,如果当前连接的用户名在此列表中,则不管read only怎样设置,该用户都没有写权限。可以加@来设置整个用户组的用户。 默认为空。
  • read only (S) 和writeable相反, 取值yes或no。如果yes,则连接到此共享的用户无法创建或修改文件。默认为yes
  • security mask (S) 类似上面的create mask 和direct mask,用4位数字来表示。客户端在windows上对文件权限修改后,还要与此mask进行与运算,得到最终文件的全限制。比如0777就是不做额外限制,client可以任意修改文件权限(If not set explicitly this parameter is 0777, allowing a user to set all the user/group/world permissions on a file.)。而某一位置零则该文件最终该位权限就是零。默认值为0777.
  • security (G) 这个是最重要的设置之一。默认值为user。这也是和windows 交流时最常用的。其他选项有 share, server, domain.
  • smb passwd file (G) 用于设定加密后的smbpasswd文件路径。默认的编译到了Samba路径, 即/etc/samba/smbpasswd
  • smb ports (G) 指定server监听的端口,默认 smb ports = 445 139
  • socket address (G) This option allows you to control what address Samba will listen for connections on. This is used to support multiple virtual interfaces on the one server, each with a different configuration. By default Samba will accept connections on any address.
    Default: socket address =
    Example: socket address = 192.168.2.20
  • user, users, usernames (S) 三者相同,用逗号分割的用户列表,用户某些客户端无法提供用户名的时候。
  • valid users 允许访问此共享的用户列表。用法类似invalid users,当一个用户同时出现在valid users和invalid users列表里时,则被禁止访问。
  • workgroup This controls what workgroup your server will appear to be in when queried by clients. Default: workgroup = WORKGROUP
  • writable, writeable(S), 二者相同,和read only 反义,无默认值。所以如果一个共享如果即没有写read only,也没有写writable,则采用默认的额read only 默认值yes,为只读模式。
  • write list (S) 具有读写权限的用户列表,不管read only设置如何。默认为空,Example: write list = admin, root, @staff

实例

下面写几个实际操练一下

[TestReadOnly]
path=/home/xx/testreadonly

默认public(guest ok)的值为no,所以不允许guest访问,默认的read only 是yes,所以上述共享是只读模式,要求密码访问。

[TestWrite]
path=/home/xx/testwrite
writable = yes
public = yes

允许任意guest访问,且可写,这个最具安全风险,需结合防火墙来保证符合要求的ip或ip 范围。