Linux基础服务 ·

FTP服务简介

FTP 是 File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”。用于 Internet 上的控制文件的双向传输。同时,它也是一个应用程序(Application)。基于不同的操作系统有不同的 FTP 应用程序,而所有这些应用程序都遵守同一种协议以传输文件。在 FTP 的使用当中,用户经常遇到两个概念:"下载"(Download)和"上传"(Upload)。"下载"文件就是从远程主机拷贝文件至自己的计算机上;"上传"文件就是将文件从自己的计算机中拷贝至远程主机上。用 Internet 语言来说,用户可通过客户机程序向(从)远程主机上传(下载)文件。

FTP 用户分类

Real帐户

这类用户是指在FTP服务上拥有帐号。当这类用户登录FTP服务器的时候,其默认的主目录就是其帐号命名的目录。但是,其还可以变更到其他目录中去。如系统的主目录等等

Guest用户

在 FTP 服务器中,我们往往会给不同的部门或者某个特定的用户设置一个帐户。但是,这个账户有个特点,就是其只能够访问自己的主目录。服务器通过这种方式来保障FTP服务上其他文件的安全性。这类帐户,在 Vsftpd 软件中就叫做 Guest 用户。拥有这类用户的帐户,只能够访问其主目录下的目录,而不得访问主目录以外的文件。

Anonymous(匿名)用户

这也是我们通常所说的匿名访问。这类用户是指在FTP服务器中没有指定帐户,但是其仍然可以进行匿名访问某些公开的资源。

在组建FTP服务器的时候,我们就需要根据用户的类型,对用户进行归类。默认情况下,Vsftpd 服务器会把建立的所有帐户都归属为 Real 用户。但是,这往往不符合企业安全的需要。因为这类用户不仅可以访问自己的主目录,而且,还可以访问其他用户的目录。这就给其他用户所在的空间带来一定的安全隐患。所以,企业要根据实际情况,修改用户所在的类别。

FTP 的运作流程与使用到的端口

FTP 的传输使用的是 TCP 封包协议, TCP 在建立联机前会先进行三次握手。不过 FTP 服务器是比较麻烦一些,因为 FTP 服务器使用了两个联机,分别是命令信道与数据流通道(ftp-data) ,这两个联机都需要经过三次握手!底下我们先以 FTP 预设的主动式(active)联机来对这两个联机通道的关系作个简略的说明:

FTP 服务器的主动式联机示意图
简单的联机流程就如上图所示,至于联机的步骤是这样的:

  1. 建立命令通道的联机
    如上图所示,客户端会随机取一个大于 1024 以上的端口(port AA)来与 FTP 服务器端的 port 21 达成联机,这个过程当然需要三次握手!达成联机后客户端便可以通过这个联机来对 FTP 服务器下达指令,包括查询文件名、下载、上传等等指令都是利用这个通道来下达的;
  2. 通知 FTP 服务器端使用 active 且告知连接的端口
    FTP 服务器的 21 都能看主要用在命令的下达,但是当牵涉到数据流时,就不是使用这个联机了。客户端在需要数据的情况下,会告知服务器端要用什么方式来联机,如果是主动式(active)联机时,客户端会先随机启用一个端口(上图当中的 port BB) ,且通过命令通道告知 FTP 服务器这两个信息,并等待FTP服务器的联机;
  3. FTP 服务器『主动』向客户端联机
    FTP 服务器由命令通道了解客户端的需求后,会主动的由 20 这个端口向客户端的 port BB 联机,这个联机当然也会经过三次握手!此时 FTP 的客户端与服务器端共会建立两条联机,分别用在命令的下达与数据的传递。而预设 FTP 服务器端使用的主动联机端口就是 port 20!

如此一来则成功的建立起『命令』与『数据传输』两个信道!不过,要注意的是, 『数据传输信道』是在有数据传输的行为时才会建立的通道!并不是一开始连接到FTP 服务器就立刻建立的通道!

主动式联机使用到的端口

