Securing the LINSTOR Encryption Passphrase By Using systemd-creds and TPM 2.0

Before version 1.33.0, LINSTORⓇ did not have a method of entering the LINSTOR controller service master passphrase when the service was restarted unless it was stored in plain text within the .toml configuration file for the service, or stored in an environment variable. The LINSTOR controller service uses the LINSTOR master passphrase for the LINSTOR encypted disk feature. For security-conscious users, storing a sensitive encryption key in plain text on disk presents a risk.

With a feature added in LINSTOR version 1.33.0, LINSTOR users can use the systemd-creds utility to store a hashed version of the passphrase. By using this feature, the LINSTOR controller service can automatically unlock encrypted volumes on startup without exposing a plain text passphrase. This method requires either physical TPM 2.0 hardware or TPM 2.0 emulation for virtual machines. You can enter a systemd-analyze has-tpm2 (or systemd-creds has-tpm2 on older systemd versions) command to verify that your system supports TPM 2.0.

Method 1: Using a systemd service file

Use systemd-ask-password to collect the passphrase, then pipe it into systemd-creds to generate a host-specific encrypted credential:

systemd-ask-password -n | systemd-creds --name=linstor-masterpassphrase encrypt -p - -

Example output:

🔐 Password: •••••••
Credential secret file '/var/lib/systemd/credential.secret' is not located on encrypted media, using anyway.
SetCredentialEncrypted=linstor-masterpassphrase: \
        Whxqht+dQJax1aZeCGLxmiAAAAABAAAADAAAABAAAADJwSSiH4neI09LWpQAAAAA2Tx+P \
        1teV6QaDhlioJChA775cKFZzWNgHCXy8dvYvkcl/wWQgVej+1NvkZVL9pZIvNjNKgmVW9 \
        lmmvZsX4sm+oeBuHhKpZeoYQ==

❗ IMPORTANT: In a highly available LINSTOR controller service configuration, each system that could host the LINSTOR controller service must generate its own hashed passphrase. You cannot copy a credential from one host to another. The hash is unique per host.

Use the following command to edit the LINSTOR controller systemd unit override on each potential LINSTOR controller node:

systemctl edit linstor-controller.service

Copy the generated SetCredentialEncrypted=... string into the service override:

### Editing /etc/systemd/system/linstor-controller.service.d/override.conf
### Anything between here and the comment below will become the new contents of the file

[Service]
SetCredentialEncrypted=linstor-masterpassphrase: \
        Whxqht+dQJax1aZeCGLxmiAAAAABAAAADAAAABAAAADJwSSiH4neI09LWpQAAAAA2Tx+P \
        1teV6QaDhlioJChA775cKFZzWNgHCXy8dvYvkcl/wWQgVej+1NvkZVL9pZIvNjNKgmVW9 \
        lmmvZsX4sm+oeBuHhKpZeoYQ==

### Lines below this comment will be discarded
[...]

Restart the LINSTOR controller service to load the new masterpassphrase:

systemctl restart linstor-controller.service

You should now see a log message confirming that the LINSTOR controller service is using systemd-creds:

journalctl -u linstor-controller.service | grep masterpass

Example output:

Oct 14 17:52:36 linstor-ctrl-0 Controller[3371]: 2025-09-17 17:52:36.335 [Main] INFO  LINSTOR/Controller/ffffff SYSTEM - Using masterpassphrase provided by systemd-creds

Alternatively, you can verify that the LINSTOR controller service is unlocked using the LINSTOR REST API:

curl -X GET http://127.0.0.1:3370/v1/encryption/passphrase

Expected response from the API:

{"status":"unlocked"}

If the passphrase is not loaded, the status will show as unset or locked.

Method 2: Starting without a service file

For advanced use cases where the LINSTOR controller service is not managed by a systemd unit, you can still use systemd-creds to create an encrypted credential and pass it to the LINSTOR controller service manually.

