如果想对外提供一份文件上传服务但又不想额外搭建 HTTP/FTP 服务器,可以使用 SSH 自带的 SFTP 进行文件上传
1 、前言
因为懒,也不是很喜欢 vsftpd 的服务搭建和管理方式,scp 传输协议 和 SSH 绑定的太彻底,所以最后选了 SFTP 给别人上传数据用。
2 、搭建方法
首先创建 sftp 用户,并修改好密码,本例用户名 sftpuser
useradd -s /sbin/nologin -M -d /sftp sftpuser
passwd sftpuser
然后我们需要修改 sshd 配置文件,找到文件最后一行
Subsystem sftp /usr/libexec/openssh/sftp-server
将这行内容替换为以下内容,注意为了区分和 SSH 的登陆方式这里限制为仅密码认证
Subsystem sftp internal-sftp Match User sftpuser AuthenticationMethods password X11Forwarding no AllowTcpForwarding no PermitTTY no ForceCommand internal-sftp ChrootDirectory /sftp
改好后,我们需要修改文件夹权限
chown -R root:root /sftp chmod 755 /sftp mkdir /sftp/upload chown -R sftpuser:sftpuser /sftp/upload
改好后可以查看到文件夹权限结构如下图所示
ls -al /sftp drwxr-xr-x. 4 root root 35 Dec 20 11:10 . drwxr-xr-x. 12 root root 137 Dec 20 11:08 .. drwxr-xr-x. 4 sftpuser sftpuser 4096 Dec 20 12:53 upload
最后,我们就可以进行测试 SFTP 登录了
sftp -P 22 [email protected]
3 、额外说明
3.1 、出现 broken pipe 错误
查阅资料的时候发现会出两个 broken pipe 的情况
第一种是在连接时直接提示 packet_write_wait: Connection to 127.0.0.1 port 22 : broken pipe
这个错误的原因,文件夹权限配置错误,你需要将 ChrootDirectory /home/sftpuser
目录配置为 无写入 权限 (r-x)
第二种是在连接后超时被 broken pipe ,但是我没有遇到。解决方式是在用户配置块里添加两个额外参数
ClientAliveInterval 60 ClientAliveCountMax 1
3.2 、配置 mount 自动挂载
如果我们需要进行开机自动挂载 Sftp,则需要提前安装两个组件
yum install -y sshfs
接着需要创建一对证书 ( 链接 ),并将 Sftp 验证方式修改为 证书登录。
Match User sftpuser AuthenticationMethods publickey
配置上开机挂载选项 [ 链接 ]
vim /etc/fstab
[email protected]:/upload /opt fuse.sshfs rw,IdentityFile=/home/sftpuser/.ssh/id_rsa,port=22,defaults,auto,_netdev,nofail,uid=1000,gid=1002,umask=022,reconnect,default_permissions,allow_other,x-systemd.device-timeout=10s 0 0
参数含义 写入类型 rw 可读可写 私钥证书 IdentityFile=/home/sftpuser/.ssh/id_rsa 远程端口 port=22 挂载方式 defaults 默认参数,等效 "rw,suid,dev,exec,auto,nouser,async" 开机挂载 auto 自动 存储类型 _netdev 网络存储 (当服务无法访问时不会抛出错误)(fuse3 不支持该选项) 权限类型 uid=1000,gid=1002,umask=002 作为指定用户的挂载与配置写入的默认权限 权限类型 default_permissions 检查本地用户是否拥有远程服务器操作权限 权限类型 allow_other 允许他人使用该挂载 (默认挂载使用者为 root) 存储类型 nofail 设备不存在时不报告错误 挂载超时 x-systemd.device-timeout=10 等待设备挂载过程的超时时间秒 挂载超时 x-systemd.idle-timeout=1min 等待设备无请求进而卸载的超时时间 挂载超时 x-systemd.automount 设备启动后不挂载,产生访问请求时挂载(需 local/remote-fs.target) 挂载超时 x-systemd.mount-timeout=30 产生访问请求时的挂载超时时间秒
最后测试挂载情况,并检查是否正常写入
mount -a
ls -al /opt/ touch /opt/test.log ls -al /opt/test.log -rw-r--r--. 1 sftpuser sftpuser 0 Dec 20 13:40 test.log
3.3 、 Umask 限制
在 sshd_config 中增加参数
Subsystem sftp /usr/libexec/openssh/sftp-server -u 022
或者在用户中单独增加参数
ForceCommand internal-sftp -u 022
一些发行版可能使用 0022 而不是 022
4 、 Samba 服务端的部署
如果 SFTP 有不顺手的地方,可以部署 Samba,版本要选择 V2+V3 [ 链接 ]
apt install samba firewall-cmd --add-service=samba --permanent firewall-cmd --reload
useradd smbuser smbpasswd -a smbuser mkdir -p /mnt/samba/ chown -R smbuser:smbuser /mnt/samba setfacl -R -m "u:another_user:rwx" /mnt/samba
vim /etc/samba/smb.conf
[global] workgroup = WORKGROUP server string = %h server (Samba, Ubuntu) interfaces = enp1s0 enp2s0 example.com bind interfaces only = Yes client max protocol = SMB3 client min protocol = SMB2 log file = /var/log/samba/log.%m max log size = 1000 logging = file panic action = /usr/share/samba/panic-action %d server role = standalone server obey pam restrictions = Yes unix password sync = Yes passwd program = /usr/bin/passwd %u passwd chat = Enter\snew\s\spassword:* %n\n Retype\snew\s\spassword:* %n\n password\supdated\ssuccessfully . pam password change = No map to guest = Bad User usershare allow guests = No idmap config * : backend = tdb
[Data] comment = Data create mask = 0750 path = /mnt/samba browseable = Yes read only = No writable = Yes guest ok = No valid users = @smbuser1 @smbuser2
UUID=123456789012 /mnt/samba xfs rw,nosuid,noexec,dev,nouser,async,auto,x-systemd.device-timeout=10,nofail 0 0
systemctl restart smbd.service nmbd.service
如果需要访问,在 Windows 下直接 运行 并输入地址即可
\\192.168.1.10 \\fc00--192-168-1-10.ipv6-literal.net
5 、参考链接
通过 SSH 配置纯 SFTP 用户及权限 [ 链接 ]
SSHFS - Arch Wiki [ 链接 ]