必须将 c.notebookapp.ip 设为 '0.0.0.0' 并设置 c.notebookapp.allow_remote_access = true,密码需手动写入配置文件,root 用户需加 --allow-root 参数启动,推荐使用 ssh 隧道避免公网暴露。

直接暴露 IP 启动会失败,必须改 c.NotebookApp.ip
默认启动时只监听 127.0.0.1,别人访问你的服务器 IP(比如 192.168.1.100:8888)会直接返回连接被拒绝。关键不是“开不开”,而是监听地址必须显式设为外部可触达的接口。
不要写 c.NotebookApp.ip = 'localhost' 或留空;也不建议盲目填 '*' ——某些旧版本或特定网络环境会报 No address associated with hostname 错误。
- 优先尝试:
c.NotebookApp.ip = '0.0.0.0'(明确绑定所有 IPv4 接口) - 如果仍失败,再换
c.NotebookApp.ip = '*',并确认 Jupyter 版本 ≥ 6.0 - 务必同时设置:
c.NotebookApp.allow_remote_access = True,否则即使绑定了0.0.0.0,也会被内部拦截
jupyter notebook password 和手动生成密码效果不同
用命令 jupyter notebook password 会把哈希写进 ~/.jupyter/jupyter_notebook_config.json,但 Jupyter 启动时**并不读这个文件** —— 它只认 jupyter_notebook_config.py 里的 c.NotebookApp.password 字段。
所以两种方式实际等价,但容易漏掉一步:
- 运行
jupyter notebook password后,它不会自动修改配置文件,你得手动把生成的哈希(形如argon2:$argon2id$v=19$m=...)复制进jupyter_notebook_config.py的c.NotebookApp.password = u'...' - 如果用 Python 手动生成:
from notebook.auth import passwd; passwd(),输出结果同样要完整粘贴过去,注意保留u''前缀(Python 2 兼容写法,新版也支持) - 别混淆
sha1:和argon2:前缀 —— 新版默认用 argon2,旧配置里写 sha1 可能导致登录失败
不配 SSH 隧道就直接开放端口,等于裸奔
如果你把 c.NotebookApp.ip = '0.0.0.0' + c.NotebookApp.port = 8888 直接跑在公网服务器上,且没配防火墙或反向代理,那等于把 Jupyter 控制台暴露在互联网中。攻击者扫到端口后,可能暴力破解密码、上传恶意文件、甚至执行任意代码。
更安全的做法是跳过公网暴露,改用本地 SSH 端口转发:
- 本地终端执行:
ssh -N -L localhost:8888:localhost:8888 user@your-server-ip - 然后浏览器访问
http://localhost:8888,所有流量经 SSH 加密隧道传输 - 服务器上启动时加
--no-browser,避免在远程机器弹窗(没意义还占资源) - 如果本地 8888 被占,换成其他端口(如
-L localhost:8889:localhost:8888),两边端口不必一致
启动命令漏掉 --allow-root 就会卡住
很多人在服务器用 root 用户跑 Jupyter,但默认禁止 root 启动 —— 不是因为权限不够,而是安全策略主动拦截。现象是:输入 jupyter notebook 后终端卡住不动,或报错 Running as root is not recommended。
这不是警告,是阻断。解决方法只有两个:
- 切到普通用户再启动(推荐)
- 坚持用 root,则每次启动必须加
--allow-root参数:jupyter notebook --allow-root --no-browser - 注意:
--allow-root不能写在配置文件里,只作用于命令行参数
真正容易被忽略的是:配置文件改完、密码写对、IP 绑定正确,但启动时忘了加 --allow-root,就会以为“配置没生效”,反复检查配置项,其实根本没跑起来。











