여기에있는 것은 정확히 seccomp 의 사용 사례입니다 .
seccomp를 사용하면 다양한 방식으로 syscall을 필터링 할 수 있습니다. 당신이이 상황에서하고 싶은 직후 인 fork()
설치, seccomp
사용을 허용하지 필터 open(2)
, openat(2)
, socket(2)
(등을). 이를 위해 다음을 수행 할 수 있습니다.
- 먼저
seccomp_init(3)
기본 동작 인을 사용하여 seccomp 컨텍스트를 작성하십시오 SCMP_ACT_ALLOW
.
- 그런 다음
seccomp_rule_add(3)
거부하려는 각 syscall을 사용하여 컨텍스트에 규칙을 추가하십시오 . SCMP_ACT_KILL
syscall을 시도하거나 syscall이 SCMP_ACT_ERRNO(val)
지정된 errno
값 또는 action
매뉴얼 페이지에 정의 된 다른 값을 리턴하지 못하도록 프로세스를 종료 하는 데 사용할 수 있습니다 .
- 컨텍스트를 사용하여로드하십시오
seccomp_load(3)
.
계속하기 전에 주의를 이와 같은 블랙리스트 접근 방식은 일반적으로 화이트리스트 방식보다 약한이다. 명시 적으로 허용되지 않아서 필터를 무시할 수있는 모든 syscall을 허용 합니다 . 실행하려는 자식 프로세스가 필터를 피하려고 악의적으로 시도한다고 생각되거나 자식이 어떤 syscall을 필요로하는지 이미 알고 있다면 화이트리스트 접근 방식이 더 좋으며 위와 반대의 작업을 수행해야합니다. 기본 동작으로 필터를 만들고로 SCMP_ACT_KILL
필요한 syscall을 허용합니다 SCMP_ACT_ALLOW
. 코드 측면에서 차이는 최소화됩니다 (허용 목록이 더 길지만 단계는 동일 함).
위의 예는 다음과 같습니다 ( exit(-1)
단순히하기 위해 오류가 발생했을 때 하고 있습니다 ).
#include <stdlib.h>
#include <seccomp.h>
static void secure(void) {
int err;
scmp_filter_ctx ctx;
int blacklist[] = {
SCMP_SYS(open),
SCMP_SYS(openat),
SCMP_SYS(creat),
SCMP_SYS(socket),
SCMP_SYS(open_by_handle_at),
// ... possibly more ...
};
// Create a new seccomp context, allowing every syscall by default.
ctx = seccomp_init(SCMP_ACT_ALLOW);
if (ctx == NULL)
exit(-1);
/* Now add a filter for each syscall that you want to disallow.
In this case, we'll use SCMP_ACT_KILL to kill the process if it
attempts to execute the specified syscall. */
for (unsigned i = 0; i < sizeof(blacklist) / sizeof(blacklist[0]); i++) {
err = seccomp_rule_add(ctx, SCMP_ACT_KILL, blacklist[i], 0);
if (err)
exit(-1);
}
// Load the context making it effective.
err = seccomp_load(ctx);
if (err)
exit(-1);
}
이제 프로그램에서 위 함수를 호출하여 다음과 같이 seccomp 필터를 바로 다음에 적용 할 수 있습니다 fork()
.
child_pid = fork();
if (child_pid == -1)
exit(-1);
if (child_pid == 0) {
secure();
// Child code here...
exit(0);
} else {
// Parent code here...
}
seccomp에 대한 몇 가지 중요한 참고 사항 :
- 일단 적용된 seccomp 필터는 프로세스에 의해 제거되거나 변경 될 수 없습니다.
- 경우
fork(2)
또는 clone(2)
필터에 의해 허용되는, 자식 프로세스는 동일한 필터에 의해 제한됩니다.
- 경우
execve(2)
허용되는 기존 필터에 대한 호출을 통해 유지됩니다 execve(2)
.
- 경우
prctl(2)
콜이 허용되는 프로세스가 더욱 필터를 적용 할 수 있습니다.