我正在尝试创建一个沙盒来运行不受信任的用户代码,我希望允许用户在网络套接字(Linux上)上侦听。但我想限制他们能监听的端口。我已经尝试过apparmor,但是apparmor只提供了一个完全禁用tcp连接的选项。我需要一个更精细的策略。
我也试过ptrace,但只能拦截sys_socketcall系统调用,但无法获取端口号。另外,我知道ptrace并不完全安全,所以这不是一个合适的解决方案。
下面是我试图用来截取提供给绑定的端口号的代码:
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结构的指针时一定做错了什么。根据http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.htmlecx中的第二个参数是指向参数列表的指针,其中参数是[socket_d,sockaddr*]。但没用。为什么?
有没有比ptrace更好的方法?
最佳答案
selinux将允许您非常严格地限制进程,包括端口访问。它甚至还附带了一个sandbox
命令,可以在一个非常受限的沙盒域中运行进程,然后可以将其替换为自定义域,以便提供对文件和端口的适当访问。
关于linux - 限制监听端口访问,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20373816/