Systemd 장치 파일에 암호를 전달하는 일반적인 방법이 있습니까?

Systemd 장치 파일에 암호를 전달하는 일반적인 방법이 있습니까?

systemd 단위 파일을 사용하여 서비스를 시작하고 싶습니다. 서비스를 시작하려면 비밀번호가 필요합니다. 누구나 읽을 수 있으므로 시스템 장치 파일에 암호를 일반 텍스트로 저장하고 싶지 않습니다. 또한 이 비밀번호를 대화형으로 제공하고 싶지 않습니다.

이에 대한 일반 스크립트를 작성하는 경우 제한된 권한(400 또는 600)을 가진 루트 소유의 파일에 자격 증명을 저장한 다음 해당 파일을 스크립트의 일부로 읽습니다. 이를 수행하는 특정 시스템 스타일 방법이 있습니까? 아니면 일반 쉘 스크립트와 동일한 프로세스를 따라야 합니까?

답변1

요구 사항에 따라 두 가지 가능한 접근 방식이 있습니다. 만약 너라면원하지 않는다서비스를 활성화할 때 비밀번호를 묻는 메시지를 표시하려면 이 EnvironmentFile명령을 사용하십시오. 에서 man systemd.exec:

Environment=와 유사하지만 텍스트 파일에서 환경 변수를 읽습니다. 텍스트 파일에는 줄 바꿈으로 구분된 변수 할당이 포함되어야 합니다.

만약 너라면하다메시지를 표시하려면 systemd-ask-password다음 명령 중 하나를 사용할 수 있습니다. 에서 man systemd-ask-password:

systemd-ask-password는 명령줄에 지정된 질문 메시지를 사용하여 사용자의 시스템 비밀번호 또는 비밀번호를 쿼리하는 데 사용할 수 있습니다. TTY에서 실행되면 TTY에 비밀번호를 쿼리하고 이를 표준 출력으로 인쇄합니다. TTY 없이 또는 --no-tty를 사용하여 실행하면 활성 사용자가 여러 프록시를 통해 응답할 수 있도록 하는 시스템 전체 쿼리 메커니즘을 사용합니다.

답변2

systemd 매뉴얼(systemd.exec 등)에 따르면 자격 증명 관리를 위해 일반 환경 변수를 사용해서는 안 됩니다. Systemd에는 LoadCredential, LoadCredentialEncrypted, SetCredential, SetCredentialEncrypted와 같은 옵션을 설명하는 완전한 매뉴얼 페이지가 있습니다. 바라보다https://systemd.io/CREDENTIALS/systemd에서 이 작업을 수행하는 올바른 방법에 대한 전체 설명은 systemd.exec 매뉴얼 페이지를 참조하세요.

환경 변수를 사용한다는 것은 자격 증명이 필요하지 않은 프로세스가 여전히 이러한 변수를 상속하거나 액세스할 수 있다는 것을 의미하며 잠재적으로 비밀이 실수로 공개될 수 있습니다. Bitwarden CLI와 systemd 서비스를 통합하고 다음 설명에 따라 SetCredentialEncrypted를 사용하고 싶습니다.https://systemd.io/CREDENTIALS/. 몇 가지 조정 후( bwHOME 환경 변수 설정 예상) 내 Bitwarden 마스터 비밀번호는 디스크에 저장되어 암호화되며 내 서비스 부서만 액세스하여 내 Bitwarden 계정을 잠금 해제할 수 있습니다.

그게 내가하는 일이야. 먼저 일반 파일에 Bitwarden 마스터 비밀번호를 적어두었습니다./tmp/bwmaster.pass. 돌이켜보면 Btrfs보다는 램디스크에 쓰는 것이 더 나았을 것입니다. 아마도 옵션일 것입니다./달리기/(이 모든 명령에는 루트 액세스가 필요합니다). 다음으로 마스터 비밀번호의 암호화된 복사본을 만들었습니다.

# systemd-creds encrypt --pretty --name=bwmp /tmp/bwmaster.pass -

이렇게 하면 시스템 서비스 단위 파일의 [Service] 섹션에 직접 또는 재정의로 추가할 수 있는 SetCredentialEncrypted=bwmp 개요가 인쇄됩니다. 이것은 내 결과입니다.

