I have created a web service that requires a password to decipher its config data. The password could not be stored as raw data anywhere on the disk (very strict bureaucratic requirements from the customer). Therefore I went for a solution similar to Nginx that asks for the private key password upon startup.
In general, it works fine - my systemd unit asks for the password on startup and starts the service, passing the password through systemd environment variable.
However, the problem is in cases when the service decides to restart itself (due to a crash or just to reset its internal accumulated memory to clean up from possible memory leaks). In this case, a message pops up for currently logged in user:
Code:
Broadcast message from root@my_ubuntu (Mon 2020-08-31 19:05:54 EEST):
Password entry required for 'Please enter encryption password' (PID 1339).
Please enter password with the systemd-tty-ask-password-agent tool!
It works with systemd-tty-ask-password-agent tool. But it can get inconvenient to enter the password on automatic restarts and I would like to avoid it, if possible.
Is there any way to tell systemd to somehow reuse the old password in cases when systemd itself attempts to restart the service?
I have seen some keyring and cache options for systemd-ask-password but they are too short-lived.
I would like the service to ask for the password only when the admin manually restarts/stops&starts the service or the server itself is restarted and not in those cases when systemd itself attempts to keep the service alive because of Restart settings.
Another doubt is that I could not find any better mechanism for passing the password down to my process, other than to use environment variables. I've read that it's not good to store secret values in env vars because they can be extracted easily, so I ensured that I clean them up as soon as possible using Post
commands in my unit file.
If you know any more secure way to pass the entered password to the underlying process, then please let me know.
The systemd unit file script follows:
Code:
[Unit]
Description=ask-pass-test
[Service]
WorkingDirectory=/var/www/exper
# Starts with plus sign as a workaround for missing permissions to call systemd-ask-password for non-root users
ExecStartPre=+/bin/sh -c 'systemctl set-environment srvc_enckey=`systemd-ask-password --timeout=0 "Please enter encryption password"`'
# A debug command, will be removed later - dumping current variables to see if the entered password was set
ExecStartPre=+/bin/sh -c 'set > /var/www/exper/set-results1.txt'
# The service itself that needs to access srvc_enckey upon every start and restart without storing it as plain text
ExecStart=/bin/sh -c '/var/www/exper/ask-pass-test.sh'
# Attempt to remove the environment variable on both successful start and also on stop and failed start, because it's unsafe to store secrets in the environment
ExecStartPost=+/bin/sh -c 'systemctl unset-environment srvc_enckey'
ExecStopPost=+/bin/sh -c 'systemctl unset-environment srvc_enckey'
# A debug command, will be removed later - dumping current variables after normal start to test if the entered password was indeed removed
ExecStartPost=+/bin/sh -c 'set > /var/www/exper/set-results2.txt'
# Restart service after 10 seconds if it crashes
Restart=always
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=ask-pass-test
User=www-data
[Install]
WantedBy=multi-user.target