有没有将密码传递到Systemd Unit文件的典型方法?


10

我想使用systemd单位文件启动服务。此服务需要密码才能启动。我不想将密码以明文形式存储在systemd单元文件中,因为它是世界可读的。我也不想以交互方式提供此密码。

如果要为此编写普通脚本,则将凭据存储在具有受限权限(400或600)的root拥有的文件中,然后将其作为脚本的一部分读取。是否有任何特定的systemd风格的方法可以执行此操作,还是应该遵循与常规Shell脚本中相同的过程?


Answers:


11

根据您的要求,这里有两种可能的方法。如果你不做要被提示输入密码时,该服务被激活时,使用的EnvironmentFile指令。来自man systemd.exec

类似于Environment =,但是从文本文件读取环境变量。文本文件应包含以换行符分隔的变量分配。

如果确实要提示您,则可以使用其中一个systemd-ask-password指令。来自man systemd-ask-password

使用命令行上指定的问题消息,systemd-ask-password可用于从用户查询系统密码或密码短语。从TTY运行时,它将查询TTY上的密码并将其打印到标准输出。在不使用TTY或--no-tty的情况下运行时,它将使用系统范围的查询机制,该机制允许活动用户通过多个代理进行响应


2
请注意,在环境变量中传递密码是有缺点的(即使设置了变量的文件受到保护),因为通常可以窥探属于其他用户的进程的环境变量(例如使用ps ajxewww),因此有人可以从那里捡起来。
filbranden

谢谢!EnvironmentFile具有具有400个权限的文件的绝对路径的条目效果很好。
levibostian

@filbranden您无法读取属于其他用户的进程的环境变量。
woky

2

还有第三种选择,以及@jasonwryan的2条建议。

摘自ServerFault的Michael Hampton的答案- 如何在systemd服务中设置环境变量?

当前要做到这一点最好的方法是运行systemctl edit myservice,它会为你创建一个覆盖文件或让您编辑现有的一个。

在正常安装中,这将创建一个目录/etc/systemd/system/myservice.service.d,并在该目录内创建一个文件名.conf(通常为override.conf)结尾的文件,您可以在该文件中添加或覆盖发行版随附的设备的任何部分。

例如,在一个文件中/etc/systemd/system/myservice.service.d/myenv.conf

[Service]
Environment="SECRET=pGNqduRFkB4K9C2vijOmUDa2kPtUhArN"
Environment="ANOTHER_SECRET=JP8YLOc2bsNlrGuD6LVTq7L36obpjzxd"

另请注意,如果目录存在且为空,则将禁用您的服务!如果您不打算在目录中放置某些内容,请确保该内容不存在。


1

我可以提供其他适合您需求的替代方案,但需要满足一些先决条件:

后续步骤如下:

使用secret-toolfrom libsecret来存储您的密码。例如:

$ secret-tool store --label=myProgram myService password
Password: <type it here>

如果您的可执行文件支持从环境变量读取密码,则最好:

[Service]
ExecStart=/usr/bin/sh -c 'env SECRET=$(secret-tool lookup myService password) /usr/bin/script'

如果您的可执行文件接受密码作为参数,您仍然可以secret-tool像这样使用:

[Service]
ExecStart=/usr/bin/sh -c '/usr/bin/script --secret=$(secret-tool lookup myService password)'

注意:运行密码时,该密码将清晰可见,systemctl --user status myUnit.service因为该密码将参数显示为在命令行上运行。这意味着这对于运行top或的用户也将是可见的ps -aux

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.