我正在尝试创建一个沙箱来运行不受信任的用户代码,我想允许用户在网络套接字上侦听(在Linux上)。但我想限制他们可以听的端口。我尝试过apparmor,但是apparmor只提供了一个完全禁用tcp连接的选项。我需要一个更细粒度的政策。
我也尝试了ptrace,但只能拦截sys_socketcall系统调用,但无法获取端口号。此外,我知道ptrace不是完全安全的,所以这不是一个合适的解决方案。
以下是我一直试图拦截提供给bind的端口号的代码:
params[0] = ptrace(PTRACE_PEEKUSER,
child, 4 * EBX,
NULL);
params[1] = ptrace(PTRACE_PEEKUSER,
child, 4 * ECX,
NULL);
params[2] = ptrace(PTRACE_PEEKUSER,
child, 4 * EDX,
NULL);
printf("SYS_socketcall called with %u\n", (int)params[0]);
if(params[0] == 2){ // SYS_BIND
int call = params[0];
int *args = (intptr_t*)params[1];
int socket = args[0];
struct sockaddr_in *addr = (struct sockaddr_in*)args[1];
int len = args[2];
//struct sockaddr_in *addr = (struct sockaddr_in*)args[1];
printf("BIND CALLED WITH call: %d, fd: %d, addr: %p\n", call, socket, addr);
}
但它是段错误的,因为在获取传递给syscall的sockaddr结构的指针时,我一定做错了。根据{{3}},ECX中的第二个参数是一个指向参数列表的指针,其中参数是[socket_fd,sockaddr *]。但它不起作用。为什么呢?
有没有比用ptrace更好的方法呢?
答案 0 :(得分:0)
SELinux将允许您非常严格地限制进程,包括端口访问。它甚至附带一个sandbox
命令,可以在非常有限的沙箱域中运行进程,然后您可以使用自定义域替换该进程,以便根据需要提供对文件和端口的访问。