sftp

环境说明

[root@sftp ~]# cat /etc/redhat-release 
CentOS Linux release 7.8.2003 (Core)
[root@sftp ~]# ssh -V
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017
[root@sftp ~]# uname -a
Linux sftp.localdomain 3.10.0-1127.19.1.el7.x86_64 #1 SMP Tue Aug 25 17:23:54 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
  • sftp是Secure File Transfer Protocol的缩写,安全文件传送协议。可以为传输文件提供一种安全的加密方法。sftp与ftp 有着几乎一样的语法和功能。SFTP 为 SSH的一部分,是一种传输档案至Blogger伺服器的安全方式。
  • 其实在SSH软件包中,已经包含了一个叫作SFTP(Secure File Transfer Protocol)的安全文件传输子系统,SFTP本身没有单独的守护进程,它必须使用sshd守护进程(端口号默认是22)来完成相应的连接操作,所以从某种意义上来说,SFTP并不像一个服务器程序,而更像是一个客户端程序。
  • SFTP同样是使用加密传输认证信息和传输的数据,所以,使用SFTP是非常安全的。但是,由于这种传输方式使用了加密/解密技术,所以传输效率比普通的FTP要低得多,如果您对网络安全性要求更高时,可以使用SFTP代替FTP。
  • SFTP是一种安全的交互式文件传输程序,其工作方式与FTP(文件传输协议)类似。然而sFTP比FTP更安全,它通过加密SSH传输处理所有操作。它可以配置使用几个有用的SSH功能,如公钥认证和压缩。它连接并登录到指定的远程机器,然后切换到交互式命令模式,在该模式下用户可以执行各种命令。

直接使用sshd配置文件配置sftp

[root@sftp ~]# cp /etc/ssh/sshd_config{,-bak$(date +%Y%m%d)}
[root@sftp ~]# vim /etc/ssh/sshd_config
132 # Subsystem     sftp    /usr/libexec/openssh/sftp-server

134 Subsystem       sftp    internal-sftp -l INFO -f AUTH
#这行指定使用sftp服务使用系统自带的internal-sftp
···
最后添加以下内容
Match Group sftp    #匹配sftp组
    ChrootDirectory /sftp/%u  #定义组目录
    X11Forwarding no
    AllowTcpForwarding no
    #ForceCommand internal-sftp -l INFO -f local5
    #ForceCommand internal-sftp -l INFO -f AUTH
    ForceCommand internal-sftp -l INFO -f AUTH -u 2
[root@sftp ~]# mkdir /sftp
[root@sftp ~]# groupadd sftp
[root@sftp ~]# systemctl restart sshd

创建sftp用户 含创建脚本

[root@sftp ~]# vim create_sftp_user.sh

创建脚本

#!/bin/bash
##################################################################
# 用于创建 sftp 用户
# LastUpdate: 
# Mender: 
# updateDescription: 创建sftp账号须将对方的公钥放于我对应账户下
#################################################################

curr_user=$(whoami)
if [ ${curr_user} != "root" ];then
	echo -e "\n 请使用 root 用户执行该脚本 .\n"
	exit
fi
Usage(){
	echo -e "\n Usage : sh create_sftp_user.sh UserName [ GroupName ] \n"
}

