로그인 세션을 사용하여 다른 사용자로 Systemd 서비스 실행

로그인 세션을 사용하여 다른 사용자로 Systemd 서비스 실행

질문

/run/user/uid시작 시 임의의 사용자로 임의의 서비스를 실행하고 해당 사용자로 명시적으로 로그인하지 않고 이 사용자(특별 포함 아래의 모든 유용한 기능)에 대해 생성된 로그인 세션을 사용할 수 있습니까 ?

배경

뿌리 없는 Podman + systemd 서비스와 작동하도록 docker-compose 배포를 변환 중입니다. Podman에 관한 대부분의 내용을 파악했지만 특히 systemd를 통해 실행하는 데 어려움을 겪고 있습니다.

이전 배포에서는 각 서비스에 대한 사용자 계정을 만들고 해당 사용자로 실행되도록 컨테이너를 구성했습니다. 이는 파일 시스템 제어 및 유지 관리 관점에서 매우 편리하며 실제로 유지하고 싶은 주요 속성입니다.

이를 위해 나는 찾았다이것askubuntu 문제를 통해 사용자를 내 시스템 작업에 직접 포함시키고 해당 사용자로 실행할 수 있었습니다. 완벽한.

문제는 다음과 같습니다. Fedora는 cgroups v2로 마이그레이션했으며, 현재는 systemd에서 처리하고 있습니다. 이것이 실제로 이 작업의 첫 번째 이유입니다. 따라서 Podman은 기본적으로 로그인 세션을 설정하기 위해 로그인해야 하는 systemd와 대화할 수 있어야 합니다(내가 이해하는 경우).이것링크가 맞습니다.) 저는 시스템 전문가가 아니므로 질문이 있으면 정정해 주시기 바랍니다.

내가 찾았어사용자 세션 대기에 대한 또 다른 질문이것은 내가 추구하는 것과 비슷하지만 불가능하다는 것을 나타내는 것 같습니다. 내 상황은 크게 두 가지 측면에서 다릅니다.

  • 나는 기다리고 싶지 않아어느세션(예: 시작 시 상호 작용 없이 실행되어야 함)
  • 내 솔루션은 서비스를 시작 및 종료하기 위한 수동 개입을 견딜 수 있을 만큼 강력해야 합니다.

따라서 위에서 언급한 것처럼 저는 서비스 애플리케이션이 systemd(또는 최소한 cgroups v2 부분)에 연결하기 위한 충분한 로그인 환경을 갖춘 특정 사용자로 systemd 서비스를 실행할 수 있는 방법을 찾고 있습니다.

마지막으로, 아래는 systemd에 연결해야 할 때까지 예상대로 작동하는 서비스 중 하나에 대한 샘플 systemd 단위 파일입니다. 또한 로그인한 사용자로 수동으로 실행하면 Podman 호출이 완벽하게 작동합니다.

[Unit]
Description=Emby Podman Container

[Service]
User=emby
Group=emby
Restart=on-failure
ExecStartPre=/usr/bin/rm -f /%t/%n-pid /home/emby/%n-cid
ExecStart=/usr/bin/podman run --conmon-pidfile /%t/%n-pid --cidfile /home/emby/%n-cid -d --name=emby --cgroup-manager=systemd -e TZ="$TZ" -p 8096:8096 -p 8920:8920 -v /opt/docker/storage/emby:/config -v /media/media/:/media emby/embyserver
ExecStop=/usr/bin/sh -c "/usr/bin/podman rm -f `cat /home/emby/%n-cid`"
KillMode=none
Type=forking
PIDFile=/%t/%n-pid

[Install]
WantedBy=multi-user.target

답변1

그래서 약간의 브레인스토밍 끝에 비록 덜 우아하긴 하지만 생각보다 간단하고 효과적인 솔루션을 찾았습니다. 본론으로 들어가 기능 단위 파일을 살펴보겠습니다.

[Unit]
Description=Emby Podman Container
[email protected]
[email protected]

