ubuntu samba - hanyong/note GitHub Wiki
ubuntu samba 配置
本文简单说明如何在 ubuntu 16.04 安装配置 samba 服务, 实现与 windows 共享文件.
安装:
sudo aptitude install samba
编辑 /etc/samba/smb.conf
配置。
参考:
- Securing File and Print Server: https://help.ubuntu.com/lts/serverguide/samba-fileprint-security.html
man 5 smb.conf
samba 配置项可以由多个空格分割的单词组成, 这个要注意一下, 如:
create mask = 0755
重要的几个配置有 security
, read only
, create mask
, directory mask
几个。
多数配置都有合适的默认值, 简单做如下修改即可。
-
read only
默认是yes
, 要创建可写共享, 可修改为no
。 -
create mask
默认是0755
, 一般文件不需要执行权限, 建议修改为0644
。 -
默认注释了
[homes]
配置, 可取消注释, 允许访问用户 home 目录。
[homes] ; comment = Home Directories ; browseable = no ```
- 默认配置了打印机共享, 通常不需要, 可注释掉这部分内容。
#[printers]
# comment = All Printers
# browseable = no
# path = /var/spool/samba
# printable = yes
# guest ok = no
# read only = yes
# create mask = 0700
#
## Windows clients look for this share name as a source of downloadable
## printer drivers
#[print$]
# comment = Printer Drivers
# path = /var/lib/samba/printers
# browseable = yes
# read only = yes
# guest ok = no
- 添加自定义共享配置
[repo]
path = /repo
如果修改了配置, 重启 samba 服务即可生效:
sudo systemctl restart smbd
samba 有自己的用户认证方式, 并与 linux 用户做映射实现权限控制。 默认同一用户名即同一用户。
可使用 smbpasswd
命令添加 samba 用户并设置密码:
sudo smbpasswd -a $USER
如果安装了 libpam-smbpass
,
则 linux 用户登录时会自动同步用户名和密码到 samba 服务。
但 ubuntu 16.04 下貌似没这个软件包了, 那就手动使用 smbpasswd 命令操作一下吧。
参考:
- https://launchpad.net/ubuntu/xenial/amd64/libpam-smbpass/
- Why is package libpam-smbpass removed? https://lists.ubuntu.com/archives/ubuntu-devel-discuss/2016-March/016298.html
samba 在 Linux 文件系统上提供 windows 网络文件系统(CIFS)(而不是专门提供 CIFS),从而实现 windows 可以共享访问 Linux 文件系统。 所以这套文件系统有两个视角,一个是从 windows 的角度看,一个是从 Linux 的角度看。
文件系统不只是读写数据,还跟用户认证(谁在读写操作)和权限控制(操作者有哪些权限)紧密相连。 而 samba 需要想办法把两者联系对应起来,就像 cygwin 也要做类似的映射(参考: https://cygwin.com/cygwin-ug-net/ntsec.html)。
搭建/使用这套文件系统有以下事项需要关注:
-
用户认证。使用用户名密码登录,samba 使用用户名将登录用户和 Linux 用户关联起来。
-
文件大小写。windows 不区分大小写,Linux 区分大小写。samba 默认配置是保留大小写但不区分大小写。 所以如果一个文件夹下有两个名字相同大小写不同的文件夹,Linux 访问正常,windows 访问就会混乱,应避免这种用法。
-
文件属性和权限。dos/windows 下有 R/S/H 等属性(参考 attrib 命令),Linux 下有 user/group/other rwx 标志位。 samba 默认将一些属性(如 readonly)和标志位映射起来,没有映射的就不支持。 samba 也支持配置将这些属性存储到 Linux 文件系统的
user_xattr
,默认没有打开。
cygwin 使用 samba 共享的问题
默认没有映射 System 属性(参考 man smb.conf
中 map system
一节),
而 Cygwin 默认 symlink 依赖此属性(参考 https://cygwin.com/cygwin-ug-net/using.html#pathnames-symlinks ),
导致 samba 共享上的 Cygwin 不能正常工作。
解决办法是打开映射或使用 user_xattr
存储 dos 属性,xfs 默认开启了 user_xattr,ext4 需要 mount 时手动指定开启。
但还有用户和组映射的问题,安装 cygwin 尝试执行 /bin/rebase-trigger
脚本时报没有权限。
windows 用户是 "域\名字" 两层结构,没有加入域的计算机本地用户域为本机(一台计算机即一个本机域?),而 Linux 用户用 id 标识。 与 samba 关联的 Linux 用户默认显示为本机域下面的本地用户,没有关联 samba 的用户和组显示为 "Unix User" 和 "Unix Group" (两个特殊域?) 下的用户和组。 windows 用户也有一个 SID,但这个 SID 需要与域关联,只有在关联域下才有意义(?)。 共享文件的用户和组只能设置为共享文件所在域(默认即 samba 主机)下的用户和组。 Linux 文件系统有所有者和所有组,windows 只有所有者,没有所有组,然后可以设置各个用户和组的权限,特殊公共用户 Everyone 表示所有人。
参考 cygwin 做用户映射的逻辑: https://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-mapping ,
可以映射通用用户,本机本地用户,本机所在主域用户,但无法映射其他机器上的本地用户(无法协调 windows SID 和 Linux uid/gid 的映射关系)。
如 F:
是 samba 网络盘,文件所有者为 samba 主机上本地用户,
网络盘上运行的 cygwin 无法识别网络文件系统(整个 cygwin 根文件系统)所属用户和组,
显示为 "Unknown+User","Unix_Group+1000",不能与本地用户(即 cygwin 运行用户) 匹配。
但本地文件系统(如 "/d/cygwin64/" 可以识别)。
C:\Users\hanyong>F:\cygwin64\bin\ls -ald / /d/ /f/ /d/cygwin64/
drwxrwxrwx+ 1 Unknown+User Unix_Group+1000 0 Oct 18 00:14 /
drwx------+ 1 Unknown+User SYSTEM 0 Oct 18 01:28 /d/
drwxrwxrwx+ 1 hanyong None 0 Jun 23 22:19 /d/cygwin64/
drwxr-xr-x 1 Unknown+User Unix_Group+1000 0 Oct 18 09:20 /f/
C:\Users\hanyong>F:\cygwin64\bin\ls -ald / /d/ /f/ /d/cygwin64/ -n
drwxrwxrwx+ 1 4294967295 4278191080 0 Oct 18 00:14 /
drwx------+ 1 4294967295 18 0 Oct 18 01:28 /d/
drwxrwxrwx+ 1 197610 197121 0 Jun 23 22:19 /d/cygwin64/
drwxr-xr-x 1 4294967295 4278191080 0 Oct 18 09:20 /f/
C:\Users\hanyong>F:\cygwin64\bin\id
uid=197610(hanyong) gid=197121(None) groups=197121(None),545(Users),4(INTERACTIVE),66049(CONSOLE LOGON),11(Authenticated Users),15(This Organization),113(本地帐户),66048(LOCAL),262154(NTLM Authentication),4294967295(Unknown+Group),401408(Medium Mandatory Level)
但发现本地文件系统上运行的 cygwin 可以识别挂载的 samba 共享文件所有者为本地用户(为什么?)。
C:\Users\hanyong>D:\cygwin64\bin\ls -ald / /d/ /f/ /d/cygwin64/
drwxrwxrwx+ 1 hanyong None 0 Jun 23 22:19 /
drwxr-xr-x 1 hanyong None 0 Oct 18 01:28 /d/
drwxr-xr-x 1 hanyong None 0 Jun 23 22:19 /d/cygwin64/
drwxr-xr-x 1 hanyong None 0 Oct 18 09:20 /f/
C:\Users\hanyong>D:\cygwin64\bin\ls -ald / /d/ /f/ /d/cygwin64/ -n
drwxrwxrwx+ 1 197610 197121 0 Jun 23 22:19 /
drwxr-xr-x 1 197610 197121 0 Oct 18 01:28 /d/
drwxr-xr-x 1 197610 197121 0 Jun 23 22:19 /d/cygwin64/
drwxr-xr-x 1 197610 197121 0 Oct 18 09:20 /f/
C:\Users\hanyong>D:\cygwin64\bin\id
uid=197610(hanyong) gid=197121(None) groups=197121(None),545(Users),4(INTERACTIVE),66049(CONSOLE LOGON),11(Authenticated Users),15(This Organization),113(本地帐户),66048(LOCAL),262154(NTLM Authentication),4294967295(Unknown+Group),401408(Medium Mandatory Level)
推测 windows 读写操作权限控制的原理是,虽然当前进程是本机用户,但 samba 共享使用远程机器上的用户登录,
所以读写操作使用远程机器上的用户进行,没有问题。
而 cygwin 发现当前进程用户(本地用户)与文件系统用户不匹配,一些操作权限验证即不通过。
如安装 cygwin 时执行 rebase-trigger
脚本报错,但执行二进制文件却可以,执行二进制文件不校验 execute 标识位?
推测二进制文件直接调 windows API 运行,windows 检查可执行位 OK (以远程机器用户访问检查)。
而 windows API 不能直接运行脚本,先由 cygwin 处理,而 cygwin 检查可执行位不通过(以当前用户(作为other)检查)。
C:\Users\hanyong>F:\cygwin64\bin\env /bin/ls /bin/ls /bin/rebase-trigger -al
-rwxrw-r-- 1 Unknown+User Unix_Group+1000 127507 Feb 4 2017 /bin/ls
-rwxrw-r-- 1 Unknown+User Unix_Group+1000 1476 Feb 7 2016 /bin/rebase-trigger
C:\Users\hanyong>F:\cygwin64\bin\env /bin/rebase-trigger
/usr/bin/env: '/bin/rebase-trigger': Permission denied
另外按默认配置, windows 上修改 samba 共享的所有者和权限貌似不会生效(确认?)。
要让 cygwin 正确识别和使用 samba 共享的权限控制,需要把 3 者的用户和权限打通联系起来。 对应 cygwin (Unix like) -> samba/cifs (Windows) -> Linux (Unix like)。
可能的解决办法:
- 加入域,本机进程和 samba 共享都使用域用户。依赖重, windows 10 家庭版不能加入域。
- samba 共享使用 Everyone 权限, 弱化权限控制。
- samba 共享文件系统用户映射成本地用户。是否可行?
尝试方法2,
发现 Everyone 是 windows 下的一个虚拟用户,samba 没有这个用户,没法设置文件所有者为 Everyone。
就连 cygwin 下的 getent passwd
和 getent group
都没有 Everyone,可见这是个完全虚拟的用户。
想过指定一个 Linux 用户为 Everyone,没找到 samba 有自定义 SID/uid map 的地方,
只发现 idmap 保存, winbindd 查询,没有自定义添加条目的地方,好像都是 samba 添加用户时自动生成 SID 并保存管理(?)。
查看 man idmap_tdb2
倒是发现可以指定一个脚本查询 SID/uid 映射关系,
但他要你处理所有 id 映射,而不是只加一个自定义映射。
而且这是个全局配置,不能只操作一个共享目录,好在 idmap 配置可以限定 uid 范围。
作为 workaround 可以配置一个 idmap 只包含一个 uid,设置脚本将这个 idmap 对应的 SID 无条件设置为 Everyone 的 SID (实际只有一个uid)。
但是这样还有个问题,samba 共享文件的权限会自动根据 other 权限生成 Everyone 的权限条目,
如果 Everyone 同时是 user (和 group?),那么 Everyone 就会出现多个权限条目,这会不会有问题?
另外用一台 windows 机器共享 Everyone 为所有者测试,共享上的 cygwin 还是不能正常工作,这条路不通。
方法3也没想到可能的办法,那么就只剩下方法1,加入域。