| jul2005.tar |
|
| display_errors = On | Change to: display_errors = Off |
| log_errors = Off | Change to: log_errors = On |
| ignore_repeated_errors = Off | Change to: ignore_repeated_errors = On |
| ;error_log = filename | Change to: error_log = /mnt/usb/tmp/php_errors.txt |
These changes will force errors to be logged to a file and not to the browser. It is a potential security risk to have the errors sent to the browser, because paths, names, and code are all given away in the error message.
If you want or need to enable File Uploads, go to the File Uploads section and make the following changes:
| ;upload_tmp_dir = | Change to: upload_tmp_dir = /mnt/usb/tmp or /tmp |
| upload_max_filesize = 2M | Change to: upload_max_filesize = ?M, where the ? is whatever you want the size to be. Be careful due to the limited space. |
Thttpd can be run from the command line with switches and options, or it can be run with reference to a config file. I prefer the config file method, because I can run multiple instances of thttpd on different ports, or as a different user, etc. by selecting a different config file.
For simplicity, I place my config files in /mnt/usb/etc. You can name them anything you want because you will be referencing them when you start thttpd. For now, I will show you a config file for a single thttpd. You will be able to see from the example how to implement multiple instances:
dir=/mnt/usb/www chroot user=nobody # default logfile=/mnt/usb/log/thttpd.log pidfile=/mnt/usb/log/thttpd.pid # This section _documents_ defaults in effect port=81 # nosymlink# default = !chroot # novhost # nocgipat # nothrottles # host=0.0.0.0 # charset=iso-8859-1The default directories where our PHP files will reside and to which the log files and PID file will be written are set to the expected /mnt/usb paths. The Web server runs as the default user "nobody", which should already exist in pretty much every Unix environment. The Web server runs on port 81, rather than the standard port 80, in case the host computer is already running a Web server such as Apache on port 80.
To test the configuration, create a trivial PHP script /mnt/usb/www/info.php with the following contents:
<? phpinfo(); ?>Then start thttpd with:
# /mnt/usb/sbin/thttpd -C /mnt/usb/etc/thttpd.confFrom any computer on the network, you should be able to open a browser and type in:
http://<linux server>:81/info.phpwhere <linux server> is the IP address or name of the server on which you installed thttpd.
Congratulations! You should now see the phpinfo for the installation of PHP on your Linux server. You now have a self-contained, fully capable Web server with a full-featured scripting language with database connectivity.
If you don't see the phpinfo page, you will need to go back through the installation process to see where you may have gone wrong. Read the rest of this article first, as there might be a permissions problem with your files. Also check whether thttpd is running:
ps -ef | grep thttpdIf thttpd is not running, you will need to find out why, possibly by checking the log in /mnt/usb/log/thttpd.log. Also check whether user nobody exists. If the page tries to download the phpinfo.php file to you, you have made an error in the order of compilation/installation of PHP and thttpd. PHP must be installed first, then thttpd.
For manipulating data and SQLite databases, tables, etc., you will probably want to download SQLite either in binary or source form and install it on your development server. If you decide to include it with any distribution, it will only take up about 50 KB of space. You will need the 2.X version of SQLite as it is compatible with PHP. Databases created with SQLite are portable between platforms, so if you create a SQLite 2.X database on your Windows workstation, you can copy it to the USB pen drive for use with thttpd and PHP on Linux, and vice versa.
Startup and Shutdown of thttpd
Under the source directory for thttpd, you will find a nice startup/shutdown script, thttpd.init, that can be modified for your purpose. It is under thttpd-2.21b/contrib/redhat-rpm. You can edit the paths to match our/your install paths as you wish, or you can simply use the startup.sh and shutdown.sh scripts below. I place these in the root directory of the USB pen drive:
#!/bin/sh
# This is the startup.sh for thttpd
/mnt/usb/bin/thttpd -C /mnt/usb/etc/thttpd.conf
#!/bin/sh
# This is the shutdown.sh for thttpd
STOP='ps -ef | awk '/thttpd/ && !/awk/ {print $2}''
kill $STOP
Set the execute bit on both files then test. Now you have your easy
startup and shutdown commands for the application.
To disconnect the device, first cd off it, then issue the umount command:
# umount /mnt/usbRemove the device from the USB slot.
File Permissions, Security, and Distribution
The following information on file permissions is reprinted from the thttpd man page (see Resources). Thttpd is picky about file permissions. It wants data files (HTML, images) to be world-readable. Readable by the group that the thttpd process runs as is not enough -- thttpd checks explicitly for the world-readable bit. This is so that no one ever gets surprised by a file that's not set to be world-readable and yet somehow is readable by the HTTP server and therefore the whole world.
The same logic applies to directories. Like the standard Unix ls program, thttpd will only let you look at the contents of a directory if its read bit is on; but as with data files, this must be the world-read bit, not just the group-read bit.
Thttpd also wants the execute bit to be off for data files. A file that is marked executable but doesn't match the CGI pattern might be a script or program that accidentally got left in the wrong directory. Allowing people to fetch the contents of the file might be a security breach, so this is prohibited. Of course if an executable file does match the CGI pattern, then it just gets run as a CGI.
In summary, data files should be mode 644 (rw-r--r--), directories should be 755 (rwxr-xr-x) if you want to allow indexing and 711 (rwx--x--x) to disallow it, and CGI programs should be mode 755 (rwxr-xr-x) or 711 (rwx--x--x).
The SQLite database files must be in the /mnt/usb/www or a subdirectory of it because we have done a chroot to /mnt/usb/www. I keep mine separate from my PHP pages in a subdirectory of www called data.
SQLite permissions, or so I have found, can be very restrictive. I set mine at 600 or (rw-------) for the databases. If you allow PHP to create a database, the permissions will be the default set by the umask, which most likely will be 644 (rw-r-r--).
Once the read, write, and execute permissions are all set correctly, I do a global change to nobody or the user that the thttpd runs as:
cd /mnt chown -R nobody:nobody *This will recursively change the permissions to the Web server user. It also prevents any issues with not being able to write to or read from data files.
While some would argue that placing data files in the same directory or subdirectory with your Web files is a non-secure method for a Web/database application, I think that due to the restrictions placed on us by thttpd, we haven't much choice. This solution, as described, is for use on an intranet and should be used as such. You should take reasonable security precautions when exposing any daemon to the Internet.
The biggest security advantage of this solution is that you only have a single daemon running, thttpd. The database is only accessible on the local file system with no daemon of its own, there is limited space on the device, and the thttpd is running as a non-root user. As long as your permissions are in order and your PHP coding is up to standards (preventing SQL injections, etc.), there should be little to worry about.
Distributing code causes many programmers/developers a little grief, but don't despair; there are code obfuscators out there for PHP. So, if you have a proprietary solution, protect yourself and your code by passing it through an obfuscator.
SQLite is a great database solution for a wide range of applications because it is ACID-compliant. However, there are limitations. If you write an application that requires frequent writes, you may want to consider a different database server, although I am confident that the developers of SQLite will continue to improve it.
Conclusion
I have attempted, in this article, to provide an overview of an interesting solution to allow your users access to a very capable Web database solution in a very small package. As media become less expensive, and with the use of USB hubs, you could potentially provide several Web database applications all running their own Web servers on different ports for different departments. Did I mention that it is portable?
Resources
Database servers -- http://www.linuxlinks.com/Software/Databases
Nanoweb -- http://nanoweb.si.kz
PHP 5.x -- http://www.php.net/downloads.php
Thttpd version 2.21 -- http://www.acme.com/software/thttpd/thttpd-2.21b.tar.gz
Thttpd man page -- http://www.acme.com/software/thttpd/thttpd_man.html
Web servers -- http://www.linuxlinks.com/Software/Internet/WebServers
Kenneth Hess is a Linux enthusiast and advocate. He began his obsession with Linux in 1995 and fervently defended his 1.2.13 kernel until he buried it in late 1999 along with his aspirations of becoming a famous actor. He can be reached for dialog at: kenneth.hess@gmail.com.