SFTP(SSH File Transfer Protocol)是SSH协议的一部分,提供安全的文件传输功能。与传统的FTP不同,SFTP通过加密的SSH连接传输数据,确保文件传输的安全性。
通过SSH加密所有数据传输,防止信息泄露
使用SSH认证机制,支持密钥和密码认证
支持完整的文件系统操作(上传、下载、删除等)
# 检查是否已安装
which sftp
# 通常包含在openssh-client中
sudo apt update
sudo apt install openssh-client
# 检查安装
rpm -qa | grep openssh
# 安装客户端
sudo yum install openssh-clients
# 安装SSH服务器(已包含SFTP)
sudo apt install openssh-server # Ubuntu
sudo yum install openssh-server # CentOS
# 启动SSH服务
sudo systemctl start sshd
sudo systemctl enable sshd
# macOS已内置sftp
sftp -V
# 如果需要更新
brew install openssh
sftp [选项] [用户名@]主机名[:路径]
sftp [选项] [用户名@]主机名[:路径] [本地路径]
| 选项 | 描述 | 示例 |
|---|---|---|
-P 端口 |
指定SSH端口(注意大写P) | -P 2222 |
-i 密钥文件 |
指定身份密钥文件 | -i ~/.ssh/id_rsa |
-b 批处理文件 |
从文件读取批处理命令 | -b commands.txt |
-v |
详细模式(显示调试信息) | -v |
-q |
安静模式(不显示进度信息) | -q |
-B 缓冲区大小 |
指定传输缓冲区大小 | -B 32768 |
-R 重试次数 |
连接失败时的重试次数 | -R 3 |
-o SSH选项 |
设置SSH选项 | -o ConnectTimeout=30 |
使用用户名密码连接远程服务器:
# 标准连接(使用默认端口22)
sftp username@server.example.com
# 连接时指定远程目录
sftp username@server.example.com:/home/username/
# 连接并切换到指定本地目录
sftp username@server.example.com ~/local_dir
使用SSH密钥文件连接(无需密码):
# 使用指定密钥文件
sftp -i ~/.ssh/id_rsa username@server.example.com
# 指定非标准端口
sftp -i ~/.ssh/id_rsa -P 2222 username@server.example.com
# 使用配置文件中的主机别名
sftp myserver # 需在~/.ssh/config中配置
# 连接成功后进入sftp>提示符
sftp> help # 显示可用命令
sftp> pwd # 显示远程当前目录
sftp> lpwd # 显示本地当前目录
sftp> ls # 列出远程目录内容
sftp> lls # 列出本地目录内容
sftp> cd /remote/path # 切换远程目录
sftp> lcd /local/path # 切换本地目录
sftp> mkdir newdir # 创建远程目录
sftp> lmkdir newdir # 创建本地目录
sftp> rm file.txt # 删除远程文件
sftp> rmdir empty_dir # 删除远程空目录
sftp> rename old new # 重命名远程文件
sftp> chmod 755 file.sh # 修改远程文件权限
sftp> chown user file # 修改远程文件所有者
sftp> df # 显示远程磁盘使用情况
sftp> !command # 执行本地shell命令
sftp> exit # 退出sftp会话
sftp> quit # 退出sftp会话
# 上传单个文件
sftp> put local_file.txt
sftp> put local_file.txt remote_file.txt # 重命名上传
# 上传多个文件
sftp> put file1.txt file2.txt file3.txt
# 使用通配符上传
sftp> put *.txt
sftp> put *.pdf /remote/path/
# 上传整个目录(-r递归)
sftp> put -r local_directory/
# 保留文件时间戳和权限
sftp> put -p important_file.txt
# 下载单个文件
sftp> get remote_file.txt
sftp> get remote_file.txt local_name.txt # 重命名下载
# 下载多个文件
sftp> get file1.txt file2.txt file3.txt
# 使用通配符下载
sftp> get *.log
sftp> get /var/log/*.log
# 下载整个目录(-r递归)
sftp> get -r remote_directory/
# 恢复下载(断点续传)
sftp> reget large_file.zip
sftp> reput large_file.zip
# 创建批处理文件 commands.txt
echo "cd /remote/uploads" > commands.txt
echo "put file1.txt" >> commands.txt
echo "put file2.txt" >> commands.txt
echo "mkdir backup" >> commands.txt
echo "put -r backup_files/ backup/" >> commands.txt
echo "bye" >> commands.txt
# 执行批处理
sftp -b commands.txt username@server.example.com
# 带密码自动登录(不推荐生产环境使用)
sshpass -p 'password' sftp -b commands.txt user@host
#!/bin/bash
# auto_backup.sh - 自动备份脚本
REMOTE_USER="backupuser"
REMOTE_HOST="backup.server.com"
REMOTE_DIR="/backup/$(hostname)"
LOCAL_DIR="/data/backup"
BACKUP_FILE="backup-$(date +%Y%m%d).tar.gz"
# 1. 创建本地备份
tar -czf $LOCAL_DIR/$BACKUP_FILE /important/data/
# 2. 创建sftp批处理命令
cat > /tmp/sftp_cmds.txt << EOF
cd $REMOTE_DIR
mkdir -p $(date +%Y)/$(date +%m)
cd $(date +%Y)/$(date +%m)
put $LOCAL_DIR/$BACKUP_FILE
ls -la
bye
EOF
# 3. 执行sftp传输
sftp -b /tmp/sftp_cmds.txt $REMOTE_USER@$REMOTE_HOST
# 4. 清理临时文件
rm /tmp/sftp_cmds.txt
echo "Backup completed: $BACKUP_FILE"
# SFTP连接优化配置
Host myserver
HostName server.example.com
User username
Port 2222
IdentityFile ~/.ssh/id_rsa
Compression yes
ServerAliveInterval 60
ServerAliveCountMax 3
TCPKeepAlive yes
# SFTP特定优化
RekeyLimit 1G
# 连接复用
ControlMaster auto
ControlPath ~/.ssh/%r@%h:%p
ControlPersist 10m
Host backup-*
User backup
IdentityFile ~/.ssh/backup_key
# 限制为SFTP only
ForceCommand internal-sftp
ChrootDirectory /backup
PasswordAuthentication no
AllowTcpForwarding no
PermitTunnel no
X11Forwarding no
# 1. 限速传输(需要lftp配合)
# 安装lftp: sudo apt install lftp
lftp sftp://user:pass@host -e "set net:limit-rate 102400; put largefile.iso; exit"
# 2. 并行传输多个文件
cat > upload.txt << EOF
put file1.txt
put file2.txt
put file3.txt
EOF
sftp -b upload.txt user@host &
# 3. 监控传输进度
sftp user@host << EOF
progress
put large_file.iso
EOF
# 4. 使用代理服务器
sftp -o "ProxyCommand=nc -X connect -x proxy:8080 %h %p" user@host
# 5. 强制IPv4或IPv6
sftp -4 user@host # 强制IPv4
sftp -6 user@host # 强制IPv6
# 6. 调试连接问题
sftp -v -v -v user@host 2>&1 | tee debug.log
# 7. 使用expect脚本自动输入密码(不推荐生产环境)
#!/usr/bin/expect
spawn sftp user@host
expect "password:"
send "your_password\r"
expect "sftp>"
send "put file.txt\r"
expect "sftp>"
send "exit\r"
| 特性对比 | SFTP | SCP |
|---|---|---|
| 协议 | SSH文件传输协议 | 安全复制协议 |
| 交互性 | 交互式命令行,支持完整文件操作 | 仅传输文件,无交互 |
| 断点续传 | 支持(reget/reput) | 不支持 |
| 目录操作 | 支持ls、cd、mkdir等 | 不支持 |
| 文件权限 | 支持chmod、chown | 仅保留基本权限 |
| 传输速度 | 稍慢(协议开销) | 较快(简单协议) |
| 适用场景 | 交互式管理、复杂操作、大文件传输 | 简单文件复制、脚本自动化 |
# 生成SSH密钥对
ssh-keygen -t rsa -b 4096 -f ~/.ssh/sftp_key
# 设置密钥权限
chmod 600 ~/.ssh/sftp_key
chmod 644 ~/.ssh/sftp_key.pub
# 上传公钥到服务器
ssh-copy-id -i ~/.ssh/sftp_key.pub user@host
# /etc/ssh/sshd_config
Subsystem sftp internal-sftp
# 限制用户只能使用SFTP
Match Group sftpusers
ChrootDirectory /home/%u
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
# 错误: Connection refused
# 解决方案:
# 1. 检查SSH服务状态
sudo systemctl status sshd
# 2. 检查防火墙
sudo ufw allow 22/tcp
# 或
sudo firewall-cmd --add-service=ssh --permanent
# 3. 检查SELinux
getenforce
# 如果是Enforcing模式
sudo setsebool -P ssh_chroot_full_access on
# 错误: Permission denied
# 可能原因:
# 1. 密钥文件权限太开放
chmod 600 ~/.ssh/id_rsa
# 2. Chroot目录权限问题
# Chroot目录必须为root所有且权限为755
sudo chown root:root /chroot
sudo chmod 755 /chroot
# 3. 用户家目录权限
chmod 755 ~
# 传输速度慢的优化
# 1. 启用压缩
sftp -C user@host
# 2. 增大缓冲区
sftp -B 65536 user@host
# 3. 使用更快的加密算法
# 在~/.ssh/config中添加:
Ciphers aes128-ctr,aes192-ctr,aes256-ctr
# 启用详细日志
sftp -v user@host 2>&1 | tee sftp.log
# 服务器端日志
sudo tail -f /var/log/auth.log
# 或
sudo journalctl -u sshd -f
# 增加SSH日志级别
# 在sshd_config中添加:
LogLevel VERBOSE
# 备份MySQL数据库并传输
mysqldump -u root -p database | gzip > backup.sql.gz
sftp backup@server << EOF
cd /backup/mysql
put backup.sql.gz
ls -lh *.gz
EOF
# 部署网站文件
tar -czf site.tar.gz public_html/
sftp deploy@webserver << EOF
cd /var/www
put site.tar.gz
!tar -xzf site.tar.gz
rm site.tar.gz
chmod -R 755 public_html
EOF
# 同步到云服务器
sftp -b - user@cloud-storage << 'EOF'
cd /storage/backup
mkdir -p $(date +%Y-%m-%d)
cd $(date +%Y-%m-%d)
put -r /local/data/
EOF
# 迁移网站数据
sftp oldserver << EOF
get -r /var/www/html /tmp/old_site
EOF
sftp newserver << EOF
cd /var/www
put -r /tmp/old_site
chown -R www-data:www-data html
EOF
~/.ssh/config简化连接命令-C启用压缩ls确认目录位置!command执行本地检查