多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Dify Docker 连接宿主机 MCP 服务 403 排障指南

Dify Docker 连接宿主机 MCP 服务 403 排障指南 Dify Docker 连接宿主机 MCP 服务 403 排障指南问题场景Dify通过 Docker Compose 部署在宿主机MCP 服务如 searXNG-mcp运行在宿主机监听0.0.0.0:3456宿主机本地测试 MCP 服务正常Dify 界面添加 MCP 服务时报错Failed to connect to MCP server: code403 messageClient error 403 Forbidden for url http://192.168.31.184:3456/mcp根因分析Dify 的 docker-compose 中包含一个ssrf_proxy容器基于 Squid用于防止 SSRF 攻击。Squid 配置中默认拦截所有内网 IP 段的请求squid.conf.template第 13 行http_access deny to_private_networksto_private_networksACL 包含192.168.0.0/16宿主机 IP192.168.31.184被命中Dify 内部发出的外部请求走ssrf_proxy:3128代理因此 MCP 请求在到达宿主机前被 Squid 拦截返回 403。关键文件文件作用docker/ssrf_proxy/squid.conf.template主配置模板第 12 行 include 白名单第 13 行 deny 私网docker/ssrf_proxy/docker-entrypoint.sh入口脚本读取环境变量动态生成白名单.envDify 环境变量配置文件入口脚本白名单机制docker-entrypoint.sh第 55 行write_optional_private_allowlistSSRF_PROXY_ALLOW_PRIVATE_IPSdify_allowed_private_networksdst该函数读取SSRF_PROXY_ALLOW_PRIVATE_IPS环境变量逗号分隔的 IP 列表动态生成/etc/squid/dify_allow_private.conf内容格式acl dify_allowed_private_networks dst 192.168.31.184 http_access allow client_localnet dify_allowed_private_networks该文件在deny to_private_networks之前被 include因此匹配的请求会被提前放行。解决步骤第一步确保 MCP 服务绑定 0.0.0.0部分 MCP 服务默认绑定127.0.0.1来自外部包括 Docker的请求无法到达。mcp-searxng 示例dockerrun--rm-p3456:3000\-eMCP_HTTP_PORT3000\-eMCP_HTTP_HOST0.0.0.0\-eSEARXNG_URLhttp://192.168.31.184:8080\isokoliuk/mcp-searxng:latest验证netstat-ano|findstr :3456# 应显示 0.0.0.0:3456 或 [::]:3456而非 127.0.0.1:3456第二步配置 SSRF 代理白名单在 Dify 的.env文件中添加SSRF_PROXY_ALLOW_PRIVATE_IPS192.168.31.184多个 IP 用逗号分隔SSRF_PROXY_ALLOW_PRIVATE_IPS192.168.31.184,192.168.31.185第三步完整重启 Dify必须dockercompose downdockercompose up-d重要不能使用docker compose restart ssrf_proxy。restart不会重新读取.env文件的环境变量白名单配置不会生效。第四步验证代理链路# 测试直连不走代理dockerexec-itdocker-api-1curl-vhttp://192.168.31.184:3456/mcp# 测试代理链路走 ssrf_proxydockerexec-itdocker-api-1curl-v--proxyhttp://ssrf_proxy:3128 http://192.168.31.184:3456/mcp预期结果两条命令都应返回HTTP/1.1 400 Bad RequestInvalid or missing session ID。400是 MCP 服务正常响应curl 未携带 MCP 协议头如果仍返回403 ForbiddenERR_ACCESS_DENIED说明环境变量未生效排障方法论宿主机 curl → MCP 服务 → 确认服务可用 Dify 容器 curl 直连 → MCP 服务 → 确认网络通 Dify 容器 curl 代理 → MCP 服务 → 确认 SSRF 代理是否拦截先确认宿主机自身能访问 MCP 服务用docker exec进入容器测试直连排除 Docker 网络问题用--proxy参数测试代理链路定位 SSRF 拦截查看 Squid 日志docker logs docker-ssrf_proxy-1常见错误码速查响应含义400 Bad RequestMCP 服务正常curl 未带 Session ID403 ERR_ACCESS_DENIEDSSRF 代理拦截检查白名单配置Connection refused端口未监听或防火墙阻断Could not resolve hostDNS 解析失败检查 IP 是否正确
返回列表