if [ $# -lt 1 ];then
	Usage
	exit
fi

UserName=$1

if [[ ${UserName} =~ ^[a-z][a-z0-9_]+$ ]];then
	:
else
	echo -e "\n 用户名不合规范 .\n"
	exit
fi

id ${UserName} &>/dev/null
if [ $? -eq 0 ];then
	echo -e "\n 该用户已存在或者非法,请检查.\n"
	exit
fi

if [ $# -eq 1 ];then
GroupName=sftp

else
	GroupName=$2
	egrep -q "^${GroupName}\:" /etc/group
	if [[ $? -ne 0 ]];then
       		echo -e "\n ${GroupName} 用户组不存在 .\n"
	        exit
	fi
fi

useradd -s /sbin/nologin ${UserName}
usermod -g ${GroupName} -G ${UserName} ${UserName}
echo -e "\n 创建用户 完成 .\n"

passwd -x 9999	${UserName}
echo -e "\n 设置20年不过期 完成 .\n"

ssh_dir=/home/${UserName}/.ssh
key_dir=/opt/sshkey/${UserName}
mkdir -p ${ssh_dir} ${key_dir}
ssh-keygen -t rsa -P '' -f ${key_dir}/${UserName}
echo -e "\n 生成密钥对 完成 ."

cat ${key_dir}/${UserName}.pub >>${ssh_dir}/authorized_keys
echo -e "\n 配置公钥授信 完成 ."

chown ${UserName}.${GroupName} /home/${UserName}/.ssh -R
chmod 755 ${ssh_dir}
chmod 600 ${ssh_dir}/authorized_keys
echo -e "\n 权限配置 完成 ."

if [ $# -eq 1 ];then
	mkdir -p /sftp/${UserName}/{upload,download}
	chmod 755 /sftp/${UserName}
	chown ${UserName}.${GroupName} /sftp/${UserName}/{upload,download}
	echo -e "\n sftp目录以及权限配置 完成 ."
else
	mkdir -p /sftp/${GroupName}/${UserName}/{upload,download}
	chmod 755 /sftp/${GroupName}/${UserName}
	chmod 775 /sftp/${GroupName}/${UserName}/*
	chown ${UserName}.${GroupName} /sftp/${GroupName}/${UserName}/{upload,download}
	echo -e "\n sftp目录以及权限配置 完成 ."

fi

cp ${key_dir}/${UserName} /tmp/
echo -e "\n\n [ 密钥文件位于 /tmp/${UserName} ,请将该私钥文件导出,放置于客户端服务器上 ]\n\n"
echo -e "\n\n [ 请将合作方公钥文件内容追加至/home/${UserName}/.ssh/authorized_keys中 ]\n\n"

创建用户 testuser 进行测试

[root@sftp ~]# chmod +x create_sftp_user.sh
[root@sftp ~]# ./create_sftp_user.sh testuser

 创建用户 完成 .

调整用户密码老化数据testuser。
passwd: 操作成功

 设置20年不过期 完成 .

Generating public/private rsa key pair.
Your identification has been saved in /opt/sshkey/testuser/testuser.
Your public key has been saved in /opt/sshkey/testuser/testuser.pub.
The key fingerprint is:
SHA256:4uldZ+yj/o2yOzMuLnZ8Ia0OTR6ZNeW0oreZZ5cO2EA root@sftp
The key's randomart image is:
+---[RSA 2048]----+
|            o    |
|           + .   |
|          E o    |
|         * o     |
|      . S.o      |
|     . *.ooO   . |
|      +.oo*.O o  |
|     .oo=.**.*   |
|     ..=+=*X+.o  |
+----[SHA256]-----+

 生成密钥对 完成 .

 配置公钥授信 完成 .

 权限配置 完成 .

 sftp目录以及权限配置 完成 .


 [ 密钥文件位于 /tmp/testuser ,请将该私钥文件导出,放置于客户端服务器上 ]




 [ 请将合作方公钥文件内容追加至/home/testuser/.ssh/authorized_keys中 ]

使用测试机器client进行登陆测试

[root@client ~]# scp root@192.168.10.10:/tmp/testuser ./
root@192.168.10.10's password: 
testuser                                                                                                                   100% 1679     1.0MB/s   00:00    
[root@client ~]# echo "This is a test file" >testfile.txt
[root@client ~]# sftp -i testuser testuser@192.168.10.10
Connected to 192.168.10.10.
sftp> ls
download  upload    
sftp> cd upload/   
sftp> put testfile.txt 
Uploading testfile.txt to /upload/testfile.txt
testfile.txt                                                                                                               100%   20    29.0KB/s   00:00

server端查看

[root@sftp ~]# cd /sftp/testuser/upload/
[root@sftp upload]# ls
testfile.txt
[root@sftp upload]# cat testfile.txt 
This is a test file

创建sftp服务

清除之前的环境,还原机器

创建sftp服务的配置文件

可以直接复制sshd_config进行修改

[root@sftp ~]# cd /etc/ssh/
[root@sftp ssh]# cat sftpd_config 
Port 23456
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
SyslogFacility AUTHPRIV
MaxSessions 200
AuthorizedKeysFile	.ssh/authorized_keys
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication no
GSSAPICleanupCredentials no
UsePAM yes 
X11Forwarding yes
TCPKeepAlive yes
ClientAliveInterval 120
ClientAliveCountMax 0
UseDNS no
PidFile /var/run/sftpd.pid
MaxStartups 2000
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
Subsystem	sftp	internal-sftp -l INFO -f AUTH

Match Group sftp
ChrootDirectory /sftp/%u
X11Forwarding no
AllowTcpForwarding no
ForceCommand    internal-sftp -l INFO -f AUTH

#AllowGroups	sftp2 sftp

#Match User sftp2
#ChrootDirectory /sftp/sftp2
#X11Forwarding no
#AllowTcpForwarding no
#ForceCommand    internal-sftp -l INFO -f AUTH -u 2

#Match Group sftp2
#ChrootDirectory /sftp/sftp2/%u
#X11Forwarding no
#AllowTcpForwarding no
#ForceCommand    internal-sftp -l INFO -f AUTH -u 2

创建sftp服务关键文件

[root@sftp ~]# vim /etc/ssh/sshd_config
132 # Subsystem     sftp    /usr/libexec/openssh/sftp-server
[root@sftp ~]# mkdir /sftp
[root@sftp ~]# groupadd sftp
[root@sftp ~]# cp /usr/sbin/sshd /usr/sbin/sftpd
[root@sftp ~]# cp /etc/pam.d/sshd /etc/pam.d/sftpd
[root@sftp ~]# cp /etc/sysconfig/sshd /etc/sysconfig/sftpd
[root@sftp ~]# cp /usr/lib/systemd/system/sshd.service /usr/lib/systemd/system/sftpd.service
[root@sftp ~]# vim /usr/lib/systemd/system/sftpd.service
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.service
Wants=sshd-keygen.service

[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/sftpd
PIDFile=/var/run/sftpd.pid
ExecStart=/usr/sbin/sftpd -D $OPTIONS -f /etc/ssh/sftpd_config
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target

启动sftpd服务

[root@sftp ~]# systemctl restart sftpd.service
[root@sftp ~]# systemctl status sftpd.service
● sftpd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sftpd.service; disabled; vendor preset: disabled)
   Active: active (running) since 六 2023-01-07 16:32:41 CST; 6s ago
     Docs: man:sshd(8)
           man:sshd_config(5)
 Main PID: 2679 (sftpd)
   CGroup: /system.slice/sftpd.service
           └─2679 /usr/sbin/sftpd -D -f /etc/ssh/sftpd_config

1月 07 16:32:41 sftp systemd[1]: Starting OpenSSH server daemon...
1月 07 16:32:41 sftp sftpd[2679]: Server listening on 0.0.0.0 port 23456.
1月 07 16:32:41 sftp sftpd[2679]: Server listening on :: port 23456.
1月 07 16:32:41 sftp systemd[1]: Started OpenSSH server daemon.
[root@sftp ~]# netstat -anpt | grep 2345
tcp        0      0 0.0.0.0:23456           0.0.0.0:*               LISTEN      2679/sftpd          
tcp6       0      0 :::23456                :::*                    LISTEN      2679/sftpd

使用上面脚本创建用户

[root@sftp ~]# sh create_sftp_user.sh sftp_testuser
访问测试
[root@client ~]# scp root@192.168.10.10:/tmp/sftp_testuser ./
root@192.168.10.10's password: 
sftp_testuser                                                                                                              100% 1679     2.1MB/s   00:00 
[root@client ~]# sftp -P 23456 -i ./sftp_testuser sftp_testuser@192.168.10.10
Connected to 192.168.10.10.
sftp> ls
download  upload    
sftp> cd upload/
sftp> put test_file.txt 
Uploading test_file.txt to /upload/test_file.txt
test_file.txt                                                                                                              100%   20    30.0KB/s   00:00 

sftp-serverinternal-sftp

sftp-server 和 internal-sftp 都是 OpenSSH 的一部分。 sftp-server 是一个独立的二进制文件。 internal-sftp 只是一个配置参数,它告诉 sshd 使用 sshd 内置的 SFTP 服务器代码,而不是像sftp-server运行另一个进程。
与独立的 sftp-server 二进制文件相比, internal-sftp 的诞生时间要晚得多(2008 年的 OpenSSH 4.9p1)。在新版的redhat8及centos8中internal-sftp已经成为默认,保留sftp-server的目的只是为了更好的兼容。
从功能的角度来看,sftp-server和internal-sftp几乎完全相同。 它们是使用相同的源代码构建的。
internal-sftp的主要优点是,当与ChrootDirectory指令一起使用时,它不需要任何支持文件。

对于Subsystem指令:

指定sftp-server实现SFTP文件传输子系统或者internal-sftp实现进程内SFTP服务,这可以简化使用ChrootDirectory强制配置以在客户端上强制使用不同的文件系统root的配置。

对于ForceCommand指令:

指定internal-sftp命令将强制使用与ChrootDirectory一起使用时不需要支持文件的进程内SFTP服务。

对于ChrootDirectory指令:

ChrootDirectory必须包含支持用户会话所需的文件和目录。对于交互式会话,这至少需要一个shell(通常是sh)和基本/ dev节点,例如null,zero,stdin,stdout,stderr和tty设备。对于使用SFTP的文件传输会话,如果使用进程内sftp服务器,则无需对环境进行其他配置,但使用日志记录的会话可能需要在某些操作系统上的chroot目录中使用/ dev / log(请参阅sftp-server以获取细节)。

例:
通过internal-sftp的ChrootDirectory实现限制sftp_users用户组内的用户目录

# For normal SFTP(Without Chroot) add the following configuration in sshd_config file. 
Subsystem  sftp /usr/libexec/openssh/sftp-server -P remove,rmdir,rename,posix-rename
# For Chroot SFTP  add the following configuration in sshd_config file.
Subsystem sftp internal-sftp 
Match Group sftp_users
        ChrootDirectory %h
        ForceCommand internal-sftp  -P remove,rmdir,rename,posix-rename
        X11Forwarding no
        AllowTcpForwarding no

此处的ChrootDirectory中的 %h代表的是home,即用户的家目录

posted @ 2021-11-18 21:35  Chuyio  阅读(531)  评论(0编辑  收藏  举报