Admin Portal Installation Guide

© 2022 MonkeyProof Solutions BV

info@monkeyproofsolutions.nl

www.monkeyproofsolutions.nl

T: +31 (0)76 8200 314

Table of contents

Admin Portal Installation Guide

Table of contents


NGINX configuration

Apache .htaccess

Introduction

The Portal Server v0.2.0 is an application written in PHP 8.

The Portal Server has the following main tasks:

  1. Web based Admin Portal for:
    • Configuring deployed applications
    • Managing application access
    • Managing available front-end versions
    • Providing log access
  2. Web based User Portal for:
    • Listing the authorized applications and relevant information
  3. Deliver "static" content (the generic frontend application versions) to the client browser
  4. Manage user sessions including:
    • Authentication/authorization
    • Mapping of application instances to the appropriate back-end endpoints
    • Data flow

Configurations are stored in a json file and, if applicable, configuration/application specific data in additional supporting files.

No SQL database is required.

System Requirements

This paragraph provides some guidance in server hard- and software requirements.

The server does not need to be a high performance computing server, the back-end server(s) do the hard computational work.

Depending on the type of deployed applications, the dataflow can be significant and needs to be managed in-memory.

The duration of computations and the number of simultaneous users need to be accomodated. If there are many users doing many long-running computations, the server resources (memory) and number of simultaneous PHP processes need to be scaled up accordingly.

Server Hardware Requirements

Server type

The server can be a metal, virtualized. containerized or even "serverless" web- or app-server, that supports PHP 8.

CPU and Memory

As for any web application, you should size your server based on the traffic on the site.

Typically analytics applications deployed through the Portal Server are quite data intensive. During interaction with the server all data, including file up- and downloads, lives in memory in the Portal Server.

It is recommended to assign 512MB per simultaneous active server request. If applications do not do significant file up- and download this can be reduced.

Disk

The Portal Server application code is less than 50MB.

The main driving factors behind required additional disk space are:

  1. The amount of front-end versions to be supported (current production versions < 10M each).
  2. Logging enabled in combination with traffic through the server.

Logging directory can be configured outside the installation directory (recommended).

Particularly when traffic logging (intended for debugging purposes only) is enabled for an application log files can grow rapidly. File up- and download data is never being logged to save space.

Apart from disk space for logging it is recommended to allocate at least 1GB of diskspace for the application itself.

Server Software Requirements

Operating System

The Portal Server runs on Windows, and Linux (and most likely on other plaforms supporting webserver and PHP 8 technology).

Web Server

The Portal Server has been developed and tested with NGINX and Apache. Most likely it will work with any recent web server software with PHP 8 support.

PHP

The web server must support PHP 8. It can be installed as CGI or any other integration technology.

PHP extensions

The development and testing of the Portal Server has been done by means of a standard binairy PHP build including the standard range of extensions.

Next to those extensions the below are required to be enabled in the php.ini file of your server.

Mandatory extensions:

ExtensionComment
curlrequired for communication between the Portal Server and the MATLAB/Python backend servers
fileinfogeneral purpose
ldaprequired for LDAP or Active Directory authentication
opensslrequired for HTTPS communication between Portal Server and MATLAB/Python backend servers
zlibrequired to enable output compression

Please refer to the Installation paragraph where the check.php script is dicussed for highlighting permissions and lsting of values of som key settings. The location of the php.ini file used is also listed in the check.php results.

PHP.INI settings

PHP SettingSuggested ValueComment
max_execution_time300Excludes the time required for the curl call to the backend. Curl timeout is configured per application.
max_input_time300-
memory_limit512MThis limit should be sufficiently large (e.g. 4x the maximum expected payload incl. file uploads).
post_max_size256MThis limit should be sufficiently large (e.g. 2x the maximum expected payload incl. file uploads).

Please refer to the PHP documentation for more information.

Note that your webserver settings may be more restrictive than the PHP settings listed here.

Client Requirements

The Portal Server should run on all recent browsers in the market, including but not limited to:

  • Chrome
  • Firefox
  • Edge
  • Safari

