Obfuscating Passwords in tc Runtime Configuration Files

SpringSource tc Runtime stores its configuration files in the CATALINA_BASE/conf directory; these files include server.xml, context.xml, web.xml, and jmxremote.password. By default, passwords in these files are in cleartext. This is typically not a problem during development; however, when you move to production, you will probably want to protect these passwords for security reasons so that the actual password string does not show up in the configuration files.

Passwords appear in these configuration files in a variety of places. For example, as described in Configuring the High Concurrency JDBC Connection Pool, you use the <Resource> element of the server.xml file to configure a JDBC connection pool, and the element's password attribute specifies the password of the user who connects to the database server, as shown in the following sample snippet of the server.xml file (only relevant parts shown):

<?xml version='1.0' encoding='utf-8'?>
<Server port="-1" shutdown="SHUTDOWN">

 ...

  <GlobalNamingResources>

  <Resource name="jdbc/TestDB"
            auth="Container"
            type="javax.sql.DataSource"
            username="root"
            password="mypassword"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/mysql?autoReconnect=true"
	    ...
  </GlobalNamingResources>
  ...
  <Service name="Catalina">
  ...
  </Service>
</Server>

Another example is the jmxremote.password file that contains the password for the JMX username/role that HQ uses to connect to the JMX server associated with the tc Runtime instance. By default, the password is in cleartext. The following example shows the out-of-the-box file in which the admin role has the password springsource:

# The "admin" role has password "springsource".
admin springsource

The remainder of this section describes how to protect the password text in any of the following tc Runtime configuration files located in the CATALINA_BASE/conf directory:

The section is divided into four topics. The first topic provides the basic obfuscation procedure, and the next three topics provide additional security. All four topics use the <Resource> element of the server.xml as an example. Apply the same procedure to protect passwords in any of the other configuration files, except where noted.

Note: This section does not apply to the tomcat-users.xml file. In this file, you should hash the password using MD5 or SHA1 to prevent it from being disclosed.

Using Base64 Encoding to Obfuscate Passwords

The following procedure describes the standard way to obfuscate passwords in the configuration files using base64 encoding. Base64 encoding is a scheme that encodes binary data by treating it numerically and translating it into a base 64 representation.

  1. Open a terminal command window and change to the INSTALL_DIR/vfabric-tc-server-edition directory, where INSTALL_DIR refers to the directory in which you installed tc Runtime and edition refers to your tc Server edition, such as developer or standard. For example:

    prompt$ cd /opt/vmware/vfabric-tc-server-standard
  2. Run the following java command on Unix; substitute version with the version of tc Runtime you are using, such as 6.0.32.A-RELEASE and substitute password with the actual password text you want to obfuscate:

    prompt$ java -cp \
       tomcat-version/lib/tcServer.jar:tomcat-version/bin/tomcat-juli.jar:tomcat-version/lib/tomcat-coyote.jar \
       com.springsource.tcserver.security.PropertyDecoder -encode base64 password
    

    In a Windows command prompt, the syntax is slightly different in that you use back-slashes instead of forward-slashes and semi-colons instead of colons:

    prompt> java -cp \
       tomcat-version\lib\tcServer.jar;tomcat-version\bin\tomcat-juli.jar;\
       tomcat-version\lib\tomcat-coyote.jar \
       com.springsource.tcserver.security.PropertyDecoder -encode base64 password
    

    For example, if you are using version 6.0.32.A-RELEASE of tc Runtime and want to obfuscate the password mypassword, run the following command on Unix:

    prompt$ java -cp \
       tomcat-6.0.32.A-RELEASE/lib/tcServer.jar:tomcat-6.0.32.A-RELEASE/bin/tomcat-juli.jar:\
       tomcat-6.0.32.A-RELEASE/lib/tomcat-coyote.jar \
       com.springsource.tcserver.security.PropertyDecoder -encode base64 mypassword

    On Windows:

    prompt> java -cp \
       tomcat-6.0.32.A-RELEASE\lib\tcServer.jar;tomcat-6.0.32.A-RELEASE\bin\tomcat-juli.jar;\
       tomcat-6.0.32.A-RELEASE\lib\tomcat-coyote.jar \
       com.springsource.tcserver.security.PropertyDecoder -encode base64 mypassword

    The preceding commands are shown on multiple lines, but you should run the command on a single line.

    The preceding java command outputs the encoded password; it will look something like bXlwYXNzd29yZA==.

  3. Edit the relevant configuration file (server.xml in our example) and substitute the cleartext password with a variable; use the form ${variable_name}. The following example shows how to substitute the password of the <Resource> element with the variable ${db.password}:

    <Resource name="jdbc/TestDB"
               auth="Container"
               type="javax.sql.DataSource"
               username="root"
               password="${db.password}"
               driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/mysql?autoReconnect=true"
               ...

    Important: Variable replacement as described in the preceding example is supported only in the XML files, specifically server.xml, global and application context.xml files, and global and application web.xml files. This means you cannot use variable replacement in the jmxremote.password file. For this file, you directly replace the cleartext password with the encoded password. For example:

    # The "admin" role 
    admin s2enc://c3ByaW5nc291cmNl
  4. Edit the catalina.properties file (in the case of obfuscating passwords in XML files) and add the following properties:

    org.apache.tomcat.util.digester.PROPERTY_SOURCE=com.springsource.tcserver.security.PropertyDecoder
    com.springsource.tcserver.security.PropertyDecoder.passphrase=base64
    db.password=s2enc://bXlwYXNzd29yZA==

    The first two properties specify how tc Runtime should decode the encoded password; the third property (db.password) is the variable you substituted in the server.xml file. The value of this property is the encoded password you generated from a previous step, preceded by the required text s2enc://.

    Note

    When obfuscating passwords in tc Runtime configuration files, always precede the encoded text with the hard-coded string s2enc://.

  5. Restart tc Runtime for the changes to take effect.

