哪些因素会影响 Linux 上用户是否可以挂载 NTFS 分区?

A. *_*nda 7 linux mount ntfs

我的系统上有两个 Win8 制作的 NTFS 分区。运行 Debian 测试,Linux 内核 3.16,我可以以普通用户身份挂载其中一个,但尝试挂载另一个会导致错误:

$ mount /media/WinC
Error opening '/dev/sda1': Permission denied
Failed to mount '/dev/sda1': Permission denied
Please check '/dev/sda1' and the ntfs-3g binary permissions,
and the mounting user ID. More explanation is provided at
http://tuxera.com/community/ntfs-3g-faq/#unprivileged
Run Code Online (Sandbox Code Playgroud)

两者都可以由 root 安装,从而在 中产生相同的条目/etc/mtab

/dev/sda1 /media/WinC fuseblk rw,nosuid,nodev,noexec,relatime,user_id=0,group_id=0,allow_other,blksize=4096 0 0
/dev/sdb6 /media/WinE fuseblk rw,nosuid,nodev,noexec,relatime,user_id=0,group_id=0,allow_other,blksize=4096 0 0
Run Code Online (Sandbox Code Playgroud)

/etc/fstab两者的条目是相同的:

/dev/sda1  /media/WinC  ntfs-3g  rw,user,noauto  0  0
/dev/sdb6  /media/WinE  ntfs-3g  rw,user,noauto  0  0
Run Code Online (Sandbox Code Playgroud)

挂载点的访问权限是相同的:

drwxr-xr-x  2 root root 4096 Jan 25  2013 WinC/
drwxr-xr-x  2 root root 4096 Nov 27 22:58 WinE/
Run Code Online (Sandbox Code Playgroud)

最后,块设备的访问权限是相同的:

brw-rw---- 1 root disk 8,  1 Dec 10 20:17 /dev/sda1
brw-rw---- 1 root disk 8, 22 Dec 10 16:24 /dev/sdb6
Run Code Online (Sandbox Code Playgroud)

那么,使以用户身份安装其中一个工作而另一个失败的因素是什么?


按照 podwysoc 的要求,这里是输出strace ntfs-3g /dev/sda1 /media/WinC

