如何使用 SSH 安全地通过 SCP 和 SFTP 传输文件

通过SSH使用SCP和SFTP安全传输文件,包括实用命令、密钥认证以及更安全的服务器端访问控制。

如何使用SCP和SFTP通过SSH安全传输文件

在本地和远程系统之间传输文件是系统管理和开发的基本需求。然而,使用未加密的协议(如标准FTP或R命令)会使敏感数据面临拦截和攻击的风险。安全外壳(SSH)协议提供了两种强大且加密的文件传输方法:安全复制协议(SCP)和SSH文件传输协议(SFTP)。

本指南将解释何时使用SCP、何时使用SFTP,以及如何避免那些使安全文件传输在实践中变得不那么安全的常见错误。

理解基础:SSH

SCP和SFTP都利用SSH(通常运行在端口22上)作为底层传输层。当你使用任一协议发起传输时,SSH首先在客户端和服务器之间建立一个安全的加密隧道。所有数据,包括身份验证凭据和文件内容,都通过此隧道传输,这使得这两种方法成为传统文件传输协议的高度安全替代方案。

SSH基础提供的关键特性:

  • 加密: 所有数据都是端到端加密的。
  • 身份验证: 支持密码验证以及更安全的公钥/私钥对验证。
  • 完整性: 使用加密哈希确保文件在传输过程中不被更改。

安全复制协议(SCP)

SCP是一种基于远程复制协议(rcp)但包裹了SSH安全性的网络协议。它设计用于简单和快速,非常适合快速、非交互式的传输,尤其是在脚本编写或自动化中。

SCP特性与特点

  1. 简单性: 使用与标准Unix cp命令非常相似的语法。
  2. 速度: 对于简单的一次性复制通常很快,但性能取决于SSH实现、密码、网络和文件集。
  3. 非交互式: 一旦启动,传输将运行至完成,无法管理会话或中断传输状态。

实用SCP命令

SCP的一般语法是 scp [选项] [源] [目标]

1. 将文件从本地复制到远程服务器

将本地文件推送到远程用户的主目录:

scp /path/to/local/file.txt user@remote_host:/home/user/destination/

2. 将文件从远程复制到本地系统

从服务器拉取文件到当前目录:

scp user@remote_host:/var/log/system.log . 
# 注意:'.' 表示当前本地目录

3. 复制整个目录(递归)

使用 -r(递归)标志复制目录及其所有内容:

scp -r /path/to/local/folder/ user@remote_host:/data/backups/

4. 指定非标准端口

如果你的SSH守护进程运行在非22端口上,请使用 -P 标志(注意是大写P):

scp -P 2222 local_file.zip user@remote_host:/tmp/

关于SCP的说明: 传统SCP协议行为存在文件名和路径处理风险的历史。一些现代OpenSSH客户端默认在底层使用SFTP进行 scp,但并非每个客户端或服务器的行为都相同。对于新的工作流程,除非你特别需要SCP兼容性,否则首选 SFTP通过SSH的rsync

SSH文件传输协议(SFTP)

SFTP是SSH的一个子系统,提供了更丰富的交互式文件管理环境。与纯粹是复制工具的SCP不同,SFTP是一个有状态协议,允许通过同一个受SSH保护的连接进行文件列表、删除、重命名和目录创建。

SFTP特性与特点

  1. 交互式会话: 传输在专用的交互式shell会话中进行。
  2. 健壮性: 支持在会话内进行查找、恢复和管理单个传输。
  3. 全面管理: 允许使用会话命令(putgetlcdlmkdir)列出(ls)、更改目录(cd)以及操作远程和本地文件。
  4. 安全性: 使用SSH进行传输,是现代交互式文件传输的更好默认选择。

实用SFTP命令

1. 启动SFTP连接

启动到远程服务器的交互式会话:

sftp user@remote_host

如果使用特定端口:

sftp -P 2222 user@remote_host

2. SFTP交互式命令