Development and testing is primarily being done with Chrome and Firefox (in that order).

Pre-installation

These tasks cover the download and deployment of the Portal Server, and should be performed prior to any new installation or upgrade.

  1. Download Portal Server per instructions received per email.

  2. Transfer the downloaded file to your webserver.

  3. Extract the release. The extraction process should create a new directory like webserver-v0.2.x, in the remainder of this document this will be referred to as the <INSTALL_ROOT>.

  4. The <INSTALL_ROOT>/public directory is the root of the web application. The other directories at this level only need to be accessed by PHP itself and should not be directly served by the webserver.

  5. All routes that do not refer to an existing file or directory in or under the <INSTALL_ROOT>/public/ directory need to be routed through <INSTALL_ROOT>/public/index.php. A sample nginx configuration and a sample (apache) .htaccess file are included as appendices. These are starting points, the same routing result can be achieved in different ways.

  6. Documentation can be found under <INSTALL_ROOT>/public/doc. Index index.php needs to be served at this top level. It is advisable to serve index.html for sub directories. This can be accomplished in your webserver configuration or by means of .htaccess file(s).

New Installation

This chapter explains how to perform a new installation of Portal Server.

Start by checking “System Requirements” and the "Pre-Installation tasks".

When the webserver with PHP 8 is up and running with <INSTALL_ROOT>/public as root, move or copy the <INSTALL_ROOT>/check.php file to <INSTALL_ROOT>/public/check.php.

From your web browser, access https://yoursite/check.php and inspect the results and see if to see if there are obvious missing requirements.

When done either delete or move the script file back to <INSTALL_ROOT>/check.php to prevent direct access or execution by unauthorized users.

Configuration

Next step is to configure the Portal Server by creating the <INSTALL_ROOT>/config/config.php.

Copy <INSTALL_ROOT>/config/config.php.sample to <INSTALL_ROOT>/config/config.php and open it in your favorite editor.

Main Portal Settings

The $portal['title'] (string), $portal['subtitle'] (string) and $portal['logo'] (string: system path to file) are used in the header of the user- and admin-portals as well as in the login box.

The $portal['debug'] (boolean) setting indicates if additional debugging info may be shown. The $portal['debug_error_reporting'] and $portal['debug_ini_set_display_errors'] settings refer to values per standard PHP debugging levels.

Please refer to PHP documentation https://www.php.net/manual/en/function.error-reporting.php and https://www.php.net/manual/en/errorfunc.configuration.php#ini.display-errors for more details.

Enabling debugging can provide additional information to track down issues but is recomended to disable for regular use. Due to unpredictable behaviour it may break functionality of the portal. Inspecting error logs is a better starting point to identify issues.

The $portal['https'] setting allows for telling PHP that the portal is served over https. By default it is attempted to detect if the application is served over https but PHP cannot always correctly determine this due to webservers not setting values per the standard. This setting will make it explicit.

// BEGIN PORTAL
$portal['title']                          = '';
$portal['subtitle']                       = '';
$portal['logo']                           = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'monkeyproof.png';

$portal['debug']                          = false;
$portal['debug_error_reporting']          = 'E_ERROR';
$portal['debug_ini_set_display_errors']   = '1';

//true if serving over https, false if not, null to ignore this setting. 
//(This is an "override" if $_SERVER['HTTPS'] is not available on server or contains a value if not serving over https).
$portal['https']                          = null; 
// END PORTAL

Logging

The $logging['dir'] (string) contains the path to the top level logging directory. The default value included writes logs into the installation directory is not preferred for production environments. You can set any location with write permission for the php/webserver user here.

The $logging['log_rotate_enabled'] (boolean) setting enables or disables log rotation. When enabled log files are rotated on a daily basis (when there is activity). The $logging['log_rotate_keep'][*] (number) settings allow for setting the number of logs to keep for each log type. To keep rotated logs forever set to 0. Note that traffic logs are intended for debugging issues and can grow rapidly.

