9.1 FTP SecurityWhat would we do without FTP? You can use FTP to install Linux, download software from public archives, and share files with friends and colleagues. It's both venerable and ubiquitous: nearly every major site on the Internet offers some level of public FTP access. But like many other Internet applications, FTP is showing its age. Designed for a simpler era, FTP is gradually going the way of Telnet: it's still useful for "anonymous" (public) access, but its clear-text login makes it too dangerous for use with important user accounts.
Anonymous FTP, though, will probably remain with us for some time, so let's discuss FTP security, both in general and with specific regard to my preferred FTP server, ProFTPD. 9.1.1 Principles of FTP SecurityWith FTP, we have several major threat models. The first concerns anonymous access: anonymous users shouldn't be able to do anything but list and download public files and maybe upload files to a single "incoming" directory. Needless to say, we don't want them to "escalate" their privileges to those of a more trusted user. Another important FTP threat model involves local user accounts. If a local user logs in via FTP to upload or download something to or from his home directory, we don't want that session hijacked or eavesdropped on by anybody else, or the user's credentials may be stolen and used with other services such as telnet, SSH, etc. The third threat model worth considering involves confidentiality. At the very least, login credentials must be protected from disclosure, as should any other sensitive data that is transmitted. Unfortunately, by its very design FTP fails miserably in addressing any but the first of these threat models: a good FTP server package that is carefully configured can protect against privilege escalation, but like telnet, the FTP protocol as described in RFC 959 (ftp://ftp.isi.edu/in-notes/rfc959.txt) is designed to transmit both authentication credentials and session data in clear text. Accordingly, FTP is the wrong tool for almost anything but the anonymous exchange of public files. Using real user accounts for FTP exposes those users' credentials to eavesdropping attacks; all subsequent session data is similarly exposed. For this reason most people's FTP security efforts tend to focus on properly configuring anonymous FTP services and on keeping their FTP server software up to date. Protecting FTP transactions themselves is all but futile. If your users need to move data onto or off of the system, require them to use scp, sftp, or rsync in combination with stunnel. I describe all of these later in the chapter. 9.1.1.1 Active mode versus passive mode FTPTo make matters worse, FTP's use of TCP ports is, to put it charitably, inopportune. You may have already learned that FTP servers listen on TCP port 21. However, when an FTP client connects to an FTP server on TCP port 21, only part of the transaction uses this initial "control" connection. By default, whenever an FTP client wishes to download a file or directory listing, the FTP server initiates a new connection back to the client using an arbitrary high TCP port. This new connection is used for transmitting data, as opposed to the FTP commands and messages carried over the control connection. FTP with server-initiated data channels is called "active mode" FTP. If you think allowing externally initiated (i.e., inbound) data connections in through your firewall is a really bad idea, you're right. Networks protected by simple packet filters (such as router ACLs) are often vulnerable to PORT theft attacks. Herein an attacker opens a data channel (requested by a legitimate user's PORT command) to the user's system before the intended server responds. PORT commands can also be used in FTP Bounce attacks, in which an attacking FTP client sends a PORT command requesting that the server open a data port to a different host than that from which the command originated. FTP Bounce attacks are used to scan networks for active hosts, to subvert firewalls, and to mask the true origin of FTP client requests (e.g., to skirt export restrictions). The only widely supported (RFC-compliant) alternative to active mode FTP is passive mode FTP, in which the client rather than the server opens data connections. That mitigates the "new inbound connection" problem, but passive FTP still uses a separate connection to a random high port, making passive FTP only slightly easier to deal with from a firewall engineering perspective. (Many firewalls, including Linux iptables, now support FTP connection tracking of passive mode FTP; a few can track active mode as well.) There are two main lessons to take from this discussion of active versus passive FTP. First, of the two, passive is preferable since all connections are initiated by the client, making it somewhat easier to regulate and harder to subvert than active mode FTP. Second, FTP is an excellent candidate for proxying at the firewall, even if your firewall is otherwise set up as a packet filter. SuSE's Proxy Suite, which can be run on any Linux distribution (not just SuSE), contains an FTP proxy that interoperates well with iptables and ipchains. This proxy, ftp-proxy, can broker all FTP transactions passing through your firewall in either direction (in or out). In this way, you can control at the firewall which commands may be used in FTP sessions. You can also prevent buffer overrun attempts and other anomalies from reaching either your FTP servers or clients.[1]
Using an FTP proxy will require your users to configure their FTP software accordingly, unless you've configured your firewall to act as a transparent proxy — i.e., to redirect automatically all outbound and/or inbound FTP connections to its local proxy. (To use a Linux 2.4 iptables firewall for transparent proxying, you'll first need to load the module ipt_REDIRECT.) See Chapter 2 for a detailed explanation of proxies and application gateways and what they do. Additionally, iptables includes the kernel module ip_conntrack_ftp for tracking FTP connections. While this module doesn't give as granular control as ftp-proxy, it effectively tracks PORT requests (active FTP transactions), passive FTP data requests, and their respective new data channels, and it is intelligent enough to deny spoofed data connections. ip_conntrack_ftp can be used with or without an FTP proxy such as ftp-proxy. 9.1.1.2 The case against nonanonymous FTPAs I mentioned earlier, the FTP protocol transmits logon credentials in clear text over the network, making it unsuitable for Internet use by accounts whose integrity you wish to protect. Why, you may wonder, is that so? Admittedly, it's unlikely that a given Internet FTP session will be eavesdropped by, say, an evil system administrator at an ISP somewhere on that data's path. The problem is that it's trivially easy for such a person to eavesdrop if she's so inclined. It's equally unlikely that a burglar will rattle the doorknob on your front door at any given moment, but equally easy for one to try. This is reason enough to keep your door locked, and the simplicity of eavesdropping attacks is reason enough to protect one's logon credentials from them. Furthermore, you may trust your own ISP, but what about the various other unknown networks between you and the other hosts with which you interact across the Internet? What if, at some point, the data passes over a shared medium such as a cable-modem network? Remember, it's very difficult to predict (let alone control) which parts of the Internet your packets will traverse once you send them off. So again, since it's possible that your packets will encounter eavesdroppers, it must be planned against. For the most part, this means that FTP constitutes an unacceptable risk except when you don't care whether the logon session is eavesdropped (as in anonymous FTP) and whether the subsequent data transfers are eavesdropped. This doesn't quite make FTP obsolete: as anyone who's ever installed Linux over FTP can attest, there's plenty of value in anonymous FTP. A great deal of the data shared over the Internet is public data. I'm not going to elaborate here on how to tighten nonanonymous FTP security: I feel strongly that this is a losing proposition and that the only good FTP is anonymous FTP. If remote users need to read or write data to nonpublic areas, use one of the tools described later in this chapter (i.e., rsync, scp, and sftp). 9.1.1.3 Tips for securing anonymous FTPI do have some guidelines to offer on securing anonymous FTP. They can be summarized as follows:
Let's examine these tips in depth and then look at how to implement them using my FTP server of choice, ProFTPD. First, run the FTP daemon as an unprivileged user and group: this sounds like and is common sense, but it may or may not be possible with your chosen FTP server package. The problem is that FTP servers are expected to listen for incoming connections on TCP port 21 and, in some circumstances, to send data from TCP port 20. These are both privileged ports, and any process that needs to bind to them must run as root (at least initially). ProFTPD by default starts as root, binds to TCP 21, and promptly demotes itself to the user "nobody" and the group "nogroup." (This behavior is customizable if you have a different user or group you'd like ProFTPD to run as.) D. J. Bernstein's minimalist FTP/www server, publicfile, also starts as root and immediately demotes itself. WU-FTPD, however, does not appear to support this feature; as best as I can determine, it runs as root at all times. My second tip, to make sure that your anonymous FTP account (usually "ftp") specifies a bogus shell, should also be obvious, but is extremely important. /bin/false and /bin/true are both popular choices for this purpose. You don't want an anonymous FTP user to somehow execute and use a normal shell such as /bin/sh, nor do you want anyone to trick some other process into letting them run a shell as the user "ftp." Note that by "bogus," I do not mean "invalid": any shell specified in any line of /etc/passwd should be listed in /etc/shells, regardless of whether it's a real shell, though some FTP server applications are more forgiving of this than others. A related tip is to make sure in both /etc/passwd and /etc/shadow (if your system uses shadowed passwords) that the password-hash for your anonymous user account is set to *. This prevents the account from being usable for login via any service other than FTP. Next, build an appropriate chroot jail for anonymous FTP users. Obviously, this directory hierarchy must contain all the things you want those users to be able to download. Be careful not to create any links from within the jail to files outside of it: symbolic links that point outside of the jail will simply not work, but hard links will, and thus they will present attackers with a way out of the chroot jail. Historically, this chroot jail has needed to contain not only the actual download directory, pub/, but also a bin/ directory with its own copy of ls, an etc/ directory containing passwd, group, and localtime, and sometimes copies of other system directories and files. WU-FTPD requires some of these, but ProFTPD and publicfile do not: the latter two use their own internal versions of ls rather than the system's and function without their own versions of /etc/passwd, etc. The chroot directory itself and every directory within it should be owned by root, not by your anonymous FTP account (e.g., ftp) or the daemon's "run-as" account (e.g., nobody). A common configuration error on anonymous-FTP servers is for the FTP root to be owned by the FTP account, which constitutes a major exposure, since an anonymous FTP user could write a .rhosts or .forward file to it that extends the user's access to the system. Proper FTP root (chroot jail) ownerships and permissions are illustrated in Example 9-1, which shows a recursive listing of a sample FTP chroot jail in /var/ftp/. Example 9-1. ls -lR of an FTP chroot jail/var/ftp: total 12 d--x--x--x 2 root root 4096 Apr 16 00:19 bin dr--r--r-- 2 root root 4096 Apr 16 00:27 etc drwxr-xr-x 2 root wheel 4096 Apr 16 06:56 pub /var/ftp/bin: total 44 ---x--x--x 1 root root 43740 Apr 16 00:19 ls /var/ftp/etc: total 12 -r--r--r-- 1 root root 63 Apr 16 00:26 group -r--r--r-- 1 root root 1262 Apr 16 00:19 localtime -r--r--r-- 1 root root 106 Apr 16 00:27 passwd /var/ftp/pub: total 1216 -rw-r--r-- 1 root root 713756 Apr 16 06:56 hijinks.tar.gz -rw-r--r-- 1 root root 512540 Apr 16 06:56 hoohaw.tar.gz -rw-r--r-- 1 root root 568 Apr 16 06:43 welcome.msg The directory /var/ftp itself is set up like this: drwxr-xr-x 2 root root 4096 Apr 16 00:06 ftp If your FTP server is to be maintained by a nonroot user, or if you wish to add files to the pub/ directory without being root, it's okay to make pub/ group writable and owned by a group to which your nonroot account belongs. Since the group wheel is used on many systems to define which user accounts may perform su root, and it's a group that to which you or your subadministrators probably already belong, it's a logical choice for this purpose. If you make pub/ or any of its subdirectories group writable, however, in no circumstances should their group ID be equal to that of the anonymous user account! My final general guideline for anonymous FTP is not to allow anonymous uploads unless you know exactly what you're doing, and if you do, to configure and monitor such directories very carefully. According to CERT, publicly writable FTP directories are a common avenue of abuse (e.g., for sharing pornography and pirated software) and even for Denial of Service attacks (e.g., by filling up disk volumes). If you decide to create such an FTP drop-off directory (conventionally named incoming/), there are a number of things you can do to make it harder to abuse:
9.1.2 Using ProFTPD for Anonymous FTPThat's how you secure anonymous FTP in a general sense. But what about actual configuration settings on an actual FTP server? Let's examine some, using the powerful ProFTPD package as our example. 9.1.2.1 Getting ProFTPDProFTPD is now included in binary form in most Linux distributions, including Red Hat, SuSE, and Debian. Make sure, however, that your distribution's version is no older than 1.2.0rc3, due to known vulnerabilities in prior versions. As of this writing, the most current stable version of ProFTPD is 1.2.4. If your distribution of choice provides a ProFTPD package older than 1.2.0rc3 and doesn't have a newer one on its "updates" or "errata" web site (see Chapter 3), you can get ProFTPD from the official ProFTPD download site, ftp://ftp.proftpd.org. Source code is located at this site (and its mirrors) in the /distrib/source/ directory; RPM and SRPM packages are located in /distrib/packages/. Note that if you use the official ProFTPD RPMs, you'll need to download two packages: the base package proftpd plus one of proftpd-inetd, proftpd-standalone, proftpd-inetd-mysql, or proftpd-standalone-mysql — depending on whether you intend to run ProFTPD from inetd/xinetd or as a standalone daemon and whether you need a ProFTPD binary that was compiled with MySQL database support. (ProFTPD can be compiled to support the use of a MySQL database for authenticating FTP users.) 9.1.2.1.1 Inetd/Xinetd Versus standalone modeOn a lightweight, multipurpose system on which you don't anticipate large numbers of concurrent FTP users, you may want to run ProFTPD from inetd or xinetd : in this way, the FTP daemon will be started only when an FTP user tries to connect. This means that ProFTPD won't consume system resources except when being used. Also, whenever you edit /etc/proftpd.conf, the changes will be applied the next time a user connects without further administrative intervention, since the daemon reads its configuration file each time it's invoked by inetd or xinetd. The other advantage of this startup method is that you can use Tcpwrappers with ProFTPD, leveraging the enhanced logging and access controls Tcpwrappers provides. The disadvantages of starting ProFTPD from an Internet superserver such as inetd or xinetd are twofold. The first is performance: ProFTPD's full startup each time it's invoked this way, in which it reads and processes its entire configuration file, is inefficient if the daemon is started repeatedly in a short period of time, and users will notice a delay when trying to connect. The second disadvantage is that some of ProFTPD's best features, such as virtual servers, are available only in standalone mode. On a dedicated FTP system, therefore, or any other on which you expect frequent or numerous FTP connections, standalone mode is better. When run as a persistent daemon, ProFTPD reads its configuration only once (you can force ProFTPD to reread it later by issuing a kill -HUP command to its lowest-numbered process), which means that whenever a new child process is spawned by ProFTPD to accept a new connection, the new process will get to work more quickly than an inetd-triggered process. 9.1.2.2 ProFTPD modulesLike Apache, ProFTPD supports many of its features via source-code modules. If you install ProFTPD from binary packages, the choice of which modules to compile in ProFTPD has already been made for you (which is why you have multiple RPMs from which to choose from downloading Red Hat ProFTPD packages). Some modules are included automatically in all ProFTPD builds (and thus all binary packages): mod_auth, mod_core, mod_log, mod_ls, mod_site, mod_unixpw, mod_xfer, and, if applicable to your platform, mod_pam. These modules provide ProFTPD's core functionality, including such essentials as authentication, syslog logging, and FTP command parsers. Optional and contributed modules, which you generally must compile into ProFTPD yourself, include mod_quota, which provides support for putting capacity limits on directory trees, and mod_wrap, which provides support for TCPwrappers-style access control (i.e., via /etc/hosts.allow and /etc/hosts.deny). There are many other ProFTPD modules: see the file README.modules in the ProFTPD source code for a complete list. Compiling ProFTPD is simple using the conventional ./configure && make && make install method. You can tell the configure script which optional/contributed modules to include via the — with-modules flag, e.g.: [root@myron proftpd-1.2.4]# ./configure --with-modules=mod_readme:mod_quota It isn't necessary to specify the automatically included modules mod_auth, mod_core, etc. 9.1.2.3 Setting up the anonymous FTP account and its chroot jailOnce ProFTPD is in place, it's time to set it up. You should begin by creating or configuring the anonymous FTP user account, which is usually called "ftp." Check your system's /etc/passwd file to see whether your system already has this account defined. If it's there already, make sure its entry in /etc/passwd looks like the one in Example 9-2. Example 9-2. An /etc/passwd entry for the user ftpftp:x:14:50:FTP User:/home/ftp:/bin/true Make sure of the following:
If you don't already have the account "ftp," first create a group for it by adding a line like this to /etc/group: ftp:x:50: (Alternatively, you can use an existing unprivileged group such as "nobody" or "nogroup.") Then, add the user "ftp" using the useradd command: [root@myron etc]# useradd -g ftp -s /bin/true ftp To specify a different directory on Red Hat Linux or to tell your non-Red Hat useradd to create the user directory, use the -d directive, e.g.: [root@myron etc]# useradd -g ftp -s /bin/true -d /var/ftp ftp If useradd didn't create your ftp user's home directory (i.e., the chroot jail), do so manually. In either case, make sure this directory's user ID is root and its group ID is either root or some other privileged group to which your anonymous FTP account does not belong. If useradd did create your ftp user's home directory, either because you passed useradd the -m flag or because you run Red Hat, remove the dot (".") files and anything else in this directory copied over from /etc/skel. ProFTPD won't let anonymous users see such "invisible" files, but the fact that they aren't needed is reason enough to delete them if present. With ProFTPD it's also unnecessary for this directory to contain any copies of system files or directories. (ProFTPD doesn't rely on external binaries such as ls.). Thus, all you need to do is create the jail directory itself, populate it with the things you intend to make available to the world, and set appropriate ownerships and permissions on the jail and its contents, as described earlier in Section 9.1.1.3 and illustrated in Example 9-1. Continuing our sample ProFTPD setup, suppose you want the jail to be group writable for your system administrators, who all belong to the group wheel. Suppose further that you need to accept files from anonymous users and will therefore allow write access to the directory incoming/. Example 9-3 shows a recursive listing on our example anonymous FTP chroot jail, /home/ftp. Example 9-3. Example ProFTPD chroot jail/home: drwxrwxr-x 2 root wheel 4096 Apr 21 16:56 ftp /home/ftp: total 12 -rwxrwx-wx 1 root wheel 145 Apr 21 16:48 incoming -rwxrwxr-x 1 root wheel 145 Apr 21 16:48 pub -rw-rw-r-- 1 root wheel 145 Apr 21 16:48 welcome.msg /home/ftp/incoming: total 0 /home/ftp/pub: total 8 -rw-rw-r-- 1 root wheel 145 Apr 21 16:48 hotdish_recipe_no6132.txt -rw-rw-r-- 1 root wheel 1235 Apr 21 16:48 pretty_good_stuff.tgz As you can see, most of Example 9-3 is consistent with Example 9-1. Notable differences include the absence of etc/ and bin/ and the fact that everything is writable by its group-owner, wheel. Also, in Example 9-3 there's a world-writable but non-world-readable incoming/ directory, to which all the warnings offered earlier under Section 9.1.1.3 are emphatically applicable. (Make sure this directory has a quota set or is mounted as a discrete filesystem, and move anything uploaded there into a privileged directory as soon as possible). 9.1.2.4 General ProFTPD configurationNow that we've built the restaurant, it's time to train the staff. In the case of ProFTPD, the staff is pretty bright and acclimates quickly. All we need to do is set some rules in /etc/proftpd.conf. As I stated earlier, ProFTPD has an intentionally Apache-like configuration syntax. Personally, I consider this to be not only a convenience but also, in a modest way, a security feature. Confusion leads to oversights, which nearly always result in bad security; ergo, when applications use consistent interfaces, allowing their administrators to transfer knowledge between them, this ultimately enhances security. (This, and not mental laziness, is the main reason I hate sendmail.cf's needlessly arcane syntax — see Chapter 7.) The /etc/proftpd.conf file installed by default requires only a little customization to provide reasonably secure anonymous FTP services. However, for our purposes here, I think it's more useful to start fresh. You'll understand ProFTPD configuration better this way than if I were to explain the five or six lines in the default configuration that may be the only ones you need to alter. Conversely, if your needs are more sophisticated than those addressed by the following examples, view the documentation of the ProFTPD binary packages generally put under /usr/share/doc/proftpd/ or /usr/share/doc/packages/proftpd/. Particularly useful are the "ProFTPD Configuration Directives" page (Configuration.html) and the sample proftpd.conf files (in the subdirectory named either examples/ or sample-configurations/, depending on your version of ProFTPD). Before we dive into proftpd.conf, a word or two about ProFTPD architecture are in order. Like Apache, ProFTPD supports "virtual servers," parallel FTP environments physically located on the same system but answering to different IP addresses or ports. Unlike Apache, however, ProFTPD does not support multiple virtual servers listening on the same combination of IP address and port. This is due to limitations of the FTP protocol. Whereas HTTP 1.1 requests contain the hostname of the server being queried (i.e., the actual URL entered by the user), FTP requests do not. For this reason, you must differentiate your ProFTPD virtual servers by IP address (by assigning IP aliases if your system has fewer ethernet interfaces than virtual hosts) or by listening port. The latter approach is seldom feasible for anonymous FTP, since users generally expect FTP servers to be listening on TCP 21. (But this is no big deal: under Linux, it's very easy to assign multiple IP addresses to a single interface.) 9.1.2.5 Base-server and global settingsOn to some actual configuring. The logical things to start with are base-server settings and global settings. These are not synonymous: base-server (or "primary-server") settings apply to FTP connections to your server's primary IP address, whereas global settings apply both to the base server and to all its virtual servers. You might be tempted in some cases to assume that base-server settings are inherited by virtual servers, but resist this temptation, as they usually aren't. With regard to directives that may be specified in both base-server and virtual-host configurations, the base server is a peer to your virtual servers, not some sort of master. Thus, you need both base-server and global settings (unless you have no virtual servers — in which case you can put everything with your base-server settings). There are some base-server settings that are inherited by virtual hosts: most of these settings may only be set in the base-server section. They include ServerType, MaxInstances, the Timeout... directives, and the SQL... directives. See ProFTPD's Configuration.html file for a complete reference, which includes each directive's permitted contexts. Example 9-4 contains settings that apply only to the base server, plus some that apply globally because of their very nature. Example 9-4. Base-server settings in /etc/proftpd.conf# Base Settings: ServerType standalone MaxInstances 30 TimeoutIdle 300 TimeoutNoTransfer 300 TimeoutStalled 300 UseReverseDNS no LogFormat uploadz "%t %u\@*l \"%r\" %s %b bytes" SyslogFacility LOCAL5 # Base-server settings (which can also be defined in <VirtualHost> blocks): ServerName "FTP at Polkatistas.org" Port 21 MasqueradeAddress firewall.polkatistas.org <Limit LOGIN> DenyAll </Limit> Let's step through the settings of Example 9-4 one by one, beginning with what I think of as "base-server but actually global" settings (settings that may only be specified in the base-server section and that actually apply globally). Paradoxically, none of these may be set in a <Global> configuration block.
And this brings us to Example 9-4's "plain vanilla" base-server settings. These directives may be declared in either base-server or virtual-server sections. None of these, however, may be declared in a <Global> block (which, in this case, makes sense).
After base-system settings, you should define global settings. This is done via one or more <Global> configuration blocks (multiple blocks will be combined into one by proftpd's configuration parser). Example 9-5 lists our sample FTP server's global settings. (That is, our technically global settings, not our "base-server-but-actually-global" settings.) Example 9-5. Global settings in /etc/proftpd.conf# Global Settings: shared by base server AND virtual servers <Global> ServerIdent off AllowRetrieveRestart on MaxClients 20 "Sorry, all lines are busy (%m users max)." MaxClientsPerHost 1 "Sorry, your system is already connected." Umask 022 User nobody Group nogroup </Global> Again, let's examine these directives:
9.1.2.6 Anonymous FTP setupNow that your base-server and global-server options are defined, it's time to tell your base server whether and how to handle anonymous FTP connections. Directives in an <Anonymous> configuration block override any also set in its "parent" configuration (the base-, global-, or virtual-server section within which the Anonymous block is nested). Since in Example 9-5 you disabled ordinary user logins (actually all logins) in the base-server configuration, you'll need to enable it here, and indeed you shall (Example 9-6). Example 9-6. Anonymous FTP settings in /etc/proftpd.conf# Anonymous configuration, uploads permitted to "incoming" <Anonymous ~ftp> User ftp Group ftp UserAlias anonymous ftp MaxClients 30 DisplayLogin welcome.msg ExtendedLog /var/log/ftp_uploads WRITE uploadz AllowFilter "^[a-zA-Z0-9 ,.+/_\-]*$" <Limit LOGIN> AllowAll </Limit> <Limit WRITE> DenyAll </Limit> <Directory incoming/*> <Limit READ DIRS CWD> DenyAll </Limit> <Limit STOR> AllowAll </Limit> </Directory> </Anonymous> And here's the blow-by-blow explanation of Example 9-6:
That may have seemed like a lot of work, but we've got a lot to show for it: a hardened ProFTPD installation that allows only anonymous logins to a restricted chroot environment, with a special log file for all attempted uploads. Hopefully, you also now understand at least the basics of how to configure ProFTPD. These examples are by no means all inclusive; there are many other configuration directives you may use. See the "ProFTPD Configuration Directives" page (Configuration.html), included with ProFTPD packages and source code, for a comprehensive reference for proftpd.conf. 9.1.2.7 Virtual-server setupBefore we move on to other things, there's one more type of ProFTPD configuration we should examine due to its sheer usefulness: virtual servers. I've alluded to these a couple of times in the chapter, but to review, virtual-server definitions host multiple FTP sites on the same host in such a way that they appear to reside on separate hosts. Let's look at one example that adds a virtual server to the configuration file illustrated in Examples Example 9-4 through Example 9-6. Suppose our FTP server has, in addition to its primary IP address 55.44.33.22, the IP alias 55.44.33.23 bound to the same interface. A virtual-server definition for this second IP address might look like this (Example 9-7). Example 9-7. A virtual server definition in /etc/proftpd.conf<VirtualHost 55.44.33.23> Port 21 <Limit LOGIN> DenyAll </Limit> <Anonymous /home/ftp_hohner> User ftp Group ftp UserAlias anonymous ftp MaxClients 30 DisplayLogin welcome_hohner.msg AllowFilter "^[a-zA-Z0-9 ,]*$" <Limit LOGIN> AllowAll </Limit> <Limit WRITE> DenyAll </Limit> </Anonymous> </VirtualHost> Besides the <VirtualHost> configuration block itself, whose syntax is fairly obvious (you must specify the IP address or resolvable name of the virtual host), you've seen all these directives in earlier examples. Even so, two things are worth pointing out. First, the IP specified in the <VirtualHost> tag can be the host's primary address — i.e., the IP of the base server. However, if you do this, you must use the Port directive to specify a different port from the base server's in the virtual host setup. A virtual server can have the same IP address or the same listening port as the base server, but not both. Second, absent from this configuration block but implicit nonetheless are the settings for ServerIdent, AllowRetrieveRestart, MaxClients, MaxClientsPerHost, Umask, User, and Group defined earlier in the <Global> definitions in Example 9-5 (so are the first eight directives listed in Example 9-4.) By the way, you may have noticed that I didn't bother specifying ServerName or Masquerade Address. Since the global ServerIdent setting is off, these wouldn't be displayed anyway.
|