2 Enabling General Security Measures

This chapter provides instructions for enabling general security measures. The measures help to protect against unauthorized use of the Oracle Coherence API and system resources. They also protect against unauthorized connections to a cluster.

This chapter includes the following sections:

2.1 Using the Java Security Manager

Java provides a security manager that controls access to system resources using explicit permissions. The COHERENCE_HOME/lib/security/security.policy policy configuration file specifies a minimum set of permissions for Oracle Coherence. Use the file as provided, or modify the file to set additional permissions. Coherence also includes a set of local (non-clustered) permissions.

The section includes the following topics:

2.1.1 Enable the Java Security Manager

To enable the Java security manager and use the COHERENCE_HOME/lib/security/security.policy file, set the following properties on a cluster member:

  1. Set the java.security.manager property to enable the Java security manager. For example:
    -Djava.security.manager
    
  2. Set the java.security.policy property to the location of the policy file. For example:
    -Djava.security.manager
    -Djava.security.policy=/coherence/lib/security/security.policy
    
  3. Set the coherence.home system property to COHERENCE_HOME. For example:
    -Djava.security.manager
    -Djava.security.policy=/coherence/lib/security/security.policy
    -Dcoherence.home=/coherence
    

Note:

The security policy file assumes that the default Java Runtime Environment (JRE) security permissions have been granted. Therefore, you must be careful to use a single equal sign (=) and not two equal signs (==) when setting the java.security.policy system property.

2.1.2 Specify Permissions

Modify the COHERENCE_HOME/lib/security/security.policy file to include additional permissions as required. See the Java SE Security Guide for details about the file format and syntax:

http://download.oracle.com/javase/7/docs/technotes/guides/security/permissions.html

To specify additional permissions in the security.policy file:

  1. Edit the security.policy file and add a permission for a resource. For example, the following permission grants access to the coherence.jar library:
    grant codeBase "file:${coherence.home}/lib/coherence.jar"
        {
                permission java.security.AllPermission;
        };
    
  2. When you declare binaries, sign the binaries using the JDK jarsigner tool. The following example signs the coherence.jar resource declared in the previous step:
    jarsigner -keystore ./keystore.jks -storepass password coherence.jar admin
    

    Add the signer in the permission declaration. For example, modify the original permission as follows to add the admin signer.

    grant SignedBy "admin" codeBase "file:${coherence.home}/lib/coherence.jar"
        {
                permission java.security.AllPermission;
        };
    
  3. Use operating system mechanisms to protect all relevant files from malicious modifications.

2.1.3 Programmatically Specifying Local Permissions

The com.tangosol.net.security.LocalPermission class provides a way to set permissions for local (non-clustered) Coherence API operations. Clients are either allowed or not allowed to perform the declared operations (referred to as targets). For example:

LocalPermission lp = new LocalPermission("Cluster.shutdown");

To use local permissions, the Java security manager must be enabled. For details, see "Enable the Java Security Manager."

Table 2-1 lists and describes the target names that can be declared.

Table 2-1 Local Permission Targets

Target Name Description

CacheFactory.setCacheFactoryBuilder

Protects the programmatic installation of a custom cache factory builder. Special consideration should be given when granting this permission. Granting this permission allows code to set a cache factory builder and intercept any access or mutation requests to any caches and also allows access to any data that flows into and from those caches.

Cluster.shutdown

Protects all services from being shutdown. Granting this permission allows code to programmatically shutdown the cluster node.

BackingMapManagerContext.getBackingMap

Protects direct access to backing maps. Special consideration should be given when granting this permission. Granting this permission allows code to get a reference to the backing map and access any stored data without any additional security checks.

BackingMapManagerContext.setClassLoader

Protect changes to class loaders used for storage. The class loader is used by the cache service to load application classes that might not exist in the system class loader. Granting this permission allows code to change which class loader is used for a particular service.

Service.getInternalService

