FTP(File Transfer Protocol,文件传输协议)是一种标准的网络协议,用于在远程网络之间传输文件。注意区分 SFTP,其是 SSH 文件传输协议 (SSH File Transfer Protocol),该协议具有安全性。SCP 代表安全复制协议,它对Linux 系统之间的文件传输进行加密。而 FTP 不具有安全性,是明文传输,但可以搭配 SSL/TLS,实现 FTPS 进行安全传输。本篇以 Debian 10 为例,所有命令以普通用户运行,部分命令可能需要 sudo 权限。

安装

1
2
sudo apt update
sudo apt install vsftpd

安装后,系统默认会配置自启动,查看服务是否启动

1
sudo systemctl status vsftpd

配置

申请证书

安装后,最重要的就是配置,首先配置 SSL,申请证书请查看我的另一篇:搭配 nginx、cloudflare 和 acme.sh 让网站走 https 协议

这里给出一种自签证书的方法,可以自定义证书有效期。假设,我们要创建一个有效期为 10 年的 2048 为私钥和自签名的证书。

1
2
sudo apt install openssl
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/ssl/private/vsftpd.key -out /etc/ssl/private/vsftpd.crt

或者

1
2
3
4
# 先生成私钥
openssl ecparam -genkey -name prime256v1 -out /etc/ssl/private/vsftpd.key
# 再生成证书
openssl req -new -x509 -days 3650 -key /etc/ssl/private/vsftpd.key -out /etc/ssl/private/vsftpd.crt -subj "/CN=bing.com"

配置 vsftpd.conf

然后,配置 vsftpd.conf

1
sudo vim /etc/vsftpd.conf

更改为如下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
listen=NO
listen_ipv6=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
chroot_local_user=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/private/vsftpd.crt
rsa_private_key_file=/etc/ssl/private/vsftpd.key
ssl_enable=YES # 当不想通过 SSL 加密连接时,设置为 NO
user_sub_token=$USER
local_root=/home/$USER/ftp
pasv_min_port=30000
pasv_max_port=31000
userlist_enable=YES
userlist_file=/etc/vsftpd.user_list
userlist_deny=NO

配置完后,记得重启

1
sudo systemctl restart vsftpd

打开防火墙

如果防火墙已关闭,则可以跳过。如果防火墙已打开,可以开放如下几个端口。

1
2
sudo ufw allow 20:21/tcp
sudo ufw allow 30000:31000/tcp

21 端口为建立 FTP 链接时使用。20 端口为传输数据时使用。30000-31000端口为服务器传输接收数据时动态使用。

使用

如果服务器上已经有用户,在可以直接使用该用户名和SSH登录密码连接,客户端工具建议使用:FillZilla

输入服务器地址、用户名、密码以及端口 21,即可连接。

禁用 shell 程序访问权限

默认情况下,创建用户时,如果未明确指定,则该用户将具有对服务器的SSH访问权限。

要禁用shell程序访问,我们将创建一个新的外壳程序,该外壳程序将仅打印一条消息,告诉用户其帐户仅限于FTP访问。

创建/bin/ftponly外壳并使其可执行:

1
2
echo -e '#!/bin/sh\necho "This account is limited to FTP access only."' | sudo tee -a  /bin/ftponly
sudo chmod a+x /bin/ftponly

将新的外壳程序添加到/etc/shells文件中的有效外壳程序列表中:

1
echo "/bin/ftponly" | sudo tee -a /etc/shells

将用户外壳更改为/bin/ftponly

1
sudo usermod newftpuser -s /bin/ftponly

使用相同的命令来更改只希望授予FTP访问权限的所有用户的外壳。

Mac 连接 FTP 服务器

首先,在 Mac 上安装 ftp 命令

1
2
3
4
brew install telnet
brew unlink telnet
brew install inetutils
brew link --overwrite inetutils

然后,打开终端连接

1
2
ftp server_ip
# 然后输入登录用户名和密码

或者

1
2
3
ftp
ftp> open server_ip
# 然后输入用户名和密码

退出 ftp 命令行,输入

1
ftp> bye

一些常用命令:

本地目录操作 服务器操作
lcd 目录名(进入本机目录) cd 目录名(进入服务器目录)
lcd \(退到本机根目录) cd \(退到服务器根目录)
lcd ..(退回到上一级目录) cd ..(退回到上一级目录)
!pwd pwd
!ls ls

下载文件

单个文件下载

1
2
# 将文件从远端主机中传送至本地主机中
ftp> get remote-file local-file

多个文件下载

1
2
3
4
ftp> mget remote-files
# 示例
ftp> mget *.*
# 此时每下载一个文件,都会有提示。如果要除掉提示,则在 mget *.* 命令前先执行: prompt off

上传文件

单个文件上传

1
ftp> put local-file remote-file

多个文件上传

1
2
3
ftp> mput local-files
# 示例
ftp> mput *.htm

下载文件夹

1
wget -r -nH -P . ftp://server_ip:server_port/dir\* --ftp-user=username --ftp-password=password

参数说明

  1. 星号 * 必须有,否则下载下来的就一个文件 index.html
  2. -r 参数就是用来目录下载的,递归下载
  3. -nH 参数不包含主机文件夹;不创建以主机名命名的目录。
  4. -P 参数下载到指定目录
  5. dir 参数表示要下载的目录

参考文献

  1. 如何在Debian 9上使用VSFTPD设置FTP服务器
  2. 如何在Debian 10上安装FTP服务器
  3. mac ftp命令安装即使用
  4. Linux下使用wget下载FTP服务器文件
  5. linux下怎么访问windows下的ftp服务器