利用上述的说明来整理一下 FTP 服务器端会使用到的端口主要有:

  • 命令通道的 ftp (默认为 port 21)
  • 数据传输的 ftp-data (默认为 port 20)

这两个端口的工作是不一样的,而且,重要的是两者的联机发起端是不一样的!首先 port 21 主要接受来自客户端的主动联机,至于 port 20 则为FTP服务器主动联机至客户端!这样的情况在服务器与客户端两者同时为公共 IP (Public IP)的因特网上面通常没有太大的问题。

不过,万一你的客户端是在防火墙后端,或者是NAT服务器后端,那么可能就会无法正常联机工作了。

在主动联机的FTP 服务器与客户端之间具有防火墙的联机问题

一般来说,很多的局域网络都会使用防火墙(iptables)的 NAT 功能,那么在 NAT 后端的 FTP 用户如何连接到FTP服务器呢?我们可以简单的以下图来说明:

                                    FTP 客户端与服务器端联机中间具有防火墙的联机状态

1.用户与服务器间命令信道的建立:
因为 NAT 会主动的记录由内部送往外部的联机信息,而由于命令信道的建立是由客户端向服务器端联机的,因此这一条联机可以顺利的建立起来的;

2.用户与服务器间数据信道建立时的通知:
同样的,客户端主机会先启用 port BB ,并通过命令通道告知 FTP 服务器,且等待服务器端的主动联机;

3.服务器主动连到 NAT 等待转递至客户端的联机问题:
但是由于通过 NAT 的转换后,FTP 服务器只能得知 NAT 的 IP 而不是客户端的 IP ,因此 FTP 服务器会以 port 20 主动的向 NAT 的 port BB 发送主动联机的要求。但你的 NAT 并没有启动 port BB 来监听FTP服务器的联机!

在FTP的主动式联机当中,NAT 将会被视为客户端,但 NAT 其实并非客户端,这就造成问题了。如果你曾经在 IP 分享器后面连接某些 FTP 服务器时,可能偶尔会发现明明就连接上 FTP 服务器了(命令通道已建立),但是就是无法取得文件名的列表,而是在超过一段时间后显示『 Can't build data connection: Connection refused,无法进行数据传输』之类的讯息,那肯定就是这个原因所造成的困扰了。

解决方法

  • 使用 iptables 所提供的 FTP 侦测模块:

iptables 提供了许多的模块了,你可以使用 modprobe 这个指令来加载 ip_conntrack_ftp 及 ip_nat_ftp 等模块,这几个模块会主动的分析『目标是port 21的联机』信息,所以可以得到 port BB 的资料,此时若接受到 FTP 服务器的主动联机,就能够将该封包导向正确的后端主机了!

不过,如果你链接的目标FTP服务器他的命令通道默认端口号并非标准的 21 端口时(例如某些地下FTP服务器),那么这两个模块就无法顺利解析出来了!

  • 客户端选择被动式(Passive)联机模式:

除了主动式联机之外,FTP 还提供一种称为被动式联机的模式,主动式是由服务器向客户端联机,反过来讲,被动式就是由客户端向服务器端发起联机的!既然是由客户端发起联机的,那自然就不需要考虑来自 port 20 的联机!

客户端选择被动式联机模式

那么什么是被动式联机呢?我们可以使用底下的图示来作个简略的介绍:

FTP 的被动式数据流联机流程

1.用户与服务器建立命令信道:
同样的需要建立命令通道,通过三次握手就可以建立起这个通道了。

2.客户端发出 PASV 的联机要求:
当有使用数据信道的指令时,客户端可通过命令通道发出 PASV 的被动式联机要求(Passive的缩写),并等待服务器的回应;

3.FTP 服务器启动数据端口,并通知客户端联机:
如果你的 FTP 服务器是能够处理被动式联机的,此时 FTP 服务器会先启动一个端口在监听。这个端口号码可能是随机的,也可以自定义某一范围的端口,端口看你的 FTP 服务器软件而定。然后你的 FTP 服务器会通过命令通道告知客户端该已经启动的端口(图中的 port PASV),并等待客户端的联机。

