프로세스가 시스템 로그에 기록되는 것을 방지하는 방법은 무엇입니까?

프로세스가 시스템 로그에 기록되는 것을 방지하는 방법은 무엇입니까?

타사 .NET Core 애플리케이션(VS Code 확장에서 사용하는 바이너리 배포)을 사용하고 있는데 불행하게도 애플리케이션에 진단 로깅이 활성화되어 있지만 이를 비활성화할 수 있는 명확한 방법이 없습니다(작성자에게 이 내용을 조금 보고했습니다). . 비활성화하는 것 이외의 이상적인 솔루션은 해당 특정 프로그램에 대해 아무것도 기록하지 않도록 systemd에 지정할 수 있지만 이를 수행할 수 있는 방법을 찾을 수 없는 경우입니다. 지금까지 시도한 모든 것은 다음과 같습니다.

내가 시도한 첫 번째 일은 다음 으로 stdout리디렉션하는 것이었습니다 . 이렇게 하면 일반 출력이 비활성화되지만 진단 로깅은 여전히 ​​systemd 로그에 기록됩니다.stderr/dev/nulldotnet-app > /dev/null 2>&1

애플리케이션에 진단 로깅을 비활성화할 수 있는 명령줄 매개변수가 있었으면 좋겠습니다. 여기에는 긴 매개변수가 있지만 실험 결과 진단 로깅이 아닌 일반 출력에만 영향을 미치는 것으로 보입니다.

.에 대한 호출을 사용 strace하고 찾아보니 connect애플리케이션이 /dev/log. 에 직접 진단 로그를 기록한다는 사실을 발견했습니다.

경로는 /dev/log에 대한 심볼릭 링크 /run/systemd/journal/dev-log이므로 결과를 확인하기 위해 심볼릭 링크를 를 가리키도록 변경했습니다 /dev/null. 이렇게 하면 진단 로깅이 systemd 로그에 표시되지 않습니다.

누군가 나에게 연결을 시도한 후 LD_PRELOAD표준을 내 버전으로 대체하는 라이브러리를 만들었습니다 . 이것은 내 테스트 프로그램에서는 제대로 작동했지만 .NET Core 앱에서는 실패했습니다 . 인수를 표준 함수에 직접 전달해도 여전히 동일한 오류로 실패합니다.connect/dev/logconnect ENOENT /tmp/CoreFxPipe_1ddf2df2725f40a68990c92cb4d1ff1econnect

그런 다음 .NET Core 애플리케이션 만 /dev/log가리키 도록 Linux 네임스페이스를 사용하여 구현해 보았습니다 . 테스트 프로그램에서는 다시 작동하지만 동일한 오류로 인해 실패합니다. 그냥 사용해도 오류가 발생하여 실패합니다./dev/nullunshare --map-root-user --mount sh -c "mount --bind /dev/null /dev/log; dotnet-app $@"unshare --map-root-user --mount dotnet-app "$@"

다음으로, 애플리케이션이 실행되는 동안 파일 설명자를 닫아 보았습니다 gdb. /dev/log이것은 작동하지만 잠시 후에 다시 켜집니다. 또한 를 가리키도록 파일 설명자를 변경해 보았지만 /dev/null역시 작동했지만 /dev/log잠시 후 .

나의 마지막 시도는 .NET Core 애플리케이션에서 작성된 모든 것을 필터링하는 자체 UNIX 소켓을 작성하는 것이었습니다. 이것은 작동하지만 PID는 UNIX 소켓에 기록된 내용과 함께 전송되므로 systemd 로그에 전달된 모든 항목은 UNIX 소켓을 지원하는 프로그램에서 PID를 보고한다는 것을 알게 되었습니다.

현재 이 솔루션은 내 시스템에서 거의 사용되지 않으므로 수용 가능 /dev/log하지만 더 나은 솔루션을 환영합니다. 나 같은뭔가가 UNIX 소켓의 루트가 되도록 속일 수 있음을 알게 되었습니다., 하지만 이에 대한 추가 정보를 찾을 수 없습니다.

또는 간단한 C 테스트 프로그램이 제대로 실행되는 동안 .NET Core 앱에서 실패하는 이유 LD_PRELOAD와 무엇이 실패할 수 있는지 에 대한 통찰력을 갖고 있는 사람이 있다면 ?unshare/dev/log

답변1

즉, LD_PRELOAD재정의하여 라이브러리를 로드합니다.시스템 로그(3)연결하는 대신(3).

Unix /dev/log소켓은 syslog(3) glibc 함수에 의해 연결되어 데이터를 쓰는 데 사용됩니다. glibc 내의 syslog(3) 구현이 connect(2)를 수행하기 때문에 connect(3) 재정의가 작동하지 않을 수 있습니다.시스템 호출라이브러리 함수가 아닌 LD_PRELOAD후크는 syslog(3) 내에서 호출을 캡처하지 않습니다.

strace시스템 호출을 보여주는 것과 LD_PRELOAD재정의할 수 있는 라이브러리 함수(이 경우 glibc의 함수) 사이에는 연결이 끊어졌습니다 .연결(3)또 다른 glibc 함수가 있습니다연결(2)시스템 호출도 이러한 혼란을 해결하는 데 도움이 됩니다. (syslog(3)에 대한 호출을 표시하려면 대신 using을 사용하는 것이 ltrace도움이 될 수 있습니다.)

명시적으로 연결하는 대신 테스트 프로그램에서 syslog(3)를 직접 호출하도록 하여 connect(3)를 재정의한 내용이 LD_PRELOADsyslog(3)에서 작동하지 않는다는 것을 확인할 수 있습니다 /dev/log. 이는 .NET Core 애플리케이션이 실행되는 방식이라고 생각됩니다.

syslog(3)에 연결하는 것이 더 유용할 수도 있습니다. 스택의 상위에 있으면 해당 후크를 사용하여 선택적으로 전달과 같은 결정을 내릴 수 있기 때문입니다.일부시스템 로그로 전송된 메시지입니다. (glibc를 사용하여 syslog 함수를 로드한 dlsym(RTLD_NEXT, "syslog")다음 해당 함수 포인터를 사용하여 syslog(3)를 호출하여 실제로 후크에서 전달하려는 메시지를 얻을 수 있습니다.)

/dev/logto를 심볼릭 링크로 대체하는 방법은 connect(2) 작업(open(2)과 같은 파일 작업만)을 허용하지 않기 /dev/null때문에 결함이 있습니다. /dev/null따라서 syslog(3)는 연결을 시도하고 어떤 방법으로든 오류가 발생합니다. 어쨌든 부작용이 있을 수 있는 이를 처리하거나 호출자에게 반환합니다.

LD_PRELOADsyslog(3)를 사용한 재정의가 귀하의 요구 사항을 충족할 수 있기를 바랍니다 .

관련 정보