Apache HTTPD Web Server Configuration for HealthShare
Tags: soap, suse, linux, healthshare
Published: 2020-10-13 19:20:23

There are often questions surrounding the ideal Apache HTTPD Web Server configuration for HealthShare.  The contents of this article will outline the initial recommended web server configuration for any HealthShare product. 

As a starting point, Apache HTTPD version 2.4.x (64-bit) is recommended.  Earlier versions such as 2.2.x are available, however version 2.2 is not recommended for performance and scalability of HealthShare.

<!--break-->

## **Apache Configuration**

### Apache API Module without NSD 

HealthShare requires the installation option Apache API Module without NSD. The version of the dynamically linked modules depends on the Apache version:

  * CSPa24.so (Apache Version 2.4.x)

The configuration of Caché Server Pages in the Apache httpd.conf is best left to be performed by the HealthShare installation that is detailed further on in this document. However the configuration can be performed manually. For more information please see Apache Configuration Guide in the InterSystems documentation:  <a href="http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GCGI_ux#GCGI_ux_api" rel="nofollow">Recommended Option: Apache API Module without NSD (CSPa24.so)</a>

## **Apache Multi-Processing Module (MPM) Recommendations** 

### Apache Prefork MPM Vs. Worker MPM 

Apache HTTPD web server comes with three Multi-Processing Modules (MPM) - Prefork, Worker, and Event.  The MPMs are responsible for binding to network ports on the machine, accepting requests, and dispatching children to handle the requests. By default, Apache is usually configured with Prefork MPM which does not scale well for high transaction or high concurrent user workloads.

For HealthShare production systems, the Apache MPM **_Worker_** should be enabled for performance and scalability reasons. Worker MPM is preferred because of the following:

  * Prefork MPM uses multiple child processes with one thread each and each process handles one connection at a time. When using Prefork, concurrent requests suffer because as each process can only deal with a single request at a time the requests are queued until a server process becomes free. Additionally in order to scale, more Prefork child processes are required which consumes significant amounts of memory.
  * Worker MPM uses multiple child processes with many threads each. Each thread handles one connection at a time, which is big help for concurrency and reduces memory requirements. Worker handles concurrency better than Prefork because there will usually be free threads available to serve the requests instead of single threaded Prefork processes which may be busy.

### Apache Worker MPM Parameters 

By using threads to serve requests, Worker is able to serve a large number of requests with fewer system resources than the Prefork process-based server.   
The most important directives used to control Worker MPM are **ThreadsPerChild** which controls the number of threads deployed by each child process and **MaxRequestWorkers** which controls the maximum total number of threads that may be launched.  
The recommended Worker MPM common directive values are detailed in the table below:

<table>
  <caption>Recommended Apache HTTPD Web Server Parameters</caption> <tr>
    <th>
      Apache Worker MPM Directives
    </th>
    
    <th>
      Recommended Value
    </th>
    
    <th>
      Comments
    </th>
  </tr>
  
  <tr>
    <td>
      MaxRequestWorkers 
    </td>
    
    <td>
      Maximum # of HealthShare Clinical Viewer concurrent users, or the for other HealthShare components set to sum of all inbound Business Service pool sizes for all defined interface productions. * Note: If all unknown at time of configuration start with a value of '1000'
    </td>
    
    <td>
        MaxRequestWorkers sets the limit on the number of simultaneously requests that will be served, i.e. restricts the total number of threads that will be available to serve clients. MaxRequestWorkers is important to be set correctly because if it is set too low then resources go to waste and if too high then server performance will be impacted. Note that when more connections are attempted than there are workers, the connections are placed into a queue. The default queue can be adjusted with the ListenBackLog directive.  
    </td>
  </tr>
  
  <tr>
    <td>
      MaxSpareThreads
    </td>
    
    <td>
      250
    </td>
    
    <td>
        MaxSpareThreads deals with idle threads on a server-wide basis. If there are too many idle threads in the server then child processes are killed until the number of idle threads is less than this number. Increasing the amount of spare threads higher than default is to reduce the chance of re-spawning of processes.  
    </td>
  </tr>
  
  <tr>
    <td>
      MinSpareThreads
    </td>
    
    <td>
      75
    </td>
    
    <td>
        MinSpareThreads deals with idle threads on a server-wide basis. If there is not enough idle threads in the server then child processes are created until the number of idle threads is greater than this number. Reducing the amount of spare threads lower than the default reduces the chance of re-spawning of processes.  
    </td>
  </tr>
  
  <tr>
    <td>
      ServerLimit
    </td>
    
    <td>
      MaxRequestWorkers divided by ThreadsPerChild
    </td>
    
    <td>
        Maximum value for MaxRequestWorkers for the lifetime of the server. ServerLimit is a hard limit on the number of active child processes, and must be greater than or equal to the MaxRequestWorkers directive divided by the ThreadsPerChild directive. With worker use this directive only if your MaxRequestWorkers and ThreadsPerChild settings require more than 16 server processes (default).  
    </td>
  </tr>
  
  <tr>
    <td>
      StartServers
    </td>
    
    <td>
      20
    </td>
    
    <td>
        The StartServers directive sets the number of child server processes created on startup. As the number of processes is dynamically controlled depending on the load, there is usually little reason to adjust this parameter except to ensure the server is ready to handle a lot of connections right when it's started.  
    </td>
  </tr>
  
  <tr>
    <td>
      ThreadsPerChild
    </td>
    
    <td>
      25
    </td>
    
    <td>
        This directive sets the number of threads created by each child process, 25 by default. Keeping the default value is recommended because increasing it could lead to over-dependency with a single process.  
    </td>
  </tr>
</table>