4.客户端随机取用大于 1024 的端口进行连接:
然后你的客户端会随机取用一个大于 1024 的端口号来对主机的 port PASV 联机。如果一切都顺利的话,那么你的 FTP 数据就可以通过 port BB 及 port PASV 来传送了。

被动式 FTP 数据信道的联机方向是由客户端向服务器端联机的!如此一来,在 NAT 内部的客户端主机就可以顺利的连接上 FTP Server !但是,万一 FTP 主机也是在 NAT 后端那就牵涉到更深入的DMZ技巧了,我们这里暂不介绍这些深入的技巧,先理解一下这些特殊的联机方向,这将有助于你未来服务器架设时候的考虑因素!

此外,通过 PASV 模式,服务器在没有特别设定的情况下,会随机选取大于 1024 的端口来提供客户端连接之用。那么万一服务器启用的端口被搞鬼怎么办?而且, 如此一来也很难追踪来自入侵者攻击的登录信息!所以,这个时候我们可以通过 passive ports 的功能来『限定』服务器启用的 port number !

FTP 的安全性问题与替代方案

在 FTP 上面传送的数据很可能被窃取,因为 FTP 是明码传输的!而且某些 FTP 服务器软件的信息安全历史问题也是很严重的。因此,一般来说,除非是学校或者是一些社团单位要开放没有机密或授权问题的资料之外,FTP 是少用为妙的。

不过目前我们已经有较为安全的 FTP 了,那就是 ssh 提供的 sftp 这个 server !这个 sftp-server 最大的优点就是:『在上面传输的数据是经过加密的』!所以在因特网上面传输的时候,比较安全一些!所以建议你,除非必要,否则的话使用 SSH 提供的 sftp-server 功能。

然而这个功能对于一些习惯了图形接口,或者是有中文文件名的使用者来说,不怎么方便, 虽说目前有个图形接口的 filezilla 客户端软件,不过很多时候还是会发生一些莫名的问题!所以,有的时候 FTP 网站还是有其存在的需要的。如果真的要架设 FTP 网站,那么还是得需要注意几个事项:

  1. 随时更新到最新版本的 FTP 软件,并随时注意漏洞讯息;
  2. 善用 iptables 来规定可以使用FTP 的网域;
  3. 善用 TCP_Wrappers 来规范可以登入的网域;
  4. 善用 FTP 软件的设定来限制使用你 FTP 服务器的使用者的不同权限;
  5. 使用 Super daemon 来进阶管理你的 FTP 服务器;
  6. 随时注意用户的家目录、以及匿名用户登入的目录的『文件权限』;
  7. 若不对外公开的话,或许也可以修改 FTP 的 port 。
  8. 也可以使用 FTPs 这种加密的 FTP 功能!

无论如何,在网络上听过太多人都是由于开放 FTP 这个服务器而导致整个主机被入侵的事件,所以, 这里真的要给他一直不断的强调,要注意安全!

开放什么身份的使用者登入

FTP 是以明码传输,并且某些早期的FTP 服务器软件也有不少的安全漏洞,但是总是有人有需要这个玩意儿的,譬如说各大专院校不就有提供 FTP 服务,这样可以让校内的同学共同分享校内的网络资源!不过,由于 FTP 登入者的身份可以分为三种, 你到底要开放哪一种身份登入呢?这个时候你可以这样简单的思考一下:


开放实体用户的情况(Real user):

很多的 FTP 服务器默认就已经允许实体用户的登入了。不过,需要了解的是,以实体用户做为 FTP 登入者身份时, 系统默认并没有针对实体用户来进行『限制』的,所以他可以针对整个文件系统进行任何他所具有权限的工作。因此,如果你的 FTP 使用者没能好好的保护自己的密码而导致被入侵,那么你的整个 Linux 系统数据将很有可能被窃取!开放实体用户时的建议如下:

