mod_dbacl
The mod_dbacl
module is used to map commands/requests to
ACLs, and then to look up the ACLs/permissions for the path/file in question,
on a per-command/request basis, from a SQL table. Thus the
mod_dbacl
module allows the use of SQL tables for controlling
permissions of files, directories, etc on the server.
Installation instructions are discussed here.
The most current version of mod_dbacl
can be found at:
http://www.castaglia.org/proftpd/
Please contact TJ Saunders <tj at castaglia.org> with any questions, concerns, or suggestions regarding this module.
2011-05-11: Thanks to Ben Timby <btimby at gmail.com> for providing the path splitting idea and suggested lookup query.
<VirtualHost>
, <Global>
The DBACLEngine
directive enables or disables the
mod_dbacl
module.
<VirtualHost>
, <Global>
The DBACLPolicy
directive configures the default policy to use,
when mod_dbacl
is unable to retrieve the ACL setting from the
SQL table, e.g. due to database misconfiguration or due to lack of
database entries for the paths/ACLs in question.
The default DBACLPolicy
setting of "allow" is
highly recommended. You should only use "DBACLPolicy deny" if you need
to have a "fail-closed" system of permissions on your server.
<VirtualHost>
, <Global>
The DBACLSchema
directive can be used to override the
default SQL table and column names expected by the mod_dbacl
module. More details on the SQL schema used by this module can be found in
the usage section.
<VirtualHost>
, <Global>
The DBACLWhereClause
directive configures an additional clause
to add to the SQL WHERE
clause constructed by
mod_dbacl
. The configured WHERE
clause can be
used to look up user/group-specific ACLs, for example.
Example WHERE
clause of user-specific lookups:
DBACLWhereClause "user = '%u'"Note: If you use
DBACLWhereClause
, make sure that
the columns named in the WHERE
clause also have indexes on them,
so that the SQL query can be executed more quickly.
mod_dbacl
, copy the mod_dbacl.c
file into
the third-party module area in the proftpd source code:
cp mod_dbacl.c proftpd-dir/contrib/after unpacking the latest proftpd-1.3.x source code. For including
mod_dbacl
as a staticly linked module:
./configure --with-modules=mod_dbacl:mod_sql ...Alternatively,
mod_dbacl
can be built as a DSO module:
./configure --enable-dso --with-shared=mod_dbacl ...Then follow the usual steps:
make make install
Since the mod_dbacl
module looks up ACLs/permissions from
SQL tables, it requires that the mod_sql
module (and a
mod_sql
module such as mod_sql_mysql
,
mod_sql_postgres
, mod_sql_sqlite
, etc) be
used. For example, your configure
command to build
proftpd
might look like:
# ./configure --with-modules=mod_sql:mod_sql_sqlite:mod_dbacl ...
Mapping Commands/Requests to ACLs
The mod_dbacl
works by first mapping each command/request to
a specific ACL (i.e. a "permission group"), and then looking for the
value for that ACL/path pair in the SQL table.
The ACLs currently supported by mod_dbacl
, and the
commands/requests for those ACLs, are:
ACL | Commands | |
READ |
RETR |
|
WRITE |
APPE , STOR , STOU |
|
DELETE |
DELE , RMD , XRMD |
|
CREATE |
MKD , XMKD , LINK , SYMLINK |
|
MODIFY |
MFF , MFMT , SITE CHGRP , SITE CHMOD , SETSTAT , FSETSTAT |
|
MOVE |
RNFR , RNTO , SITE CPTO , RENAME |
|
VIEW |
LIST , MDTM , MLSD , MLST , NLST , SIZE , STAT , LSTAT , OPENDIR , READLINK |
|
NAVIGATE |
CDUP , XCDUP , CWD , XCWD , PWD , XPWD , REALPATH |
Use the NAVIGATE
ACL with caution. Many clients, both FTP
and SFTP, will not function properly if they are unable to execute commands
such as PWD
or REALPATH
. If you do use
the NAVIGATE
ACL, make sure that it restricts only very specific
areas of your filesystem.
Splitting Paths into Component List
Once the command/request has been mapped to its ACL, the mod_dbacl
looks at the path to the file/directory being requested by the client.
Note that mod_dbacl
always works on absolute paths;
it resolves the path as sent by the client into the absolute path, regardless
of any chroot(2)
which may be in effect for the session.
The path-splitting algorithm takes a path like:
/home/user/dir/file.txtand breaks it down into a list of ever-more specific paths, like this:
/home /home/user /home/user/dir /home/user/dir/file.txtArmed with this list, the
mod_dbacl
module can look for the
closest-matching path in the SQL table, if any, which covers the path
requested by the client.
This approach allows administrators to configure ACLs that cover broad ranges of filesystems (e.g. "/var") to very specific files, as they need.
Database Schema
So what does the database schema used by mod_dbacl
look like?
Here's an example SQLite script, which creates the table used by
mod_dbacl
, using the default table and column names:
CREATE TABLE ftpacl ( path TEXT NOT NULL, read_acl TEXT, write_acl TEXT, delete_acl TEXT, create_acl TEXT, modify_acl TEXT, move_acl TEXT, view_acl TEXT, navigate_acl TEXT ); CREATE INDEX ftpacl_path_idx ON ftpacl (path);Note that creating an index on the
ftpacl.path
column
is strongly recommended. Without an index on that column, your
mod_dbacl
lookups will be quite slow.
The string values which can appear in the ACL columns can be any of the following:
mod_dbacl
will deny that request.
Module Configuration
Configuring the mod_dbacl
module is quite simple, as most of
the configuration lies in the SQL tables. To enable mod_dbacl
and use the default table/column names, simply use:
<IfModule mod_dbacl.c> DBACLEngine on </IfModule>That's it!
Example Command
To illustrate all of this, let's take a common FTP command and walk through
how mod_dbacl
would work. First, the FTP client (after
authenticating) sends a RETR
command to download a file:
RETR dir/file.txt
The RETR
command is mapped to its ACL, i.e. the "READ" ACL.
Then the path is resolved to the absolute path, then split into a list,
i.e.:
/home /home/user /home/user/dir /home/user/dir/file.txt
With the ACL and the path list, mod_dbacl
builds up the SQL
query to use:
SELECT read_acl FROM ftpacl WHERE path IN ('/home', '/home/user', '/home/user/dir', '/home/user/dir/file.txt') ORDER BY LENGTH(path) DESC LIMIT 1
In the ftpacl
database table, assume the following rows are
present:
|--------------------------------------------------| | PATH | READ_ACL | |--------------------------------------------------| | /home | false | | /home/user/dir | false | | /home/user/dir/file.txt | true | |--------------------------------------------------|The longest matching path in the table is "/home/user/dir/file.txt", which matches the path being download by the FTP client. The value for the
ftpacl.read_acl
column is "true", thus mod_dbacl
allows the command to proceed.
Note that mod_dbacl
does not override any
<Directory>
/<Limit>
sections which may
also be configured, nor does it override the underlying filesystem permissions.
Logging/Debugging
Rather than having its own separate log file, the mod_dbacl
module uses the "dbacl" trace log channel in the TraceLog
. Thus to enable logging
for mod_dbacl
, in order to debug configuration issues, you would
use the following in your proftpd.conf
:
TraceLog /path/to/ftpd/trace.log Trace dbacl:20 ...
SFTP/SCP Interoperability
The mod_dbacl
does work with the mod_sftp
module
such that SFTP requests are also handled/processed, just as FTP commands are
handled. Note that SCP transfers may not work as expected with
mod_dbacl
yet (notably directory creation for recursive SCP
uploads).