A self-hosted Dify already has a proxy. Its Docker setup runs a Squid container called ssrf_proxy, and the HTTP Request node, custom API tools and the code node send their requests through it. Squid refuses private and local addresses, then forwards everything else straight from your server. So a residential proxy belongs behind Squid, as its parent, and not in place of it. That takes two lines in one file. We read every setting on this page in Dify 1.17.1, released on 10 September 2026.
Why would Dify need a proxy?
Dify's HTTP Request node sends a plain request, with no browser behind it. We tested what a plain request gets on 19 September 2026: thirteen sites, twice from our server in a hosting network and twice through a residential line. A residential IP changed the answer at four of them: Zillow, Instagram, Reddit and DuckDuckGo. Indeed, Glassdoor, Amazon and Booking refused both. At Indeed and Glassdoor, Cloudflare asked for a JavaScript check that a plain request cannot pass, whatever its IP. The table per site is on our OpenClaw page.
What goes through Dify's own proxy?
In the Compose files, the API points SSRF_PROXY_HTTP_URL and SSRF_PROXY_HTTPS_URL at http://ssrf_proxy:3128, and the code sandbox points SANDBOX_HTTP_PROXY and SANDBOX_HTTPS_PROXY at the same Squid:
| Traffic | Through Squid? |
|---|---|
| HTTP Request node | yes |
| Custom API tools | yes |
| MCP servers over HTTP, remote files | yes |
| Code node (sandbox) | yes |
| Calls to the plugin marketplace through Squid | yes, the template allows it |
| Plugins | not in Dify's example files |
Squid's template refuses private networks first, allows the plugin marketplace, and sends the rest out directly. It has no parent proxy, so every one of those requests leaves from your server's IP.
How do I put a residential proxy behind it?
Add two lines at the end of docker/ssrf_proxy/squid.conf.template:
cache_peer GATEWAY_HOST parent GATEWAY_PORT 0 no-query default login=USERNAME:PASSWORD
never_direct allow all
Then recreate the container, so its entrypoint builds the configuration from the template again:
docker compose up -d --force-recreate ssrf_proxy
cache_peer names your proxy as Squid's parent, and login= sends it the username and password. never_direct allow all forces every request through that parent instead of out directly. Dify's own rules still run first, so private and local addresses stay refused. One detail from Squid's reference: a % in the password has to be written as %%.
To check it, point an HTTP Request node at https://api.ipify.org and compare the answer with your server's IP.
Why not set the proxy somewhere else?
Two shortcuts look simpler and cost more:
SSRF_PROXY_*straight at the proxy. The API then skips Squid, and with it the refusal of private and local addresses thatssrf_proxyexists for.HTTP_PROXYon every container. It also catches internal traffic. One user's knowledge base stopped answering once the API's calls to the vector database went to the proxy. And it does not even move the HTTP Request node: its client is set to Squid explicitly, and Squid still goes direct.
The same user also tried http_access allow all in Squid's template. That line opens private addresses again, so leave Dify's access rules as they are.
Which proxy type fits Dify?
Residential, for the sites that refuse a hosting IP. One parent serves the whole instance, so every workflow shares the line. A rotating line suits page-by-page reads. A sticky line suits a workflow that logs in and then reads pages as that user.
HProxy residential gateways fit either way. Allow your server's IP on a Residential Premium plan, up to 150 per plan, and the cache_peer line needs no login= at all, so no password sits in the template. Rotating ports change the IP, and a sticky port holds one. An allowed IP takes no country or city targeting. For a country, use a generated line: its username carries the targeting and goes into login=. A sticky IP can still change early if its device leaves the network, so let the workflow retry. The residential proxies page lists the plans, and the plan API generates lines and manages allowed IPs from code.
What breaks when the proxy is on?
- Nothing changed after the edit. The container still runs the old configuration. Recreate it.
- Internal hosts you allowed stop answering. Hosts let through with
SSRF_PROXY_ALLOW_PRIVATE_IPSor_DOMAINSnow go to the parent too, which cannot reach your network. Add analways_directrule for them. - The knowledge base cannot reach the vector database.
HTTP_PROXYis set on the containers. Remove it, or list every internal service inNO_PROXY. - Marketplace calls cost traffic. Squid's template allows the plugin marketplace by name, so calls that reach it through Squid now use the residential line too.
- Plugins still use your server's IP. They run in the plugin daemon, which this setup does not cover.
- 407 Proxy Authentication Required. The
login=value is wrong, or a%was not doubled. On our gateways a 407 means a wrong password or a line from another plan. Our 407 guide walks through it. - Requests to a bare IP address hang. One user reported this in
ssrf_proxywith DNS errors in Squid's log. Use a hostname where you can. - The site still shows a JavaScript check. A proxy changes the address, not the client.
What this page does not cover
We read Dify 1.17.1's API code, Docker files and Squid templates, and Squid's reference pages. We did not run Dify or Squid. The plugin daemon is a separate program we did not read. The blocking test used plain requests from one server IP and one residential line, over one afternoon. Dify releases every few weeks, and a pull request for a new egress proxy is open, so we will read these settings again by 19 October 2026.
Where to go from here
Proxies for n8n covers another workflow builder, and proxies for self-hosted Firecrawl a scraper that Dify workflows often call. Sticky vs rotating sessions explains the choice above, and how websites detect proxies explains the checks behind the refusals.
Sources
- The SSRF proxy client (api/core/helper/ssrf_proxy.py) and its settings, the HTTP Request node factory, custom API tools, the ssrf_proxy service in docker-compose.yaml, the env examples, the Squid templates and entrypoint, and the LICENSE. langgenius/dify, release 1.17.1, 10 September 2026.
- cache_peer and never_direct. Squid configuration reference, squid-cache.org, read 19 September 2026.
- Issues #29701, #22228 and #29792, and pull request #39771. Dify issue tracker, 2025 to 2026.
- Plans, IP whitelist and sticky sessions; errors; the proxy API. HProxy documentation, hproxy.com/docs, 19 September 2026.
- Our own test of 19 September 2026: plain GET requests to 13 sites and 3 controls, two runs from our server and two through a residential line of our own house plan, with curl 8.5.0. Raw output is kept in the research folder of our OpenClaw page.