[Service]
User=emby
Group=media
Restart=on-failure
ExecStartPre=/usr/bin/rm -f /home/emby/%n-pid /home/emby/%n-cid
ExecStartPre=-/usr/bin/podman rm emby
ExecStart=/usr/bin/podman run --conmon-pidfile /home/emby/%n-pid --cidfile /home/emby/%n-cid \
          --name=emby --rm --cgroup-manager=systemd \
          -e TZ="$TZ" \
          -p 8096:8096 -p 8920:8920 \
          -v /opt/docker/storage/emby:/config \
          -v /media/media/:/media \
          emby/embyserver
ExecStop=/usr/bin/sh -c "/usr/bin/podman rm -f `cat /home/emby/%n-cid`"
KillMode=none
Type=forking
PIDFile=/home/emby/%n-pid

[Install]
WantedBy=multi-user.target

여기서 중요한 통찰력은 systemd가 사용자 세션 자체를 관리하도록 하는 것입니다(다른 작업을 수행하도록 허용하는 대신). Emby 서비스가 실제로 시작되기 전에 Emby 사용자의 사용자 세션이 완전히 생성되도록 하기 때문에 이 구성에서는 BindsTo및를 사용하는 것이 After필수적입니다 . 또한 이렇게 하면 관리자(읽기: 본인)가 세션을 활성화하기 위해 모든 사용자에 로그인할 필요가 없어져 더 많은 서비스와 사용자가 추가될 때 도움이 됩니다.

설정에 대한 기타 유용한 참고 사항:

  • -d플래그는 stdout을 통해 볼 수 있도록 podman에서 제거되었습니다 journalctl -fu emby _TRANSPORT=stdout. 테스트 및 검증에 편리합니다.
  • ~에 따르면[이메일 보호됨]매뉴얼 페이지, 사용자 서비스는 이름 대신 UID로 인스턴스화되어야 합니다(내 시스템에서는 emby == 1012). Exec명령이 아닌 항목에서 확장을 수행하는 방법을 찾지 못했기 때문에 지금은 하드코딩되어 있습니다. 청소하는 방법을 아는 사람이 있으면 듣고 싶습니다.
  • PID 파일은 쓸 수 없기 때문에 사용자의 홈 디렉토리로 이동되었습니다 /run(그것도 괜찮습니다).

내가 시도한 다른 것들아니요일하다:

  • 에서 직접 사용자 서비스를 시작합니다 ExecPre. 장치가 사용자로 실행 중이므로 해당 사용자(닭고기와 달걀)에 대해 systmd를 시작할 수 없습니다.
  • 사용자를 자동으로 로그인합니다. 참고: 이는 다음과 같을 수 있습니다.할 수 있다작동하지만 완전히 로그인한 사용자에게는 보안 위험이 있습니다.
  • su를 통해 사용자를 변경합니다. systemd 관리자는 su에 대해 다소 비관적인 견해를 가지고 있습니다.그리고 그것을 고치는 것을 거부했습니다. 종교적 논쟁은 제쳐두고, 간단한 설명은 작동하지 않습니다.

추가 참고자료:


편집하다:

물론, 이 글을 올리자마자, 저를 다음 페이지로 이끈 마법의 검색 문자열을 찾아냈습니다.기사이것은 내 접근 방식을 제거합니다.

간결하게 하기 위해 위 문서에서는 서비스를 루트로 실행하고 컨테이너의 루트 사용자를 필수 시스템 사용자에 사용 --uidmap/ 매핑하는 것에 중점을 둡니다.--gidmap

그러나 이 솔루션은 Podman에만 적용되므로 루트나 Podman이 아닌 프로세스가 systemd에 액세스해야 하는 다른 사용자를 위해 위의 내용을 남겨 두겠습니다.

마지막으로 나는생각하다공격자가 컨테이너 런타임을 손상시키더라도 범위는 여전히 권한이 없는 사용자로 제한되기 때문에 내 솔루션은 더 안전합니다. 이는 다른 사용자 서비스를 실행하는 공격 표면이 증가하여 상쇄될 수 있으므로 아마도 세척일 수도 있습니다.

관련 정보