서비스 시작 시 sudo를 실행할 수 없습니다(단, 스크립트 내에서만 가능).

서비스 시작 시 sudo를 실행할 수 없습니다(단, 스크립트 내에서만 가능).

외부 USB 드라이브를 마운트하려는 스크립트에서 서비스 시작 중에 오류가 발생했습니다.

sudo: 유효한 uid는 0이 아닙니다. /usr/bin/sudo가 "nosuid" 옵션이 설정된 파일 시스템에 있거나 루트 권한이 없는 NFS 파일 시스템에 있습니까?

(마운트 작업은 동기식이어야 하므로 서비스 외부의 다른 곳에 배치하는 것만으로는 ExecStartPre충분하지 않습니다. 성공적인 서비스 시작을 위해서는 마운트가 엄격한 종속성이어야 합니다. 규칙: 어떤 이유로든 마운트가 실패하면 서비스가 시작되지 않습니다. 나중에 알림을 처리합니다).

사용자 컨텍스트에서 실행되는 내 서비스 구성은 다음과 같습니다 admin.

### Editing /etc/systemd/system/[email protected]/override.conf
### Anything between here and the comment below will become the new contents of the file

[Service]
ExecStartPre=/usr/local/bin/mount-sync-drive.sh

### Lines below this comment will be discarded

### /lib/systemd/system/[email protected]
# [Unit]
# Description=Syncthing - Open Source Continuous File Synchronization for %I
# Documentation=man:syncthing(1)
# After=network.target
# StartLimitIntervalSec=60
# StartLimitBurst=4
#
# [Service]
# User=%i
# ExecStart=/usr/bin/syncthing serve --no-browser --no-restart --logflags=0 --home=/media/pi/MyBook/.config/syncthing
# Restart=on-failure
# RestartSec=1
# SuccessExitStatus=3 4
# RestartForceExitStatus=3 4
#
# # Hardening
# ProtectSystem=full
# PrivateTmp=true
# SystemCallArchitectures=native
# MemoryDenyWriteExecute=true
# NoNewPrivileges=true
#
# # Elevated permissions to sync ownership (disabled by default),
# # see https://docs.syncthing.net/advanced/folder-sync-ownership
# #AmbientCapabilities=CAP_CHOWN CAP_FOWNER
#
# [Install]
# WantedBy=multi-user.target

...그리고 내 스크립트는 다음과 같습니다.

#!/bin/bash

exec &>> /var/log/syncthing.log
echo ""
date

# Check if /dev/sda1 is already mounted
if ! grep -qs '/dev/sda1' /proc/mounts; then
    # Mount /dev/sda1 to /media/pi/MyBook
    echo "Mounting /dev/sda1 to /media/pi/MyBook"
    sudo mount -v /dev/sda1 /media/pi/MyBook
fi

스크립트를 수동으로 실행하면 admin드라이브가 제대로 마운트됩니다.

pi@RPI:~ $ mount | grep sda1
pi@RPI:~ $ sudo -u admin /usr/local/bin/mount-sync-drive.sh
mount: /dev/sda1 mounted on /media/pi/MyBook.
pi@RPI:~ $ mount | grep sda1
/dev/sda1 on /media/pi/MyBook type ext4 (rw,relatime)

내용은 다음과 같습니다 syncthing.log.

Wed 22 Feb 15:57:43 AKST 2023
Mounting /dev/sda1 to /media/pi/MyBook
sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?

Wed 22 Feb 15:57:44 AKST 2023
Mounting /dev/sda1 to /media/pi/MyBook
sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?

Wed 22 Feb 15:57:45 AKST 2023
Mounting /dev/sda1 to /media/pi/MyBook
sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?

Wed 22 Feb 15:57:46 AKST 2023
Mounting /dev/sda1 to /media/pi/MyBook
sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?

다음은 서비스 시작 오류입니다( journalctl추가 정보 공개 없음).

pi@RPI:~ $ sudo systemctl status [email protected][email protected] - Syncthing - Open Source Continuous File Synchronization for admin
     Loaded: loaded (/lib/systemd/system/[email protected]; enabled; vendor preset: enabled)
    Drop-In: /etc/systemd/system/[email protected]
             └─override.conf
     Active: failed (Result: exit-code) since Tue 2023-02-21 17:23:14 AKST; 33s ago
       Docs: man:syncthing(1)
    Process: 959 ExecStartPre=/usr/local/bin/mount-sync-drive.sh (code=exited, status=1/FAILURE)
        CPU: 53ms

