mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
refactor: run python code without su -.
This commit is contained in:
parent
39d4ebc49c
commit
71f1e26c8f
|
|
@ -186,6 +186,7 @@ except Exception as e:
|
|||
def generate_mcp_server_code(self, code_str, params):
|
||||
python_paths = CONFIG.get_sandbox_python_package_paths().split(',')
|
||||
code = self._generate_mcp_server_code(code_str, params)
|
||||
set_run_user = f'os.setgid({pwd.getpwnam(self.user).pw_gid});os.setuid({pwd.getpwnam(self.user).pw_uid});' if self.sandbox else ''
|
||||
return f"""
|
||||
import os, sys, logging
|
||||
logging.basicConfig(level=logging.WARNING)
|
||||
|
|
@ -194,6 +195,7 @@ logging.getLogger("mcp.server").setLevel(logging.ERROR)
|
|||
path_to_exclude = ['/opt/py3/lib/python3.11/site-packages', '/opt/maxkb-app/apps']
|
||||
sys.path = [p for p in sys.path if p not in path_to_exclude]
|
||||
sys.path += {python_paths}
|
||||
{set_run_user}
|
||||
os.environ.clear()
|
||||
exec({dedent(code)!a})
|
||||
"""
|
||||
|
|
@ -202,30 +204,17 @@ exec({dedent(code)!a})
|
|||
_code = self.generate_mcp_server_code(code, params)
|
||||
maxkb_logger.debug(f"Python code of mcp tool: {_code}")
|
||||
compressed_and_base64_encoded_code_str = base64.b64encode(gzip.compress(_code.encode())).decode()
|
||||
if self.sandbox:
|
||||
tool_config = {
|
||||
'command': 'su',
|
||||
'args': [
|
||||
'-s', sys.executable,
|
||||
'-c',
|
||||
f'import base64,gzip; exec(gzip.decompress(base64.b64decode(\'{compressed_and_base64_encoded_code_str}\')).decode())',
|
||||
self.user,
|
||||
],
|
||||
'cwd': self.sandbox_path,
|
||||
'env': {
|
||||
'LD_PRELOAD': self.sandbox_so_path,
|
||||
},
|
||||
'transport': 'stdio',
|
||||
}
|
||||
else:
|
||||
tool_config = {
|
||||
'command': sys.executable,
|
||||
'args': [
|
||||
'-c',
|
||||
f'import base64,gzip; exec(gzip.decompress(base64.b64decode(\'{compressed_and_base64_encoded_code_str}\')).decode())',
|
||||
],
|
||||
'transport': 'stdio',
|
||||
}
|
||||
tool_config = {
|
||||
'command': sys.executable,
|
||||
'args': [
|
||||
'-c',
|
||||
f'import base64,gzip; exec(gzip.decompress(base64.b64decode(\'{compressed_and_base64_encoded_code_str}\')).decode())',
|
||||
],
|
||||
'env': {
|
||||
'LD_PRELOAD': self.sandbox_so_path,
|
||||
},
|
||||
'transport': 'stdio',
|
||||
}
|
||||
return tool_config
|
||||
|
||||
def _exec(self, execute_file):
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@ RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
|
|||
mkdir -p /opt/maxkb-app/sandbox/lib && chmod -R 550 /opt/maxkb-app/sandbox && \
|
||||
useradd --no-create-home --home /opt/maxkb-app/sandbox sandbox -g root && \
|
||||
chmod g-xr /usr/local/bin/* /usr/bin/* /bin/* /usr/sbin/* /sbin/* /usr/lib/postgresql/17/bin/* && \
|
||||
chmod g+xr /usr/bin/ld.so && \
|
||||
chmod g+x /usr/local/bin/python* && \
|
||||
chmod -R g-rwx /tmp /var/tmp /var/lock && \
|
||||
apt-get clean all && \
|
||||
rm -rf /var/lib/postgresql /var/lib/apt/lists/* /usr/share/doc/* /usr/share/man/* /usr/share/info/* /usr/share/locale/* /usr/share/lintian/* /usr/share/linda/* /var/cache/* /var/log/* /var/tmp/* /tmp/*
|
||||
|
|
|
|||
|
|
@ -212,11 +212,6 @@ static int not_supported(const char *function_name) {
|
|||
_exit(1);
|
||||
return -1;
|
||||
}
|
||||
static pid_t ppid = 0;
|
||||
// 在进程初始化时保存 PID
|
||||
__attribute__((constructor)) static void init_sandbox() {
|
||||
ppid = getpid();
|
||||
}
|
||||
#define RESOLVE_REAL(func) \
|
||||
static typeof(func) *real_##func = NULL; \
|
||||
if (!real_##func) { \
|
||||
|
|
@ -224,22 +219,12 @@ __attribute__((constructor)) static void init_sandbox() {
|
|||
}
|
||||
int execv(const char *path, char *const argv[]) {
|
||||
RESOLVE_REAL(execv);
|
||||
// fprintf(stdout, "execv path: %s ppid=%d pid=%d\n", path, sandbox_pid, getpid());
|
||||
if (!allow_create_subprocess()) {
|
||||
// 只允许创建python进程,但不允许python进程替换(用os.execvp里又启动另一个python进程)
|
||||
if (strstr(path, "bin/python") == NULL || getpid() == ppid) {
|
||||
return deny();
|
||||
}
|
||||
}
|
||||
if (!allow_create_subprocess()) return deny();
|
||||
return real_execv(path, argv);
|
||||
}
|
||||
int __execv(const char *path, char *const argv[]) {
|
||||
RESOLVE_REAL(__execv);
|
||||
if (!allow_create_subprocess()) {
|
||||
if (strstr(path, "bin/python") == NULL || getpid() == ppid) {
|
||||
return deny();
|
||||
}
|
||||
}
|
||||
if (!allow_create_subprocess()) return deny();
|
||||
return real___execv(path, argv);
|
||||
}
|
||||
int execve(const char *filename, char *const argv[], char *const envp[]) {
|
||||
|
|
@ -259,16 +244,24 @@ int execveat(int dirfd, const char *pathname,
|
|||
return real_execveat(dirfd, pathname, argv, envp, flags);
|
||||
}
|
||||
int execvpe(const char *file, char *const argv[], char *const envp[]) {
|
||||
return not_supported("execvpe");
|
||||
RESOLVE_REAL(execvpe);
|
||||
if (!allow_create_subprocess()) return deny();
|
||||
return real_execvpe(file, argv, envp);
|
||||
}
|
||||
int __execvpe(const char *file, char *const argv[], char *const envp[]) {
|
||||
return not_supported("__execvpe");
|
||||
RESOLVE_REAL(__execvpe);
|
||||
if (!allow_create_subprocess()) return deny();
|
||||
return real___execvpe(file, argv, envp);
|
||||
}
|
||||
int execvp(const char *file, char *const argv[]) {
|
||||
return not_supported("execvp");
|
||||
RESOLVE_REAL(execvp);
|
||||
if (!allow_create_subprocess()) return deny();
|
||||
return real_execvp(file, argv);
|
||||
}
|
||||
int __execvp(const char *file, char *const argv[]) {
|
||||
return not_supported("__execvp");
|
||||
RESOLVE_REAL(__execvp);
|
||||
if (!allow_create_subprocess()) return deny();
|
||||
return real___execvp(file, argv);
|
||||
}
|
||||
int execl(const char *path, const char *arg, ...) {
|
||||
return not_supported("execl");
|
||||
|
|
|
|||
Loading…
Reference in New Issue