CASifying ZPanel X

ZPanel is a free and complete web hosting control panel for Microsoft® Windows™ and POSIX (Linux, UNIX and MacOSX) based servers. ZPanel is written in PHP and uses several open-source (or freely available) software packages to provide a secure, web hosting system.

This pages outlines 2 ways to CASify ZPanel:

phpCAS

1. Firstly (I assume you already have both a ZPanel and a CAS server up and running), you need to put phpCAS client in a place suitable for ZPanel to find it. In my case, I choose a new "cas" folder in "modules".

2. Create a config file to store the following values: CAS host, CAS port and CAS context. In my setup, I have CAS running on https://my.cas.server:9443/cas, so I put in my config.inc:

<?php
$cas_host = 'my.cas.server';
$cas_port = 9443;
$cas_context = '/cas';
?>


Next, some little changes in file dryden/ctrl/auth.class.php, as follows:

3. Insert phpCAS authentication in ctrl_auth::RequireUser()

static function RequireUser() {
// Begin: added for CAS
require_once('./modules/cas/CAS-1.3.2/CAS.php');
require_once('./modules/cas/config.inc'); // This is the same "config.inc" I created in step 2.
phpCAS::client(CAS_VERSION_2_0, $cas_host, $cas_port, $cas_context);
phpCAS::setNoCasServerValidation(); // For testing with self-signed certs.
phpCAS::forceAuthentication();
$username = phpCAS::getUser();
self::Authenticate($username, $_COOKIE['zPass'], false, true);
// End: added for CAS
global $zdbh;
if (!isset($_SESSION['zpuid'])) {
 if (isset($_COOKIE['zUser'])) {


4. As the user is already identified, you don't want ZPanel asking for password, but you can retrieve from the ZPanel users' database. So change ctrl_auth::Authenticate() so that reads:

$sqlString = "SELECT * FROM
 x_accounts WHERE
ac_user_vc = :username AND
ac_enabled_in = 1 AND
ac_deleted_ts IS NULL";

$bindArray = array(':username' => $username);


5. Also in ctrl_auth::Authenticate(), get the ZPanel password for setting zPass cookie (this is for having the ZPanel feature "Remember me" working. I think this is actually not needed, as we're never authenticating with ZPanel password)

if ($row) {
     //Disabled till zpanel 10.0.3
//runtime_sessionsecurity::sessionRegen();
$password = $row['ac_pass_vc'];
ctrl_auth::SetUserSession($row['ac_id_pk']);


And you're done.

 

mod_auth_cas (for Apache)

Very similar to process above but ended up being less invasive in our environment. Also, in ZPanel 10.1.1, it appears that ctrl_auth::RequireUser() requires an additional parameter. Code for phpCAS needs minor modification but I've not tested the change.

 

Ensure you have at least 1 CAS user configured in ZPanel as an admin prior to proceeding. You will be locked out if the username in ZPanel does not match the username CAS returns after successful auth.

 

  1. Install and configure both ZPanel and mod_auth_cas for Apache
    1. README for mod_auth_cas is very useful
    2. At a high level, you need to:
      1. Build mod_auth_cas on your ZPanel server
      2. Configure your ZPanel server's Apache instance to use mod_auth_cas
  2.  Make sure mod_auth_cas is configured to protect the ZPanel directory (%zpanel-root%/panel - typically /etc/zpanel/panel)
      1. Use .htaccess or the main Apache configuration



    CAS Authentication Sample
    AuthType CAS
    require user someuser
  3.  Edit ZPanel's auth.class.php as follows: (%zpanel-root%/panel/dryden/ctrl/auth.class.php - typically /etc/zpanel/panel/dryden/ctrl/auth.class.php)
    1. Make ZPanel use REMOTE_USER (set by CAS) for authentication
      1. Add self::Authenticate line to beginning of RequireUser() as follows

        auth.class.php -> static function RequireUser()
        static function RequireUser()
            {
                //Modifications for CAS login
                self::Authenticate($_SERVER['REMOTE_USER'], $_COOKIE['zPass'], false, true, false);
                //End modifications for CAS login
         
                global $zdbh;
                if (!isset($_SESSION['zpuid'])) {
                    if (isset($_COOKIE['zUser'])) {
                        if (isset($_COOKIE['zSec'])) {
      2. Remove password line from SQL and change array near beginning of Authenticate() as follows:

        auth.class.php -> static function Authenticate
        static function Authenticate($username, $password, $rememberme = false, $iscookie = false, $sessionSecuirty)
            {
                global $zdbh;
                $sqlString = "SELECT * FROM
                              x_accounts WHERE
                              ac_user_vc = :username AND
                              ac_enabled_in = 1 AND
                              ac_deleted_ts IS NULL";
         
                $bindArray = array(':username' => $username);

       

    2. That should be all

      1. Navigate to your ZPanel URL and you should receive a CAS login screen

      2. Login via CAS and you will see your ZPanel account