I’ve been running LAMP-setups throughout the last 12 years or so, but security have always been a big concern. User convenience, simplicity and accessibility have also been big concerns, so security features and a locked down system can not decrease any of theese key points.
This is still a draft, needs to be updated. Consider it as a work in progress.
The setup below is a continous work and will probably be modified, but should be considered as a request-for-comment document. There will likely be lots of improvements possible, and it might even contain security holes that I havent thought about yet.
I expect to keep the following services:
- ssh/scp/sftp access
- apache
- mysql database
- php
- outgoing emails
- use of subversion and git through ssh
- possibly memcached(to be added later)
Common attack scenarios are
- sql injections
- execution of arbitrary phpcode
Goals:
- Limit successful attacks to a single user account
- Limit successful attacks so they can not cause much harm to affected user
First and foremost - ssh/scp/sftp
Allow users to ssh and scp into their chrooted home directory. Although, they should be able to use most stuff locally in there, like subversion, git and also access their weblog files. Uploading should be made with scp or preferrably managed with some version control system.
I found this script which sets up a chroot jail where users are sent after successful scp and ssh. Seems to work reasonably well.
http://www.fuschlberger.net/programs/ssh-scp-sftp-chroot-jail/
My biggest worry with it is that its really old. :)
My $APPS-list in it is:
/usr/bin/git-* /bin/chmod /usr/bin/git /usr/bin/file /bin/nc /usr/bin/giftopnm /usr/bin/jpegtopnm /usr/bin/bmptoppm /usr/bin/pnmscale /usr/bin/ppmtojpeg /usr/bin/ppmquant /usr/bin/ppmtogif /usr/bin/pngtopnm /usr/bin/pnmtopng /usr/bin/tail /usr/bin/php /bin/cat /usr/bin/crontab /usr/bin/svnadmin /usr/bin/grep /usr/bin/ssh-keygen /bin/nano /bin/hostname /usr/bin/svn /bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /sbin/unix_chkpwd
This makes users locked into a “fake” system-chroot in /home/jail/. Right now I run multiple users in the same /home/jail, although, they have separate user homedirs in /home/jail/home/user but share the binaries.
The user-row in /etc/passwd looks like:
user-name:x:1032:1032::/home/jail/home/user-name:/bin/chroot-shell
And this is added to the /etc/sshd_config:
Match Group webuser
ChrootDirectory /home/jail/
AllowTCPForwarding no
X11Forwarding no
Running apache as the real user-user
I’ve been thinking about this a lot, whichever is the best. Now I’m running apache as the real user, within the chroot with help of the mpm-itk module for apache.
This is an example of the virtualhost used. Apache is running as the real jailed user, and documentroot is set as below.
<VirtualHost 127.0.0.1>
ServerName hostname.domain
DocumentRoot /home/jail/home/user-name/www/
AssignUserID user-name user-name
php_value mysql.default_user db-user-name
php_value mysql.default_password db-password
php_value mysql.default_host localhost
php_admin_value open_basedir /home/jail/home/user-name/
php_admin_value upload_tmp_dir /home/jail/home/user-name/tmp/
php_admin_value session.save_path /home/jail/home/user-name/tmp/
</VirtualHost>
The virtualhost-config-file can be owned and only readable by root, which means the user can access the environment variables in php with the getenv()-function. This is good, since the user doesnt need to store the database username and password in their homedirectory, makeing it a little bit more protected.
Read more about mpm itk at http://mpm-itk.sesse.net/
Using suhosin to limit PHP
Some things in PHP have so sharp edges that users are more or less expected to do mistakes with them, therefor, I’ve been disabling the following functions:
suhosin.executor.func.blacklist = “register_globals, enable_dl, show_source, system, shell_exec, passthru, exec, popen, proc_open, allow_url_fopen”
TODO:
- Lots of documentation and clarifications to make
- Add some example code to verify that its not possible to escape the jail. Would be nice with a thorough testsuite.
If you see problems somewhere, see good improvements, or have questions, leave a message.