我是 Windows 版 OpenSSH(Server 2019)的新手,但我找不到我需要的答案......
我正在尝试是否可以配置 OpenSSH,以便不同的用户可以访问不同的目录。
基本上,我的客户将使用 OpenSSH 让其供应商通过它发送数据。大多数情况下,它们都将进入一个目录,但有一个目录除外,该目录需要进入另一个目录(如果可能,通过 UNC 路径)。
有人知道这是否可能吗?
答案1
是的,你可以。类似如下
ForceCommand internal-sftp
Subsystem sftp sftp-server.exe -d "C:\"
#Match User User1
#ChrootDirectory D:\Data1
Match User User2
ChrootDirectory D:\Data2
Match User User3
ChrootDirectory D:\Data3
Match User User4
ChrootDirectory D:\Data4
这里的User1,User2,User3是机器的本地用户或者AD用户
您甚至可以创建用户组和大权限
Match Group SFTPUsers
ChrootDirectory D:\Data
答案2
对于那些像我一样挣扎时间的人,请注意,有一些条件:
- 用户名必须为小写
- 目录必须由用户或其组拥有
例如,c:\Users\Public 的子目录没有成功。
请注意,您还可以将多个用户帐户用逗号分隔开(无空格),甚至可以使用通配符(*,?)来共享同一个目录:
- 示例 1:匹配用户 user1,user2
- 示例 2:匹配用户“user*”
答案3
要将用户“锁定”(又称“监禁”)到 Windows OpenSSH/SFTP 中的特定目录,请尝试以下操作sshd_config
:
Subsystem sftp sftp-server.exe
ForceCommand internal-sftp
# Optional: only allow specific users / groups to use the system:
# AllowUsers ftp_user1 ftp_user2 ftp_user3 administrator
# ... and/or:
# AllowGroups ftp_users administrators
Match User ftp_user1
ChrootDirectory %h\Documents\
Match User ftp_user2
ChrootDirectory %h\
Match User ftp_user3,ftp_user4,ftp_user5*
ChrootDirectory C:\SFTP\Shared\
以上内容将:
- “锁定”
ftp_user1
到他们的<home directory>\Documents\
文件夹 - “锁定”
ftp_user2
到他们的<home directory>\
文件夹 - “锁定”
ftp_user3
,ftp_user4
,以及任何符合以下条件ftp_user5*
的用户C:\SFTP\Shared\
Match Group
PS 在我的实验中,openssh/sftp 开始表现得不可预测,并且仅仅因为存在一个指令就拒绝几乎所有人的访问(但并非总是如此!)sshd_config
- 即使对于不受该指令影响的用户帐户也是如此。(在两个 WS2019 VM 上尝试过。)所以我会远离它并改用Match User
(如果需要,使用通配符)。
tl;dr(很长):
基本上,我的客户将使用 OpenSSH 让他们的供应商通过它发送数据。
我假设这意味着使用sftp
OpenSSH 子系统 - 这是一件好事,因为该子系统似乎唯一允许通过指令将用户“监禁”到特定目录的子系统ChrootDirectory
:
ChrootDirectory(在 v7.7.0.0 中添加支持)
此指令仅支持 sftp 会话。cmd.exe 的远程会话不会遵守 ChrootDirectory。要设置仅支持 sftp 的 chroot 服务器,请将 ForceCommand 设置为 internal-sftp。您还可以通过实现仅允许 scp 和 sftp 的自定义 shell 来设置带有 chroot 的 scp。
如果您需要 sftp,那么它可以(某种程度上)工作 - 正如其他答案中提到的那样 - 但对我来说,该指令与该Match Group
指令结合使用时似乎会破坏某些东西,并且行为不可预测。没有它,Windows 的标准 OpenSSH/SFTP 功能(对我们来说)用处有限,并且使其更难(和更不安全)维护。
考虑以下超级简单的设置,在一个干净且完全修补了 AD 加入的 Windows Server 2019 上,OpenSSH 的安装如下:开始使用适用于 Windows 的 OpenSSH来自微软的说明。
进行了以下更改C:\ProgramData\ssh\sshd_config
:
SyslogFacility LOCAL0
LogLevel DEBUG3
(以上只是详细地记录到文件而不是 Windows 事件中)
ForceCommand internal-sftp
Subsystem sftp sftp-server.exe -d %d
(以上强制任何 ssh 用户仅使用 sftp,并为 sftp 指定“子系统”,即sftp-server.exe
带有可选-d %d
标志的命令,该命令在用户的主目录中启动该命令 - 请参阅OpenBSD 手册。
已创建本地用户test
并将其添加到标准组。请注意,配置中users
尚无此用户。ChrootDirectory
接下来,我尝试 4-5 次从我的 Win11 桌面通过 PowerShell 使用命令 sftp 到服务器,所有尝试都成功了。由于指令中的标志,sftp
用户进入他们的 Windows 用户目录,并能够浏览整个文件系统,即用户不会-d %d
Subsystem
被判入狱到主目录:
PS> sftp test@sftpserver
test@sftpserver's password:
Connected to sftpserver.
sftp> pwd
Remote working directory: /C:/Users/test
sftp> ls ..
../user1 ../user2 ../All Users ../Default
../Default User ../Public ../user3 ../desktop.ini
../test ../user4
sftp> quit
接下来,我们添加ChrootDirectory
指令(并sshd
在服务器上重新启动服务):
Match Group users,administrators
ChrootDirectory C:\Users\
sftp
连续几个会话,客户端和服务器均未发生任何变化:
PS> sftp test@sftpserver
test@sftpserver's password:
Connected to sftpserver.
sftp> pwd
Remote working directory: /
sftp> ls
user1 user2 All Users Default
Default User Public user3 desktop.ini
test user4
sftp> exit
PS> sftp test@sftpserver
test@sftpserver's password:
client_loop: send disconnect: Connection reset
Connection closed
PS> sftp test@sftpserver
test@sftpserver's password:
Permission denied, please try again.
test@sftpserver's password:
Permission denied, please try again.
test@sftpserver's password:
Connection closed
请注意,在这 3 次尝试中,服务器的响应都是不同的:
- 第一次尝试登录成功,并且用户似乎已被成功“监禁”
C:\Users\
(耶!)。 client_loop: send disconnect: Connection reset
并Connection closed
进行第二次尝试。Permission denied
第三次(以及后续的)尝试
深入研究日志:
5920 2024-02-28 12:45:13.237 debug3: fd 5 is not O_NONBLOCK
5920 2024-02-28 12:45:13.237 debug3: spawning "C:\\Windows\\System32\\OpenSSH\\sshd.exe" "-R"
[... skipping a bunch of lines that don't tell me much ...]
4536 2024-02-28 12:45:13.331 Connection from <source_ip> port 65442 on <this_server_ip> port 22
4536 2024-02-28 12:45:13.331 debug1: Client protocol version 2.0; client software version OpenSSH_for_Windows_8.6
4536 2024-02-28 12:45:13.331 debug1: match: OpenSSH_for_Windows_8.6 pat OpenSSH* compat 0x04000000
4536 2024-02-28 12:45:13.331 debug1: Local version string SSH-2.0-OpenSSH_for_Windows_7.7
4536 2024-02-28 12:45:13.331 debug2: fd 3 setting O_NONBLOCK
4536 2024-02-28 12:45:13.393 debug3: spawning "C:\\Windows\\System32\\OpenSSH\\sshd.exe" "-y"
4536 2024-02-28 12:45:13.409 debug2: Network child is on pid 6016
[...]
4536 2024-02-28 12:45:13.487 debug3: receive packet: type 5 [preauth]
4536 2024-02-28 12:45:13.487 debug3: send packet: type 6 [preauth]
4536 2024-02-28 12:45:13.487 debug3: receive packet: type 50 [preauth]
4536 2024-02-28 12:45:13.487 debug1: userauth-request for user test service ssh-connection method none [preauth]
注意test
上面最后一行中的用户。继续:
4536 2024-02-28 12:45:13.487 debug1: attempt 0 failures 0 [preauth]
4536 2024-02-28 12:45:13.487 debug3: mm_getpwnamallow entering [preauth]
4536 2024-02-28 12:45:13.487 debug3: mm_request_send entering: type 8 [preauth]
4536 2024-02-28 12:45:13.487 debug3: mm_getpwnamallow: waiting for MONITOR_ANS_PWNAM [preauth]
4536 2024-02-28 12:45:13.487 debug3: mm_request_receive_expect entering: type 9 [preauth]
4536 2024-02-28 12:45:13.487 debug3: mm_request_receive entering [preauth]
4536 2024-02-28 12:45:13.487 debug3: mm_request_receive entering
4536 2024-02-28 12:45:13.487 debug3: monitor_read: checking request 8
4536 2024-02-28 12:45:13.487 debug3: mm_answer_pwnamallow
4536 2024-02-28 12:45:13.487 debug2: parse_server_config: config reprocess config len 398
4536 2024-02-28 12:45:13.487 debug3: checking match for 'Group users,administrators' user test host <source_IP> addr <source_IP> laddr <this_server_IP> lport 22
4536 2024-02-28 12:45:13.487 debug3: LsaLogonUser Succeeded (Impersonation: 0)
4536 2024-02-28 12:45:13.487 debug2: get_user_groups: extracting all groups of user test
4536 2024-02-28 12:45:13.487 debug3: Added group 'none' for user test
4536 2024-02-28 12:45:13.487 debug3: Added group 'sftp_users' for user test
4536 2024-02-28 12:45:13.487 debug3: Added group 'users' for user test
4536 2024-02-28 12:45:13.487 debug2: get_user_groups: done extracting all groups of user test
4536 2024-02-28 12:45:13.487 debug1: user matched group list users,administrators at line 95
笔记两个空格在上面最后一行user matched group
中没有用户名. 与成功(上次)登录的类似行进行比较:
7460 2024-02-28 12:44:41.670 debug1: user test matched group list users,administrators at line 95
继续:
4536 2024-02-28 12:45:13.487 debug3: match found
4536 2024-02-28 12:45:13.487 debug3: reprocess config:96 setting ChrootDirectory C:\\Users\\
4536 2024-02-28 12:45:13.487 debug3: checking match for 'Group administrators' user host <source_IP> addr <source_IP> laddr <this_server_IP> lport 22
4536 2024-02-28 12:45:13.487 debug3: get_passwd: Invalid account type: 3.
4536 2024-02-28 12:45:13.487 debug1: Can't match group at line 106 because user does not exist
4536 2024-02-28 12:45:13.487 debug3: match not found
4536 2024-02-28 12:45:13.487 debug3: mm_answer_pwnamallow: sending MONITOR_ANS_PWNAM: 0
4536 2024-02-28 12:45:13.487 debug3: mm_request_send entering: type 9
4536 2024-02-28 12:45:13.487 debug2: monitor_read: 8 used once, disabling now
4536 2024-02-28 12:45:13.487 debug3: mm_inform_authserv entering [preauth]
4536 2024-02-28 12:45:13.487 debug3: mm_request_send entering: type 4 [preauth]
4536 2024-02-28 12:45:13.487 debug2: input_userauth_request: try method none [preauth]
4536 2024-02-28 12:45:13.487 debug3: userauth_finish: failure partial=0 next methods="publickey,password,keyboard-interactive" [preauth]
4536 2024-02-28 12:45:13.487 debug3: send packet: type 51 [preauth]
4536 2024-02-28 12:45:13.487 debug3: mm_request_receive entering
4536 2024-02-28 12:45:13.487 debug3: monitor_read: checking request 4
4536 2024-02-28 12:45:13.487 debug3: mm_answer_authserv: service=ssh-connection, style=
4536 2024-02-28 12:45:13.487 debug2: monitor_read: 4 used once, disabling now
4536 2024-02-28 12:45:13.503 debug3: receive packet: type 50 [preauth]
4536 2024-02-28 12:45:13.503 debug1: userauth-request for user test service ssh-connection method keyboard-interactive [preauth]
4536 2024-02-28 12:45:13.503 debug1: attempt 1 failures 0 [preauth]
4536 2024-02-28 12:45:13.503 debug2: input_userauth_request: try method keyboard-interactive [preauth]
4536 2024-02-28 12:45:13.503 debug1: keyboard-interactive devs [preauth]
4536 2024-02-28 12:45:13.503 debug1: auth2_challenge: user=test devs= [preauth]
4536 2024-02-28 12:45:13.503 debug1: kbdint_alloc: devices '' [preauth]
4536 2024-02-28 12:45:13.503 debug2: auth2_challenge_start: devices [preauth]
4536 2024-02-28 12:45:13.503 debug3: userauth_finish: failure partial=0 next methods="publickey,password,keyboard-interactive" [preauth]
4536 2024-02-28 12:45:13.503 debug3: send packet: type 51 [preauth]
换句话说(根据我迄今为止的经验),当与 结合时Match Group
,ChrootDirectory
会严重破坏事情,甚至导致 sftp 无法使用。
PS 当使用Match User
指令而不是时Match Group
,一切似乎都有效。