추가 읽기

추가 읽기

man 7 daemon

기존 SysV 데몬이 시작되면 초기화의 일부로 다음 단계를 실행해야 합니다. 이러한 단계는 새로운 스타일의 데몬(아래 참조)에는 필요하지 않으며 SysV와의 호환성이 필수적인 경우에만 구현해야 합니다.

[...]

6. 하위에서 setid()를 호출하여 터미널에서 분리하고 독립 세션을 만듭니다.

7. 자식에서는 다시 fork()를 호출합니다.데몬이 다시는 터미널을 다시 획득할 수 없도록 하기 위해.

하지만 이를 SysV 호환성의 흔적 없이 시작된 프로세스와 비교해 보세요.

$ ps -efj
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
root         1     0     1     1  0 May10 ?        00:06:44 /sbin/init
...
root       185     1   185   185  0 May10 ?        00:09:48 /lib/systemd/systemd-journald
root     16434     1 16434 16434  0 May26 ?        00:00:11 /usr/sbin/rsyslogd -n

rsyslog.service및 둘 다에 대한 프로세스는 systemd-journal.service세션 리더(SID = PID)입니다.

이러한 프로그램이 TTY에 로그인하도록 구성된 경우 TTY를 제어 터미널로 확보하고 TTY가 끊어지거나 Ctrl+C를 수신할 때 원치 않는/치명적인 신호를 수신하는 것으로 보입니다. TTY 파일을 열 때 O_NOCTTY를 설정하는 것을 기억하지 않는 한.

프로그램이 사용자 정의 파일에 메시지 쓰기를 지원하는 경우 SysV 호환성 없이 시스템 서비스로 실행되도록 프로그램을 작성하거나 변환할 때 이는 약간의 함정인 것 같습니다. 체계적인 스타일을 옹호하는 이 문서에서는 이를 지적하지 않는 것 같습니다. 문서에서는 SysV에서 이를 방지하려면 이중 포크가 필요하다고 주장하고 기본 시스템 서비스가 사용할 단계를 설명할 때 이를 문제로 언급하지 않음으로써 오히려 그 반대를 암시합니다.

그 맞습니까? systemd는 내가 간과한 이에 대한 보호 기능을 제공합니까, 아니면 systemd 문서의 다른 곳에서 문제가 지적되어 있습니까?

답변1

systemd는 이에 대한 보호 기능을 제공합니까 [...]?

당신은 그렇게 해야 한다고 가정하고 있습니다. 반대로 다음과 같은 설정 TTYPath및 서비스를 고려하십시오 [email protected]. 제어 단말기를 얻는 능력은 실제로필요한, 서비스 관리가 정확하게 수행해야 하는 TTY 로그인 서비스를 포함할 수 있도록 합니다.

실제로 이를 방지하는 방법은 제어 터미널의 자동 할당에서 벗어나 open()이전 의미를 폐기하는 것입니다. 또는~일 것이다그것으로부터 보호하십시오. Linux에서는 그렇지 않지만 FreeBSD, NetBSD, OpenBSD 및 Hurd에서는 요즘 플래그 O_NOCTTYopen()완전히 불필요합니다. 그만큼오직제어 터미널을 획득하는 방법은 ioctl(…TIOSCTTY). 이것은 실제로 4.4BSD 시대 이후 거의 25년 동안 지속되어 왔습니다.

그동안 Linux에 들어가는 습관은 systemd 이전에도 오랫동안 있었던 습관입니다.O_NOCTTY어디에나. ☺

(예, GNU 및 musl C 라이브러리는 에 대해 이를 제공하지 않습니다 . 이것이 여전히 유용한 메커니즘인 fopen()여러 이유 중 하나입니다 .)fdopen()

nosh 도구 세트를 사용한 서비스 관리는 service-manager이에 대해 약간 다른 방식을 취합니다. 항상 데몬 프로세스를 세션 리더로 만드는 대신, 각 서비스에 할당된 자체 커널 세션 객체는 더 이상 사용되지 않으며 특정 서비스만 setsid명시적으로 연결됩니다. 을 사용하는 서비스 , 물론 제어 단말기를 설정하는 서비스, 서비스 등이 있습니다 . (서비스 소스에 명시된 대로 자신을 호출합니다 .)ttylogin@*open-controlling-ttyagetty@*agettygetty@*mgettysetsid()

추가 읽기

답변2

systemd는 제어 터미널을 획득하는 것에 대해 서비스 프로그램을 보호하지 않습니다. 사용자가 지정한 로그 파일을 열 때 플래그를 사용하여 자신을 보호해야 합니다 O_NOCTTY.

$ rpm -q systemd
systemd-238-8.git0e0aa59.fc28.x86_64

$ systemctl cat test
# /etc/systemd/system/test.service
[Service]
Type=simple
ExecStart=/bin/sh -c "exec cat </dev/tty10 >/dev/tty10"

$ systemctl status test
● test.service
   Loaded: loaded (/etc/systemd/system/test.service; static; vendor preset: disabled)
   Active: active (running) since Fri 2018-06-01 11:28:41 BST; 1min 35s ago
 Main PID: 12173 (cat)
    Tasks: 1 (limit: 4915)
   Memory: 180.0K
   CGroup: /system.slice/test.service
           └─12173 cat

Jun 01 11:28:41 alan-laptop systemd[1]: Started test.service.

$ ps -ejf
UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD
...
root     12173     1 12173 12173  0 11:28 tty10    00:00:00 cat

또한 tty10으로 전환하고 Ctrl+C를 누르면 프로세스가 중지되는 것도 확인했습니다 cat.

관련 정보