使用替代的 FTP 方案较佳: 由于实体用户本来就可以通过网络连接到主机来进行工作(例如SSH),因此实在没有需要特别的开放 FTP 的服务!因为例如 sftp 本来就能达到传输文件的功能!

限制用户能力,如 chroot 与 /sbin/nologin 等: 如果确定要让实体用户利用 FTP 服务器的话,那么你可能需要让某些系统账号无法登入 FTP 才行,例如 bin, apache 等等。最简单常用的作法是通过 PAM 模块来处理,譬如 vsftpd 这个软件默认可以通过 /etc/vsftpd/ftpusers 这个文件来设定不想让他具有登入 FTP 的账号。另外,将使用者身份 chroot 是相当需要的!


访客身份(Guest)

通常会建立 guest 身份的文件当中,多半是由于服务器提供了类似『个人Web 首页』的功能给一般身份用户, 那么这些使用者总是需要管理自己的网页空间,这个时候将使用者的身份压缩成为 guest ,并且将他的可用目录设定好,即可提供使用者一个方便的使用环境了!且不需要提供他 real user 的权限!常见的建议如下:

仅提供需要登入的账号即可,不需要提供系统上面所有人均可登入的环境!

当然,我们在服务器的设定当中,需要针对不同的访客给他们不一样的『家目录』, 而这个家目录与用户的权限设定需要相符合!例如要提供 dmtsai 这个人管理他的网页空间,而他的网页空间放置在 /home/dmtsai/www 底下,那我就将 dmtsai 在 FTP 提供的目录仅有 /home/dmtsai/www 而已,这样比较安全和方便!

针对这样的身份者,需要设定较多的限制,包括:上下传文件数目与硬盘容量的限制、 联机登入的时间限制、许可使用的指令要减少很多很多,例如 chmod 就不要允许他使用等等!


匿名登录使用者(anonymous)

虽然提供匿名登录给因特网的使用者进入实在不是个好主意,因为每个人都可以去下载你的数据, 万一带宽被吃光光怎么办?但如同前面讲过的,学校单位需要分享全校同学一些软件资源时, FTP 服务器也是一个很不错的解决方案!你说是吧。如果要开放匿名用户的话,要注意:

无论如何,提供匿名登录都是一件相当危险的事情,因为只要你一不小心, 将重要的资料放置到匿名者可以读取的目录中时,那么就很有可能会泄密!与其战战兢兢,不如就不要设定~

果真要开放匿名登录时,很多限制都要进行的,这包括:

(1)允许的工作指令要减低很多, 几乎就不许匿名者使用指令。

(2)限制文件传输的数量,尽量不要允许『上传』数据的设定。

(3)限制匿名者同时登入的最大联机数量,可以控制盗链!

一般来说,如果你是要放置一些公开的、没有版权纠纷的数据在网络上供人下载的话, 那么一个仅提供匿名登录的 FTP 服务器,并且对整个因特网开放是可以的!不过,如果你预计要提供的的软件或数据是具有版权的,但是该版权允许你在贵单位内传输的情况下, 那么架设一个『仅针对内部开放的匿名FTP 服务器(利用防火墙处理) 』也是可以的!

如果你还想要让使用者反馈的话,那是否要架设一个匿名者可上传的区域呢?这件事情是.... 『万万不可』!如果要让使用者反馈的话,除非该使用者是你信任的,否则不要允许对方上传!所以此时一个文件系统权限管理严格的 FTP 服务器,并提供实体用户的登入就有点需求啦!总之,要依照你的需求来思考是否有需要!

FTP 传输方式

FTP的传输有两种方式:ASCII、二进制。

ASCII传输方式

假定用户正在拷贝的文件包含的简单 ASCII 码文本,如果在远程机器上运行的不是 UNIX,当文件传输时 ftp 通常会自动地调整文件的内容以便于把文件解释成另外那台计算机存储文本文件的格式。

