Hardening the system without breaking ISPConfig

Discussion in 'Installation/Configuration' started by Norman, May 17, 2006.

  1. Norman

    Norman Member HowtoForge Supporter

    First of all, I'll list what I want to do and proceed with the issues I've encountered.

    Needs:
    - Prevent users from reading eachothers directories and subdirectories. <- Is this solvable without implementing ssh chroot?
    - Diskquotas reportable by "quota"

    Tests:
    chmod 711 /var/www/web* <- will prevent people from listing the initial subdirectories however it will not prevent people to pry into subdirectories with lax chmod like 755 etc.
    chmod 700 /var/www/web* <- will do some extra work but will prevent apache from displaying the sites.

    Setting either of these chmod's will break ispconfig's ability to see disk statistics for the users. Even if the sudo option for du is activated in ispconfig's configuration-file.

    Also if quota is activated on the system it doesnt seem to use diskquotas for the users? how so?
     
  2. till

    till Super Moderator Staff Member ISPConfig Developer

    If you configured du to be executed with root priveliges via sudo, the statistics are correct. You can test if your configuration is correct by running:

    su admispconfig
    sudo du -h --max-depth=1 /home/www/web1

    Have you enabled quotas for all partitions where userdata is stored?
     
  3. Dave Lane

    Dave Lane New Member

    Hardening ISPConfig

    Hi Till and Falko,

    We're very happy with ISPConfig, and would like to thank you guys for making it available to us! At this point, we are keen to "harden" our servers running ISPConfig and would like to do, as Norman suggests, a chmod 750 on /home/www/* to prevent other clients (and their users) from accessing any other client directory...

    As Norman points out, however, this breaks access for Apache (running as user www-data on our Ubuntu system). We notice that any new web?? group automatically includes the admispconfig user - how could we also automatically include the user www-data? We've grepped the ISPConfig code looking for hints, but haven't found the right place... Any suggestions would be greatly appreciated.

    Kind regards,

    Dave
     
  4. till

    till Super Moderator Staff Member ISPConfig Developer

    The admispconfig user is added to the group of the web in line 1101 in the file /root/ispconfig/scripts/config.lib.php
     
  5. Ovidiu

    Ovidiu Active Member

    anyone tried using bastille for hardening?
     
  6. Dave Lane

    Dave Lane New Member

    Bastille hardening

    Hi Tenaka,

    Yesterday we installed Bastille on our Ubuntu server (via APT) in addition to the Bastille firewall provided by ISPConfig. We configured it for everything but the firewall - but as yet, we haven't applied stricter permissions (via the umask) on the user directories yet as doing so would block the webserver from serving up user web accounts... Fixing that requires a minor hack on ISPConfig to ensure that the Apache user (in our case www-data) is included in each customer group. We're working on that.
    Cheers,

    Dave
     
  7. Dave Lane

    Dave Lane New Member

    Right - applied a minor hack to ISPConfig (version 2.2.2) see below for diff - to add the Webserver user (in our case on Ubuntu Dapper Linux it's "www-data") to each web?? customer's default group, and also to create new users in our web directory (in our case /home/www) with permissions 750 rather than the default 755 (which allows users of any customer to look into any other customer's web directories and read email, database passwords, etc. - NOT GOOD).

    To apply this fix retroactively, go into your web root directory and run the following (note - DON'T use the -R flag, as that will screw things up big time) - assuming you're using web? or web?? to designate your web customers:
    Code:
    chmod 750 web?? web?
    
    Following this, restart apache - on Ubuntu Dapper, it's
    Code:
     /etc/init.d/apache2 restart
    
    otherwise you might find that some sites fail to display (not sure why this happens, but a restart seems to fix it) with "permission denied" errors in the logs and "could not access .htaccess" or similar.

    At this stage, I'm not aware of any problems with this solution - seems to work well - but it might have implications on quota management or other ISPConfig maintenance task - not sure.

    Here's the diff for /root/ispconfig/scripts/lib/config.lib.php that makes it all happen.

    Code:
    Index: config.lib.php
    ===================================================================
    --- config.lib.php      (revision 2844)
    +++ config.lib.php      (working copy)
    @@ -1087,14 +1087,33 @@
       $mod->system->add_user_to_group("web".$doc_id);
       //////////////////// admispconfig der Gruppe hinzuf�gen ENDE //////////////
    
    +  // modified by [email protected] 20060919 to ensure that the web user can read into //
    +  // all web client directories, but web clients can't read other web client's directories
    +  // Adding Apache2 "www-data" user to each web group by default.
       $apache_user = $this->apache_user;
    +  $mod->system->add_user_to_group("web".$doc_id,$apache_user);
    +  // end [email protected] 20060919 modification //
    +
    +
    +  $apache_user = $this->apache_user;
       if($update == 0 || $dir_new){
         exec("chown -R $apache_user:web$doc_id $web_path_realname &> /dev/null");
         exec("chown -R $apache_user:web$doc_id $web_path &> /dev/null");
         exec("chmod -R 775 $web_path");
         exec("chmod -R 775 $web_path_realname");
    -    exec("chmod 755 $web_path");
    -    exec("chmod 755 $web_path_realname");
    +    // modified by [email protected] 20060919 to set up permissions: drwxr-x--- //
    +    // to keep users from accessing the directories of other web?? customers.
    +    // This does not lock out other users of the same web?? customer (who, by default,
    +    // belong to the web?? group.
    +    // users associated with the //
    +    // exec("chmod 755 $web_path");
    +    // exec("chmod 755 $web_path_realname");
    +    exec("chmod 750 $web_path");
    +    // note: not sure why we do this, as the "realname" appears to be a simple symbolic link to the
    +    // "web_path" directory, and in Linux filesystems, links simply inherit the permissions of the
    +    // thing they're linked to (at least on our system with ext3 filesystems)...
    +    exec("chmod 750 $web_path_realname");
    +    // end [email protected] 20060919 modification //
         exec("chmod 755 $web_path/user"); // user-Verzeichnis sollte nicht group-writable sein, weil Sendmail sonst warnings ausgeben k�nnte wg. der .forward-Datei
         exec("chmod 755 $web_path/log");
         exec("chmod 755 $web_path/ssl");
    
    Hope that's helpful to someone. Falko, Till, is there any reason that ISPConfig isn't already configured like this? Perhaps my solution is too simplistic? I would've thought that the default 755 permissions would be very loose for a production virtual hosting environment, no?

    Kind regards,

    Dave
     
  8. till

    till Super Moderator Staff Member ISPConfig Developer

    There was a reason in some older ISPConfig versions, at thi time the WebFTP was file based and not FTP based. But in the current versions I see no reasons why this wont work except of the problem with backwards compatibility.
     
  9. meemu

    meemu New Member

    admispconfig

    thanks for this Dave.

    One thing that might be of interest is that at least here /home/admispconfig is (was) world readable.
     
  10. till

    till Super Moderator Staff Member ISPConfig Developer

    There is nothing hidden in this directory that you can not see if you download the ISPConfig sources from sourceforge or svn. There is just one file that contains the login information for the database and this can be only read by the admispconfig user.
     
  11. meemu

    meemu New Member

    Thanks Till. I hadn't checked the file's permissions. It's true.

    Can I bother you with one more problem? I promise I'll write a howto for debian etch with fastcgi in the next couple of days.

    I have a web application with a shared code base. It is used via Alias and shtml includes. The solution I came up with is is to add the sharing respective ispconfig user to the shared application's user group.
    The weird thing is that ispconfig keeps overwriting my group file. In there I have:

    sharedwebappgroup:x:9001:sharedwebappuser,www-data,web1_user

    On changes in the ispconfig web interface it removes the web1_user

    I thought it might use some sort of minimum gid but doesn't look like.

    Is there a way of "protecting" this from overwrites by ispconfig?


    Thanks in advance and for all your help
     
  12. falko

    falko Super Moderator Howtoforge Staff

    Are you talking about the /etc/group file? You'd have to modify the ISPConfig sources to change that behaviour.
     
  13. meemu

    meemu New Member

    Yes that's what I had in mind. Any starting points?
     
  14. falko

    falko Super Moderator Howtoforge Staff

    The interesting functions are in /root/ispconfig/scripts/lib/classes/ispconfig_system.lib.php.
     
  15. meemu

    meemu New Member

    Does not look like an easy hack to me. I am not sure I understand what is happening here. In general, does it parse the whole group file, the parse it line by line and write it back? Or does it skip something under certain circumstances?
    After a quick glance I have the feeling it parses it line by line, looks for any entries containing ispconfig groups/users and does an integrity check on those. Is that how it works?
    What approach would you recommend for what I'm trying to do?
    Something like a minimum gid and below that it won't touch the entry?

    Thanks for all your help. I promise I'll convert the walkthrough into a howto as soon as I have gone live with this machine.
     
  16. meemu

    meemu New Member

    What I've found is this:

    Code:
        foreach($group_file_lines as $group_file_line){
          if(trim($group_file_line) != ""){
            list($f1, $f2, $f3, $f4) = explode(":", $group_file_line);
            $group_users = explode(",", str_replace(" ", "", $f4));
            if(in_array($user_username, $group_users)){
              $g_users = array();
              foreach($group_users as $group_user){
                if($group_user != $user_username) $g_users[] = $group_user;
              }
              $f4 = implode(",", $g_users);
            }
            $new_group_file[] = $f1.":".$f2.":".$f3.":".$f4;
          }
        }
    
    As far as I understand, this means the update script runs for each ispconf user. Checks each line of group and amends it according to what is in the ispconfig db (isp_isp_user, isp_dep tables).

    I'd like to think something like this could solve my problem:


    Code:
    ...
    define (GID_MIN_PROTECTED,9000);
    define (GID_MAX_PROTECTED,9999);
    ...
        foreach($group_file_lines as $group_file_line){
          if(trim($group_file_line) != ""){
            list($f1, $f2, $f3, $f4) = explode(":", $group_file_line);
            $group_users = explode(",", str_replace(" ", "", $f4));
            if(  ($f3 >= GID_MIN_PROTECTED) && ($f3 <= GID_MAX_PROTECTED) ) { 
              $new_group_file[] = $f1.":".$f2.":".$f3.":".$f4;
              continue;
            }
            if(in_array($user_username, $group_users)){
              $g_users = array();
              foreach($group_users as $group_user){
                if($group_user != $user_username) $g_users[] = $group_user;
              }
              $f4 = implode(",", $g_users);
            }
            $new_group_file[] = $f1.":".$f2.":".$f3.":".$f4;
          }
        }
    
    Would this break something?


    Thanks
     
  17. meemu

    meemu New Member

    turning this into my blog...

    actually I think this might be more elegant:
    Code:
            if($f3 < $this->server_conf["groupid_von"]) {
              $new_group_file[] = $f1.":".$f2.":".$f3.":".$f4;
              continue;
            }
    
    This way the admispconfig user could be broken. But it doesn't need to get changed after the install install.
     
  18. meemu

    meemu New Member

    No success

    I have tried this but it doesn't work oddly enough. The update still removes the user, though it does not seem to be happening at this point.

    Any other pointers?
     
  19. meemu

    meemu New Member

    resolved

    Finally figured it out. This patch protects groups with a gid lower than what is configured in the ispconfig server config as "gid_von" from being changed on updates.

    /root/ispconfig/scripts/lib/classes/ispconfig_system.lib.php

    Code:
    172a173,177
    >         // hack to prevent ispconfig from overwriting other groups that contain that user
    >         if( intval($f3) < intval($this->server_conf["groupid_von"])) {
    >         $new_group_file[] = $f1.":".$f2.":".$f3.":".$f4;
    >         continue;
    >       }
    174c179
    <         if(in_array($user_username, $group_users)){
    ---
    >               if(in_array($user_username, $group_users)){
    176c181
    <           foreach($group_users as $group_user){
    ---
    >                 foreach($group_users as $group_user){
    178c183
    <           }
    ---
    >                 }
    545a551,555
    >       // hack to prevent ispconfig from overwriting other groups that contain that user
    >       if(intval($f3) < intval($this->server_conf["groupid_von"])) {
    >         $new_group_file[] = $f1.":".$f2.":".$f3.":".$f4;
    >         continue;
    >       }
    976c986
    < ?>
    \ No newline at end of file
    ---
    > ?>
    
     
  20. till

    till Super Moderator Staff Member ISPConfig Developer

    Thanks for the patch. I added it to the bugtracker for integration in ISPConfig.
     

Share This Page