224 lines
6.8 KiB
HTML
224 lines
6.8 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>ProFTPD: Connection ACLs</title>
|
|
</head>
|
|
|
|
<body bgcolor=white>
|
|
|
|
<hr>
|
|
<center><h2><b>ProFTPD: Connection ACLs</b></h2></center>
|
|
<hr>
|
|
|
|
<p>
|
|
Many sites running <code>proftpd</code> have the need to limit/reject
|
|
connections from known bad addresses, or to accept connections only from
|
|
known good addresses. ProFTPD supports several different mechanisms for
|
|
implementing FTP connection ACLs.
|
|
|
|
<p>
|
|
However, there is one important thing to note: <b>ProFTPD is not a firewall.</b>
|
|
Never forget this. You <b>cannot</b> <i>prevent</i> TCP connections from ever
|
|
reaching <code>proftpd</code> in the first place by using <code>proftpd</code>
|
|
itself. This means that for many sites with connection ACL needs, their
|
|
system's firewall capabilities may be a better mechanism for implementing ACLs.
|
|
|
|
<p>
|
|
<b><code><Limit LOGIN></code>, and Whitelists versus Blacklists</b><br>
|
|
The easiest way of accepting/rejecting connections is to use ProFTPD's
|
|
<a href="Limit.html"><code><Limit></code></a> syntax, particularly
|
|
<code><Limit LOGIN></code>.
|
|
|
|
<p>
|
|
For example, you can simply reject all connections to your <code>proftpd</code>
|
|
instance by using:
|
|
<pre>
|
|
<Limit LOGIN>
|
|
DenyAll
|
|
</Limit>
|
|
</pre>
|
|
A more practical example would look like:
|
|
<pre>
|
|
<Limit LOGIN>
|
|
# These are trusted addresses
|
|
Allow from 1.2.3.4 5.6.7.8
|
|
Allow from trusted-domain.com
|
|
|
|
# Everyone else is denied
|
|
DenyAll
|
|
</Limit>
|
|
</pre>
|
|
|
|
<p>
|
|
The above configuration demonstrates the concept of a <i>whitelist</i>: known
|
|
trusted (<i>i.e.</i> "white") addresses are explicitly listed and allowed, and
|
|
all others are denied. Conversely, you might use a <i>blacklist</i>, where
|
|
known bad/malicious/untrusted (<i>i.e.</i> "black") addresses are explicitly
|
|
listed and denied, and all others are allowed:
|
|
<pre>
|
|
<Limit LOGIN>
|
|
Order deny,allow
|
|
|
|
# These are known bad addresses
|
|
Deny from 1.2.3.4 5.6.7.8
|
|
Deny from evil-domain.com
|
|
|
|
# Everyone else is allowed
|
|
AllowAll
|
|
</Limit>
|
|
</pre>
|
|
|
|
<p>
|
|
It is useful to know about whitelists versus blacklists, as it can affect
|
|
how large your ACLs become. Sites which run publicly available FTP servers
|
|
but which need to weed out bad clients tend to use blacklists; over time,
|
|
these blacklists can become quite large. Sites which know who will be using
|
|
their FTP server and only want those people to be able to connect will use
|
|
whitelists; these whitelists tend to remain fairly small/short.
|
|
|
|
<p>
|
|
<b>Large Blacklists</b><br>
|
|
Let's assume that you are running a public FTP server, and that you are using
|
|
a <code><Limit LOGIN></code> section to make a blacklist. Your site
|
|
may even have some script which detects bad clients, and automatically adds
|
|
them to your blacklist, <i>e.g.</i>:
|
|
<pre>
|
|
<Limit LOGIN>
|
|
Order deny,allow
|
|
|
|
# -- Add blacklisted addresses here --
|
|
Deny from ...
|
|
Deny from ...
|
|
# <b>Many</b> more <code>Deny from</code> lines
|
|
|
|
# Allow everyone not explicitly blacklisted
|
|
AllowAll
|
|
</Limit>
|
|
</pre>
|
|
Over time, your number of blacklisted IP addresses starts to become large
|
|
and unwieldy. You might have thousands of such addresses; you notice that
|
|
<code>proftpd</code> starts acting strangely, and starts slowing down.
|
|
|
|
<p>
|
|
When this happens, you should start looking for ways to make your list shorter.
|
|
If your list is comprised of entries for each individual IP address, you
|
|
should think about using glob expressions and netmasks to reduce the number
|
|
of entries. For example, rather than using something like
|
|
this:
|
|
<pre>
|
|
Deny from 1.2.3.4
|
|
Deny from 1.2.3.5
|
|
Deny from 1.2.3.6
|
|
Deny from 1.2.3.7
|
|
Deny from 1.2.3.8
|
|
Deny from 1.2.3.9
|
|
</pre>
|
|
you could (as of <code>proftpd-1.3.4rc1</code> and later) use a range:
|
|
<pre>
|
|
Deny 1.2.3.[4-9]
|
|
</pre>
|
|
or even use a glob wildcard such as this, which makes for even fewer entries
|
|
in your address lists:
|
|
<pre>
|
|
Deny 1.2.3.*
|
|
</pre>
|
|
Or you could use netmasks such as:
|
|
<pre>
|
|
Deny 1.2.3.0/8
|
|
</pre>
|
|
|
|
<p>
|
|
<b>Using Classes</b><br>
|
|
Now let's assume that at this point you have used glob ranges and wildcards
|
|
and netmasks to make your ACL shorter, but it is still large, and
|
|
<code>proftpd</code> is still slow. It is time for you to use ProFTPD's
|
|
connection <a href="Classes.html">classes</a>.
|
|
|
|
<p>
|
|
To do this, you would rewrite your large <code><Limit LOGIN></code>
|
|
section to look something like this:
|
|
<pre>
|
|
<Class blacklist>
|
|
# Put all of your blacklisted address/range lines here, as <code>From</code> lines
|
|
From ...
|
|
From ...
|
|
From ...
|
|
</Class>
|
|
|
|
<Limit LOGIN>
|
|
Order deny,allow
|
|
|
|
# Rejected blacklisted clients
|
|
DenyClass blacklist
|
|
|
|
# Allow everyone else
|
|
AllowAll
|
|
</Limit>
|
|
</pre>
|
|
|
|
<p>
|
|
Why does using classes like this make things faster? When using classes, the
|
|
label (<i>i.e.</i> the class name in the <code><Class></code> section,
|
|
like "blacklist" in the above example) is determined when the client
|
|
<i>first</i> connects to <code>proftpd</code>, before any comands are sent.
|
|
That is when all of the various netmasks and such are checked -- and
|
|
<i>only</i> at that time. After that, all of the configuration-based ACLs
|
|
are evaluated just using that label.
|
|
|
|
<p>
|
|
When you do not use classes, then proftpd scans each configuration, each
|
|
netmask/address <b><i>for each command</i></b>. That's why things slow down so
|
|
much.
|
|
|
|
<p>
|
|
<b>Alternatives</b><br>
|
|
There are a couple of other ways in which to implement connection ACLs; these
|
|
alternatives may be more efficient and/or better suited to your site's needs.
|
|
|
|
<p>
|
|
You can use a module like
|
|
<a href="../contrib/mod_wrap2.html"><code>mod_wrap2</code></a>, particular its
|
|
support for storing ACLs in SQL tables. SQL lookups can be very quick, and
|
|
can easily support large numbers of addresses efficiently.
|
|
|
|
<p>
|
|
And if you find yourself starting to block large blocks of addresses from
|
|
countries/regions, you should start thinking about connection ACLs in terms of
|
|
geolocation information. For this, the <a href="../contrib/mod_geoip.html"><code>mod_geoip</code></a> module for ProFTPD is quite useful.
|
|
|
|
<p><a name="FAQ">
|
|
<b>Frequently Asked Questions</b><br>
|
|
|
|
<p>
|
|
<font color=red>Question</font>: Is there a limit to how many addresses can
|
|
appear in a single line in the config file?<br>
|
|
<font color=blue>Answer</font>: No. However, there <i>is</i> a maximum line
|
|
length, which is determined by the buffer size used by the configuration file
|
|
parser. That buffer size is usually 1024 bytes (1K).
|
|
|
|
<p>
|
|
This 1024 byte length limitation can be worked around, however, by breaking
|
|
a single line in the configuration file into multiple lines using the
|
|
line continuation syntax, <i>e.g.</i>:
|
|
<pre>
|
|
Allow 1.2.3.4 5.6.7.8 9.10.11.12
|
|
</pre>
|
|
can also appear as:
|
|
<pre>
|
|
Allow \
|
|
1.2.3.4 \
|
|
5.6.7.8 \
|
|
9.10.11.12
|
|
</pre>
|
|
|
|
<p>
|
|
<hr>
|
|
<font size=2><b><i>
|
|
© Copyright 2017 The ProFTPD Project<br>
|
|
All Rights Reserved<br>
|
|
</i></b></font>
|
|
<hr>
|
|
|
|
</body>
|
|
</html>
|