This page last changed on Apr 04, 2012 by jdeolive.

Overview

A completely reengineered security system with emphasis on flexibility and configurability.

This proposal supersedes the following past proposals:

Proposed By

Christian Mueller
Justin Deoliveira

Assigned to Release

Intended for 2.2

State

Under Discussion, In Progress, Completed, Rejected, Deferred

Motivation

This proposal is a major retrofit of the GeoServer security subsystem. The following highlights the added functionality:

  • Support for groups, with ability to assign roles to an entire group rather than individual users
  • Support for password encryption allowing for storing user passwords in non-plain text
  • Configurability - ability to configure new types of authentication (ex. LDAP) out of the box
  • Extensibility - ability to extend system to add new authentication types, user and role database backends, etc... through plug-ins

Proposal

Quick Info

GeoServerSecurityManager

A new class named GeoServerSecurityManager is the facade for the new security subsystem and plays the same role that Catalog plays for the catalog subsystem, and GeoServer plays for the configuration subsystem.

The current version of the class can be found here

User/Group and Role Services

The new security subsystem adds two entities:

  • User/Group Service - Backend database for users
  • Role Service - Backend database for roles, and their assignment to users and groups

A user/group service provides a source user/group database and is a replacement for what is currently stored in the users.properties file. This service is explain in more detail here.

A role service provides a source for role information, including available roles and the users/group those roles are assigned to. This service also replaced information currently stored in users.properties. This service is documented in more detailed here.

Both user/group and role services can be read or read-write, the former providing a service that is only a source of user/role information, the latter providing the ability to modify.

Password Encryption