Protects access to an internal service, cluster or cache reference. Granting this permission allows code to obtain direct access to the underlying service, cluster or cache storage implementation.

Service.registerResource

Protects service registries. Granting this permission allows code to re-register or unregister various resources associated with the service.

Service.registerEventInterceptor

Protects the programmatic installation of interceptors. Special consideration should be given when granting this permission. Granting this permission allows code to change or remove event interceptors associated with the cache service thus either getting access to underlying data or removing live events that are designed to protect the data integrity.

2.2 Using Host-Based Authorization

Host-based authorization is a type of access control that allows only specified hosts (based on host name or IP address) to connect to a cluster. The feature is available for both cluster member connections and extend client connections.

This section includes the following topics:

2.2.1 Overview of Host-Based Authorization

Host-based authorization uses the host name and IP address of a cluster member or extend client to determine whether a connection to the cluster is allowed. Specific host names, addresses, and address ranges can be defined. For custom processing, a custom filter can be created to validate hosts.

Host-based authorization is ideal for environments where known hosts with relatively static network addresses are joining or accessing the cluster. In dynamic environments, or when updating a DNS server, IP addresses can change and cause a cluster member or extend client to fail authorization. Cache operations may not complete if cluster members or extend clients are no longer authorized. Extend clients are more likely to have access problems because of their transient nature.

When using host-based authorization, consider the dynamic nature of the network environment. The need to reconfigure the list of authorized hosts may become impractical. If possible, always use a range of IP addresses instead of using a specific host name. Or, create a custom filter that is capable of resolving address that have changed. If host-based authorization becomes impractical, consider using extend client identity tokens (see "Using Identity Tokens to Restrict Client Connections") or SSL (Using SSL to Secure Communication).

2.2.2 Specify Cluster Member Authorized Hosts

The default behavior of a cluster allows any host to connect to the cluster and become a cluster member. Host-based authorization changes this behavior to allow only hosts with specific host names or IP addresses to connect to the cluster.

Configure authorized hosts in an operational override file using the <authorized-hosts> element within the <cluster-config> element. Enter specific addresses using the <host-address> element or a range of addresses using the <host-range> element. The <host-address> and <host-range> elements support an id attribute for uniquely identifying multiple elements.

The following example configures a cluster to accept only cluster members whose IP address is either 192.168.0.5, 192.168.0.6, or within the range of 192.168.0.10 to 192.168.0.20 and 192.168.0.30 to 192.168.0.40.

<?xml version='1.0'?>

<coherence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"
   xsi:schemaLocation="http://xmlns.oracle.com/coherence/
   coherence-operational-config coherence-operational-config.xsd">
   <cluster-config>
      <authorized-hosts>
         <host-address id="1">192.168.0.5</host-address>
         <host-address id="2">192.168.0.6</host-address>
         <host-range id="1">
            <from-address>192.168.0.10</from-address>
            <to-address>192.168.0.20</to-address>
         </host-range>
         <host-range id="2">
            <from-address>192.168.0.30</from-address>
            <to-address>192.168.0.40</to-address>
         </host-range>
      </authorized-hosts>
   </cluster-config>
</coherence>

2.2.3 Specify Extend Client Authorized Hosts

The default behavior of an extend proxy server allows any extend client to connect to the cluster. Host-based authorization changes this behavior to allow only hosts with specific host names or IP addresses to connect to the cluster.

Configure authorized hosts in a cache configuration file using the <authorized-hosts> element within the <tcp-acceptor> element of a proxy scheme definition. Enter specific addresses using the <host-address> element or a range of addresses using the <host-range> element. The <host-address> and <host-range> elements support an id attribute for uniquely identifying multiple elements.

The following example configures an extend proxy to accept only client connections from clients whose IP address is either 192.168.0.5, 192.168.0.6, or within the range of 192.168.0.10 to 192.168.0.20 and 192.168.0.30 to 192.168.0.40.

