Match 的應用( force sftp, chroot sftp, sftp log )

最後更新: 2022-04-07

 

目錄

 


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

 


 

Creative Commons license icon Creative Commons license icon