This proposal adds the ability to store passwords encrypted, rather than in plain text. This is supported for both user passwords (previously stored in users.properties and also configuration passwords for stores (ex. database passwords), stored in the store.xml for a particular store.

A variety of encryption methods are available, including:

  • Plain-text
  • Digest
  • Password based encryption (PBE)

PBE encryption comes in two flavours, strong and weak. Strong PBE encryption requires additional JCE jars not included in all Java installations. For those system that don't come with strong encryption out of the box it is possible to download install them manually.

More documentation available here.

Password Policies

The new security work adds the ability to place constraints on user passwords such as password length, mix of case and characters, etc...

Documented in more detail here.

Authentication

The security subsystem allows for the control of how users are authenticated in geoserver, with the ability to add and configure new types of authentication such as LDAP. The notion of an "authentication chain" is provided to allow for a number of authentication strategies and scenarios.

More documentation about authentication here.

Root Account

Because of the highly configurable nature of the new security subsystem it is quite possible that through a misconfiguration the administrator could potentially disable authentication, preventing even herself from logging in the geoserver admin ui to fix the problem. For this reason the notion of a root account is added. The root account is one that is meant to always be available regardless of the state of the normal authentication chain.

The username for the root account is "root" and the password is the master password, explained in more detail below.

Encryption Keys and the Keystore

With the ability to do password encryption comes the requirement to store encryption keys in a secure way. This is achieved with a java keystore. For this reason an internal keystore is maintained in the security directory under the data directory. The keystore is named geoserver.jceks.

As the name implies the type of keystore used is JCEKS rather than the default JKS type. This is because JCEKS is capable of storing secret keys as well as private keys. JKS can only do private keys. More information about the difference available in this article.

The keystore is protected by the master password, explained in more detail below. Documentation regarding the keystore can be found here.

Master Password

As mentioned above the master password serves two purposes:

  1. As the password for the root account
  2. Protect the internal keystore that contains keys used for encryption

Naturally is important that the master password be stored in a secure way since the master password being compromised means that the entire system has been compromised. A number of measures are taken to enhance the security of the master password.

The first is that we use a digest encryption method for the purposes of simple password validation, for instance during login to the root account. Digest encryption is one-way which means we avoid ever having to decrypt the master password back into plain text.

However, there is one case in which we must decrypt the master password back into plain text and that is to access the keystore. To facilitate this we store a separately encrypted version of the master password. The encryption method used in this secondary case is a PBE method in which the key is generated by applying a permutation to a pre-defined alphabet. This obviously is not perfect since it means a malicious user could easily decrypt the master password by studying the GeoServer source code. But it is better than simply storing the master password in plain text on the file system.

The method of storing the master password is extensible, with the above scheme being the default that comes out of the box. In environments that require a higher level of security it is recommended an alternate scheme be used. One such possibility is by using an external url for the source of the master password. This url can be a link to a static resource, or a link to a dynamic web service that can generate the master password. And finally there is the option of writing a completely custom master password provider.

That said, when handling the master password in plain text, obtained from whichever method, we always take two precautions to minimize the exposure of the password.

  1. Never store it in a String, instead we use a char array
  2. Always scramble the char array when we are done

To illustrate with code, instead of doing this:

String masterpw = getSecurityManager().getMasterPassword();
//do sometthing

We always do this:

char[] masterpw = getSecurityManager().getMasterPassword();
try {
  // do something
}
finally {
  getSecurityManager().disposePassword(masterpw);
}

The reason for this is that java strings are immutable, and pooled in memory for performance reasons. Which means it would be possible to analyze the contents of the java heap to retrieve the master password. So for this reason we use a char[] array and scramble the contents of it after we are done in order to minimize the risk.

So it is important that code never do this:

  char[] masterpw = getSecurityManager().getMasterPassword();
  new String(masterpw);

Lastly the GeoServerSecurityManager.getMasterPassword() method is of package visibility meaning only code within the org.geoserver.security package has the ability to retrieve its value in plain text. Furthermore this package is sealed so that it is not possible for a third party extension to place itself within the same package.

More documentation regarding passwords and encryption is available here.

New Data Directory Structure

The new security subsystem comes with a new structure in the data directory under the security directory. The new file tree looks like the following:

config.xml
geoserver.jceks
layers.properties
service.properties
rest.properties
auth/
filter/
masterpw
pwpolicy
role
usergroup
  • config.xml is the top level configuration file. It contains global security options.
  • geoserver.jceks is the keystore used for encryption keys. Explained above.
  • layers.properties, service.properties, and rest.properties are unchanged.
  • auth is the root directory for authentication provider configurations. Example above.
  • filter is the root directory for security filter configurations.
  • masterpw is the root directory for master password provider configurations. Exampled above.
  • pwpolicy is the root directory for password policy configurations.
  • role is the root directory for role service configurations. Explained above.
  • usergroup is the root directory for user group service configurations. Explained above.

Under each of the individual directories, auth, filter, masterpw, etc... can contain multiple configurations, each contained within another subdirectory named the same as the configuration name. Under each directory contains a file named config.xml that contains the persisted configuration itself as XML. Depending on the entity the directory will also contain other files, for instance a usergroup configuration directory can contain the xml files containing the actual user database.

Read on to the next section for more information.

Security Configuration Migration

Upon upgrade to the new security subsystem the old configuration is migrated to the new. This is similar to how the catalog and configuration are migrated upon upgrading from a pre geoserver 1.7.x configuration.

The first part of the migration involves replacing users.properties with a user group service and role service configuration. Both of the configurations are named "default" and located under the usergroup and role directories respectively.

usergroup/
   default/
       config.xml
       users.xml
       users.xsd
role/
   default/
       config.xml
       roles.xml
       roles.xsd

Both services persist the user and role databases as xml. The default users.xml has the following contents:

<userRegistry version="1.0" xmlns="http://www.geoserver.org/security/users">
    <users>
      <user enabled="true" name="admin" password="crypt1:e114FDdortfDNv01rzEpnDk3cmd+UsNE"/>
    </users>
    <groups>
    </groups>
</userRegistry>

The default roles.xml has the following contents:

<roleRegistry version="1.0" xmlns="http://www.geoserver.org/security/roles">
    <roleList>
        <role id="ROLE_ADMINISTRATOR"/>
    </roleList>
    <userList>
        <userRoles username="admin">
            <roleRef roleID="ROLE_ADMINISTRATOR"/>
        </userRoles>
    </userList>
    <groupList/>
</roleRegistry>

Also during migration a default authentication provider is created that authenticates users by using the usergroup service to look up user info, and verify passwords.

auth/
   default/
      config.xml

The config.xml contains mainly the name of the usergroup service to use for the user lookup.

<usernamePassword>
  <id>-344bdadf:1358c667d8c:-7ffb</id>
  <name>default</name>
  <className>org.geoserver.security.UsernamePasswordAuthenticationProvider</className>
  <userGroupServiceName>default</userGroupServiceName>
</usernamePassword>

During migration a master password provider configuration is created for storing the geoserver master password. For historical reasons the default master password is "geoserver".

A master password provider is an extension point for allowing different strategies for storing and retrieving the geoserver master password. The default provider uses a file named passwd inside of the configuration directory that stores the encrypted master password.

masterpw/
  default/
     config.xml
     passwd

Master password providers explained in more detail above.

During migration two password policies are created:

pwpolicy/
  default/
    config.xml
  master/
    config.xml

The first, "default", is the default policy used for user passwords. It places no constraints on user passwords.

The second, "master" is the policy used to constrain the master password. The only constraint it places is a minimum length of 8 characters, which is required in order to password protect the keystore.

Password policies explained in more detail above.

Feedback

Issue/Concern Resolution
Developer docs  
User doc tweaks  
JCE policy jars not available everywhere, state that  

Backwards Compatibility

As explained above this proposal changes the security configuration structure, but migrates old configuration upon startup. So the work is backward compatible but not forward compatible. This mirrors how the catalog / configuration handed backward compatibly during the upgrade from 1.7 to 2.0.

Voting

Andrea Aime:
Alessio Fabiani:
Ben Caradoc-Davies:
Gabriel Roldán:
Justin Deoliveira:
Jody Garnett:
Mark Leslie:
[~roba]:
Simone Giannecchini:

Links

JIRA Task
[Email Discussion|]
[Wiki Page|]

Document generated by Confluence on May 14, 2014 23:00