summaryrefslogtreecommitdiffstats
path: root/mod_suphp-0.6.1-chroot.patch
diff options
context:
space:
mode:
authorRemi Collet <fedora@famillecollet.com>2012-06-13 18:43:31 +0200
committerRemi Collet <fedora@famillecollet.com>2012-06-13 18:43:31 +0200
commit3eb5696b8ee245c48c11dd6aefbda531054a0eec (patch)
treecd7b7a8c909f6a2dd2d4978cf590032083d3b906 /mod_suphp-0.6.1-chroot.patch
reorg repoHEADmaster
Diffstat (limited to 'mod_suphp-0.6.1-chroot.patch')
-rw-r--r--mod_suphp-0.6.1-chroot.patch252
1 files changed, 252 insertions, 0 deletions
diff --git a/mod_suphp-0.6.1-chroot.patch b/mod_suphp-0.6.1-chroot.patch
new file mode 100644
index 0000000..337fb81
--- /dev/null
+++ b/mod_suphp-0.6.1-chroot.patch
@@ -0,0 +1,252 @@
+Hello list!
+
+I've written a patch around the chroot() function in
+suPHP 0.6.1. First I'll explain our old setup and why
+we find this patch useful.
+
+Since we are improving our webserver security at the
+moment, we were looking for a possibility to
+chroot() some users.
+
+Our old setup consists of mod_php and PHP per VirtualHost
+configurations like:
+ php_admin_value open_basedir ...
+ php_admin_value upload_tmp_dir ...
+ ...
+With disable_functions we disabled functions like exec(),
+system(), etc to let the user stay in his open_basedir
+(executed programs don't got the open_basedir
+restrictions).
+
+Some users requested the possibility to exec programs like
+the ImageMagick tools, needed for Typo3 or other PHP
+programs like PHP gallery. I know about the possibility to
+configure a safe_mode_exec_dir within the php.ini, but it
+is not the best solution.
+
+The new suPHP version 0.6.1 offers the possibility to
+chroot and it works nice. Though there are some problems:
+- There is only one configuration file and the chroot-path
+ is configured within the global config. If you want to
+ chroot each virtual host into it's own chroot-jail it
+ isn't possible.
+- When chrooted the path of the php script stays like
+ outsite the chroot environment.
+ Example:
+ before suPHP chroot()
+ SCRIPT_FILENAME = /chroot/YOUR_SITE/var/www/index.php
+ CURRENT_ROOT = /
+ CHROOT = /chroot/YOUR_SITE/
+
+ after suPHP chroot()
+ SCRIPT_FILENAME = /chroot/YOUR_SITE/var/www/index.php
+ CURRENT_ROOT = /chroot/YOUR_SITE/
+
+ PHP will look for a file called
+ /chroot/YOUR_SITE/var/www/index.php
+ inside the chroot environment.
+ Infact the file is
+ /var/www/index.php
+ inside the chroot environment.
+
+What the attached patch does:
+- It adds a mod_suphp configuration option called
+ "suPHP_Options" (the name might not be the best, but
+ since suPHP_ConfigPath was already in use, I've choosen
+ this name)
+- It "translates" the script path after chroot() so that
+ PHP will find the right script.
+
+Here are the steps I used to build a chroot environment for
+a virtual host:
+- Create a directory structure for the chroot directory:
+ $ mkdir -p /chroot/YOUR_SITE/\
+{bin,etc,lib,tmp,usr/bin,usr/lib/,var/www}
+
+- Copy the php binary and depending libraries into the
+ chroot directory:
+ $ ldd /usr/bin/php-cgi | sed -e \
+'s,.*=> /\(.*\) (0x.*,\1,' | while read lib; \
+do
+ LIBDIR="/chroot/YOUR_SITE/`dirname ${lib}`"; \
+ test ! -d $LIBDIR && mkdir -p $LIBDIR; \
+ cp -v /${lib} /chroot/YOUR_SITE/${lib}; \
+done
+
+- Copy a php.ini into the chroot directory and change the
+ doc_root configuration parameter.
+ $ cat /chroot/YOUR_SITE/etc/php.ini |
+ sed -e 's,^doc_root.*$,doc_root ="/var/www/",' > \
+ /chroot/YOUR_SITE/etc/php.ini
+
+- Create a apache VirtualHost:
+ <VirtualHost *>
+ ServerName YOUR_SITE.EXAMPLE
+ ServerAdmin [11]YOU at YOUR_SITE.EXAMPLE
+
+ DocumentRoot /chroot/YOUR_SITE/var/www/
+ <Directory /chroot/YOUR_SITE/var/www>
+ suPHP_Engine On
+ suPHP_Options /chroot/YOUR_SITE-suphp.conf
+
+ # chrooted view
+ suPHP_ConfigPath /etc/
+ </Directory>
+ </VirtualHost>
+
+- Create a suPHP configuration file.
+ Just pick the default file and set
+ chroot=/chroot/YOUR_SITE/
+
+WARNING there are some limitations with this patch:
+- First, I'm not the best C, C++ developer and this is my
+ first apache module work
+- The code is mostly quick and dirty hacked, because I
+ wanted to try if this would work.
+- Only the apache2 module was patched.
+
+I'd appreciate if you review this patch and post your
+comments on this.
+
+Greetings,
+Jan
+
+--- suphp-0.6.1/src/apache2/mod_suphp.c.orig 2006-05-24 04:31:35.000000000 +0200
++++ suphp-0.6.1/src/apache2/mod_suphp.c 2006-05-24 04:34:58.000000000 +0200
+@@ -114,6 +114,7 @@
+ char *target_user;
+ char *target_group;
+ #endif
++ char *suphp_options;
+ apr_table_t *handlers;
+ } suphp_conf;
+
+@@ -130,7 +131,9 @@
+ cfg->target_user = NULL;
+ cfg->target_group = NULL;
+ #endif
+-
++
++ cfg->suphp_options = NULL;
++
+ /* Create table with 0 initial elements */
+ /* This size may be increased for performance reasons */
+ cfg->handlers = apr_table_make(p, 0);
+@@ -175,6 +178,13 @@
+ else
+ merged->target_group = NULL;
+ #endif
++
++ if (child->suphp_options)
++ merged->suphp_options = apr_pstrdup(p, child->suphp_options);
++ else if (parent->suphp_options)
++ merged->suphp_options = apr_pstrdup(p, parent->suphp_options);
++ else
++ merged->suphp_options = NULL;
+
+ merged->handlers = apr_table_overlay(p, child->handlers, parent->handlers);
+
+@@ -265,6 +275,17 @@
+ return NULL;
+ }
+
++static const char *suphp_handle_cmd_options(cmd_parms *cmd, void *mconfig,
++ const char *arg)
++{
++ suphp_conf *cfg;
++ cfg = (suphp_conf *) mconfig;
++
++ cfg->suphp_options = apr_pstrdup(cmd->pool, arg);
++
++ return NULL;
++}
++
+
+ #ifdef SUPHP_USE_USERGROUP
+ static const char *suphp_handle_cmd_user_group(cmd_parms *cmd, void *mconfig,
+@@ -315,6 +336,7 @@
+ #endif
+ AP_INIT_ITERATE("suPHP_AddHandler", suphp_handle_cmd_add_handler, NULL, RSRC_CONF | ACCESS_CONF, "Tells mod_suphp to handle these MIME-types"),
+ AP_INIT_ITERATE("suPHP_RemoveHandler", suphp_handle_cmd_remove_handler, NULL, RSRC_CONF | ACCESS_CONF, "Tells mod_suphp not to handle these MIME-types"),
++ AP_INIT_TAKE1("suPHP_Options", suphp_handle_cmd_options, NULL, OR_OPTIONS, "The configuration file suPHP should use for this virtual host"),
+ {NULL}
+ };
+
+@@ -436,6 +458,11 @@
+ {
+ apr_table_setn(r->subprocess_env, "SUPHP_PHP_CONFIG", apr_pstrdup(p, dconf->php_config));
+ }
++
++ if (dconf->suphp_options)
++ {
++ apr_table_setn(r->subprocess_env, "SUPHP_OPTIONS", apr_pstrdup(p, dconf->suphp_options));
++ }
+
+ apr_table_setn(r->subprocess_env, "SUPHP_HANDLER", r->handler);
+
+--- suphp-0.6.1/src/Application.cpp.orig 2006-05-24 04:31:35.000000000 +0200
++++ suphp-0.6.1/src/Application.cpp 2006-05-24 04:34:13.000000000 +0200
+@@ -50,16 +50,23 @@
+ API& api = API_Helper::getSystemAPI();
+ Logger& logger = api.getSystemLogger();
+
+-#ifdef OPT_CONFIGFILE
+- File cfgFile = File(OPT_CONFIGFILE);
+-#else
+- File cfgFile = File("/etc/suphp.conf");
+-#endif
+
+ std::string interpreter;
+ TargetMode targetMode;
+ Environment newEnv;
+
++ File cfgFile = File("");
++
++ try {
++ cfgFile = File(env.getVar("SUPHP_OPTIONS").c_str());
++ } catch (KeyNotFoundException &e) {
++#ifdef OPT_CONFIGFILE
++ cfgFile = File(OPT_CONFIGFILE);
++#else
++ cfgFile = File("/etc/suphp.conf");
++#endif
++ }
++
+ // Begin try block - soft exception cannot really be handled before
+ // initialization
+ try {
+@@ -88,14 +95,23 @@
+ return 1;
+ }
+
+- this->checkScriptFile(scriptFilename, config, env);
+-
+ // Root privileges are needed for chroot()
+ // so do this before changing process permissions
+ if (config.getChrootPath().length() > 0) {
+ api.chroot(config.getChrootPath());
++
++ // after chroot() the SCRIPT_FILENAME path has changed
++ // and needs to get "translated"
++ std::string strChrootPath(config.getChrootPath());
++
++ // TODO: check if there is a "/" at the beginning of scriptFilename
++ scriptFilename.replace(scriptFilename.find(strChrootPath), strChrootPath.length(), "");
++ env.setVar("DOCUMENT_ROOT", "/");
++ env.setVar("SCRIPT_FILENAME", scriptFilename);
+ }
+
++ this->checkScriptFile(scriptFilename, config, env);
++
+ this->changeProcessPermissions(scriptFilename, config, env);
+
+ interpreter = this->getInterpreter(env, config);
+@@ -396,6 +412,8 @@
+ env.deleteVar("SUPHP_AUTH_PW");
+ if (env.hasVar("SUPHP_PHP_CONFIG"))
+ env.deleteVar("SUPHP_PHP_CONFIG");
++ if (env.hasVar("SUPHP_OPTIONS"))
++ env.deleteVar("SUPHP_OPTIONS");
+
+ // Reset PATH
+ env.putVar("PATH", config.getEnvPath());