Feb 21 17:23:14 RPI systemd[1]: [email protected]: Scheduled restart job, restart counter is at 4.
Feb 21 17:23:14 RPI systemd[1]: Stopped Syncthing - Open Source Continuous File Synchronization for admin.
Feb 21 17:23:14 RPI systemd[1]: [email protected]: Start request repeated too quickly.
Feb 21 17:23:14 RPI systemd[1]: [email protected]: Failed with result 'exit-code'.
Feb 21 17:23:14 RPI systemd[1]: Failed to start Syncthing - Open Source Continuous File Synchronization for admin.

mount제가 틀렸다면 정정해 주세요. 하지만 오류 메시지에 언급된 모든 가능성을 배제했다고 생각합니다 .

1. 파일 시스템의 /usr/bin/sudo에는 'nosuid' 옵션이 설정되어 있습니다.

pi@RPI:~ $ mount | grep nosuid
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,nodev,size=186292k,nr_inodes=819200,mode=755)
tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k)
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot)
pstore on /sys/fs/pstore type pstore (rw,nosuid,nodev,noexec,relatime)
bpf on /sys/fs/bpf type bpf (rw,nosuid,nodev,noexec,relatime,mode=700)
mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)
tracefs on /sys/kernel/tracing type tracefs (rw,nosuid,nodev,noexec,relatime)
debugfs on /sys/kernel/debug type debugfs (rw,nosuid,nodev,noexec,relatime)
fusectl on /sys/fs/fuse/connections type fusectl (rw,nosuid,nodev,noexec,relatime)
configfs on /sys/kernel/config type configfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /run/user/1000 type tmpfs (rw,nosuid,nodev,relatime,size=93144k,nr_inodes=23286,mode=700,uid=1000,gid=1000)

2. NFS 파일 시스템이 있고 루트 권한이 없는 파일 시스템의 /usr/bin/sudo:

pi@RPI:~ $ df -T /usr/bin/sudo
Filesystem     Type 1K-blocks    Used Available Use% Mounted on
/dev/root      ext4  30343244 4241732  24811444  15% /

admin다음 명령을 사용하여 sudoers 파일에 추가 하고 visudo재부팅했습니다.

admin ALL=(ALL) NOPASSWD: /bin/mount

매우 이상한 점은 잘 작동하는 또 다른 유사한 시스템이 있다는 것입니다. 모든 구성을 확인하고 다시 확인했는데 동일합니다.

이는 무엇을 의미하며 sudo: effective uid is not 0어떻게 해결합니까?

- 편집하다 -

@ajgringo619댓글의 질문에 따르면 :

pi@RPI:~ $ sudo -lU admin
Matching Defaults entries for admin on RPI:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, env_keep+=NO_AT_BRIDGE, env_keep+="http_proxy
    HTTP_PROXY", env_keep+="https_proxy HTTPS_PROXY", env_keep+="ftp_proxy FTP_PROXY", env_keep+=RSYNC_PROXY, env_keep+="no_proxy NO_PROXY"

User admin may run the following commands on RPI:
    (ALL : ALL) ALL
    (ALL) NOPASSWD: /bin/mount

- 편집하다 -

roaima댓글의 질문에 따르면 :

pi@RPI:~ $ ls -l /usr/bin/sudo
-rwsr-xr-x 1 root root 178432 Jan 14 04:29 /usr/bin/sudo

답변1

귀하의 스크립트는 if ! grep -qs '/dev/sda1' /proc/mounts; then각 인스턴스에 대해 이 스크립트를 실행하는 문제를 해결하기 위한 것이라고 생각합니다 [email protected]. 다른 인스턴스가 실행 중이거나 이전에 실행된 경우 마운트가 이미 존재하므로 이 확인이 필요합니다. 그렇지 않으면 ExecStartPre=실패합니다.

sudo내 다른 대답은 스크립트에서 이를 제거하는 방법을 설명 하지만 또 다른 해결책은 mount스크립트를 systemd의 내장 단위로 바꾸는 것입니다.

단위는 다음과 같이 간단할 수 있습니다.

