Securing Apache Geode With Your Corporate LDAP
This is a guest blog post written by Apache Geode contributor Guillermo Tantachuco
To protect your data and to mitigate threats such as spoofing, information disclosure, replay attacks and elevation of privileges, Apache Geode (incubating) provides mature security features such as authentication, authorization and SSL communication that have consistently addressed customer’s security requirements for over a decade. Apache Geode provides a flexible security framework and lets you integrate it with your organization’s preferred authentication method. In this article, we are going to discuss system-level authentication with LDAP and a sample authorization method. For system-level security, you need a service account, which is an account that belongs to your application instead of to an individual end-user. This is similar to how most applications currently connect to a relational database.
Apache Geode provides two (2) types of authentication:
- Cache server authentication allows a new member to join a cluster. The membership coordinator is responsible for authenticating credentials of the new member. Geode assumes that the coordinator is authenticated and subsequent members authenticate against the coordinator. When using locators, the coordinator is the first locator to join the cluster. When using multicast, the coordinator is the first server to join the cluster
- Client authentication enables client apps to provide service account credentials to a server during connection initialization and for each operation request so that servers never process the same request twice
To protect the membership coordinator, it is important to point out that you should always run the Geode cluster in a secure environment.
To prevent replay attacks, the server generates a random unique identifier and returns it to the client to use in its next operation request (get, put, destroy, among others). Then the server verifies the client’s unique identifier, processes the client request, and responds with a new randomly generated unique identifier, for the client to include in its next request. Please see Apache Geode online documentation for more details about authentication
The authorization of operations performed by a client application on a cluster can be restricted or completely blocked according to your configurations and programmatic authorization callback. There are two (2) types of authorization callbacks:
- Pre-operation: you can program the authorization callback to do something before the operation is executed
- Post-operation: All client operations that return a result (like get and query) and all notifications can also be authorized where the callback can peek and even modify the result before it is sent out to the client
What about audit trails? Any authorization implementation can also create an audit trail given that the following information is available to you: authorized user, code of the operation performed, region name, remote client and operation data (e.g: data for PUT and PUTALL commands). All that information can be stored wherever you decide including but not limited to: database table, log file and Apache Geode region. Please see Apache Geode online documentation for more details about authorization
Sample security scenario
The best way to illustrate authentication and authorization is with an example. In this example, we use a local LDAP server. The picture below shows two (2) sample applications that provide bank account access to employees and customers, respectively. The LDAP service account used by the employee application can read and update multiple bank accounts (Put, PutAll, Get and Query). The LDAP Service account used by the customer-facing application can only read and update information of a single bank account (Put and Get)
In our example, the cluster hosts two (2) regions: The Account region is a partitioned region that stores bank account information such as account ID, account number, account type, balance and credit line. The PermissionPerRole region is a replicated region that stores the roles of each LDAP user for a given Apache Geode region
Running the sample code
You can find the source code of the sample security scenario on this Github repository . The README.MD file contains detailed instructions to build and execute our sample client application with a local Apache Geode cluster and a local LDAP server. Once you have the environment configured, you can execute the sample client application, change to the ‘sample-client-security’ folder and execute this command: java -jar target/sample-client-security-0.1.0.jar
To run the test scenarios using the Customer application’s service account, enter 1. To use the Employee application’s service account, enter 2. This screenshot shows the menu that the sample client application displays.
When we use the Customer application’s service account to execute a PUT on the Account region, the “server1/server1.log” file of the cluster contains the following ALLOWED log messages:
However, when we use the Customer application’s service account to execute a PUT-ALL on the Account region, the “server1/server1.log” file correctly indicates that said service account could not perform the aforementioned operation by displaying a DENIED log message:
Now let’s walk through our sample authentication and authorization implementations.
Implementing Authentication for Apache Geode servers
Apache Geode has two (2) authentication interfaces that you need to implement: AuthInitialize and Authenticator which are located in the com.gemstone.gemfire.security package. Our sample implementations of AuthInitialize and Authenticator are called UserPasswordAuthInit and LdapUserAuthenticator, respectively. Both classes are part of the org.mycompany.security.samples package.
Locators and servers use our sample gemfire-server.properties file to store any security-related properties. Here is an excerpt of our sample properties file, feel free to change any LDAP-related settings to run this example in your environment:
- security-ldap-url=ldap://localhost:10389/
- security-ldap-basedn=o=sevenSeas
- security-ldap-filter=(&(objectClass=inetOrgPerson)(uid={0}))
- security-username=geode-system
- security-password=pass
These properties represent the URL of your LDAP server; the search base is the location in the LDAP directory tree from which any LDAP user search begins; the search filter defines LDAP user search criteria. Last but not least, both username and password to be used to join the cluster.
The properties file also specifies the fully qualified names of our sample implementations.
- security-peer-auth-init=org.mycompany.security.samples.UserPasswordAuthInit.create
- security-peer-authenticator=org.mycompany.security.samples.LdapUserAuthenticator.create
The security-peer-auth-init property should be set to the name of a zero-argument static method that returns an AuthInitialize object on the members while the security-peer-authenticator property should be set to the name of a zero-argument static method that returns an Authenticator object on the members and locators. You can find the source code of UserPasswordAuthInit and LdapUserAuthenticator implementation classes on Github.
Implementing Authentication for Apache Geode clients
To enable client authentication, we need to configure both cluster members and the client application.
Cluster configuration: To configure the cluster, we need to add this entry to our properties file:
- security-client-authenticator=org.mycompany.security.samples.LdapUserAuthenticator.create
The security-client-authenticator property should be set to the name of a zero-argument static method that returns an Authenticator object on all the servers.
Client application configuration: the settings required for the client application are described below.
The security-client-auth-init property should be set to the name of a zero-argument static method that returns an AuthInitialize object on all the clients. We also set both username and password to be used by client applications to authenticate with the cluster.
It is important to note that, in our example, we are using the same UserPasswordAuthInit class to obtain service accounts of client applications and servers.
Implementing Authorization
There is an authorization interface that you need to implement: AccessControl, which is part of the com.gemstone.gemfire.security package. Our sample implementation of AccessControl is called PrePostAuthorization as described in below diagram. This class is part of the org.mycompany.security.samples package.
To enable cluster authorization, we need to add these two (2) entries to our cluster’s properties file:
- security-client-accessor=org.mycompany.security.samples.PrePostAuthorization.create
- security-client-accessor-pp=org.mycompany.security.samples.PrePostAuthorization.create
For pre-operation calls, set security-client-accessor to the fully qualified name of the static method you programmed to return an instance of the class. For post-operation calls, set security-client-accessor-pp to the fully qualified name of the static method you programmed to return an instance of the class. You can find the source code of the PrePostAuthorization class on Github.
Summary
Now you know the mechanisms to enable system-level authentication and authorization of a Apache Geode cluster. It is important to point out that Apache Geode is very flexible and allows you to configure system users and their corresponding roles and permissions based on your security policy and technology. We find that most enterprise customers typically have a common infrastructure such as single sign-on or centralized authentication systems they need to integrate with. You can join Apache Geode project right now and start reaping the benefits of using a powerful distributed in-memory database that provides applications ultra-low latency access to terabytes of operational data at a massive scale, in a secure manner.