Using a Passphrase to Encrypt Passwords

Strengthen password protection by specifying your own passphrase when encrypting the password, rather than using base64. The steps for using passphrase encryption are similar to using base64 encoding but with the following changes:

  • When generating the encrypted password, specify your own passphrase rather than the text base64. The following Unix example uses the passphrase mypassphrase; you can substitute any phrase you want:

    prompt$ java -cp \
       tomcat-6.0.32.A-RELEASE/lib/tcServer.jar:tomcat-6.0.32.A-RELEASE/bin/tomcat-juli.jar:\
       tomcat-6.0.32.A-RELEASE/lib/tomcat-coyote.jar \
       com.springsource.tcserver.security.PropertyDecoder -encode mypassphrase mypassword

    On Windows:

    prompt> java -cp \
       tomcat-6.0.32.A-RELEASE\lib\tcServer.jar;tomcat-6.0.32.A-RELEASE\bin\tomcat-juli.jar;\
       tomcat-6.0.32.A-RELEASE\lib\tomcat-coyote.jar \
       com.springsource.tcserver.security.PropertyDecoder -encode mypassphrase mypassword

    The command is shown on multiple lines, but you should run the command on a single line.

    The preceding java command outputs the encrypted password using passphrase encryption; it will look something like koBC0uF1N200plwJgBfeQg==.

  • When you edit the catalina.properties file and add the properties, specify your passphrase instead of base64 for the com.springsource.tcserver.security.PropertyDecoder.passphrase property and set your variable to the new encrypted password:

    org.apache.tomcat.util.digester.PROPERTY_SOURCE=com.springsource.tcserver.security.PropertyDecoder
    com.springsource.tcserver.security.PropertyDecoder.passphrase=mypassphrase
    db.password=s2enc://koBC0uF1N200plwJgBfeQg==

In the preceding example, the string mypassphrase in the catalina.properties file is in cleartext. However, this still offers a degree of protection because the seed used for encryption is not readily available; it is available only to the tc Runtime instance. If, however, you do not want the catalina.properties file to include the passphrase, or even include the encrypted password itself, you can store them in separate files and simply point to them from catalina.properties, as described in the next section.

Storing Passphrases and Encrypted Properties in Separate Files

Although storing the passphrase (when using passphrase encryption) and encrypted passwords in the catalina.properties is reasonably secure, some users might prefer to store these values in separate files.

To store the passphrase in a separate file, replace the value of the com.springsource.tcserver.security.PropertyDecoder.passphrase property with the name of a file. You can use the ${catalina.base} variable to specify a directory relative to the CATALINA_BASE of the tc Runtime instance.

In the following sample snippet of catalina.properties, the passphrase is stored in a file called secure.file in the CATALINA_BASE/conf directory of the tc Runtime instance:

org.apache.tomcat.util.digester.PROPERTY_SOURCE=com.springsource.tcserver.security.PropertyDecoder
com.springsource.tcserver.security.PropertyDecoder.passphrase=${catalina.base}/conf/secure.file
db.password=s2enc://koBC0uF1N200plwJgBfeQg==

Create the secure.file file: it should contain a single line with the passphrase. For example:

mypassphrase

