最後更新: 2022-04-07
目錄
- Match 的設定
- Match 的應用: 限制 root 只可以由某 IP Login
- Match 的應用: 限制 User 只可以 sftp
- Match的優先次序
- chroot sftp
- 一些優化
- Subsystem
- sftp log
Match 的設定
Per Group
Match group filetransfer X11Forwarding no AllowTcpForwarding no GatewayPorts no # Specifies whether tun(4) device forwarding is allowed. PermitTunnel no
Per User
Match User datahunter PasswordAuthentication no
P.S.
# comma-separated lists
User, Group, Host, Address (address/masklen)
Match 的應用: 限制 root 只可以由某 IP Login
/etc/ssh/sshd_config
PermitRootLogin no Match Address 192.168.200.254 PermitRootLogin yes #PasswordAuthentication no
Match 的應用: 限制 User 只可以 sftp
/etc/ssh/sshd_config
# For sftp only
Match group filetransfer
# 禁止所有 forwarding
AllowTcpForwarding no
PermitTunnel no
GatewayPorts no
X11Forwarding no
# ignoring any command supplied by the client and ~/.ssh/rc if present
ForceCommand internal-sftp
service sshd restart
設定 Group 及加 Member ( filetransfer - tim )
# -r, --system
useradd -r -s /bin/false filetransfer
passwd -l filetransfer
useradd -m -s /bin/false tim # 一同建立 home folder
usermod -a -G filetransfer tim # 將 tim 加到 filetransfer Group
限制誰能使用 ssh / sftp
AllowGroups root sshusers filetransfer
Notes: 加 user 入 group
usermod -a -G sshusers
當對方用 ssh 而不是 sftp 時的 log
/var/log/secure
... sshd[17923]: Accepted password for tim from 192.168.88.177 port 53740 ssh2 ... sshd[17923]: pam_unix(sshd:session): session opened for user tim by (uid=0) # uid=0 是正常的 ... sshd[17923]: pam_unix(sshd:session): session closed for user tim
Match的優先次序
先來結論: First Win
測試
# tim 同時屬於 2 個 group (sftp-only, proxy-only)
grep tim /etc/group
sftp-only:x:995:tim proxy-only:x:996:tim
/etc/ssh/sshd_config
測試1: sftp-only 的 Match 排先過 proxy-only
AllowGroups root proxy-only sftp-only Match group sftp-only ForceCommand internal-sftp ... Match group proxy-only ForceCommand /sbin/nologin ...
Result: sftp Success
測試2: proxy-only 排先過 sftp-only
AllowGroups root proxy-only sftp-only Match group proxy-only ForceCommand /sbin/nologin ... Match group sftp-only ForceCommand internal-sftp ...
Result: sftp Login Fail
chroot sftp
設定 user 要被 chroot
/etc/ssh/sshd_config
# Chroot Settings # Subsystem sftp /usr/libexec/openssh/sftp-server Subsystem sftp internal-sftp # For sftp only Match group filetransfer X11Forwarding no AllowTcpForwarding no PermitTunnel no GatewayPorts no # Chroot Settings ChrootDirectory %h ForceCommand internal-sftp # For root ssh login Match Address 192.168.123.* PermitRootLogin yes PasswordAuthentication yes AllowGroups root filetransfer
Variables
- %h <= user 's home directory
- %u <= username
sftp-server
no additional configuration of the environment is necessary
* For logging to work, sftp-server must be able to access "/dev/log"
=> syslogd(8) establish a logging socket inside the chroot directory
Troubleshoot
[1] fatal: bad ownership or modes for chroot directory
...: fatal: bad ownership or modes for chroot directory "/home/sftp/circlek" [postauth]
chown root.other /home/sftp/circlek # The chroot root directory must be owned by root
chmod 755 /home/sftp/circlek # 除了 root 外, 無人可以寫東西入頂層
chown U.G /home/sftp/circlek/upload # 設定一個可以寫東西的 Folder 比人 upload 野
chmod 770 /home/sftp/circlek/upload # Group 及 Other 不可以有 writer permission
[2]
...: subsystem request for sftp ...: error: subsystem: cannot stat /usr/libexec/openssh/sftp-server: No such file or directory ...: subsystem request for sftp failed, subsystem not found ...: pam_unix(sshd:session): session closed for user api
一些優化
ssh
PermitRootLogin no UsePAM no GSSAPIAuthentication no UseDNS no PrintMotd no
sftp
The internal-sftp supports the same set of options as the sftp-server
(https://man.openbsd.org/sftp-server)
umask
# apply a umask of "002"
# -u umask
ForceCommand internal-sftp -u 2 -d /upload
# Option -u is ineffective if -m is set.
-m force_file_perms
i.e.
-m 666
Go to folder "/upload" after login
# -d starting_directory
# %d is replaced by the home directory of the user being authenticated
# %u is replaced by the username of that user
ForceCommand internal-sftp -d /upload
sftp other opts
-R
Places this instance of sftp-server into a read-only mode.
Attempts to open files for writing, as well as other operations that change the state of the filesystem, will be denied.
-P blacklisted_requests
# If both a blacklist and a whitelist are specified,
# The blacklist is applied before the whitelist ?
-p whitelisted_requests
# All request types that are not on the whitelist will be logged and replied to with a failure message.
什麼是Subsystem
subsystem
Configures an external subsystem (e.g. file transfer daemon).
Arguments should be a subsystem name and a command (with optional arguments) to execute upon subsystem request.
i.e.
The command sftp-server(8) implements the ''sftp'' file transfer subsystem.
在 Defautl 的 sftp-server subsystem 下使用 ChrootDirectory 會
...: subsystem request for sftp ...: error: subsystem: cannot stat /usr/libexec/openssh/sftp-server: No such file or directory ...: subsystem request for sftp failed, subsystem not found ...: pam_unix(sshd:session): session closed for user tim
所以在 chroot 情況下會改用 internal-sftp
sftp-server 與 internal-sftp 分別
Both sftp-server and internal-sftp are part of OpenSSH. sftp-server is a standalone binary.
internal-sftp is just a configuration keyword that tells sshd to use SFTP server code built-into sshd,
instead of running another process (typically the sftp-server).
(They are built from the same source code.)
sftp log
# Test on Centos 7
* sftp 預設的 LogLevel 只有 log login 資訊, 沒有 upload / download 記錄
sftp Subsystem 服務
- sftp-server
- internal-sftp (支援 ChrootDirectory)
rsyslog 設定
/etc/rsyslog.d/sftp.conf
# sftp log file local6.* -/var/log/sftp &~
Remark
'&~' they would be limited to /var/log/sftp
service rsyslog restart
/etc/logrotate.d/syslog 頂加入 "/var/log/sftp"
sftp-server 設定
Opts
[-f log_facility] [-l log_level]
-f # The default is AUTH
# The possible values are: DAEMON, USER, AUTH, LOCAL0,
# LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7
-l # The default is ERROR ( 要 log transactions 就要 INFO / VERBOSE )
修改 /etc/ssh/sshd_config
Subsystem sftp /usr/lib/openssh/sftp-server -f LOCAL6 -l INFO
service ssh restart
每個 action 的 Log example
Delete
Jun 8 13:24:23 server sftp-server[18734]: remove name "/root/checkip.php"
Upload
Jun 8 13:24:50 server sftp-server[18779]: sent status No such file Jun 8 13:24:50 server sftp-server[18779]: open "/root/checkip.php" flags WRITE,CREATE,TRUNCATE mode 0666 Jun 8 13:24:50 server sftp-server[18779]: close "/root/checkip.php" bytes read 0 written 82 Jun 8 13:24:50 server sftp-server[18779]: opendir "/root" Jun 8 13:24:50 server sftp-server[18779]: closedir "/root"
Download
Jun 8 13:25:11 server sftp-server[18779]: open "/root/checkip.php" flags READ mode 0666 Jun 8 13:25:11 server sftp-server[18779]: close "/root/checkip.php" bytes read 82 written
internal-sftp
在使用 internal-sftp 時, SyslogFacility, LogLevel 係失效的.
SyslogFacility LOCAL6 LogLevel INFO
所以要用 "-f LOCAL6 -l INFO"
# For sftp only Match group filetransfer ChrootDirectory %h X11Forwarding no AllowTcpForwarding no # Ignoring any command supplied by the client and ~/.ssh/rc if present ForceCommand internal-sftp -u 2 -f LOCAL6 -l INFO
Chroot internal-sftp log
mkdir /home/sftp/circlek/dev
/etc/rsyslog.d/sftp.conf
# sftp log file local6.* -/var/log/sftp &~ # Create socket within chrooted directories to allow for logging $AddUnixListenSocket /home/sftp/circlek/dev/log