如何在远程服务器上用SFTP安全地传输文件
作者 Justin Ellingwood
导语
FTP(File Transfer Protocol),即文件传输协议,是一种在两个系统之间不加密传输文件的方法,曾一度很流行。然而时至今日,由于缺乏安全性,这种方法已被大多数现代软件弃用,几乎只出现在遗留应用程序中。
SFTP(Secure File Transfer Protocol),即安全文件传输协议,是一种内置于SSH中的协议,可以通过安全的连接实现FTP命令。一般来说,如果程序还需要用到FTP,可以直接用SFTP代替。
在几乎所有情况下,SFTP都比FTP更可取,因为它更具安全性,还可以搭载SSH连接。而FTP并不安全,只能在少数情况下或是受信任的网络中使用。
尽管SFTP已被集成到了许多图形工具中,本教程还是会在SFTP的交互式命令行界面中演示如何使用它。
如何连接SFTP
默认情况下,SFTP使用SSH协议进行身份验证和建立安全连接。因此,可以使用与SSH相同的验证方法。
虽然SSH默认用密码验证,但推荐创建SSH密钥,并将公钥传输到所有需要访问的系统中。这样更加安全,而且长远来说更省时间。
如果您可以用SSH连接到计算机,就已经满足了所有用SFTP管理文件所需的条件。使用以下命令测试SSH访问:
ssh sammy@your_server_ip_or_remote_hostname
如果该命令成功运行,可以输入以下命令退出:
$ exit
现在,可以用以下命令创建SFTP会话:
sftp sammy@your_server_ip_or_remote_hostname
这样即可连接至远程系统,提示符也会变为SFTP提示符。
如果您使用的是自定义SSH端口(非默认的22号端口),可以用以下命令创建SFTP会话:
sftp -oPort=custom_port sammy@your_server_ip_or_remote_hostname
这会将您通过指定端口连接至远程服务器。
在SFTP中打开帮助页面
最有用的,也是应最先学习的命令就是help命令。通过这条命令,您可以查阅其它SFTP命令的摘要。在提示符后任选以下两个命令中的一个输入,即可访问帮助页面:
sftp> help
或是
sftp> ?
可用命令列表就会出现:
Output
Available commands:
bye Quit sftp
cd path Change remote directory to 'path'
chgrp grp path Change group of file 'path' to 'grp'
chmod mode path Change permissions of file 'path' to 'mode'
chown own path Change owner of file 'path' to 'own'
df [-hi] [path] Display statistics for current directory or
filesystem containing 'path'
exit Quit sftp
get [-Ppr] remote [local] Download file
help Display this help text
lcd path Change local directory to 'path'
. . .
后续部分将会深入介绍其中的一部分命令。
通过SFTP浏览
有许多命令可以用来浏览远程系统的文件层次机构。这些命令在shell中都有对应,且功能也类似。
首先,找出目前所在远程系统目录位置来定位自己。与在典型shell会话中类似,可以输入以下命令获取当前位置:
sftp> pwd
Output
Remote working directory: /home/demouser
通过另一个熟悉的指令,可以查看远程系统当前目录中的内容:
sftp> ls
Output
Summary.txt info.html temp.txt testDirectory
值得注意的是,SFTP界面中的可用命令与shell的典型语法并非一模一样,命令功能也并不丰富。但它们提供了一些更重要的可选标记,例如在 ls
后添加 -la
,用来查看更多文件的元数据和权限:
sftp> ls -la
Output
drwxr-xr-x 5 demouser demouser 4096 Aug 13 15:11 .
drwxr-xr-x 3 root root 4096 Aug 13 15:02 ..
-rw------- 1 demouser demouser 5 Aug 13 15:04 .bash_history
-rw-r--r-- 1 demouser demouser 220 Aug 13 15:02 .bash_logout
-rw-r--r-- 1 demouser demouser 3486 Aug 13 15:02 .bashrc
drwx------ 2 demouser demouser 4096 Aug 13 15:04 .cache
-rw-r--r-- 1 demouser demouser 675 Aug 13 15:02 .profile
. . .
使用以下命令切换目录:
sftp> cd testDirectory
以上命令可以用来遍历远程文件系统。而当需要访问本地文件系统时,可以通过在命令前加 l 表示导向本地。
所有目前出现过的命令都有导向本地的版本。例如,可以用以下命令print本地工作目录:
sftp> lpwd
Output
Local working directory: /Users/demouser
可以用以下命令列出本地机器当前目录中的内容:
sftp> lls
Output
Desktop local.txt test.html
Documents analysis.rtf zebra.html
还可以更改想用的本地系统目录:
sftp> lcd Desktop
用SFTP传输文件
若需要从远程主机下载文件,可以用 get
命令:
sftp> get remoteFile
Output
Fetching /home/demouser/remoteFile to remoteFile
/home/demouser/remoteFile 100% 37KB 36.8KB/s 00:01
从上面可以看出,默认情况下,get
命令会将远程文件下载至本地文件系统里的同名文件中。
我们可以在以上命令后指定一个名称,用另一个名字复制远程文件:
sftp> get remoteFile localFile
get
命令后还可以添加标记。比如,通过指定递归选项,可以复制一个目录及其内部的所有内容。
sftp> get -r someDirectory
还可以用 -P
或 -p
标记使SFTP维持适当的权限和访问时间:
sftp> get -Pr someDirectory
将本地文件传输至远程系统
传输本地文件至远程系统的方法与从远程系统下载文件类似,但要使用 put
命令:
sftp> put localFile
Output
Uploading localFile to /home/demouser/localFile
localFile 100% 7607 7.4KB/s 00:00
get
后可以加的标记同样能用在 put
后。所以可以用 put -r
复制整个本地目录:
sftp> put -r localDirectory
df
命令的作用与自己的命令行版本类似,在下载与上传文件时十分有用。用这个命令可以检查是否有足够的空间来完成您想要进行的传输:
Output
Size Used Avail (root) %Capacity
19.9GB 1016MB 17.9GB 18.9GB 4%
注意,这条命令没有本地版本,但可以用 !
命令解决。!
命令将会打开一个本地shell,在这个shell中,我们可以对本地系统运行任何可用的命令。可以用以下命令检查磁盘的使用情况:
sftp> !
$ df -h
Output
Filesystem Size Used Avail Capacity Mounted on
/dev/disk0s2 595Gi 52Gi 544Gi 9% /
devfs 181Ki 181Ki 0Bi 100% /dev
map -hosts 0Bi 0Bi 0Bi 100% /net
map auto_home 0Bi 0Bi 0Bi 100% /home
其它的本地指令也会按预期运行。而输入以下命令即可回到 SFTP
会话:
$ exit
这时,您应该可以看到SFTP提示符再次出现了。
用SFTP进行简单文件操作
SFTP支持某些类型的文件系统管理。例如,使用以下命令可以改变远程系统中文件的所有者:
sftp> chown userID file
值得注意的是,与系统 chmod
命令不同,SFTP只接受UID,而不是用户名。然而,没有内置方法可以从SFTP接口中知道适当的UID。
作为替代方案,可以从 /etc/passwd
文件中获取UID。大多数Linux环境中,这个文件将用户名与UID关联:
sftp> get /etc/passwd
sftp> !less passwd
Output
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
. . .
注意,此处并不是用 !
命令本身,而是将它作为本地shell命令的前缀。这样,我们就可以在本地机器上运行所有可用的命令。而在之前的例子中,这个前缀也可以和本地 df
命令一起使用。
UID位于文件第三列,由冒号字符表示。
类似地,可用以下命令改变文件的组拥有者:
sftp> chgrp groupID file
同样,没有内置方法可以获取远程系统组的列表。对此,我们可以使用以下命令解决:
sftp> get /etc/group
sftp> !less group
Output
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
. . .
第三列中有和第一列中名字相关联的组的ID,这正是我们想要的。
chmod
SFTP命令在远程文件系统上照常运行:
sftp> chmod 777 publicFile
Output
Changing mode on /home/demouser/publicFile
并没有等价的命令能设置本地文件的权限,但可以设置本地umask,使所有被复制进本地系统的文件都有对应的权限。
可以用 lumask
命令完成这一步:
sftp> lumask 022
Output
Local umask: 022
现在,下载的全部常规文件(只要没有用过 -p
标记)都有644项权限了。
SFTP还支持在本地和远程系统中用 lmkdir
和 mkdir
分别创建目录。
而其余文件命令仅对远程文件系统生效:
sftp> ln
sftp> rm
sftp> rmdir
这些命令重复了它们的shell等价命令的核心行为。如果想在本地文件系统中执行这些操作,可以通过使用以下命令进入shell:
sftp> !
或者通过在命令前加上 !
前缀,来在本地文件系统中运行单个指令:
stfp> !chmod 644 somefile
SFTP会话完毕后,可用 exit
或 bye
关闭连接。
sftp> bye
结语
虽然SFTP语法远不如现代shell工具全面,但它能与传统FTP语法兼容,且当一些环境需要限制远程用户可用功能时会很有用。例如,在没有SSH访问权限的情况下,特定用户可以通过SFTP传输文件。
如果您习惯使用FTP或是SCP传输文件,SFTP是一个兼具二者优点的好方法。虽然并不适用于所有情况,但SFTP是一种很灵活的工具,值得贮备在您的工具箱中。