Dev, Manage, Deploy

...and things in between...

0 notes

RFC: Chrooted ssh account with lamp-webhosting

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.