<proxy-scheme>
   <service-name>ExtendTcpProxyService</service-name>
   <thread-count>5</thread-count>
   <acceptor-config>
      <tcp-acceptor>
         ...
         <authorized-hosts>
            <host-address id="1">192.168.0.5</host-address>
            <host-address id="2">192.168.0.6</host-address>
            <host-range id="1">
               <from-address>192.168.0.10</from-address>
               <to-address>192.168.0.20</to-address>
            </host-range>
            <host-range id="2">
               <from-address>192.168.0.30</from-address>
               <to-address>192.168.0.40</to-address>
            </host-range>
         </authorized-hosts>
         ...
      </tcp-acceptor>
   </acceptor-config>
   <autostart>true</autostart>
</proxy-scheme>

2.2.4 Use a Filter Class to Determine Authorization

A filter class determines whether to accept a particular host connection. Both extend client connections and cluster member connections support using filter classes. A filter class must implement the com.tangosol.util.Filter interface. The evaluate() method of the interface is passed the java.net.InetAddress of the host. Implementations should return true to accept the connection.

To enable a filter class, enter a fully qualified class name using the <class-name> element within the <host-filter> element. Set initialization parameters using the <init-params> element. See the Java API Reference for Oracle Coherence for details on the Filter interface.

The following example configures a filter named MyFilter, which determines if a host connection is allowed.

<authorized-hosts>
   <host-address id="1">192.168.0.5</host-address>
   <host-address id="2">192.168.0.6</host-address>
   <host-range id="1">
      <from-address>192.168.0.10</from-address>
      <to-address>192.168.0.20</to-address>
   </host-range>
   <host-filter>
      <class-name>package.MyFilter</class-name>
         <init-params>
            <init-param>
               <param-name>sPolicy</param-name>
               <param-value>strict</param-value>
            </init-param>
         </init-params>
   </host-filter>
</authorized-hosts>

2.3 Managing Rogue Clients

Rogue clients are extend clients that operate outside of acceptable limits. Rogue clients are slow-to-respond clients or abusive clients that attempt to overuse a proxy— as is the case with denial of service attacks. In both cases, the potential exists for a proxy to run out of memory and become unresponsive. The suspect protocol safeguards against such abuses.

The suspect algorithm monitors client connections looking for abnormally slow or abusive clients. When a rogue client connection is detected, the algorithm closes the connection to protect the proxy server from running out of memory. The protocol works by monitoring both the size (in bytes) and length (in messages) of the outgoing connection buffer backlog for a client. Different levels determine when a client is suspect, when it returns to normal, or when it is considered rogue.

Configure the suspect protocol within the <tcp-acceptor> element of a proxy scheme definition. See Developing Applications with Oracle Coherence for details on using the <tcp-acceptor> element. The suspect protocol is enabled by default.

The following example demonstrates configuring the suspect protocol and is similar to the default settings. When the outgoing connection buffer backlog for a client reaches 10 MB or 10000 messages, the client is considered suspect and is monitored. If the connection buffer backlog for a client returns to 2 MB or 2000 messages, then the client is considered safe and the client is no longer monitored. If the connection buffer backlog for a client reaches 95 MB or 60000 messages, then the client is considered unsafe and the proxy closes the connection.

<proxy-scheme>
   <service-name>ExtendTcpProxyService</service-name>
   <thread-count>5</thread-count>
   <acceptor-config>
      <tcp-acceptor>
         ...
         <suspect-protocol-enabled>true</suspect-protocol-enabled>
         <suspect-buffer-size>10M</suspect-buffer-size>
         <suspect-buffer-length>10000</suspect-buffer-length>
         <nominal-buffer-size>2M</nominal-buffer-size>
         <nominal-buffer-length>2000</nominal-buffer-length>
         <limit-buffer-size>95M</limit-buffer-size>
         <limit-buffer-length>60000</limit-buffer-length>
      </tcp-acceptor>
   </acceptor-config>
   <autostart>true</autostart>
</proxy-scheme>