但是常常有这样的情况,用户正在传输的文件包含的不是文本文件,它们可能是程序,数据库,字处理文件或者压缩文件。在拷贝任何非文本文件之前,用 binary 命令告诉 ftp 逐字拷贝。

二进制传输模式

在二进制传输中,保存文件的位序,以便原始和拷贝的是逐位一一对应的。即使目的地机器上包含位序列的文件是没意义的。例如,macintosh 以二进制方式传送可执行文件到 Windows 系统,在对方系统上,此文件不能执行。

如在 ASCII 方式下传输二进制文件,即使不需要也仍会转译。这会损坏数据。(ASCII 方式一般假设每一字符的第一有效位无意义,因为 ASCII 字符组合不使用它。如果传输二进制文件,所有的位都是重要的。)

为何使用 vsftpd

为了建构一个安全为主的 FTP 服务器, vsftpd 针对操作系统的『程序的权限 (privilege)』概念来设计,系统上面所执行的程序都会引发一个程序,我们称他为 PID (Process ID), 这个 PID 在系统上面能进行的任务与他拥有的权限有关。也就是说, PID 拥有的权限等级越高, 他能够进行的任务就越多。举例来说,使用 root 身份所触发的 PID 通常拥有可以进行任何工作的权限等级。

不过,万一触发这个 PID 的程序 (program) 有漏洞而导致被网络黑客 (cracker) 所攻击而取得此 PID 使用权时, 那么网络黑客将会取得这个 PID 拥有的权限!所以,近来发展的软件都会尽量的将服务取得的 PID 权限降低,使得该服务即使不小心被入侵了,入侵者也无法得到有效的系统管理权限,这样会让我们的系统较为安全的。 vsftpd 就是基于这种想法而设计的。

除了 PID 方面的权限之外, vsftpd 也支持 chroot 这个函式的功能,chroot 顾名思义就是『 change root directory 』的意思,那个 root 指的是『根目录』而非系统管理员。 他可以将某个特定的目录变成根目录,所以与该目录没有关系的其他目录就不会被误用了。

举例来说,如果你以匿名身份登入我们的 ftp 服务的话,通常你会被限定在 /var/ftp 目录下工作, 而你看到的根目录其实就只是 /var/ftp ,至于系统其他如 /etc, /home, /usr... 等其他目录你就看不到了! 这样一来即使这个 ftp 服务被攻破了,没有关系,入侵者还是仅能在 /var/ftp 里面跑来跑去而已,而无法使用 Linux 的完整功能。自然我们的系统也就会比较安全!

vsftpd 是基于上面的说明来设计的一个较为安全的 FTP 服务器软件,他具有底下的特点:

  • vsftpd 这个服务的启动者身份为一般用户,所以对于 Linux 系统的权限较低,对于 Linux 系统的危害就相对的减低了。此外, vsftpd 亦利用 chroot() 这个函式进行改换根目录的动作,使得系统工具不会被 vsftpd 这支服务所误用;
  • 任何需要具有较高执行权限的 vsftpd 指令均以一支特殊的上层程序所控制, 该上层程序享有的较高执行权限功能已经被限制的相当的低,并以不影响 Linux 本身的系统为准;
  • 绝大部分 ftp 会使用到的额外指令功能 (dir, ls, cd ...) 都已经被整合到 vsftpd 主程序当中了,因此理论上 vsftpd 不需要使用到额外的系统提供的指令,所以在 chroot 的情况下,vsftpd 不但可以顺利运作,且不需要额外功能对于系统来说也比较安全。
  • 所有来自客户端且想要使用这支上层程序所提供的较高执行权限之 vsftpd 指令的需求, 均被视为『不可信任的要求』来处理,必需要经过相当程度的身份确认后,方可利用该上层程序的功能。 例如 chown(), Login 的要求等等动作;
  • 此外,上面提到的上层程序中,依然使用 chroot() 的功能来限制用户的执行权限。

由于具有这样的特点,所以 vsftpd 会变的比较安全一些!

参与评论