Variable Replacers
Variable replacers are used to replace custom strings during loading the configuration, e.g., they can be used to mask sensitive information such as usernames and passwords. Of course their usage is not limited to security related information.
Variable replacers implement the interface com.hazelcast.config.replacer.spi.ConfigReplacer
and they are configured only
declaratively: in the Hazelcast’s declarative configuration files, i.e.,
hazelcast.xml
, hazelcast.yaml
and hazelcast-client
.xml
, hazelcast-client.yaml
. See the ConfigReplacer
s
Javadoc
for basic information about how a replacer works.
Variable replacers are configured within the element <config-replacers>
under <hazelcast>
,
as shown below.
<hazelcast>
...
<config-replacers fail-if-value-missing="false">
<replacer class-name="com.acme.MyReplacer">
<properties>
<property name="propName">value</property>
...
</properties>
</replacer>
<replacer class-name="example.AnotherReplacer"/>
</config-replacers>
...
</hazelcast>
hazelcast:
...
config-replacers:
fail-if-value-missing: false
replacers:
- class-name: com.acme.MyReplacer
properties:
propName: value
...
- class-name: example.AnotherReplacer
...
As you can see, <config-replacers>
is the parent element for your replacers,
which are declared using the <replacer>
sub-elements. You can define multiple
replacers under the <config-replacers>.
Here are the descriptions of elements
and attributes used for the replacer configuration:
-
fail-if-value-missing
: Specifies whether the loading configuration process stops when a replacement value is missing. It is an optional attribute and its default value is true. -
class-name
: Full class name of the replacer. -
<properties>
: Contains names and values of the properties used to configure a replacer. Each property is defined using the<property>
sub-element. All of the properties are explained in the upcoming sections.
The following replacer classes are provided by Hazelcast as example implementations of
the ConfigReplacer
interface. Note that you can also implement your own replacers.
-
EncryptionReplacer
-
PropertyReplacer
There is also a ExecReplacer which runs an external command and uses its
standard output as the value for the variable. See its
code sample.
|
Each example replacer is explained in the below sections.
EncryptionReplacer
This example EncryptionReplacer
replaces encrypted variables by its plain
form. The secret key for encryption/decryption is generated from a password
which can be a value in a file and/or environment specific values, such as MAC
address and actual user data.
Its full class name is com.hazelcast.config.replacer.EncryptionReplacer
and
the replacer prefix is ENC
. The following are the properties used to
configure this example replacer:
-
cipherAlgorithm
: Cipher algorithm used for the encryption/decryption. Its default value is AES. -
keyLengthBits
: Length of the secret key to be generated in bits. Its default value is 128 bits. -
passwordFile
: Path to a file whose content should be used as a part of the encryption password. When the property is not provided no file is used as a part of the password. Its default value is null. -
passwordNetworkInterface
: Name of network interface whose MAC address should be used as a part of the encryption password. When the property is not provided no network interface property is used as a part of the password. Its default value is null. -
passwordUserProperties
: Specifies whether the current user properties (user.name
anduser.home
) should be used as a part of the encryption password. Its default value is true. -
saltLengthBytes
: Length of a random password salt in bytes. Its default value is 8 bytes. -
secretKeyAlgorithm
: Name of the secret-key algorithm to be associated with the generated secret key. Its default value is AES. -
secretKeyFactoryAlgorithm
: Algorithm used to generate a secret key from a password. Its default value is PBKDF2WithHmacSHA256. -
securityProvider
: Name of a Java Security Provider to be used for retrieving the configured secret key factory and the cipher. Its default value is null.
Older Java versions may not support all the algorithms used as defaults. Please use the property values supported your Java version. |
As a usage example, let’s create a password file and generate the encrypted string out of this file as instructed below:
-
Create the password file:
echo '/Za-uG3dDfpd,5.-' > /opt/master-password
-
Define the encrypted variables:
java -cp hazelcast-*.jar \ -DpasswordFile=/opt/master-password \ -DpasswordUserProperties=false \ com.hazelcast.config.replacer.EncryptionReplacer \ "aCluster" $ENC{Gw45stIlan0=:531:yVN9/xQpJ/Ww3EYkAPvHdA==}
-
Configure the replacer and put the encrypted variables into the configuration:
<hazelcast> <config-replacers> <replacer class-name="com.hazelcast.config.replacer.EncryptionReplacer"> <properties> <property name="passwordFile">/opt/master-password</property> <property name="passwordUserProperties">false</property> </properties> </replacer> </config-replacers> <cluster-name>$ENC{Gw45stIlan0=:531:yVN9/xQpJ/Ww3EYkAPvHdA==}</cluster-name> </hazelcast>
-
Check if the decryption works:
java -jar hazelcast-*.jar Apr 06, 2018 10:15:43 AM com.hazelcast.config.XmlConfigLocator INFO: Loading 'hazelcast.xml' from working directory. Apr 06, 2018 10:15:44 AM com.hazelcast.instance.AddressPicker INFO: [LOCAL] [aCluster] [3.10-SNAPSHOT] Prefer IPv4 stack is true.
As you can see in the logs, the correctly decrypted cluster name value ("aCluster") is used.
PropertyReplacer
The PropertyReplacer
replaces variables by properties with the given
name. Usually the system properties are used, e.g., ${user.name}
.
There is no need to define it in the declarative configuration files.
Its full class name is com.hazelcast.config.replacer.PropertyReplacer
and the replacer prefix is empty string ("").
Implementing Custom Replacers
You can also provide your own replacer implementations. All replacers
have to implement the interface com.hazelcast.config.replacer.spi.ConfigReplacer
.
A simple snippet is shown below.
public interface ConfigReplacer {
void init(Properties properties);
String getPrefix();
String getReplacement(String maskedValue);
}