连接后,默认在远程环境中操作。使用命令管理传输和目录:

命令 描述 示例
ls 列出远程文件 ls -l
cd 更改远程目录 cd /var/www/html
put 上传文件(本地到远程) put local_data.zip
get 下载文件(远程到本地) get server_backup.tar.gz
lcd 更改本地目录 lcd /Users/me/downloads
lpwd 打印本地工作目录 lpwd
mkdir 创建远程目录 mkdir new_project
quit 退出SFTP会话 quit

示例:在SFTP会话中上传和下载

$ sftp [email protected]
sftp> cd /data/backups
sftp> lcd /home/local/reports
sftp> put daily_report.csv  # 上传文件
Uploading daily_report.csv to /data/backups/daily_report.csv
daily_report.csv                                      100% 512KB   4.3MB/s   00:00    
sftp> get configuration.yaml  # 下载文件
Fetching /data/backups/configuration.yaml to configuration.yaml
configuration.yaml                                    100% 20KB    1.1MB/s   00:00    
sftp> quit

SCP与SFTP:选择合适的工具

虽然两种协议都是安全的,但它们服务于不同的操作需求:

特性 安全复制协议(SCP) SSH文件传输协议(SFTP)
机制 简单复制协议(非交互式) 交互式文件管理协议(有状态)
用例 快速、单文件传输;脚本/自动化。 复杂传输;目录管理;交互式会话。
速度 对于简单复制通常不错。 通常足够快,具有更多文件管理功能。
恢复 有限;使用其他工具实现健壮的恢复行为。 支持更可控的传输操作,但客户端恢复行为各异。
安全状态 兼容性工具;传统协议存在设计问题。 通过SSH进行托管文件传输的更好默认选择。

何时使用SCP: 当你需要简单文件传输的最大速度,并且在脚本中执行命令(非交互式更佳)时,使用SCP。

何时使用SFTP: 对于几乎所有手动文件传输,当你需要管理多个文件、更改目录或需要会话健壮性和现代安全特性时,使用SFTP。

安全文件传输的最佳实践

使用SCP或SFTP只是第一步。在SSH服务器上进行正确的安全配置对于保护远程环境至关重要。

1. 优先使用SSH密钥认证

基于密码的身份验证容易受到暴力破解攻击。始终使用公钥/私钥SSH密钥对来验证文件传输。使用密钥可以消除在自动或手动传输期间密码泄露的风险。

生成密钥(如果需要):

ssh-keygen -t ed25519 -C "file-transfer"

使用特定密钥进行传输:

scp -i ~/.ssh/my_transfer_key file.txt user@remote_host:/tmp/
# 或
sftp -i ~/.ssh/my_transfer_key user@remote_host

2. 禁用root登录

绝不允许使用 root 用户进行直接文件传输。传输应始终由专用的、低权限用户帐户执行。如果需要管理访问权限,可以在传输后通过远程机器上的 sudo 将文件移动到适当位置。

3. 使用 ChrootDirectory 限制访问(SFTP)

对于向外部或不受信任用户提供SFTP访问的系统,在 sshd_config 文件中实现 ChrootDirectory 限制。这将SFTP用户锁定到特定目录,防止他们浏览文件系统的其余部分。

/etc/ssh/sshd_config 中的示例配置片段:

Match User sftp_external_user
  ForceCommand internal-sftp
  ChrootDirectory /var/sftp/%u
  AllowTcpForwarding no
  X11Forwarding no

4. 限制权限

确保用于传输的用户帐户仅具有完成任务所需的最低权限(最小权限原则)。如果用户只需要上传文件到 /data/uploads,请确保他们不能删除 /etc/config 中的文件。

要点

当你需要交互式地浏览、上传、下载或管理文件时,将SFTP作为默认选择。对于你信任服务器并了解客户端行为的简单兼容性情况,使用SCP。在这两种情况下,都将命令与SSH密钥、最小权限帐户和严格的目录权限配合使用。