Apache Setup
The Dropbox software package contains the following directories:
- data default location config.php will configure to contain dropoffs and the log and SQLite database file
- docs this documentation, image templates
- lib shared PHP code, used by the web pages and admin scripts
- sbin administrative scripts
- www web pages and configuration file
The
www and
lib directories must be readable by the web server running on the server, but the other two directories can be locked-down.
Assume the Dropbox package resides at
/opt/NSSDropbox (the "NSS" prefix is just a cheap way to create a unique namespace for Dropbox functions). The Apache server running on the machine has an alias defined to point to the
/opt/NSSDropbox/www directory (from
httpd.conf):
<IfModule mod_alias.c>
Alias /dropbox "/opt/NSSDropbox/www/"
<Directory "/opt/NSSDropbox/www/">
AllowOverride None
Options FollowSymLinks ExecCGI
Order allow,deny
Allow from all
</Directory>
</IfModule>
Alternatively,
DocumentRoot could be set to point to
/opt/NSSDropbox/www if Dropbox is to be the exclusive service on this web server.
The web server must have PHP 5 support enabled for Dropbox 2.1 to work. Once the web server is configured to serve the
www directory, the Dropbox support files and directories must be created and configured.
Dropbox Creation
Before discussing the creation of a Dropbox, it will be instructive to know what happens when a dropoff is made.
- The end-user submits a dropoff from his/her web browser.
- Dropbox chooses a unique 16-character identifier (the claimID) for the data as well as a 16-character passcode that will be sent to the recipients in the notification email.
- Dropbox verifies that the dropoff is valid — syntactically-correct email addresses, all files within size limits, etc.
- Dropbox creates a directory with the claimID as its name and moves the files from PHP's upload_tmp_dir into that directory.
- Dropbox adds dropoff, recipient, and file description records to its database
- Finally, Dropbox writes the HTML response — either an error report or a summary of the dropoff.
So there are essentially two directories to worry about here. First is the directory that Dropbox uses in step 4. Given a large disk mounted at
/dropbox on the target system, and within that directory we've created
/dropbox/dropoffs to hold all of the dropoff directories (again, from step 4). Of course, the web server must be able to write to this directory! So set permissions and ownership accordingly.
The other directory is the directory PHP uses to hold uploaded files; by default, PHP uses
/tmp. It may be desirable to change this to a location on the same disk as the final destination of the dropoffs, e.g.
/dropbox/incoming. The web server must be allowed to write to this directory, too.
In the end, we'll probably wind up storing Dropbox's database and log file here, as well. So what might a production
/dropbox directory look like?
$ ls -l /dropbox
total 3.9M
-rw-r--r-- 1 apache wheel 2.4M Mar 1 13:51 dropbox.log
-rw-r--r-- 1 apache wheel 720K Mar 1 13:51 dropbox.sqlite
drwxrws--- 1019 apache wheel 36K Mar 1 13:51 dropoffs
drwxrws--- 2 apache wheel 4.0K Mar 1 13:51 incoming
Both the
dropoffs and
incoming directories are locked-down so that only the web server user (
apache) and members of the administrative group
wheel can see inside them. One could likewise remove the global read permission on the log and database files to increase security.
Dropbox Configuration
The configuration file for a Dropbox lives in the
NSSDropbox/www directory and is named
preferences.php. This file contains a few definitions of constants and (primarily) an associative array (hash) of configuration parameters. An example configuration file can be found in
NSSDropbox/docs/preferences-sample.php.
The Dropbox package includes
NSSDropbox/www/config.php, a PHP script that:
- suggests default values for all parameters
- checks permissions on the data directory where dropoffs, the log file, and SQLite database file will be stored
- constructs a preferences.php file
- creates the dropoffs directory and initializes the log and SQLite database files
Essentially, after accessing this script across the web (the URL would be for example
http://hostname/dropbox/config.php) the system administrator can make minor adjustments to the resultant
preferences.php file (to setup LDAP authentication, for example). To make these changes, it's important to know what those parameters mean and what values are appropriate.
Constants
In the
preferences.php file:
define('NSSDROPBOX_BASE_DIR','/opt/NSSDropbox/');
define('NSSDROPBOX_LIB_DIR','/opt/NSSDropbox/lib/');
define('NSSDROPBOX_DATA_DIR','/dropbox/');
The first two (
NSSDROPBOX_BASE_DIR and
NSSDROPBOX_LIB_DIR) should be self-explanatory. The third (
NSSDROPBOX_DATA_DIR) is the path at which dropoffs will be stored. The trailing "
/" in the paths
is significant, so don't forget it!
There is also a constant that determines which
theme will be used on the website. The package contains several themes:
- default
- flat
- flat2
- blue
- algae
- duracell
It is relatively straightforward to craft additional themes. Image pieces go in
www/images/theme and a
theme.css file must be added to
www/css. The image pieces include the page header, footer, and button components; look at the images in
www/images/default to get a better idea.
Preference Hash
The preference file that comes with the package includes quite a bit of inline documentation to describe each of the preferences. Even so:
Key String | Description |
dropboxName |
Provides the descriptive name for the service; displayed throughout the web interface.
EXAMPLE:
"UD Dropbox Service"
|
contactInfo |
Text that should be displayed in the footer of each web page generated by Dropbox.
EXAMPLE:
"University of Delaware, Network & Systems Services | Copyright © 2006"
|
dropboxDomain |
The base DNS domain of the hosting organization, used to determine when an email address is an internal address.
EXAMPLE:
"udel.edu"
|
dropboxDirectory |
The canonical directory path where the Dropbox should store dropoff files.
EXAMPLE:
NSSDROPBOX_DATA_DIR."dropoffs"
|
dropboxDatabase |
The canonical path to the SQLite database file that the Dropbox will use to store dropoff information.
EXAMPLE:
NSSDROPBOX_DATA_DIR."dropbox.sqlite"
|
logFilePath |
The canonical path to the Dropbox log file.
EXAMPLE:
NSSDROPBOX_DATA_DIR."dropbox.log"
|
numberOfDaysToRetain |
If automatic removal of dropoffs is setup (to keep disk usage under control) the NSSDropbox/sbin/cleanup.php script uses this parameter to determine how old a dropoff can be. The value must be an integer and has an implied unit of days.
EXAMPLE:
14
|
authUserFormalDesc |
A verbose description on an internal of the Dropbox (a'la a user with an email address in dropboxDomain). The system will in some places display text like: <authUserFormalDesc> user.
EXAMPLE:
"University of Delaware"
|
authUserShortDesc |
A shortened description on an internal of the Dropbox (a'la a user with an email address in dropboxDomain). The system will in some places display text like: <authUserShortDesc> user.
EXAMPLE:
"UD"
|
emailSenderAddr |
By default, emails sent by Dropbox will come from the user the web server is running as; use this property to assign a custom "From:" address to messages originating from Dropbox.
EXAMPLE:
"UD Dropbox Service <dropbox@udel.edu>"
|
maxBytesForFile |
The maximum allowed size of a single file in a dropoff. Note that PHP's own upload_max_filesize configuration parameter in php.ini may need to be altered to increase PHP's own upload limit (the default is something like 2 MB). The Dropbox limit is applied after PHP has its say.
EXAMPLE:
10.0 * 1024 * 1024 /* 10 MB */
|
maxBytesForDropoff |
The maximum allowed size of all the files contained in a single dropoff. Note that PHP's own upload_max_filesize configuration parameter in php.ini may need to be altered to increase PHP's own upload limit (the default is something like 2 MB). The Dropbox limit is applied after PHP has its say.
EXAMPLE:
20.0 * 1024 * 1024 /* 20 MB */
|
showRecipsOnPickup |
Should the list of recipients be displayed on pickup pages when a recipient makes the pickup? This setting is mainly there for security purposes. Admins and the user who made the dropoff can always see the recipient list.
EXAMPLE:
FALSE
|
demandHTTPS |
Set this to TRUE if the Dropbox code itself should enforce the exclusive use of secure HTTP (HTTPS). Note that a Redirect or RedirectMatch directive in the Apache server's configuration can also be used to enforce the use of secure transfer:
<VirtualHost *:80>
ServerName dropbox.udel.edu
Redirect /dropbox https://po-box.nss.udel.edu/
</VirtualHost>
|
cookieName |
The cookie name that Dropbox should use for authentication purposes.
EXAMPLE:
"ud-dropbox-session"
|
cookieSecret |
The Dropbox uses a 32-character value that is known only internally to create MD5 checksums that are embedded in the cookies it uses. When Dropbox examines a cookie sent to it by a browser, this secret text helps to prove the cookie's authenticity. The config.php web page automatically generates this value and stores it in the preferences.php file it creates. See the next sub-section for details on generating cookie secrets.
|
cookieTTL |
Number of seconds before the cookie that Dropbox uses for authentication purposes expires.
EXAMPLE:
900
|
authenticator |
For internal users to login to the Dropbox system, there must be some way to authenticate that user. The package includes an LDAP-based, IMAP-based, and static authenticator class. Other mechanisms can be added by creating a concrete subclass of NSSAuthenticator — see lib/NSSAuthenticator.php.
The NSSIMAPAuthenticator class was originally written and contributed by Scott Merrill.
EXAMPLE:
"Static"
"LDAP"
"IMAP"
GENERIC AUTHENTICATOR PREFERENCES:
Key String | Description |
authAdmins |
An array of usernames who are granted administrative privileges on the Dropbox web site. Essentially, once an internal user with administrative privileges logs-in s/he will be able to view all dropoffs.
EXAMPLE:
array("jfrey","avg_joe")
|
LDAP AUTHENTICATOR PREFERENCES:
Key String | Description |
authLDAPBaseDN |
The LDAP authenticator should attempt to bind to this LDAP domain.
EXAMPLE:
"o=udel.edu"
|
authLDAPServers |
A list of LDAP servers which Dropbox can try for authentication purposes; the servers are tried in sequence until one answers the bind request. This key should always have an array-based value, even if there is only one server.
EXAMPLE:
array("ldap1.udel.edu","ldap2.udel.edu")
|
IMAP AUTHENTICATOR PREFERENCES:
Key String | Description |
authIMAPServer |
The IMAP server which Dropbox can try for authentication purposes.
EXAMPLE:
"mail.udel.edu"
|
|
The "Dictionary"
Another global hash is used to store alternate strings that should be substituted throughout the web interface: at UDel, we call the username a
UDelNetID, so throughout the interface we'd like to see that, rather than "username." The
$DROPBOX_DICTIONARY hash can currently contain the following keys with the substitution text as the value:
- 'Username' => 'UDelNetID'
- 'username' => 'UDelNetID'
- 'Authentication' => 'UD Authentication'
- 'username-regex' => '/^([a-z0-9][a-z0-9\_]*)$/'
That final entry isn't so much a translation as a quick and dirty way of allowing admininstrators to modify the criteria used to determine what is and isn't a valid username, before the chosen authenticator is even queried.
The
LookupInDict() function (defined in
lib/NSSUtils.php) receives a string as its sole argument; if
$DROPBOX_DICTIONARY contains that string as a key, the value associated with that key is returned (thus, facilitating the substitution). Otherwise, the original string itself is returned.
Generating a Cookie Secret
On a Linux system with the
/dev/random device, the following can be done:
$ /bin/dd if=/dev/random bs=1024 count=1 2>/dev/null | md5sum
bb2c85e5a037ee4c734f25c1b66fa8f1 -
Without
/dev/random, simply calculate the MD5 checksum of a word processing document, for example.
Periodic Maintenance Scripts
All of the scripts mentioned in this section will probably need to be modified for use on the target system — namely, in the path to the
php interpreter on the first line of the script.
The Dropbox package includes a script that can be run (via
cron) to remove outdated dropoffs. The script essentially takes the current system timestamp and subtracts the number of days specified for
numberOfDaysToRetain, and locates any dropoffs with a creation date before that. The files and database records for all that are found are removed.
$ /opt/NSSDropbox/sbin/cleanup.php
usage:
/opt/NSSDropbox/sbin/cleanup.php <Dropbox preference file>
The Dropbox preference file path should be canonical, not relative.
The cron specification looks like
# Daily cleanup:
5 0 * * * /opt/NSSDropbox/sbin/cleanup.php /opt/NSSDropbox/www/preferences.php > /dropbox/cleanup.log
The package also includes a script to send an email report of all dropoffs that have been made in the past 24 hours:
$ /opt/NSSDropbox/sbin/stats.php
usage:
/opt/NSSDropbox/sbin/stats.php <Dropbox preference file> {email address}
The Dropbox preference file path should be canonical, not relative.
If no email address is provided, the summary is displayed on stdout.
The cron specification looks like
# Daily summary:
0 0 * * * /opt/NSSDropbox/sbin/stats.php /opt/NSSDropbox/www/preferences.php sysadmins@udel.edu > /dev/null
On the UD Dropbox system
rrdtool is used to maintain a historical record of the daily dropoff count, total uploaded GB, total files, etc. Those scripts (and the web pages that display the graphs that are created each night with
rrdtool) are included in the package in case those facilities are desired.

Credits
Dropbox 2.1 was created to extend the functionality of the original Dropbox software, written by Doke Scott (UD Network and Systems Services). Jeffrey Frey, also of UD Network and Systems Services, updated the package with the following design goals in mind:
- Cleaner, richer web interface
- More scalable:
- dropoff/recipient/file info stored in a database
- better on-disk organization of dropped-off files
- Ability to upload multiple files in a single dropoff
- Ability to specify multiple recipients for a single dropoff
The latter two goals aim to reduce redundant dropoffs, thus saving disk space — rather than dropping off the same 10 MB file to four individuals, only one dropoff and one copy of the file is necessary.
PHP includes support for SQLite2 databases.
SQLite uses a single disk file to store an SQL database, in sharp contrast to database servers like MySQL and PostgreSQL. Thus, the initial setup of Dropbox is simplified by removing the need for the administrator to build/configure a database server. SQLite may not be the most efficient database environment out there, but it provides an easy way to store and randomly retrieve dropoff records. The single file also makes it easy to backup the database; one could run a cron job that makes an RCS diff of the database every 15 minutes. Were the database to be corrupted somehow, it can easily be rolled back to a version that was not corrupted and isn't missing too many dropoffs.