- 后端
- 前端
- 运维
- MCP 服务
【免费下载链接】nginx-ui
Yet another WebUI for Nginx
导读
本文聚焦 nginx-ui 内置的MCP(Model Context Protocol)配置管理模块,系统讲解其提供的 9 个配置文件管理工具(读取、创建、修改、重命名、启用、历史回溯等)。读者将掌握:每个工具的调用参数与返回结构、路径解析与安全性约束、写入-校验-重载的原子化流程,以及如何通过 MCP 服务令牌和读写权限分类,让 AI Agent 与自动化工具在完全受控的前提下操作 Nginx 配置。文中所涉实现细节均有仓库源码佐证,可直接对照 mcp/config 目录下的真实代码深入研读。
一、模块概览:AI Agent 操作 Nginx 配置的统一入口
MCP(Model Context Protocol)是一套让 AI 模型与外部工具交互的标准协议。nginx-ui 将"管理 Nginx 配置文件"这一高频操作抽象为一组 MCP 工具,供 AI 助手、自动化脚本和第三方工具通过标准化的 JSON 请求调用,而无需关心底层文件系统、Nginx 语法校验与重载等细节。
从源码结构看,该模块位于 mcp/config 目录,共 9 个工具,全部通过 mcp/config/register.go 中的Init()函数注册到 MCP 服务器:
| 工具名 | 类型 | 功能 |
|---|---|---|
nginx_config_base_path | tool | 获取 Nginx 配置根目录路径 |
nginx_config_list | tool | 列出配置目录下的文件 |
nginx_config_get | tool | 读取指定配置文件的完整内容 |
nginx_config_add | tool | 新建配置文件 |
nginx_config_modify | tool | 修改已有配置文件 |
nginx_config_rename | tool | 重命名文件或目录 |
nginx_config_mkdir | tool | 创建配置目录 |
nginx_config_history | tool | 查看配置文件变更历史 |
nginx_config_enable | tool | 启用配置文件(在 sites-enabled 中创建软链接) |
这些工具从读写维度分为两类(见 mcp/router.go 中的writeMCPTools与readOnlyMCPTools两个集合):
- 只读工具:
nginx_config_base_path、nginx_config_get、nginx_config_history、nginx_config_list; - 写工具:
nginx_config_add、nginx_config_enable、nginx_config_mkdir、nginx_config_modify、nginx_config_rename(此外还有reload_nginx、restart_nginx)。
读写分类直接决定了调用所需的授权级别(详见第六节),这是理解整个模块安全模型的关键。
二、路径体系:所有操作均以 Nginx 配置根目录为锚点
2.1 获取基础路径:nginx_config_base_path
该工具无需任何参数,返回 Nginx 配置目录的绝对路径。其实现(mcp/config/config_base_path.go)直接调用nginx.GetConfPath(),该值由 nginx-ui 的 Nginx 配置解析逻辑(internal/nginx)计算得出,通常为/etc/nginx一类目录。
调用示例:
{ "tool": "nginx_config_base_path", "parameters": {} }响应示例:
{ "base_path": "/etc/nginx" }2.2 路径安全约定
模块遵循两条重要规则:
- 所有路径操作都相对 Nginx 配置根目录(
nginx_config_list、nginx_config_get使用relative_path参数;nginx_config_add等使用base_dir+name组合); - 写入前会做路径包含性校验:如
nginx_config_enable在创建软链接前会调用helper.IsUnderDirectory(dstPath, sitesEnabledDir)检查目标是否位于sites-enabled目录内,防止链接逃逸(mcp/config/config_enable.go)。config.ResolveConfPath、config.ResolveAbsoluteOrRelativeConfPath等函数(internal/config/path.go)负责把相对路径安全地解析为绝对路径,目录穿越类攻击会在该层被拦截。
实战提示:在开始批量操作前,先调用
nginx_config_base_path确认根路径,所有后续调用均以此为锚点组织relative_path或base_dir,避免硬编码绝对路径带来的跨环境兼容问题。
三、读取与检索:列出、查看与回溯
3.1 列出配置文件:nginx_config_list
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
relative_path | string | 相对 Nginx 配置根目录的路径,用于限定要列出的目录 |
filter_by_name | string | 按文件名关键字过滤(可选) |
实现(mcp/config/config_list.go)将参数透传给config.GetConfigList,过滤逻辑为strings.Contains(file.Name(), filterByName),即子串匹配。
调用示例:
{ "tool": "nginx_config_list", "parameters": { "relative_path": "conf.d" } }响应示例:
{ "files": [ { "name": "default.conf", "is_dir": false, "path": "/etc/nginx/conf.d/default.conf" }, { "name": "example.conf", "is_dir": false, "path": "/etc/nginx/conf.d/example.conf" } ] }每个条目包含name、is_dir(是否为目录)、path(绝对路径)三个字段,便于后续用nginx_config_get精确读取。
3.2 读取配置内容:nginx_config_get
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
relative_path | string | 配置文件的相对路径(必填) |
调用示例:
{ "tool": "nginx_config_get", "parameters": { "relative_path": "conf.d/default.conf" } }该工具的实现(mcp/config/config_get.go)返回的信息比文档示例更丰富,实际包含:
name:文件名;content:文件完整内容;file_path:解析后的绝对路径;modified_at:文件修改时间;dir:文件所在相对目录;sync_node_ids、sync_overwrite:该文件在集群环境下的同步配置(来自数据库configs表的记录,见 model/config.go)。
这意味着 AI Agent 在一次调用中即可同时拿到文件内容与集群同步元数据,为"读取后决策、决策后修改"的完整工作流打下基础。
3.3 查看变更历史:nginx_config_history
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
filepath | string | 配置文件的完整路径(必填,用于精确匹配历史记录) |
实现(mcp/config/config_history.go)查询config_backups表(gorm gen 生成的query.ConfigBackup),按file_path过滤并按 ID 倒序返回,即最新的历史记录排在最前。
自动备份机制:正如文档 Important Notes 所述,每次配置修改都会自动生成备份记录,之后可通过历史工具查询到每次变更的版本,配合 nginx-ui 的恢复能力(见 api/config/history.go 与 internal/config/history.go)实现一键回滚。这条"修改即备份、历史可恢复"的链路是 MCP 写操作能够安全放手的前提。
四、写入操作:创建、修改与原子化安全落地
4.1 新建配置文件:nginx_config_add
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
name | string | 要创建的文件名(必填) |
content | string | 文件内容(必填) |
base_dir | string | 存放目录(可选,相对 Nginx 配置根目录) |
overwrite | boolean | 是否覆盖已存在的文件(可选,默认 false) |
sync_node_ids | array | 需要同步配置的节点 ID 列表(可选,集群场景) |
以文档示例为基础、补充完整字段的调用:
{ "tool": "nginx_config_add", "parameters": { "name": "example.com.conf", "content": "server {\n listen 80;\n server_name example.com;\n location / {\n root /usr/share/nginx/html;\n index index.html;\n }\n}", "base_dir": "sites-available", "overwrite": false } }底层安全流程(见 mcp/config/config_add.go):
- 参数校验:
name与content缺一不可,缺失即报错; - 语法校验:调用
config.ValidateConfigFile(path, content)做 Nginx 语法与安全指令校验; - 防覆盖:
overwrite=false时若文件已存在,返回ErrFileAlreadyExists; - 目录自动创建:目标目录不存在时以
0755权限递归创建; - 加锁 + 事务写入:获取
config.LockApply()写锁,通过config.FileTransaction以0644权限落盘; - 测试并重载:调用
tx.TestAndReload()执行nginx -t测试,通过后触发重载;任一环节失败立即回滚,保证"Nginx 拒绝的配置不会残留在磁盘上,也不会破坏正在运行的内存配置"; - 写入数据库并同步:在
configs表创建记录,若指定sync_node_ids则通过config.SyncToRemoteServer同步到集群节点。
4.2 修改已有配置:nginx_config_modify
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
relative_path | string | 配置文件的相对路径(必填) |
content | string | 新的完整文件内容(必填) |
sync_overwrite | boolean | 同步时是否覆盖远端已有文件(可选) |
sync_node_ids | array | 需要同步的节点 ID 列表(可选) |
调用示例:
{ "tool": "nginx_config_modify", "parameters": { "relative_path": "conf.d/default.conf", "content": "server {\n listen 80;\n server_name example.com;\n location / {\n root /usr/share/nginx/html;\n index index.html;\n }\n}" } }实现要点(mcp/config/config_modify.go):
- 目标文件不存在时返回
ErrFileNotFound; - 修改前同样执行
config.ValidateConfigFile语法与安全校验; - 若数据库尚无该文件记录,则
FirstOrCreate自动创建;随后更新sync_node_ids、sync_overwrite字段; - 最终调用
config.Save(absPath, content, cfg, "")完成保存。该函数内部同样走"写文件 → 语法测试 → 重载 → 写历史备份"的完整链路(见 internal/config/save.go),自动备份由此产生。
注意:
content必须为文件的完整新内容,而非增量补丁。AI Agent 应先用nginx_config_get获取现状,再基于现状生成完整内容提交修改。
4.3 创建配置目录:nginx_config_mkdir
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
base_path | string | 目标目录所在的基路径(可选) |
folder_name | string | 要创建的目录名(必填) |
调用示例:
{ "tool": "nginx_config_mkdir", "parameters": { "base_path": "conf.d", "folder_name": "includes" } }实现(mcp/config/config_mkdir.go)将两个参数解析合并后以0755权限调用os.Mkdir创建单级目录(注意:与nginx_config_add的自动递归创建不同,这里不会递归创建多级目录)。成功时返回message与完整path。
4.4 重命名文件或目录:nginx_config_rename
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
base_path | string | 文件/目录所在的基路径 |
orig_name | string | 原名称(必填) |
new_name | string | 新名称(必填) |
sync_node_ids | array | 需要同步重命名操作的节点 ID(可选) |
调用示例:
{ "tool": "nginx_config_rename", "parameters": { "base_path": "sites-available", "orig_name": "old-name.conf", "new_name": "new-name.conf" } }实现细节(mcp/config/config_rename.go):
- 名称相同则直接返回"无需变更";目标已存在返回
ErrFileAlreadyExists; - 文件系统层面执行
os.Rename; - 元数据联动更新:同步更新
configs表记录(filepath、name),迁移config_backups历史记录的 filepath,并联动更新 LLM 会话记录(query.LLMSession)——文件重命名后,AI 会话中记录的旧路径引用会被自动改写,目录重命名时则用Like前缀匹配 +Replace批量更新其下所有记录; - 若配置了
sync_node_ids,通过config.SyncRenameOnRemoteServer把重命名操作同步到集群节点。
五、启用配置:nginx_config_enable与 sites-enabled 软链接
这是模块中最能体现"安全自动化"设计的一个工具。参数:
| 参数 | 类型 | 说明 |
|---|---|---|
name | string | 要启用的配置文件名(必填) |
base_dir | string | 源目录,默认sites-available |
overwrite | boolean | 目标已存在时是否覆盖(可选,默认 false) |
调用示例:
{ "tool": "nginx_config_enable", "parameters": { "name": "my-site.conf", "base_dir": "sites-available", "overwrite": false } }响应示例(与文档一致):
{ "status": "success", "message": "Site enabled and Nginx reloaded successfully", "source": "/etc/nginx/sites-available/my-site.conf", "destination": "/etc/nginx/sites-enabled/my-site.conf" }完整执行链路(mcp/config/config_enable.go):
- 默认源目录为
sites-available,解析出源文件绝对路径,确认其存在; - 目标为
sites-enabled/<name>,校验目标路径必须位于sites-enabled目录内(防路径逃逸); sites-enabled不存在时自动创建(0755);- 目标已存在且
overwrite=false时报错;overwrite=true时先移除旧链接; - 通过
os.Symlink创建sites-available→sites-enabled的软链接(而非复制文件,保证两处内容始终一致); - 先测试后重载:执行
nginx.Control(nginx.TestConfig)(即nginx -t),失败则删除刚创建的链接并回滚;测试通过后再nginx.Control(nginx.Reload)重载,重载失败同样回滚并恢复 Nginx 状态。
这套"失败即回滚"的设计保证了:启用失败的配置绝不会让 Nginx 处于"带病运行"或"下次启动即挂"的状态。
六、权限与安全模型:读写分级 + 服务令牌
MCP 配置管理工具并非裸奔的 API。从 mcp/router.go 可以看到完整的四层防护:
6.1 路由与认证
- MCP 端点注册在
/mcp与/mcp_message,统一经过IPWhiteList()(IP 白名单)、mcpAuthRequired()(认证)、authorizeMCPToolRequest()(工具级授权)三个中间件; - 认证支持三种凭证(
mcpAuthRequired):- MCP 服务令牌:以
nui_pat_开头的令牌,经internalmcp.VerifyServiceToken验证,用于 Agent/自动化程序; - 用户会话令牌:普通用户 token(≤16 字符用 short token 查询,否则用完整 token 查询);
- 遗留节点密钥:
X-Node-Secret请求头,需与NodeSettings.Secret常量时间比较(subtle.ConstantTimeCompare)匹配,对应旧的节点认证方式。
- MCP 服务令牌:以
6.2 读写作用域分级
authorizeMCPToolRequest中间件会解析请求体(仅对tools/call方法分类),依据readOnlyMCPTools/writeMCPTools判定所需作用域:
- 只读工具需要
MCPTokenScopeRead; - 写工具需要
MCPTokenScopeWrite,此时还会叠加RequireSecureSession()安全会话校验; - 未知工具默认按写权限处理(fail closed),保证未来新增的可变工具在显式归类前不会绕过写权限保护。
这意味着:即使服务令牌泄露,只读令牌也无法执行nginx_config_add等破坏性操作——权限模型遵循最小化原则。
6.3 内容安全:受限指令校验
写入前执行的config.ValidateConfigFile不止做语法检查,还会拦截危险指令。测试用例 mcp/config/config_validation_test.go 验证了两类场景:
nginx_config_add拒绝包含lua_package_path的配置(TestNginxConfigAddRejectsRestrictedDirectiveContent);nginx_config_modify拒绝包含js_import的配置(TestNginxConfigModifyRejectsStatementSeparatedRestrictedDirectiveContent),且被拒后磁盘上的原文件内容保持不变。
被拦截时返回ErrConfigDirectiveNotAllowed(cosy 错误),错误参数中携带具体的受限指令名,方便 Agent 定位问题。这条防线从根源上阻止 AI 生成的配置夹带可执行代码(如 Lua/JS 扩展),属于"指令级"的纵深防御。
七、实践:组合工具构建完整的 Agent 工作流
将上述工具串联起来,即可形成一条安全、可审计的配置管理流水线:
- 探查:
nginx_config_base_path确认根路径 →nginx_config_list定位目标目录; - 读取:
nginx_config_get获取现有内容与同步元数据; - 修改:
nginx_config_modify提交完整新内容(或nginx_config_add新建,nginx_config_mkdir建目录,nginx_config_rename改名); - 启用:对位于
sites-available的新站点调用nginx_config_enable创建软链接并触发重载; - 审计:
nginx_config_history随时回溯每次修改的版本,配合 nginx-ui 的恢复功能回滚异常变更。
每步写入都伴随语法校验、自动备份、失败回滚与集群同步(可选),因此即使 Agent 生成的配置存在缺陷,也不会污染磁盘或中断线上服务。
结语
nginx-ui 的 MCP 配置管理模块(mcp/config)把"读写 Nginx 配置文件"这一危险操作封装成了 9 个参数明确、行为可预期、失败可回滚的标准工具。其核心价值在于:AI Agent 只需关心"配置长什么样",而把路径安全、语法校验、受限指令拦截、自动备份、test-and-reload 原子操作、集群同步等工程细节全部交由 nginx-ui 兜底。结合 mcp/router.go 的读写分级授权与 mcp/config/config_validation_test.go 的安全测试,可以确认这是一套面向自动化场景、具备生产级安全考量的配置管理能力。希望本文能帮助你在此基础上,安全地把 Nginx 配置管理接入自己的 AI 工具链。
- 后端
- 前端
- 运维
- MCP 服务
【免费下载链接】nginx-ui
Yet another WebUI for Nginx
相关推荐
Nginx-UI MCP 配置文件管理:用 AI 代理安全操作 Nginx 配置的 9 个工具
Nginx UI MCP 配置文件管理:用 AI 代理安全操作 Nginx 配置的 9 个工具 Nginx UI 通过 MCP(Model Context Pr
后端前端运维MCP 服务Nginx UI 的 MCP 模块:为 AI Agent 提供 Nginx 配置管理与服务控制接口
Nginx UI 的 MCP 模块:为 AI Agent 提供 Nginx 配置管理与服务控制接口 MCP(Model Context Protocol,模型上
后端前端运维MCP 服务Nginx GUI 管理工具:简化Nginx配置
Nginx GUI 管理工具:简化Nginx配置 Nginx GUI 是一个开源项目,旨在提供一个图形用户界面来管理和配置 Nginx 服务器。该项目主要使用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考