// BEGIN LOGGING
$logging['dir']                           = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR;
// enable daily log rotate
$logging['log_rotate_enabled']            = true;
//number of rotated log files to keep (i.e. the last x days of activity on the portal)
//0 means all are kept
$logging['log_rotate_keep']['access']     = 0; 
$logging['log_rotate_keep']['error']      = 30; 
$logging['log_rotate_keep']['traffic']    = 5; 
// END LOGGING

Authorization

The setting $auth['disabled'] (boolean) allows for disabling authentication. When disabled the User Portal https://yoursite/ and the Admin Portal https://yoursite/admin_portal/ are accessible without user authentication.

It is a good idea to test the installation with authentication disabled. Once the Portal Server is displaying its content as expected, start configuring the LDAP authentication/authorization.

When authentication is enabled, $auth['user_password'] (boolean) must be set to true, and $auth['type'] (string) must be set to 'ldap'. The $auth['debug'] (boolean) should be set to false in production but setting it to true may help during configuration. Also inspect the access and error logs when running into issues during configuration.

// BEGIN AUTH
$auth['disabled']                         = false;
$auth['user_password']                    = true;
$auth['type']                             = 'ldap';
$auth['debug']                            = false;
// END AUTH

LDAP

The Portal Server can be configured to authenticate against Microsoft Active Directory (Azure AD is something different although it may work with the appropriate Azure AD plugin). LDAP integration is enabled by setting the $auth['type'] (boolean) to true.

The $ldapconfig['start_tls'] setting enables TLS for secure communication with the LDAP server.

The connection with the LDAP server is set up using the standard PHP LDAP plugin and can further be configured in $ldapconfig['ldap_options'] (array) by means of an array of the LDAP_OPT_* settings. More information can be found here https://www.php.net/manual/en/ldap.constants.php. Noteworthy is the 'LDAP_OPT_X_TLS_CACERTFILE' option which contains the path to the Certificate Authority Certificat file such that the certificate of the LDAP server can ve validated.

The $ldapconfig['host'] (string) and $ldapconfig['port'] (string) setting indicate on which address and port the LDAP server can be contacted.

The $ldapconfig['domain'] (string) is your microsoft domain name. The $ldapconfig['basedn'] (string) is the top level from where searches are being doen in the LDAP server.

The $ldapconfig['usersdn'] (string) is the distinguished name where searches will be exected for users (note that we reuse/concatenate the $ldapconfig['usersdn'] setting). The $ldapconfig['user_name_attribute'] (string) is the user attribute containing the name used for authentication (for MS AD this is 'sAMAccountName'). The $ldapconfig['user_photo_attribute'] (string) and $ldapconfig['user_displayname_attribute'] (string) contain the attributes containing the user display name and photo respectively.

The $ldapconfig['groupsdn'] (string) is the distinguished name where searches for security groups will be executed. The $ldapconfig['gropup_name_attribute'] (string) is the attribute being searched for to identify user membership (for MS AD this is 'sAMAccountName').

The LDAP integration oly uses user credentials for authentication. All other communication for e.g. retrieval of user details and querying group membership happens with a read-only LDAP user with username $ldapconfig['readonly_user'] (string) and password $ldapconfig['readonly_pw'] (string).

Access to the user portal requires membership of any of the groups listed in $ldapconfig['portal_user_groups'] (array of strings). Use empty array [] to not require portal user group membership (authentication is then still required). Access to the Admin Portal requires membership of any of the groups listed in $ldapconfig['admin_groups'] (array of strings).

// BEGIN LDAP
$ldapconfig['start_tls']                  = true;

// LDAP Options - see: https://www.php.net/manual/en/ldap.constants.php
$ldapconfig['ldap_options']               = array(
    'LDAP_OPT_X_TLS_CACERTFILE'           => 'path_to_cacert.crt',
    // 'LDAP_OPT_X_TLS_CACERTDIR'            => '',
    // 'LDAP_OPT_X_TLS_CERTFILE'             => '',
    // 'LDAP_OPT_X_TLS_KEYFILE'              => '',
    'LDAP_OPT_X_TLS_REQUIRE_CERT'         => 'LDAP_OPT_X_TLS_DEMAND',
    'LDAP_OPT_PROTOCOL_VERSION'           => 3,
    'LDAP_OPT_REFERRALS'                  => 0,
    'LDAP_OPT_NETWORK_TIMEOUT'            => 10,
);