The following command creates a file named ciphertext.cred in your working directory containing the hashed passphrase:

systemd-ask-password -n | systemd-creds --name=linstor-masterpassphrase encrypt - ciphertext.cred

The resulting ciphertext.cred file containing the hashed passphrase will look similar to this:

cat ciphertext.cred
Whxqht+dQJax1aZeCGLxmiAAAAABAAAADAAAABAAAACgSALHCD7qGvD9AK4AAAAAg5EUvX6ohi6BJSV
uaC56a57qFAHvbTYlZBWvuUj23GKFidELIacN//2Kz5zRNknV9vGQ/fmTdUdoIMtWAWnhICT41+gRWK
I=

You can then start the LINSTOR controller service manually by using systemd-run, loading the credentials as part of the process:

systemd-run --wait --pty --unit=$UNIT_NAME --working-directory=${WORKING_DIR} --send-sighup \
   -p LoadCredentialEncrypted=linstor-masterpassphrase:/root/ciphertext.cred \
   /usr/bin/java -Xms256M -Xmx8G -XX:+CrashOnOutOfMemoryError \
   -classpath "/usr/share/linstor-server/lib/conf:/usr/share/linstor-server/lib/*" com.linbit.linstor.core.Controller \
   --logs=/var/log/linstor-controller --config-directory=/etc/linstor

In the startup logs, there should be a line similar to the following confirming the LINSTOR controller service is using the systemd-creds:

2025-10-14 17:35:40.758 [Thread-2] INFO  LINSTOR/Controller/ffffff SYSTEM - Using masterpassphrase provided by systemd-creds

Alternatively, you can verify the unlocked state with the same API call used in method 1:

curl -X GET http://127.0.0.1:3370/v1/encryption/passphrase

Conclusion

By using systemd-creds to store the LINSTOR controller service master passphrase, administrators can improve their security posture by avoiding plain text storage of sensitive credentials. Whether used via a systemd service file or passed at runtime, this method ensures that passphrases are not only hashed, but are TPM-bound and host-specific, reducing the attack surface significantly.

Again, to highlight the importance of the fact, each host in a highly available LINSTOR controller service setup must generate its own hashed passphrase, because credentials cannot be shared across different systems.

Picture of Matt Kereczman

Matt Kereczman

Matt Kereczman is a Solutions Architect at LINBIT with a long history of Linux System Administration and Linux System Engineering. Matt is a cornerstone in LINBIT's technical team, and plays an important role in making LINBIT and LINBIT's customer's solutions great. Matt was President of the GNU/Linux Club at Northampton Area Community College prior to graduating with Honors from Pennsylvania College of Technology with a BS in Information Security. Open Source Software and Hardware are at the core of most of Matt's hobbies.

Talk to us

LINBIT is committed to protecting and respecting your privacy, and we’ll only use your personal information to administer your account and to provide the products and services you requested from us. From time to time, we would like to contact you about our products and services, as well as other content that may be of interest to you. If you consent to us contacting you for this purpose, please tick above to say how you would like us to contact you.

You can unsubscribe from these communications at any time. For more information on how to unsubscribe, our privacy practices, and how we are committed to protecting and respecting your privacy, please review our Privacy Policy.

By clicking submit below, you consent to allow LINBIT to store and process the personal information submitted above to provide you the content requested.

Talk to us

LINBIT is committed to protecting and respecting your privacy, and we’ll only use your personal information to administer your account and to provide the products and services you requested from us. From time to time, we would like to contact you about our products and services, as well as other content that may be of interest to you. If you consent to us contacting you for this purpose, please tick above to say how you would like us to contact you.

You can unsubscribe from these communications at any time. For more information on how to unsubscribe, our privacy practices, and how we are committed to protecting and respecting your privacy, please review our Privacy Policy.

By clicking submit below, you consent to allow LINBIT to store and process the personal information submitted above to provide you the content requested.