execve("/bin/ntfs-3g", ["ntfs-3g", "/dev/sda1", "/media/WinC"], [/* 45 vars */]) = 0
brk(0)                                  = 0x7fe6bbca8000
fcntl(0, F_GETFD)                       = 0
fcntl(1, F_GETFD)                       = 0
fcntl(2, F_GETFD)                       = 0
access("/etc/suid-debug", F_OK)         = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe6bb8b9000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=157945, ...}) = 0
mmap(NULL, 157945, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe6bb892000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20o\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=137440, ...}) = 0
mmap(NULL, 2213008, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fe6bb47e000
mprotect(0x7fe6bb496000, 2093056, PROT_NONE) = 0
mmap(0x7fe6bb695000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x7fe6bb695000
mmap(0x7fe6bb697000, 13456, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fe6bb697000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libntfs-3g.so.852", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0\216\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=334248, ...}) = 0
mmap(NULL, 2429528, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fe6bb22c000
mprotect(0x7fe6bb27c000, 2097152, PROT_NONE) = 0
mmap(0x7fe6bb47c000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x50000) = 0x7fe6bb47c000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1729984, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe6bb891000
mmap(NULL, 3836448, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fe6bae83000
mprotect(0x7fe6bb022000, 2097152, PROT_NONE) = 0
mmap(0x7fe6bb222000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19f000) = 0x7fe6bb222000
mmap(0x7fe6bb228000, 14880, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fe6bb228000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe6bb890000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe6bb88f000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe6bb88e000
arch_prctl(ARCH_SET_FS, 0x7fe6bb88f700) = 0
mprotect(0x7fe6bb222000, 16384, PROT_READ) = 0
mprotect(0x7fe6bb47c000, 4096, PROT_READ) = 0
mprotect(0x7fe6bb695000, 4096, PROT_READ) = 0
mprotect(0x7fe6bbadf000, 8192, PROT_READ) = 0
mprotect(0x7fe6bb8bb000, 4096, PROT_READ) = 0
munmap(0x7fe6bb892000, 157945)          = 0
set_tid_address(0x7fe6bb88f9d0)         = 8822
set_robust_list(0x7fe6bb88f9e0, 24)     = 0
rt_sigaction(SIGRTMIN, {0x7fe6bb4849f0, [], SA_RESTORER|SA_SIGINFO, 0x7fe6bb48d8d0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {0x7fe6bb484a80, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x7fe6bb48d8d0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
open("/dev/null", O_RDWR)               = 3
close(3)                                = 0
getegid()                               = 1000
geteuid()                               = 1000
brk(0)                                  = 0x7fe6bbca8000
brk(0x7fe6bbcc9000)                     = 0x7fe6bbcc9000
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=1613360, ...}) = 0
mmap(NULL, 1613360, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe6bb704000
close(3)                                = 0
lstat("/dev", {st_mode=S_IFDIR|0755, st_size=3700, ...}) = 0
lstat("/dev/sda1", {st_mode=S_IFBLK|0660, st_rdev=makedev(8, 1), ...}) = 0
getuid()                                = 1000
getgid()                                = 1000
lstat("/dev", {st_mode=S_IFDIR|0755, st_size=3700, ...}) = 0
lstat("/dev/sda1", {st_mode=S_IFBLK|0660, st_rdev=makedev(8, 1), ...}) = 0
open("/proc/mounts", O_RDONLY|O_CLOEXEC) = 3
futex(0x7fe6bb229088, FUTEX_WAKE_PRIVATE, 2147483647) = 0
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe6bb8b8000
read(3, "rootfs / rootfs rw 0 0\nsysfs /sy"..., 1024) = 1024
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/rootfs", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/sysfs", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/proc", 0x7fffdd24c640)  = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/udev", 0x7fffdd24c640)  = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/devpts", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/tmpfs", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
lstat("/dev", {st_mode=S_IFDIR|0755, st_size=3700, ...}) = 0
lstat("/dev/disk", {st_mode=S_IFDIR|0755, st_size=140, ...}) = 0
lstat("/dev/disk/by-uuid", {st_mode=S_IFDIR|0755, st_size=200, ...}) = 0
lstat("/dev/disk/by-uuid/f522a1c8-076e-451a-8204-846884bbd509", {st_mode=S_IFLNK|0777, st_size=10, ...}) = 0
readlink("/dev/disk/by-uuid/f522a1c8-076e-451a-8204-846884bbd509", "../../sda2", 4095) = 10
lstat("/dev/sda2", {st_mode=S_IFBLK|0660, st_rdev=makedev(8, 2), ...}) = 0
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/securityfs", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/tmpfs", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/tmpfs", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/tmpfs", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/cgroup", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/pstore", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/cgroup", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
read(3, "/cgroup/cpu,cpuacct cgroup rw,no"..., 1024) = 1024
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/cgroup", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/cgroup", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/cgroup", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/cgroup", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/cgroup", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/cgroup", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/systemd-1", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/mqueue", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/debugfs", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/hugetlbfs", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/fusectl", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/tmpfs", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
lstat("/dev", {st_mode=S_IFDIR|0755, st_size=3700, ...}) = 0
lstat("/dev/sdb3", {st_mode=S_IFBLK|0660, st_rdev=makedev(8, 19), ...}) = 0
lstat("/dev", {st_mode=S_IFDIR|0755, st_size=3700, ...}) = 0
lstat("/dev/sdb2", {st_mode=S_IFBLK|0660, st_rdev=makedev(8, 18), ...}) = 0
read(3, "rdered 0 0\n/dev/sdb4 /home/ca/St"..., 1024) = 221
lstat("/dev", {st_mode=S_IFDIR|0755, st_size=3700, ...}) = 0
lstat("/dev/sdb5", {st_mode=S_IFBLK|0660, st_rdev=makedev(8, 21), ...}) = 0
lstat("/dev", {st_mode=S_IFDIR|0755, st_size=3700, ...}) = 0
lstat("/dev/sdb4", {st_mode=S_IFBLK|0660, st_rdev=makedev(8, 20), ...}) = 0
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/rpc_pipefs", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
getcwd("/home/ca", 4096)                = 9
lstat("/home/ca/tmpfs", 0x7fffdd24c640) = -1 ENOENT (No such file or directory)
read(3, "", 1024)                       = 0
close(3)                                = 0
munmap(0x7fe6bb8b8000, 4096)            = 0
stat("/media/WinC", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/proc/filesystems", O_RDONLY)     = 3
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe6bb8b8000
read(3, "nodev\tsysfs\nnodev\trootfs\nnodev\tr"..., 1024) = 338
close(3)                                = 0
munmap(0x7fe6bb8b8000, 4096)            = 0
geteuid()                               = 1000
getresuid([1000], [1000], [1000])       = 0
setresuid(4294967295, 1000, 4294967295) = 0
geteuid()                               = 1000
getegid()                               = 1000
getresgid([1000], [1000], [1000])       = 0
setresgid(4294967295, 1000, 4294967295) = 0
getegid()                               = 1000
stat("/dev/fuse", {st_mode=S_IFCHR|0666, st_rdev=makedev(10, 229), ...}) = 0
getegid()                               = 1000
geteuid()                               = 1000
stat("/dev/sda1", {st_mode=S_IFBLK|0660, st_rdev=makedev(8, 1), ...}) = 0
mmap(NULL, 135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe6bb898000
stat("/dev/sda1", {st_mode=S_IFBLK|0660, st_rdev=makedev(8, 1), ...}) = 0
open("/dev/sda1", O_RDWR)               = -1 EACCES (Permission denied)
write(2, "Error opening '/dev/sda1'", 25Error opening '/dev/sda1') = 25
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2492, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe6bb897000
read(3, "# Locale name alias data base.\n#"..., 4096) = 2492
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0x7fe6bb897000, 4096)            = 0
open("/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, ": Permission denied\n", 20: Permission denied
)   = 20
munmap(0x7fe6bb898000, 135168)          = 0
write(2, "Failed to mount '/dev/sda1'", 27Failed to mount '/dev/sda1') = 27
write(2, ": Permission denied\n", 20: Permission denied
)   = 20
write(2, "Please check '/dev/sda1' and the"..., 173Please check '/dev/sda1' and the ntfs-3g binary permissions,
and the mounting user ID. More explanation is provided at
http://tuxera.com/community/ntfs-3g-faq/#unprivileged
) = 173
exit_group(19)                          = ?
+++ exited with 19 +++
Run Code Online (Sandbox Code Playgroud)

fix*_*234 2

错误中提到的链接可能包含答案。相关部分:

\n
\n

为什么 chmod 和 chown 没有效果?

\n

默认情况下,NTFS 上的文件由 root 所有,每个人都具有完全访问权限。要获得标准的每个文件保护,您应该使用 \xe2\x80\x9cpermissions\xe2\x80\x9d 选项进行挂载。此外,如果您希望权限与特定的 Windows 配置可互操作,则必须映射用户。

\n

为什么\xe2\x80\x99t非特权用户不能挂载块设备?
\nor
\n为什么我会收到 \xe2\x80\x9cfusermount: option blkdev isprivied\xe2\x80\x9d 错误?

\n

仅当满足以下所有要求时,非特权块设备挂载才有效:

\n
    \n
  1. ntfs-3g 编译时集成了 FUSE 支持
  2. \n
  3. ntfs-3g 二进制文件至少版本为 1.2506
  4. \n
  5. ntfs-3g 二进制文件设置为 setuid-root
  6. \n
  7. 用户有权访问该卷
  8. \n
  9. 用户具有挂载点的访问权限
  10. \n
\n

root 用户可以制作一个 ntfs-3g 二进制 setuid-root ,如下所示

\n
chown root $(which ntfs-3g)\nchmod 4755 $(which ntfs-3g)\n
Run Code Online (Sandbox Code Playgroud)\n

在这种情况下,驾驶员还可以

\n
    \n
  • 修复常见的 FUSE 内核模块加载问题
  • \n
  • 创建所需但有时被错误删除或丢失的 FUSE 设备文件
  • \n
\n

请注意,使用 setuid-root 可能会导致不可预见的权限升级,因此不鼓励使用它。只有绝对信任的用户才必须被授予此类访问权限。下面是一个示例,说明如何让 ntfsuser 组中的用户能够挂载任何 NTFS 卷(如果他们也具有所需的卷访问权限)。

\n
chown root.ntfsuser $(which ntfs-3g)\nchmod 4750 $(which ntfs-3g)\n
Run Code Online (Sandbox Code Playgroud)\n

setuid-root ntfs-3g 驱动程序在其生命周期内应用最小特权原则作为安全措施。

\n

为什么 \xe2\x80\x99t \xe2\x80\x98user\xe2\x80\x99 和 \xe2\x80\x98users\xe2\x80\x99 选项在 /etc/fstab 中不起作用?

\n

\xe2\x80\x98mount\xe2\x80\x99 命令在检查并批准用户有权在指定挂载上挂载给定设备后,\xe2\x80\x99t 命令不会使用所需的权限调用 ntfs-3g 二进制文件点,据此用户可以\xe2\x80\x99打开他在/etc/fstab中获得批准的设备。这是 \xe2\x80\x98mount\xe2\x80\x99 实用程序中的问题。

\n

解决方案:至少使用 NTFS-3G 1.2506 并setuid-root设置并确保用户具有对该卷和安装点的访问权限。

\n
\n

这个问题有两个方面:

\n
    \n
  • 如何授予普通用户访问 NTFS 分区的权限
  • \n
  • 对两个分区为何表现不同的科学好奇心
  • \n
\n

分区之间没有明显差异。该链接讨论了安装实用程序的问题(以及解决方案)。可能还有其他事情发生,例如 udev 活动,使情况变得复杂。当我阅读该链接时,问题似乎实际上应该是为什么一个分区从那时起就以普通用户身份挂载mount,并且fstab只适用于 root。回答问题的第二部分可能是一个侦探和猜测游戏,鉴于现有信息,我无法帮助解决该部分。

\n

然而,问题的第一部分似乎有解决方案。根据链接,分区必须以 root 身份安装,并且根据问题,这是可行的。如上所述,常规用户访问是通过权限完成的。

\n