如何为审计目的记录Jupyter Notebook的输入内容?
针对你遇到的Jupyter Notebook审计追踪难题——需要强制记录所有用户输入、防止用户手动停止日志以满足审计要求,这里有几个可靠的方案,能从不同层面解决问题:
这个方法从IPython底层配置入手,让日志自动启动且用户无法关闭:
创建/修改全局IPython配置文件
先找到IPython的全局配置目录(JupyterHub环境建议放在管理员可控路径,比如/etc/ipython/profile_default/)。若目录不存在,用以下命令生成:ipython profile create --global编辑配置文件启用日志
打开ipython_config.py,添加或修改以下配置项:# 启动时自动开始日志记录 c.InteractiveShellApp.logstart = True # 指定日志文件路径,建议包含用户名和时间戳,方便审计溯源 c.InteractiveShellApp.logfile = '/var/log/jupyter/audit_{username}_{%Y%m%d_%H%M%S}.log' # 设置日志为追加模式,避免覆盖历史记录 c.InteractiveShellApp.logappend = True # 加载自定义扩展禁用logstop命令 c.InteractiveShellApp.extensions = ['disable_logstop']编写扩展禁用logstop魔法命令
在IPython扩展目录(比如/etc/ipython/profile_default/extensions/)创建disable_logstop.py文件,内容如下:def load_ipython_extension(ipython): # 从IPython魔法命令列表中移除logstop if 'logstop' in ipython.magics_manager.magics['line']: del ipython.magics_manager.magics['line']['logstop']这样用户就无法通过
%logstop命令停止日志,且每次启动Notebook时日志会自动开启。
如果需要更彻底的审计(比如捕获所有代码执行请求,不受用户配置修改影响),可以编写Jupyter Server扩展,在服务器层面拦截kernel的执行请求:
创建审计扩展文件
创建jupyter_audit_extension.py,内容如下:import logging from datetime import datetime from jupyter_server.base.handlers import JupyterHandler import json # 配置审计日志 audit_logger = logging.getLogger('jupyter_audit') audit_logger.setLevel(logging.INFO) # 日志文件存放在用户无权限修改的路径 log_handler = logging.FileHandler('/var/log/jupyter/audit_trail.log') log_formatter = logging.Formatter( '%(asctime)s | %(user)s | %(code)s', datefmt='%Y-%m-%d %H:%M:%S' ) log_handler.setFormatter(log_formatter) audit_logger.addHandler(log_handler) def load_jupyter_server_extension(serverapp): web_app = serverapp.web_app kernel_manager = web_app.settings['kernel_manager'] # 重写kernel的execute方法,捕获所有执行的代码 original_execute = kernel_manager.execute def wrapped_execute(kernel_id, code, *args, **kwargs): # 获取当前用户 user = serverapp.get_current_user(kernel_id).username # 记录非空代码 if code.strip(): audit_logger.info('', extra={'user': user, 'code': code}) return original_execute(kernel_id, code, *args, **kwargs) kernel_manager.execute = wrapped_execute配置Jupyter Server加载扩展
在Jupyter Server的配置文件jupyter_server_config.py中添加:c.ServerApp.extensions = ['jupyter_audit_extension']这个方案直接在服务器内核请求层面捕获代码,用户完全无法绕过——所有代码执行都必须经过kernel的execute接口。
如果你已经在用JupyterHub,可以通过Spawner钩子让所有用户的Notebook实例加载管理员控制的IPython配置,而非用户本地配置:
在jupyterhub_config.py中添加:
# 指定用户启动Notebook时使用全局IPython配置 c.Spawner.cmd = ['jupyter', 'notebook', '--ipython-dir=/etc/ipython/profile_default']
结合方案1的全局IPython配置,就能确保每个用户的Notebook都强制开启日志,且无法关闭。
- 日志存储权限:日志文件必须存放在用户没有读写权限的目录(比如
/var/log/jupyter/),防止用户删除或篡改审计记录。 - 日志备份:定期备份日志文件,确保审计记录的完整性,避免因服务器故障丢失数据。
- 测试验证:部署后要验证用户无法绕过日志,比如尝试使用
%logstop、修改本地IPython配置等操作,检查日志是否继续记录所有输入。
内容的提问来源于stack exchange,提问作者soolo