Similarly, to store the actual encrypted password in a separate file, replace the password variable (db.password in our example) in the catalina.properties file with a property called com.springsource.tcserver.security.PropertyDecoder.properties. Set this property to the name of a file that contains the password variable.

In the following sample snippet of catalina.properties, the encrypted password is stored in a file called application.properties in the CATALINA_BASE/conf directory of the tc Runtime instance:

org.apache.tomcat.util.digester.PROPERTY_SOURCE=com.springsource.tcserver.security.PropertyDecoder
com.springsource.tcserver.security.PropertyDecoder.passphrase=${catalina.base}/conf/secure.file
com.springsource.tcserver.security.PropertyDecoder.properties=${catalina.base}/conf/application.properties

Create the application.properties file and add the original password variable. Following with our example, the file would include the following:

db.password=s2enc://koBC0uF1N200plwJgBfeQg==

Being Prompted for the Passphrase When you Start the Instance

Storing the passphrase and encrypted passwords in operating system files when using passphrase encryption is reasonably secure. However, some users may want to be prompted for the passphrase so that it does not appear in cleartext in any file at all. This section describes how to do this. The section builds on the information in Using a Passphrase to Encrypt Passwords, so it is assumed that you have already read that section and that you have generated the encrypted password based on a passphrase of your choice.

Warning: This feature requires that you start the tc Runtime instance as a foreground process using the run option of tcruntime-ctl.sh|bat on both Unix and Windows. On Unix, you can then put the process in the background. On Windows, however, this means that you cannot control the instance using the Windows Services console. For this reason, this feature is not practical for production use on Windows.

To be prompted for the passphrase when you start the tc Runtime instance, update the catalina.properties file and set the com.springsource.tcserver.security.PropertyDecoder.passphrase property to the value console. For example:

org.apache.tomcat.util.digester.PROPERTY_SOURCE=com.springsource.tcserver.security.PropertyDecoder
com.springsource.tcserver.security.PropertyDecoder.passphrase=console
db.password=s2enc://koBC0uF1N200plwJgBfeQg==

Subsequently, you must start the tc Runtime instance as a foreground process using the run option of tcruntime-ctl.sh|bat. For example, on Unix:

prompt$ cd /opt/vmware/vfabric-tc-server-standard
prompt$ ./tcruntime-ctl.sh myserver run

After the usual startup information, the script asks you for the passphrase. After entering it, the tc Runtime instance starts as usual.

On Unix, if you want to now put the tc Runtime instance process in the background, first suspend the process by using control-Z, and then enter bg at the Unix prompt to put the suspended process in the background.

General Security Best Practices

The preceding sections provide specific information about obfuscating and encrypting passwords in tc Runtime configuration files using a variety of methods. This section provides general best practices for securing your tc Runtime instances.

For additional security, SpringSource recommends that:

  • On the computer on which you you have installed tc Server, create an operating system user whose only purpose is to run the tc Runtime process. In other words, this user would be the only user who starts/stops the tc Runtime instance, and this user would do nothing else but start/stop the tc Runtime process.

  • Make it impossible for anyone to log on to the computer directly as this dedicated tc Server user.

  • Set the permissions for all tc Runtime configuration files so that they are readable only by this dedicated tc Server user.

If you set up the preceding scenario, the only users who will be able read the passwords in the tc Runtime configuration files (whether they are in cleartext, are obfuscated, or encrypted) are users with root privileges.

To implement this scenario on Windows, you can use the install run-as-user option of tcruntime-ctl.bat to install the tc Runtime instance as a Windows service and specify that it should run as the dedicated tc Server user. See "tcruntime-ctl Command Reference" in Getting Started with vFabric tc Server for details.

On Unix, you can use the boot.rc.template script to customize your Unix boot process so that the tc Runtime instance starts automatically when your computer starts. Use the TOMCAT_USER variable in the script to specify the dedicated tc Server user that you want the tc Runtime instance to run as. You then use the boot script the same way you use any other Unix boot script on your computer. For example, you might copy it to the /etc/init.d directory, giving it a unique name such as my-tc-runtime-instance. Then you would link this script from /etc/rc*.d as appropriate, depending on when you want the tc Runtime instance to start during the Unix boot sequence.

Alternatively, if you do not want the tc Runtime instance to start automatically when the Unix computer boots, you can run the my-tc-runtime-instance file in the /etc/init.d directory as the root user, rather than start the tc Runtime process using the tcruntime-ctl.sh script.

For more information about the boot.rc.template script, see "Unix: Starting tc Runtime Instances Automatically at System Boot Time" in Getting Started with vFabric tc Server.