12.3. Customizing Web Services

All of the subsystems have some kind of web-based services page for agents and some for other user types, like administrators or end entities. These web-based services pages use basic HTML and JavaScript, which can be customized to use different colors, logos, and other design elements to fit in with an existing site or intranet.
The CA, DRM, OCSP, and TKS have web directories in /var/lib/instance_name/webapps/subsystem_type, with sub-directories for admin, agent, and end-entities services. The RA and TPS, which use Apache as their web server instead of Tomcat, have a docroot directory, /var/lib/instance_name/docroot, which contains sub-directories for their different interfaces, meaning admin, agent, and end-entities for the RA and the different Enterprise Security Client web UIs and admin pages for the TPS.
While any of the web services pages can be customized, the CA and RA end-entities pages are the most likely to be edited because they are public-facing.

TIP

For tutorials on HTML editing, see http://htmlprimer.com/.
Section 12.3.1, “Customizing CA End-Entities Pages” and Section 12.3.2, “Customizing RA End-Entities Pages” are not exhaustive examples of the web pages available to edit for all subsystems or all web service interfaces. These are examples of common files and interfaces to customize.

12.3.1. Customizing CA End-Entities Pages

All of the files for the end-entities services page is in /var/lib/pki-ca/webapps/ca/ee/ca.
As shown in Figure 12.2, “CA End-Entities Services Page”, the CA end-entities page is comprised of two files. The index.html file defines the header and the left menu. The center area is made up of different template files for most pages and HTML files for the profile enrollment forms.
CA End-Entities Services Page

Figure 12.2. CA End-Entities Services Page