# /etc/systemd/system/media-pi-MyBook.mount
[Mount]
What=/dev/sda1
Where=/media/pi/MyBook

그런 다음 재정의에 넣지 마십시오.

# /etc/systemd/system/[email protected]/override.conf
[Service]
ExecStartPre=/usr/local/bin/mount-sync-drive.sh

이렇게 하면 서비스를 실행하기 전에 마운트를 사용할 수 있고 실행할 수 있습니다.

# /etc/systemd/system/[email protected]/override.conf
[Unit]
Requires=media-pi-MyBook.mount
After=media-pi-MyBook.mount

이제 사용자 정의 스크립트를 삭제할 수 있습니다.

이를 통해 장치가 마운트 해제되는 시기를 제어할 수 있고 추가 확인 없이 템플릿의 모든 인스턴스에 대해 설치가 존재하는지 확인하는 등 여러 문제가 해결됩니다.

제거하려면 간단히 수행하면 모든 서비스가 자동으로 중지됩니다 sudo systemctl stop media-pi-MyBook.mount. Requires=이는 특히 템플릿 인스턴스 수가 많은 경우 스크립팅하기가 더 어렵습니다.

추가 세부정보:

내가 권장하는 재정의 [email protected]/는 가 아니라 [email protected]/템플릿의 모든 인스턴스에 대해 종속성이 존재함을 의미합니다 .syncthing@syncthing@admin

답변2

상태 확인부터 시작하세요.

systemctl show [email protected] | grep -E 'ProtectSystem|NoNewPrivileges'

아마도 NoNewPrivileges활성화되어 있을 것입니다. 그 결과 프로세스가 루트가 될 수 없으므로 sudo실행될 수 없습니다.

이런 경우에는 이 설정을 비활성화해야 합니다. 내 답변 보기rsyncd 서비스 ProtectSystem=off가 유효하지 않습니다., 유사하지만 중복되지는 않음, 이러한 값을 변경하는 방법에 대한 전체 지침

답변3

sudo스크립트 호출에는 적용할 수 없습니다. 그 목적은 대화형 사용자를 인증하는 것입니다.

이를 방지하려면 스크립트를 다시 작성해야 합니다 sudo. 스크립트는 sudo한 줄에서만 작동하지만 다른 줄은 많은 작업을 수행하지 않으므로 root이 줄로 권한을 확장하는 것은 무리가 아닙니다.

man systemd.service설명 "특수 실행 가능 접두사". 이러한 접두사를 사용하여 ExecStartPre=동작을 변경할 수 있습니다. +특히 전체 권한으로 스크립트를 실행하는 데 관심이 있습니다 .

플러그인에서 +스크립트 경로 앞에 다음을 추가하세요.

[Service]
ExecStartPre=+/usr/local/bin/mount-sync-drive.sh

sudo그런 다음 스크립트에서 제거 할 수 있습니다 .

#!/bin/bash

exec &>> /var/log/syncthing.log
echo ""
date

# Check if /dev/sda1 is already mounted
if ! grep -qs '/dev/sda1' /proc/mounts; then
    # Mount /dev/sda1 to /media/pi/MyBook
    echo "Mounting /dev/sda1 to /media/pi/MyBook"
    mount -v /dev/sda1 /media/pi/MyBook
fi

보너스 포인트: 여기에서 로그인을 많이 하게 됩니다. 수행하는 작업 은 mount이미 표준 출력으로 인쇄되어 있으므로 echo 명령은 약간 중복됩니다. 또한 줄 바꿈과 날짜를 에코합니다. 기본적으로 장치는 모든 표준 출력과 스크립트 날짜를 자동으로 기록합니다. 따라서 로그를 사용하기로 선택한 경우 yopu는 이를 제거하여 스크립트를 단순화할 수 있습니다.

#!/bin/bash

if ! grep -qs '/dev/sda1' /proc/mounts; then
    mount -v /dev/sda1 /media/pi/MyBook
fi

그런 다음 다음을 사용하여 출력을 확인할 수 있습니다.

$ sudo journalctl -u syncthing*
Feb 21 17:23:14 RPI systemd[1]: Started [email protected] - Syncthing - Open Source Continuous File Synchronization for admin
Feb 21 17:23:14 RPI mount-sync-drive.sh[1234]: mount: /dev/sda1 mounted on /media/pi.

관련 정보