$ldapconfig['host']                       = 'your.ldap.server';
$ldapconfig['port']                       = '389';

$ldapconfig['domain']                     = 'your_domain';
$ldapconfig['basedn']                     = 'dc=your,dc=domain';

$ldapconfig['usersdn']                    = 'cn=Users,' . $ldapconfig['basedn'];
$ldapconfig['user_name_attribute']        = 'sAMAccountName';
$ldapconfig['user_photo_attribute']       = 'thumbnailphoto';
$ldapconfig['user_displayname_attribute'] = 'displayname';

$ldapconfig['groupsdn']                   = 'cn=Groups,' . $ldapconfig['basedn'];
$ldapconfig['group_name_attribute']       = 'sAMAccountName';

// saMAccountName and password of (read-only) LDAP query user
$ldapconfig['readonly_user']              = '';
$ldapconfig['readonly_pw']                = '';	

$ldapconfig['portal_user_groups']         = ['your_portal_users_group']; // Must be an array. Use empty array [] to not require portal user group membership.
$ldapconfig['admin_groups']               = ['your_admin_group'];        // Must be an array
// END LDAP

Landing pages

When the Portal Server has been configured appropriately, the following pages are available:

PageComment
https://yoursite/The user portal listing available applications.
https://yoursite/admin_portal/The admin portal for cinfiguring applications.
https://yoursite/check.phpWARNING: This file should be removed or renamed after installation.

Upgrading

For this release there is no automated upgrade path from prior versions.

This version of the Portal Server is the first release allowing configuration of applications through a web interface (versus the error-prone, manual editing of json files on the server) as well as communication with a broader variety of backend servers.

Applications will need to be redeployed by means of the Admin Portal which should be a straightforward task based on working configuration(s) from prior versions.

NGINX configuration

The below is a sample nginx.conf configuration from a working NGIX installation with fastcgi PHP support.

It is intended as inspiration/starting point for your configuration - as-is and by no means as a final, complete configuration.

#user  nobody;
worker_processes  4;

error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  2700;

    #gzip  on;
	gzip on;
	gzip_vary on;
	gzip_min_length 1024;
	gzip_proxied expired no-cache no-store private auth;
	gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml application/json;
	gzip_disable "MSIE [1-6]\.";

	fastcgi_connect_timeout 2700s;
	fastcgi_keep_conn off;
	fastcgi_read_timeout 2700s;
	fastcgi_send_timeout 2700s;

	client_max_body_size 256m;

	server {
		   listen         80;
		   server_name    <YOUR_SERVER_FQDN>;
		   return         301 https://$server_name$request_uri;
	}

    # HTTPS server
    #
    server {
        listen       443 ssl;
        server_name  localhost;

        ssl_certificate      <SYSTEM_PATH_TO_THE_SERVER_CERTIFICATED DIRECTORY>/your_server-cert.crt;
        ssl_certificate_key  <SYSTEM_PATH_TO_THE_SERVER_CERTIFICATED DIRECTORY>/your_server-private-key.pem;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        root   <SYSTEM_PATH_TO_THE_SERVER_INSTALL>/public;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

		location / {
			index  index.html index.php;
			try_files $uri $uri/ /index.php;
		}

		location ~ \.php$ {
			if ($request_uri ~* "^(.*/)index\.php$") {
				return 301 $1;
			}
			
			try_files $uri =404;
			fastcgi_pass   127.0.0.1:9124;
			include        fastcgi_params;
			fastcgi_index  index.php;
			fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
		}
		
		#error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        location ~ /\.ht {
            deny  all;
        }
    }

}

Apache .htaccess

The below is a sample <INSTALL_ROOT>/public/.htaccess file from a working Apache (with PHP) installation.

This file is also included in the Portal Server package in this location.

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>