Access control to Zend Server Z-Ray using PHP prepend

Zend Server 7 contains a wonderful tool called Z-Ray, which allows you to inspect code execution from within a toolbar in your browser. It is a must have for any serious PHP developer. This guide explains you how to use the PHP configuration option auto_prepend_file to determine who gets to see Z-Ray and who does not.

Zend Server Z-Ray Access Control

The Zend Server backend comes with a control panel for Z-Ray, which allows you to disable and enable Z-Ray. This control panel also offers a Secured Mode, where you can limit access based on IP-addresses, URLs or access token. Unfortunately, this feature is disabled in the cheaper Zend Server Developer Edition. Either you need to purchase a Zend Server edition that allows you to enable this feature, or you need to apply the trick of this guide.

Prepending a PHP file

Just like Z-Ray itself is appended to each page, you can also prepend a custom PHP script. Using the auto_prepend_file option in your PHP configuration (php.ini or something similar), you can execute a PHP script php_prepend.php at every request:

auto_prepend_file = /var/www/html/php_prepend.php

This PHP file can be completely customized to allow for access control to Z-Ray. The main trick is that Z-Ray has to be enabled in the Zend Server backend, but allows for disabling at run time through the following PHP function:

zray_disable();

Access control by IP

Let's play with this a bit: Make sure that Z-Ray is enabled in the Zend Server backend. Now open up the php_prepend.php file and add the following:

<?php
$allowedIps = array('127.0.0.1');
$zray_disable = true;
if (isset($_SERVER['REMOTE_ADDR']) && in_array($_SERVER['REMOTE_ADDR'])) {
    $zray_disable = false;
}

The flag $zray_disable will be used to disable Z-Ray by default, unless we are changing that flag to false when we are accessing the webserver from a development IP (127.0.0.1). To actually disable Z-Ray, so when the flag is still true, the following code is used:

if ($zray_disable == true) {
    if (function_exists('zray_disable')) {
        zray_disable();
    }
}

Make sure to check whether the zray_disable() function exists, otherwise your sites will broken if the Z-Ray module is disabled or removed for some reason.

Access control by security token

Once you get the hang of this, you will understand that you can do whatever you want with this PHP file to allow for even better access control. The following is a sample

$allowedTokens = array('1234', '5678');
if (isset($_GET['zray']) && in_array($_GET['zray'], $allowedTokens)) {
    $zray_disable = false;
}

Now, when a site, that is running on this Z-Ray enabled webserver - is accessed with one of the matching security tokens set in the URL, again Z-Ray is enabled:

http://example.com/index.php?zray=1234

More inspiration and some considerations

Whatever you can come up with for access conditions, can be added to the prepend file. For instance, you might consider allowing access at certain times:

$startHour = 8;
$endHour = 17;
if (date('H') >= $startHour && date('H') <= $endHour) {
    $zray_disable = true;
}

And of course, any combination of these rules might be applied as well: A certain development IP is only allowed access to Z-Ray by using a specific access token at a specific time set. If a $_GET token is needed for proper access, it might also be an idea to set a cookie zray that can be used then throughout the entire cookie lifetime.

Make sure the rules you come up with are performing well. For instance, if you're travelling, you might be tempted a dynamic DNS hostname, so that access from your flexible location is always allowed. For this to work, you would use gethostbyname() to check for the right hostname. This again means a DNS lookup is made for every PHP request handled by this webserver. If DNS is slow (and with dynamic DNS, this is more likely), this might slow down the webserver as a whole. In short: Make your access rules lightning fast.