Server configuration security hardening

Operating system intrusions occur when unauthorized users log in to the operating system and gain access to sensitive resources. Employ best practices with Open Liberty to harden your server configuration and Docker images against potential operating system attacks.

Basic best practices

The following list of best practices outlines basic guidelines to harden your server configuration and ensure that it is fit for production. These best practices also apply to hardening Open Liberty Docker images if you’re working with containers:

  • Make the Open Liberty server configuration file system, which is the path where the WLP_USER_DIR environment variable points, writable only to authorized server administrators.

  • Confirm that the Open Liberty server identity doesn’t own the directory where the server configuration is stored and has only read access to it. Set the WLP_OUTPUT_DIR environment variable to point to the server logs with the same server identity as the owner of this directory.

  • Ensure that any sensitive information in the server.xml file is AES-encrypted.

  • Disable all non-TLS ports by setting ports to the value of -1 in the httpPort argument of the httpEndpoint stanza.

  • Use Transport Layer Security (TLS) instead of SSL.

  • Add the webAppSecurity ssoRequiresSSL="true" statement to the server.xml file.

  • Add the webAppSecurity httpOnlyCookies="true" statement to the server.xml file.

  • Add the httpOptions removeServerHeader="true" statement to the server.xml file.

  • Add the webContainer disableXPoweredBy="true" statement to the server.xml file.

Open Liberty Docker images

A container that runs in production must have only the tools and packages that you need to run your application. Before you run a container in production, harden the container image to remove any potential vulnerabilities that might allow exploitation of your server configuration or installation.

The simplest way to securely run Open Liberty is to start with an existing Open Liberty Docker image, which is already set up with basic security protocols. Then, if you intend to use an Open Liberty Docker image in production, harden it by following the best practices in this topic. You can find Open Liberty Docker images and related information in Docker Hub.

If you extend an Open Liberty image for use in production, opt for the leanest possible configuration by adding only tools and packages that are essential to your application. Using a minimal image reduces the number of operating system vulnerabilities that you bundle with your application.

Latest Open Liberty versions and Docker images

Keep your version of Open Liberty up to date. The zero migration policy of Open Liberty means that you can move to a later version without changing anything in your server configuration. Staying on the latest version also ensures that you get the latest security fixes because updates are first released in the current version. After security fixes are released for the current version of Open Liberty, they are rolled back to older releases. Container images in Docker Hub are updated every time a new version of Open Liberty is released. Use the most recent images from Docker Hub for the containers that you run in production.

Installation validation

You can validate your Open Liberty server installation by running the /<wlp_install_dir/bin/productInfo validate command. This command uses an MD5 checksum to check your installation for errors or potential vulnerabilities. The output message that you receive indicates whether the Open Liberty installation was validated successfully.

UNIX file permissions

A critical aspect of server security is ensuring that files and directories have the appropriate permissions, and users and groups are configured properly. All UNIX files have the following attributes: owner, group, and other. For each of these attributes, 3 bits are assigned as an octal digit. The first bit indicates read access. The second bit indicates write access. The third bit indicates execute access. For example, a 7 represents that all 3 bits are on for an attribute, which indicates read, write, and execute access. A file with 770 permissions indicates that the file owner and any user in the group have read, write, and execute access, but all others have no permissions.

Generally, the last digit in the file permissions ends in 0 so that others don’t have access to protected information. By default, Open Liberty Docker images run with USER 1001, a non-root user, as part of group 0. This setting ensures that these images don’t run as root by default.

When you configure file permissions, ensure that users who require access to the server configuration have no more than the required capability. For instance, a database administrator has access to only the data source configuration that is referenced in the server.xml file with an include statement. Attach only administrative users to the group that has write access to the server configuration files. Users that aren’t administrators or developers with specialized access, for example, users who need to view application or server logs, fall into the other group for server configuration files.

Access control

It is critical to control users' access levels so that users have the appropriate access to Open Liberty files. Non-administrative users require minimal access, based on their needs. Different types of users might need to access the configuration or logs. These users might include administrators, developers, or database support personnel. The following points provide guidance on controlling users' access:

  • The ID that the Open Liberty server uses to run: This ID needs to read its configuration and write to logs. However, when hardening a server, this ID must be configured only with read access to its own configuration files. This ID can also own files, or it can be a separate ID from the file owner.

  • Users who are responsible for administering the server: These users likely require read and write access to the server configuration files. A best practice is to not share login IDs or passwords among administrators. Instead, set up the server configuration file system owner with a dedicated ID, and permit administrators to use sudo authority to update the configuration by switching to the dedicated ID.

  • Users who are involved in server-related activities: Some of these users need read access to view the logs, while other users might need limited write access to update parts of the configuration.

  • Unauthorized users: These users are treated as part of the other group, so they don’t have access to the configuration or product file systems.

  • User registries that are safe for production: Basic and Quick Start Security user registries are useful for development environments, but they are not acceptable for readiness testing, quality assurance, or production use. For production, use an LDAP user registry, federated registries, or create a custom user registry.

    If you use an LDAP user registry, maintain your bind password in a separate include file, not in the server.xml file. If you use a custom user registry, use the UserRegistry class to implement the registry, and make sure that the registry is thoroughly reviewed before you use it in production. For more information about user registries, see User registries for application security.

  • Single-sign on: Rather than directly accessing user registries from Open Liberty, use single-sign on (SSO) technologies, such as SAML, JWT, or OpenID Connect. SSO provides better security and regulatory compliance. If you use SSO, maintain your SSO configuration in a separate include file, not in the server.xml file. For more information about SSO, see Single sign-on.

Include file processing

Include files can hold portions of the configuration outside of the server.xml file. These files are helpful in two situations:

  • When sensitive information needs to be available for select users or groups, for example, database administrators, but not the larger group with read access to the server configuration.

  • When a user needs to update only a portion of the server configuration. In this situation, ensure that a user can’t override the configuration in the server.xml file by using the onConflict attribute in the include element:

    <include location="myIncludeFile.xml" onConflict="IGNORE" />

    In this example, Open Liberty ignores XML elements in the myIncludeFile.xml file that are also found in the server.xml file.

Automated updates

Configuration updates must be carefully controlled in production environments to reduce the possibility that unknown changes or vulnerabilities are deployed to users. You can disable automated configuration updates so that your production environment isn’t changed unless you manually update it.

By default, each server contains a monitored application directory that’s named /dropins. When an application is placed in this directory, the server automatically deploys and starts the application. If you update the configuration in the server.xml file or the /dropins directory, the server automatically deploys the configuration changes.

Each server also contains a monitored directory that’s named /dropins/configDropins for configuration snippets. If you update the configuration in this directory, the server automatically deploys the configuration changes.

To ensure that you deploy only explicitly pre-configured applications where their configuration is in the server.xml file, disable monitoring of the /dropins directory:

<applicationMonitor updateTrigger="mbean" dropinsEnabled="false" />

You can also disable automatic configuration updates in the server.xml file by using the following configuration statement:

<config updateTrigger="mbean" />

Password encryption

Use AES encryption for passwords instead of Base64 encoding. You can use the securityUtility encode command with Open Liberty for plain text obfuscation. AES encryption is also preferable to XOR encryption because an XOR-encoded password is visible to any administrator.

With AES encryption, the default encryption key that is used for decryption can be overridden by setting the wlp.password.encryption.key property. This property must not be set in the server.xml file, but in a separate configuration file that is included by the server.xml file. This separate configuration file must contain only a single property declaration, and must be stored outside the normal configuration directory for the server.