SetCredentialEncrypted=bwmp: \
        k6iUCUh0RJCQyvL8k8q1UyAAAAABAAAADAAAABAAAADCNQBSGbmpFUpRgngAAAAAgAAAA \
        AAAAAALACMA0AAAACAAAAAAfgAgCE+qUDoEpxT3155oWkncltAG6Wv+IQAEm7EwIhahpw \
        gAEB8dLosK741kyXWOWXQwLRfvhx6vDf7Na6JNGNW3PQkF6TZmJsUNYsWGXLgyIbgtjkd \
        0TkS0LfVOo/e6PQ32p/xfEj0b+ZGCXgtjC0Tx6sDedhU0fIfT2b+IlwBOAAgACwAAABIA \
        ID8H3RbsT7rIBH02CIgm/Gv1ukSXO3DMHmVQkDG0wEciABAAINgs66YvSM+PW+qPTnGE/ \
        8Yq67HHaX5XMmymUojmugUkPwfdFuxPusgEfTYIiCb8a/W6RJc7cMweZVCQMbTARyIAAA \
        AAWUZXjxS/vfx0BJq8RQAAyeXdSsf7ccsz+yEcMvoUm4WYZupWzt1FW93FDsUpdyi+QID \
        pqczUQ24ODMC+HP9vP7nvLHPF4uNk+iPkR5fF7Ypl5rHdcFyfm1Bqp70g

서비스 단위 파일에 저장한 후 임시 일반 텍스트 파일을 안전하게 삭제했습니다.

# shred -uz /tmp/bwmaster.pass

man shred이에 대한 자세한 내용은 참조하세요. 이 작업을 수행할 때 Bitwarden을 사용하여 Borg 암호화된 백업 자격 증명을 저장합니다. 다음 서비스 파일을 작성했습니다.

[Unit]
Wants=network.target
After=network-online.target
[Service]
Type=oneshot
SetCredentialEncrypted=bwmp: \
        k6iUCUh0RJCQyvL8k8q1UyAAAAABAAAADAAAABAAAADCNQBSGbmpFUpRgngAAAAAgAAAA \
        AAAAAALACMA0AAAACAAAAAAfgAgCE+qUDoEpxT3155oWkncltAG6Wv+IQAEm7EwIhahpw \
        gAEB8dLosK741kyXWOWXQwLRfvhx6vDf7Na6JNGNW3PQkF6TZmJsUNYsWGXLgyIbgtjkd \
        0TkS0LfVOo/e6PQ32p/xfEj0b+ZGCXgtjC0Tx6sDedhU0fIfT2b+IlwBOAAgACwAAABIA \
        ID8H3RbsT7rIBH02CIgm/Gv1ukSXO3DMHmVQkDG0wEciABAAINgs66YvSM+PW+qPTnGE/ \
        8Yq67HHaX5XMmymUojmugUkPwfdFuxPusgEfTYIiCb8a/W6RJc7cMweZVCQMbTARyIAAA \
        AAWUZXjxS/vfx0BJq8RQAAyeXdSsf7ccsz+yEcMvoUm4WYZupWzt1FW93FDsUpdyi+QID \
        pqczUQ24ODMC+HP9vP7nvLHPF4uNk+iPkR5fF7Ypl5rHdcFyfm1Bqp70g
Environment=BWMPATH=%d/bwmp
ExecStart=/usr/local/sbin/borg.sh

조금 더 있어요보그 서비스파일에 있지만 이 주제의 중요한 부분만 포함했습니다. 매뉴얼에 따르면 스크립트에서 참조할 수 있는 $CREDENTIAL_PATH/bwmp 파일이 있어야 하는데 위와 같이 BWMPATH 환경 변수를 정의하기 전까지는 작동하지 못했습니다. 이는 아마도 bw명령(Bitwarden CLI) 도구에서 HOME 변수를 설정해야 하기 때문에 스크립트에서 설정했기 때문일 것입니다(루트만 실행됨 borg.sh).

systemd.exec 및https://systemd.io/CREDENTIALS작동 방식에 대한 자세한 정보가 포함된 설명서입니다. 이 systemd-creds명령은 TPMv2 칩(시스템에서 사용 가능한 경우)과 키 파일을 자동으로 사용합니다. 내 시스템에 TPMv2 칩이 있는지 확실하지 않습니다. 이에 대해서는 나중에 살펴보겠습니다.

이것은 Arch Linux, systemd 251.3-1에서 작동합니다(1주일 정도 업데이트 없음). 다른 버전을 사용하는 경우 이 버전이 존재하지 않을 수 있습니다.

답변3

@jasonwryan의 두 번째 제안 외에도 세 번째 대안이 있습니다.

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"

또한 이 디렉터리가 존재하고 비어 있으면 서비스가 비활성화된다는 점에 유의하세요! 해당 디렉토리에 무언가를 넣을 계획이 없다면 해당 디렉토리가 존재하지 않는지 확인하십시오.

답변4

귀하의 요구에 맞는 추가 대안을 제공할 수 있지만 몇 가지 전제 조건이 필요합니다.

다음 단계는 다음과 같습니다.

비밀번호를 저장하려면 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.

관련 정보