Most of the index.html file is JavaScript to dynamically create the tabs, profile lists, and menu options. The HTML markup within the script can be edited to change the logo, colors, and text. For example, this designs the top heading text and logo.
function loadTabs()
{
        with (top.tabsf.document) {
        writeln('<body onresize="top.doResize();" bgcolor="#cc0000" link="#FFFFFF" vlink="#FFFFFF" alink="#CCCCFF">');

                writeln('<table border=0 width="100%" cellspacing="0" cellpadding="0" bgcolor="#cc0000">');
                writeln('<tr><td>');
                writeln('<table border=0 cellspacing=12 cellpadding=0>');
                writeln('<tr>');
                writeln('<td><img src="/ca/admin/console/img/logo_header.gif"></td>');
                writeln('<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>');
                writeln('<td><font size="+1" face="PrimaSans BT, Verdana, sans-serif" color="white"><b>Red Hat<sup><font color="#cccccc" size="-2">&reg;</font></sup> Certificate Manager</b> this is a test about stuff</font></td>');
                writeln('</tr>');
                writeln('</table>');
Likewise, the *.template files also use JavaScript to generate the pages, and the HTML markup can be edited. The profile HTML pages use standard HTML markup with little generated content. For example, this is from the Manual Enrollment profile, ManCAEnroll.html:
<body bgcolor="#FFFFFF">
<font size="+1" face="PrimaSans BT, Verdana, Arial, Helvetica, sans-serif">
Certificate Manager Enrollment (for Certificate Manager Administrators)
</font><br>
  <Font size="-1" face="PrimaSans BT, Verdana, Arial, Helvetica, sans-serif">
  Use this form to submit a request for a subordinate certificate authority's
  signing certificate.
<p>
  After you click the Submit button, your request will be submitted to an
  issuing agent for approval. The certificate will be emailed to you.
</font>

TIP

Do not edit the default profile HTML pages.
To create a custom profile form, copy the existing form, edit the copy, and then place it in the /var/lib/pki-ca/webapps/ca/ee/ca directory. The custom form can be accessed by going to https://server.example.com:9444/ca/ee/ca/exampleForm.html.

12.3.2. Customizing RA End-Entities Pages

The web pages for RA services are configured in pairs, a *.cgi file which is accessed by the Apache web server and a *.vm file which contains the content for the page.
The docroot directory for the end-entities pages is /var/lib/pki-ra/docroot/ee. Each RA profile has its own sub-directory and its own specific *.cgi and *.vm file pairs. For example, the user profile enrollment forms are in /var/lib/pki-ra/docroot/ee/user/.
RA End-Entities Services Page

Figure 12.3. RA End-Entities Services Page


Each web services page uses three files to construct it. The header.vm and footer.vm files give the text and styles for the header and footer that are common for all pages. These are in the main /var/lib/pki-ra/docroot directory.

Example 12.1. Default RA Header File

<div id="header">
    <a href="http://www.redhat.com" title="Visit redhat.com for more information"><img src="/images/logo_header.gif" alt="Red Hat" id="myLogo" /></a>
    <div id="headertitle">
    <a href="/" title="Red Hat homepage">Red Hat<sup><font size="-2">&reg;</font></sup> Certificate System</a>
    </div>
    <div id="account">
          <dl><dt></dt><dd></dd></dl>
    </div>
</div>

The profile *.vm files, as with CA profiles, uses a mix of HTML and JavaScript to create the interior form or index to use in the center of the page, as shown with index.vm in /var/lib/pki-ra/docroot/ee in Figure 12.3, “RA End-Entities Services Page”. In Example 12.2, “Excerpt from the Default User Enrollment Form”, the HTML in user.vm creates the user enrollment form, located in the /var/lib/pki-ra/docroot/ee/user directory.

Example 12.2. Excerpt from the Default User Enrollment Form

<center>
<table border="0" cellspacing="1" cellpadding="1">
<tr>
  <td>UID:</td>
  <td><input type=text name=uid value=""></td>
</tr>
<tr>
  <td>Full Name:</td>
  <td><input type=text name=cn value=""></td>
</tr>
<tr>
  <td>Site ID:</td>
  <td><input type=text name=site_id value=""></td>
</tr>
<tr>
  <td>Your Email:</td>
  <td><input type=text name=email value=""></td>
</tr>
</table>
</center>

12.3.3. Setting Limits on Searches through the CA End-Entities Pages

Large PKIs can have tens of thousands, even millions, of certificates, keys, and requests maintained in its databases. When users search for their certificates or agents list requests, then, it is possible for thousands or millions of entries to be returned. Large search results can significantly affect CA performance, so it is possible to limit the number of results returned for a search or the amount of time that searches can take.
There are two files that can manage search limits for the CA end-entities pages:
  • The CS.cfg file in the /var/lib/pki-ca/conf directory
  • The web.xml file in the /var/lib/pki-ca/webapps/ca/ca/WEB-INF directory
The CS.cfg file has a single parameter which can set the maximum number of returned results for all user interfaces for all search types. To set this value:
  1. Stop the CA instance. For example:
    service pki-ca stop
  2. Open the CS.cfg file.
    vim /var/lib/pki-ca/conf/CS.cfg
  3. Change the ca.maxSearchReturns line to set the number of entries to return. The default is 1000.
    # maxSearchReturns - limits number of search results returned by SearchReqs and SrchCerts
    
    ca.maxSearchReturns=1000
  4. Start the CA instance. For example:
    service pki-ca start
The web.xml file provides more control over the results settings:
  • For one thing, both the number of results and the time limit for searches can be set, as opposed to
  • Additionally, each interface — admin, agents, and end-entities — can be configured with a different result limit and time limit.
  • Each operation can be configured with a different result limit and time limit. This means that searching for certificate requests can have different search limits than searching for certificates or CRLs.
The two parameters in the web.xml file which set the search limits are maxResults and timeLimits. These parameters are added as <param-value> lines to a servlet entry. Either one or both can be set for each entry.
Each servlet entry is identified in <servlet-name> tags and the interface (web services pages) that the servlet is used for is identified in the <param-name>interface</param-name> parameter.
Example 12.3, “web.xml Search Limit Settings” shows the setting for a time limit for searching for requests in the agent interface and the setting for a maximum number of results limit for the listing certificates search in the end-entities interface.

Example 12.3. web.xml Search Limit Settings

     <servlet-name>  casearchReqs  </servlet-name>
...
             <init-param><param-name>  interface  </param-name>
                         <param-value> agent      </param-value> </init-param>
...
             <init-param><param-name>  timeLimits  </param-name>
                         <param-value> 10 </param-value> </init-param>


     <servlet-name>  caListCerts  </servlet-name>
...
             <init-param><param-name>  interface   </param-name>
                         <param-value> ee          </param-value> </init-param>
             <init-param><param-name>  maxResults  </param-name>
                         <param-value> 1000 </param-value> </init-param>

12.3.4. Setting SSL Session Timeouts

All of the PKI subsystem instances have a default SSL session timeout period. This timeout removes data from the session cache when the timeout period (meaning, the inactive period) is reached, which decreases the ability of unauthorized users to access that information.
Web Server Subsystems Default Timeout
Tomcat 5
  • CA
  • DRM
  • OCSP
  • TKS
30 minutes
Apache 2.2
  • RA
  • TPS
86400 seconds (1 day)

12.3.4.1. Setting Session Timeouts for the CA, DRM, OCSP, and TKS

Each CA, DRM, OCSP, and TKS instance has its own Tomcat service which powers its web services pages. The configuration for the web services is in the /var/lib/instance_name/webapps/subsystem_type/WEB-INF/web.xml file in the <session-timeout> tag.

Example 12.4. Session Timeout Configuration

<!-- ==================== Default Session Configuration =============== -->
<!-- You can set the default session timeout (in minutes) for all newly -->
<!-- created sessions by modifying the value below.                     -->
<!--                                                                    -->
<!-- To disable session timeouts for this instance, set a value of -1.  -->

<session-config>
     <session-timeout>30</session-timeout>
</session-config>

The default is 30 minutes. To change this setting:
  1. Stop the instance.
    service instance_name stop
  2. Open the web.xml file and change the <session-timeout> to the new time, in minutes. Setting it to -1 disables the timeout period entirely.
    # vi /var/lib/instance_name/webapps/subsystem_type/WEB-INF/web.xml
    
    <session-config>
         <session-timeout>75</session-timeout>
    </session-config>
  3. Start the instance again.
    service instance_name start

12.3.4.2. Setting Session Timeouts for the RA and TPS

Each RA and TPS instance has its own Apache service which powers its web services pages. The configuration for the web services is in the /var/lib/instance_name/conf/nss.conf file. There are separate session cache timeout periods for SSLv2 and SSLv3, as well as a cache size setting.

Example 12.5. Session Timeout Configuration

#   Configure the SSL Session Cache. 
#   SSLSessionCacheSize is the number of entries in the cache.
#   SSLSessionCacheTimeout is the SSL2 session timeout (in seconds).
#   SSL3SessionCacheTimeout is the SSL3/TLS session timeout (in seconds).
NSSSessionCacheSize 10000
NSSSessionCacheTimeout 100
NSSSession3CacheTimeout 86400

The default for SSLv3 (the most common connection method) is 1 day. To change this setting:
  1. Stop the instance.
    service instance_name stop
  2. Open the nss.conf file and change the NSSSession3CacheTimeout value to the new time, in seconds. Setting it to -1 disables the timeout period entirely.
    # vi /var/lib/instance_name/conf/nss.conf
    
    
    NSSSession3NSSSessionCacheSize 10000
    NSSSessionCacheTimeout 600
    NSSSession3CacheTimeout 600
  3. Start the instance again.
    service instance_name start

12.3.5. Configuring Port Forwarding

As listed in Table 12.2, “Default Web Services Pages”, each subsystem instance has multiple different service URLs that users can access. For example, the CA has six different URLs: two different SSL interfaces for end users (one for client authentication), an agent interface, two for administrator interfaces (one for the Java console), and a standard port. These default URLs have this structure:
http|https://domain:port/path/
Trying to navigate through multiple interfaces, with long path directories and different port numbers, can be difficult for both users and administrators. Using port forwarding enhances the user experience by simplfying the URLs used to access web interfaces, while simultaneously providing more security by limiting user access to the instance. Port fowarding can reduce the user URL to a simpler format:
http|https://domain:port

IMPORTANT

For port forwarding to work, the machine must be configured to use three different IP addresses, one each for end-user, agent, and admin interfaces.
The default subsystem web services can be forwarded by using iptables to redirect the external, user-friendly requests to the internal standard configuration. For example, this allows administrators to use the standard SSL port 443 for external users, while redirecting the request to port 9444, for SSL end-entities.
iptables -t nat -A PREROUTING -p tcp -d 1.2.3.40 --dport 443 -j DNAT --to-destination 1.2.3.40:9444

iptables -A INPUT -m state --state NEW -p tcp -d 1.2.3.40 --dport 9444 -j ACCEPT
Example 12.6, “Port Forwarding Script” provides a sample script that invokes iptables to set up forwarding for all six CA interfaces. The IP addresses can be changed to use this for a local, real-life environment.

Example 12.6. Port Forwarding Script

            #!/bin/bash
            #
            # EXAMPLE RHCS 8 'CA' IPTABLES CONFIGURATION:
            #
            #
            #     ENTITY                     EXTERNAL VALUE          INTERNAL VALUE
            #     =========================================================================
            #     CA_EE_HTTP_HOSTNAME        ca-ee.example.com       ca-ee.example.com
            #     CA_EE_HTTP_IP              --                      1.2.3.40
            #     CA_EE_HTTP_PORT            80                      9180
            #
            #     CA_AGENT_HTTPS_HOSTNAME    ca-agent.example.com    ca-agent.example.com
            #     CA_AGENT_HTTPS_IP          --                      1.2.3.41
            #     CA_AGENT_HTTPS_PORT        443                     9443
            #
            #     CA_EE_HTTPS_HOSTNAME       ca-ee.example.com       ca-ee.example.com
            #     CA_EE_HTTPS_IP             --                      1.2.3.40
            #     CA_EE_HTTPS_PORT           443                     9444
            #
            #     CA_ADMIN_HTTPS_HOSTNAME    ca-admin.example.com    ca-admin.example.com
            #     CA_ADMIN_HTTPS_IP          --                      1.2.3.42
            #     CA_ADMIN_HTTPS_PORT        443                     9445
            #

            # Specify IP addresses
            CA_EE_HTTP_IP="1.2.3.40"
            CA_AGENT_HTTPS_IP="1.2.3.41"
            CA_EE_HTTPS_IP="1.2.3.40"
            CA_ADMIN_HTTPS_IP="1.2.3.42"

            # Specify external ports
            CA_EE_HTTP_EXTERNAL_PORT=80
            CA_AGENT_HTTPS_EXTERNAL_PORT=443
            CA_EE_HTTPS_EXTERNAL_PORT=443
            CA_ADMIN_HTTPS_EXTERNAL_PORT=443

            # Specify internal ports
            CA_EE_HTTP_INTERNAL_PORT=9180
            CA_AGENT_HTTPS_INTERNAL_PORT=9443
            CA_EE_HTTPS_INTERNAL_PORT=9444
            CA_ADMIN_HTTPS_INTERNAL_PORT=9445

            # Example:  http://ca-ee.example.com:80 --> http://ca-ee.example.com:9180
            /sbin/iptables -t nat -A PREROUTING -p tcp -d ${CA_EE_HTTP_IP} --dport ${CA_EE_HTTP_EXTERNAL_PORT} -j DNAT --to-destination ${CA_EE_HTTP_IP}:${CA_EE_HTTP_INTERNAL_PORT}
            /sbin/iptables -A INPUT -m state --state NEW -p tcp -d ${CA_EE_HTTP_IP} --dport ${CA_EE_HTTP_INTERNAL_PORT} -j ACCEPT

            # Example:  https://ca-agent.example.com:443 --> https://ca-agent.example.com:9443
            /sbin/iptables -t nat -A PREROUTING -p tcp -d ${CA_AGENT_HTTPS_IP} --dport ${CA_AGENT_HTTPS_EXTERNAL_PORT} -j DNAT --to-destination ${CA_AGENT_HTTPS_IP}:${CA_AGENT_HTTPS_INTERNAL_PORT}
            /sbin/iptables -A INPUT -m state --state NEW -p tcp -d ${CA_AGENT_HTTPS_IP} --dport ${CA_AGENT_HTTPS_INTERNAL_PORT} -j ACCEPT

            # Example:  https://ca-ee.example.com:443 --> https://ca-ee.example.com:9444
            /sbin/iptables -t nat -A PREROUTING -p tcp -d ${CA_EE_HTTPS_IP} --dport ${CA_EE_HTTPS_EXTERNAL_PORT} -j DNAT --to-destination ${CA_EE_HTTPS_IP}:${CA_EE_HTTPS_INTERNAL_PORT}
            /sbin/iptables -A INPUT -m state --state NEW -p tcp -d ${CA_EE_HTTPS_IP} --dport ${CA_EE_HTTPS_INTERNAL_PORT} -j ACCEPT

            # Example:  https://ca-admin.example.com:443 --> https://ca-admin.example.com:9445
            /sbin/iptables -t nat -A PREROUTING -p tcp -d ${CA_ADMIN_HTTPS_IP} --dport ${CA_ADMIN_HTTPS_EXTERNAL_PORT} -j DNAT --to-destination ${CA_ADMIN_HTTPS_IP}:${CA_ADMIN_HTTPS_INTERNAL_PORT}
            /sbin/iptables -A INPUT -m state --state NEW -p tcp -d ${CA_ADMIN_HTTPS_IP} --dport ${CA_ADMIN_HTTPS_INTERNAL_PORT} -j ACCEPT