Setting up a ForgeRock Directory Service instance for production may be a cumbersome task as instructions to harden the instance for production may be located all over the documentation.

This post aims to consolidate all the hardening recommendations with more detailed steps and short video guides to achieve them. Ultimately, being the go to reference for how to harden an DS instance.

Note that this post will include some of the recommendations on both ForgeRock documentation and from our own experience. We will be using the latest version of DS as of this post, 6.5.3.

If you are here just for the checklist, you can download it by clicking here (TODO: checklist and link).


1. Always Use --productionMode During Initial Setup

IMPORTANCE: BASELINE

When you set up a server without using the --productionMode option, default global access control settings allow applications to:

  • Read the root DSE
  • Read server LDAP schema
  • Read directory data anonymously
  • Modify one's own entry
  • Request extended operations and operations with certain controls

This is for ease of development purposes only and highly insecure in production environments to leave disabled.

2. Run DS as an underprivileged sytem user rather than root

As with all applications, if not needed, do not run them as the system root user as it will provide the application with more permissions than necessary.

Make sure you configure the system to let the user access privileged ports such as 389 and 636 if necessary.

3. Only Open HTTPS And LDAPS Ports

IMPORTANCE: BASELINE

You should not be using HTTP and LDAP connections as they are prone to Man-in-the-Middle (MitM) attacks even internally. Hence, in the first place they should be disabled.

4. Create Specific Administrative Accounts For Each BaseDN Using Profiles

IMPORTANCE: BASELINE

Profiles in the latest versions of DS make it much easier to set up back-ends at DS and also set up accounts for you.

When using the setup script, append these parameters, replacing the environment variables enclosed in ${...} accordingly to use the profile system:

--profile am-config
--set am-config/amConfigAdminPassword:${DS_CONFIG_PASS}
--set am-config/baseDn:ou=am-config,${DS_BASEDN}

--profile am-cts
--set am-cts/amCtsAdminPassword:${DS_CTS_PASS}
--set am-cts/baseDn:ou=tokens,${DS_BASEDN}

--profile am-identity-store
--set am-identity-store/amIdentityStoreAdminPassword:${DS_IDS_PASS}
--set am-identity-store/baseDn:ou=identities,${DS_BASEDN}

You can get more information on using profiles here https://backstage.forgerock.com/docs/ds/6.5/install-guide/index.html#chap-setup-profiles

5. Limiting Connections To TLS1.2 and Secure Cipher Suites

IMPORTANCE: RECOMMENDED

It is recommended to disable outdated TLS protocols and cipher suites to force the use of more updated and secure ones.

Running this exact script in the DS bin directory while it is offline will set the respective configuration:

bin/dsconfig set-connection-handler-prop \
        --offline \
        --handler-name LDAPS \
        --set ssl-protocol:TLSv1.2 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA \
        --no-prompt
bin/dsconfig set-connection-handler-prop \
        --offline \
        --handler-name HTTPS \
        --set ssl-protocol:TLSv1.2 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA \
        --no-prompt
bin/dsconfig set-administration-connector-prop \
        --offline \
        --set ssl-protocol:TLSv1.2 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA \
        --no-prompt
bin/dsconfig set-crypto-manager-prop \
        --offline \
        --set ssl-protocol:TLSv1.2 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 \
        --set ssl-cipher-suite:TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA \
        --set ssl-cipher-suite:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA \
        --no-prompt

6. Set Higher Maximum File Descriptors And Process Per User To Prevent Denial Of Service

IMPORTANCE: BASELINE

Identical to Access Manager, by default, the values set are too low to handle high number of connections by ForgeRock DS, it is required to set this to a higher value (recommendation of 65536)


Assuming a Linux system:

  1. su to the user where DS is installed under
su - ${AM_USERNAME}
  1. Change the file descriptor limit to 65536
ulimit -n 65536
  1. To make this persist across reboots you should run this command to these two lines to /etc/sysctl.conf as root
cat >> /etc/sysctl.conf <<- EOF
fs.file-max=65536
fs.inotify.max_user_watches=524288
EOF

Disclaimer

The document and content made available by Nebulas Tree in no way conveys any right, title, interest or license in any intellectual property rights (including but not limited to patents, copyrights, trade secrets or trademarks) contained herein. Nebulas Tree reserves the right to vary the terms of the document and content in response to changes to the specifications or information made available to Nebulas Tree.

Nebulas Tree does not assume liability for any errors or omissions in the content of this document or any referenced or associated third party document, including, but not limited to, typographical errors, inaccuracies or outdated information.  This document and all information within it are provided on an "as is" basis without any warranties of any kind, express or implied.  Any communication required or permitted in terms of this document shall be valid and effective only if submitted in writing. Reliance of any information provided herein this document is solely at your own risk.