For more information please see the relevant Apache version documentation:

  * [Apache 2.4 MPM Common Directives](http://httpd.apache.org/docs/2.4/mod/mpm_common.html)

### Example Apache 2.4 Worker MPM Configuration 

This section details how to configure Worker MPM for a RHEL7 Apache 2.4 web server required to support up to 500 TrakCare concurrent users.

  1. First check the MPM using the following command:![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0vbpy21bgw8zj78u1tf1.png)
  2. Edit the configuration file /etc/httpd/conf.modules.d/00-mpm.conf as required, by adding and removing the comment character # so that only the Worker MPM modules is loaded. Modify the Worker MPM section with the following values in the same order as below:![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/hb1eryhphwrhnvsgt8zx.png)
  3. Restart Apache
  4. After successfully restarting Apache, validate the worker processes by executing the below commands. You should see something similar to the following confirming the httpd.worker process:![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/c2ds871q52tye30zf5qi.png)
## **Apache Hardening** 

### Apache Required Modules 

The installation of the official Apache distributed package will enable a specific set of Apache modules by default. This default configuration of Apache will load these modules into each httpd process. It is recommended to disable all modules that are not required for HealthShare for the following reasons:

  * reduce the httpd daemon process footprint.
  * reduce the chance of a segmentation fault from a rogue module.
  * reduce security vulnerabilities.

The table below details the Apache modules recommended for HealthShare. Any module that is not in the below list can be disabled:

| Module Name | Description                                                                                   |
| ----------- | --------------------------------------------------------------------------------------------- |
| alias       | Mapping different parts of the host file system in the document tree and for URL redirection. |
| authz_host  | Provides access control based on client host name, IP address.                                |
| dir         | Provides for trailing slash redirects and serving directory index files.                      |
| headers     | To control and modify HTTP request and response headers                                       |
| log_config  | Logging of the requests made to the server.                                                   |
| mime        | Associates the requested file name's extensions with the file's behavior and content          |
| negotiation | Provides for content selection of the document that best matches the clients capabilities.    |
| setenvif    | Allows for setting of environment variables based on characteristics of the request           |
| status      | Displays server status and performance statistics                                             |

###  

### Disable Modules

Unnecessary modules should be disabled to harden the configuration that will reduce security vulnerabilities. The customer is responsible for web server security policy. At a minimum the following modules should be disabled.

| Modul Name | Description                                                                                                          |
| ---------- | -------------------------------------------------------------------------------------------------------------------- |
| asis       | Sends files that contain their own HTTP headers                                                                      |
| autoindex  | Generates directory indices and displays directory listing when no index.html file is present                        |
| env        | Modifies the environment variable passed to CGI scripts and SSI pages                                                |
| cgi        | cgi - Execution of CGI scripts                                                                                       |
| actions    | Executes CGI scripts based on media type or request method, action triggering on requests                            |
| include    | Server-parsed HTML documents (Server Side includes)                                                                  |
| filter     | Smart filtering of requests                                                                                          |
| version    | Handling version information in config files using IfVersion                                                         |
| userdir    | Mapping of requests to user-specific directories. i.e. ~username in URL will get translated to a directory in server |

##  

## **Apache SSL/TLS** 

To protect data in transit, ensure confidentiality and authentication InterSystems recommends all TCP/IP communication between HealthShare servers and clients be encrypted with SSL/TLS, and InterSystems also recommends HTTPS be used for all communication between the users' browser client and the web server layer of the proposed architecture.   Please be sure to consult your organization's security policies to ensure compliance with any specific security requirements of your organization. 

The customer is responsible for supplying and managing the SSL/TLS certificates.  
If using SSL certificates then add ssl\_module (mod\_ssl.so).

## **Additional Hardening Apache Parameters** 

To further harden the Apache configuration, make the following changes in the httpd.conf:

  * TraceEnable should be turned off to prevent potential Cross Site Tracing issues.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4jugfuax70bvzr1wosa7.png)

  * ServerSignature should be turned off so the web server version is not displayed.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/p5eykgcu2l0nwtnsjmo5.png)

## **Supplemental Apache Configuration Parameters** 

### Keep-Alive 

The Apache Keep-Alive setting allows the same TCP connection for HTTP communication to be used instead of opening a new connection for each new request, i.e. Keep-Alive maintains a persistent connection between client and server. When Keep-Alive option is enabled performance improvements come from reduced network congestion, reduced latency in subsequent requests, and less CPU usage caused by opening connections simultaneously. Keep-Alive is ON by default and HTTP v1.1 standard mandates that it should be presumed on.

  
However there are caveats to enabling Keep-Alive; Internet Explorer must be IE10 or higher to avoid known timeout issues with older versions of IE. Also intermediaries like firewalls, load balancers and proxies etc. can interfere with 'persistent TCP connections' and can result in unexpected closure of connections.  

  
When enabling Keep-Alive, the Keep-Alive timeout also needs to be set. The default Keep-Alive timeout for Apache is too low and needs to be increased for most configurations because issues may arise associated with broken AJAX (i.e. hyperevent) requests. These issues can be avoided by ensuring the Keep-Alive timeout on the server is greater than on the client.  In other words the client should timeout and close the connection rather than the server.  Problems occur – mostly in IE but to a lesser extent in other browsers – when the browser tries to use a connection (particularly for a POST) that it expects to be open. 

  
See below for recommended KeepAlive and KeepAliveTimeout values for a HealthShare web server.

To enable KeepAlive in Apache, make the following changes in the httpd.conf:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vpx6h8qzcown4kq8as55.png)

### **CSP Gateway** 

For CSP Gateway KeepAlive parameter, leave the value at the default No Action because the KeepAlive status is determined by the HTTP response headers for each request.