Intranet
Lightweight local HTTP file server — no Apache/nginx needed, no root required. Serves static files, mounts plugin directories, and runs index.py entry points as CGI.
Entry point: INLINECODE1
Setup
See SETUP.md for prerequisites and setup instructions.
Commands
CODEBLOCK0
Directory Layout
CODEBLOCK1
Config lives in {workspace}/intranet/config.json, webroot is {workspace}/intranet/www/. The config file is never exposed to HTTP.
Plugins
Plugins mount external directories at URL prefixes. Configure in config.json:
CODEBLOCK2
Plugin config supports simple (static only) or extended (with CGI hash) format:
CODEBLOCK3
- - Plugin paths must be inside the workspace
- If CGI is enabled and a plugin has a
hash, index.py at the plugin root handles all sub-paths — but only if its SHA-256 matches - Plugins without a
hash are static-only (CGI blocked even when globally enabled) - Generate a hash: INLINECODE8
CGI Execution
Off by default. Enable in config.json:
CODEBLOCK4
When enabled, only files named index.py can execute as CGI:
- - Webroot:
index.py in any subdirectory handles that directory's requests - Plugins:
index.py at the plugin root handles all plugin sub-paths - All other
.py files → 403 Forbidden (never served, never executed) - Scripts must have the executable bit set (
chmod +x)
Security
- - Webroot isolation — config.json is outside the webroot (
www/), never served - CGI off by default — must be explicitly enabled via
"cgi": true in config.json - Path containment — all resolved paths must stay within their base directory. Symlinks are followed but the resolved target is checked for containment.
- Plugin allowlist — only directories explicitly registered in
config.json are served; must be inside workspace - CGI restricted to
index.py — no arbitrary script execution; plugin CGI requires SHA-256 hash in config.json. Webroot CGI does not require a hash (webroot files are under your direct control) - All
.py files blocked except index.py entry points (not served as text, not executed) - Host allowlist — optional
allowed_hosts restricts which Host headers are accepted - Token auth — optional bearer token via
--token flag or config.json. Browser clients visit ?token=SECRET once → session cookie set → all subsequent navigation works. API clients use Authorization: Bearer <token> header. - Path traversal protection — all paths resolved and validated before serving
- Default bind:
127.0.0.1 (loopback only). LAN access via --host 0.0.0.0 requires both token auth and allowed_hosts in config.json.
Workspace Detection
The server auto-detects the workspace by walking up from $PWD (or the script location) looking for a skills/ directory. The detected path is printed on startup so you can verify it.
To skip autodiscovery, set INTRANET_WORKSPACE to the workspace root:
CODEBLOCK5
Notes
- - All state files are inside the workspace:
- Config:
{workspace}/intranet/config.json
- PID:
{workspace}/intranet/.pid
- Runtime:
{workspace}/intranet/.conf
- Webroot:
{workspace}/intranet/www/
- - No files are written outside the workspace
- 30-second timeout on CGI execution (when enabled)
内网服务
轻量级本地HTTP文件服务器——无需Apache/nginx,无需root权限。可提供静态文件服务、挂载插件目录,并将index.py入口点作为CGI运行。
入口点: {baseDir}/scripts/intranet.py
安装
请参阅 SETUP.md 了解前置条件和安装说明。
命令
bash
python3 {baseDir}/scripts/intranet.py start # 在默认端口8080启动
python3 {baseDir}/scripts/intranet.py start --port 9000 # 自定义端口
python3 {baseDir}/scripts/intranet.py start --host 0.0.0.0 # 局域网访问(需要token + allowed_hosts)
python3 {baseDir}/scripts/intranet.py start --token SECRET # 启用Bearer Token认证
python3 {baseDir}/scripts/intranet.py status # 检查运行状态
python3 {baseDir}/scripts/intranet.py stop # 停止服务器
目录结构
{workspace}/intranet/
├── config.json # 服务器配置(不对外提供)
└── www/ # Web根目录(存放对外提供的文件)
├── index.html
└── ...
配置文件位于 {workspace}/intranet/config.json,Web根目录为 {workspace}/intranet/www/。配置文件永远不会通过HTTP暴露。
插件
插件可将外部目录挂载到URL前缀下。在 config.json 中配置:
json
{
plugins: {
banker: {workspace}/skills/banker/web,
deliveries: {workspace}/skills/deliveries/web
}
}
插件配置支持简单格式(仅静态文件)和扩展格式(带CGI哈希值):
json
{
plugins: {
static-only: /path/to/dir,
with-cgi: {
dir: /path/to/dir,
hash: sha256:abc123...
}
}
}
- - 插件路径必须在工作空间内
- 如果启用了CGI且插件包含 hash,则插件根目录下的 index.py 将处理所有子路径——但仅在其SHA-256哈希值匹配时生效
- 没有 hash 的插件仅提供静态文件(即使全局启用了CGI,也会被阻止)
- 生成哈希值:shasum -a 256 /path/to/index.py
CGI执行
默认关闭。 在 config.json 中启用:
json
{
cgi: true
}
启用后,只有名为 index.py 的文件可以作为CGI执行:
- - Web根目录:任何子目录中的 index.py 处理该目录的请求
- 插件:插件根目录下的 index.py 处理所有插件子路径
- 所有其他 .py 文件 → 403禁止访问(既不提供也不执行)
- 脚本必须设置可执行位(chmod +x)
安全
- - Web根目录隔离 — config.json 位于Web根目录(www/)之外,永远不会被提供
- CGI默认关闭 — 必须通过 config.json 中的 cgi: true 显式启用
- 路径限制 — 所有解析后的路径必须在其基础目录内。符号链接会被追踪,但会检查解析后的目标是否在限定范围内
- 插件白名单 — 仅在 config.json 中显式注册的目录才会被提供;且必须在工作空间内
- CGI仅限于 index.py — 不允许任意脚本执行;插件CGI需要在 config.json 中包含SHA-256哈希值。Web根目录CGI不需要哈希值(Web根目录文件由你直接控制)
- 除 index.py 入口点外,所有 .py 文件均被阻止(不作为文本提供,也不执行)
- 主机白名单 — 可选的 allowedhosts 限制接受的 Host 头
- Token认证 — 通过 --token 标志或 config.json 提供可选的Bearer Token。浏览器客户端访问 ?token=SECRET 一次 → 设置会话Cookie → 后续所有导航均可正常使用。API客户端使用 Authorization: Bearer 头。
- 路径遍历防护 — 所有路径在提供前都会进行解析和验证
- 默认绑定:127.0.0.1(仅回环地址)。通过 --host 0.0.0.0 进行局域网访问需要同时启用Token认证和 config.json 中的 allowedhosts。
工作空间检测
服务器通过从 $PWD(或脚本位置)向上遍历查找 skills/ 目录来自动检测工作空间。检测到的路径会在启动时打印出来,以便你进行验证。
要跳过自动发现,请将 INTRANET_WORKSPACE 设置为工作空间根目录:
bash
INTRANET_WORKSPACE=/path/to/workspace python3 scripts/intranet.py start
说明
- 配置:{workspace}/intranet/config.json
- PID:{workspace}/intranet/.pid
- 运行时:{workspace}/intranet/.conf
- Web根目录:{workspace}/intranet/www/
- - 不会在工作空间外写入任何文件
- CGI执行超时时间为30秒(启用时)