Proxy Toolbox
Proxy Toolbox / Guides / proxifier-windows

Proxifier SOCKS5 Setup: Sending Any Windows Application Through a Proxy

Windows has no single switch that pushes every program through a proxy. Chrome picks up the system settings, curl reads an environment variable, and a large share of desktop software ignores both and opens sockets straight to the internet. Proxifier closes that gap. It sits under the network stack, catches outbound TCP connections and hands them to a proxy according to rules you write yourself. I keep it running on two work machines and on a scraping box, and I can say that the proxy entry takes 40 seconds to fill in while the rules take the rest of the evening.

This walkthrough goes in the order I actually do it: install, add the server, understand what a chain is, write rules, exclude the local network, fix DNS, then read the log until the picture matches what I expect. The endpoint I point it at is private SOCKS5 proxies I run my own jobs through, so every field value below comes from a live setup.

What Proxifier does to a Windows connection

Proxifier installs a driver that hooks the Winsock layer. When an application calls connect() on a TCP socket, the driver checks the destination against your rule list. If a rule says the connection goes through a proxy, Proxifier opens its own socket to the proxy, performs the SOCKS5 or HTTP CONNECT handshake, and then relays bytes in both directions. The application never learns about any of this. It thinks it talked to the target host directly, and that is why programs with no proxy settings of their own work fine under it.

Three consequences follow from that design, and all three cause support questions later.

Only new connections are intercepted. Sockets that were already open when you started Proxifier or when you saved a rule keep running direct until they close. Restart the application after every rule change. I have lost an hour to a scraper that kept a pooled keep alive connection open for 15 minutes and cheerfully ignored the proxy the whole time.

Processes running under other accounts are skipped by default. Anything launched by the Service Control Manager under SYSTEM, LOCAL SERVICE or another user account stays outside the profile until you turn on the services option in the profile settings. Scheduled tasks that run whether or not you are logged in fall into the same bucket.

Store applications live in an AppContainer sandbox and need the matching option enabled, because the sandbox blocks the loopback path Proxifier uses for them.

The installer needs administrator rights and loads a kernel driver, so on locked down machines it will not go in. There is a portable edition for that case. It runs from a folder and covers most of the same ground, with the services and AppContainer parts unavailable. On first launch you get a default profile holding two rules: localhost goes direct, everything else goes direct. Nothing is proxified until you say so, which is the sane default.

Where the SOCKS5 server goes in the interface

Open Profile > Proxy Servers and press Add. The dialog has four things that matter: address, port, protocol and authentication.

Address takes the host or IP of your proxy. Port takes the listening port, which is 1080 on most SOCKS5 endpoints and 3128 or 8080 on HTTP ones. Protocol is a radio group with SOCKS Version 5, SOCKS Version 4, HTTPS and HTTP. Pick SOCKS Version 5 for a SOCKS endpoint. The HTTPS entry in that group means an HTTP proxy that accepts the CONNECT method, which is what you want if you also keep an HTTP proxy entry for the same profile alongside the SOCKS one.

Access lists usually arrive in one of two shapes:

203.0.113.10:1080
203.0.113.10:1080:u4172:9fbe2c41

The first shape means the endpoint authorises you by your own WAN address, which you bind in the dashboard. Leave the Authentication checkbox empty for it. If you tick authentication and send credentials to an endpoint that expects address binding, the handshake fails with a method rejection and the log fills with authentication errors that have nothing to do with your password.

The second shape maps field by field: address, port, username, password. That is SOCKS5 access with login and password auth, and it is the shape I prefer on laptops, because a laptop changes networks and a bound address stops matching the moment you move to another office.

Two bound addresses come with a package, and the thread ceiling splits between them. A package that allows 1000 concurrent threads gives 500 per bound address once both are in use. Keep that number in mind before you point 40 browser profiles at one entry.

The Check button next to the list opens the proxy checker. It runs a handshake, requests a test page and prints latency and throughput. Run it before you write a single rule. A red line here means the problem is between you and the endpoint, and no amount of rule editing will help.

Proxy server and proxy chain are two different objects

The same dialog has a second pane on the right for chains, and this is where people mix up two concepts.

A proxy server is one hop. Your traffic leaves the machine, arrives at the endpoint, leaves the endpoint towards the target. A proxy chain is an ordered list of hops: the connection is tunneled through the first node, then through the second from inside the first, and so on down the list. You build one by pressing Create in the chain pane and dragging servers into it. The order shown top to bottom is the order the connection travels.

PropertySingle proxy serverProxy chain
Hops between you and the target12 or more, in fixed order
Latencyone round trip addedround trips add up, three hops turn 90 ms into 250 ms and higher
Failure behaviourconnection fails, retry hits the same endpointany node down kills the whole chain
Handshake support neededSOCKS5 or CONNECT on one nodeevery node must tunnel arbitrary TCP, SOCKS5 does this well
Where I use itscraping, automation, any volume workreaching an internal host through a jump box
Thread costone slot per connectionone slot on every node per connection

The thread cost line is the one that catches people. A chain of two nodes on the same package consumes two slots for one connection, so a 20 thread scraper eats 40. For volume work I keep one hop and spend the saved latency on more parallel requests.

Chains are selected as a rule action exactly like a single server, so nothing in the rule syntax changes when you switch.

How proxification rules are read, top to bottom

Open Profile > Proxification Rules. Every rule holds five things: a name, an application list, a target host list, a target port list, and an action. The action is Direct, Block, or the name of a proxy or chain you defined earlier.

Evaluation is top down and stops at the first match. A rule matches when all its filled fields match the connection: the process matches the application list, the destination matches the host list, the destination port matches the port list. Empty fields mean "any". The bottom rule is called Default, it cannot be deleted, moved or given filters, and it catches everything that reached it.

Here is the order I use on a scraping box, exactly as the list looks after I finish:

#Rule nameApplicationsTarget hostsPortsActionWhat it catches
1Localanylocalhost; 127.0.0.1; %ComputerName%; ::1anyDirectloopback, own hostname
2LANany10.0.0.0-10.255.255.255; 172.16.0.0-172.31.255.255; 192.168.0.0-192.168.255.255anyDirectRDP, database, printer, license server
3Proxifier itselfProxifier.exeanyanyDirectupdate and checker traffic, stops a loop
4Telemetry offany*.telemetry.example; *.crashpad.exampleanyBlocknoise that would eat threads
5Parserparser.exe; python.exeany80; 443; 8080-8090Proxy SOCKS5the job this box exists for
6Browserchrome.exeany80; 443Proxy SOCKS5profile work in the browser
7DefaultanyanyanyDirectWindows Update, mail client, everything else

Two ordering traps live in that table. Put rule 5 above rule 2 and every internal database call from python.exe goes out to the proxy and comes back as a timeout. Put a rule with an empty application field and an empty host field anywhere above the others and it swallows the entire list, because a rule with no filters matches everything.

The application field accepts semicolon separated executable names, wildcards such as node*.exe, and full paths. Reach for the full path when two builds share a name. I keep a portable Chrome under a separate folder and a system Chrome, and only the full path form tells them apart:

C:\Tools\chrome-portable\chrome.exe

Each rule has an enable checkbox. I switch a rule off for one test and switch it back afterwards, and the log immediately shows which rule takes over.

Sending one application through and leaving the rest direct

The practical goal most people arrive with: one program uses the proxy, the rest of the machine keeps its normal route. That is rules 5 and 7 in the table above, and the whole job takes four steps.

Find the executable name first. Task Manager, Details tab, right click the process, Open file location. Do this while the program is running and doing network work, because launchers lie. A launcher named app.exe may spawn app-core.exe or a helper under a versioned folder, and the socket belongs to the child. Proxifier matches the process that owns the socket, so the child is the name you need.

Add the rule. Name it after the program, paste the executable name into Applications, leave Target hosts and Target ports empty, and set Action to your SOCKS5 entry. Empty target fields mean the program goes through the proxy for every destination, which is what you want for a scraper.

Drag it above the Default rule and below your local exclusions. Press OK. The profile saves on OK, and rules take effect for connections opened after that moment.

Restart the program. Then watch the log pane while it makes its first request.

For a browser there is one extra move. Chrome and Edge prefer QUIC over UDP 443 when the server offers it, and the rule set you just wrote governs TCP connections. The browser falls back to TCP on its own after a delay you can feel in page load times. Start it with QUIC switched off and every request lands on the path you designed:

"C:\Program Files\Google\Chrome\Application\chrome.exe" --disable-quic --user-data-dir=C:\profiles\job7

On thread arithmetic, the unit to count is the socket. One scraper thread holds one connection at a time, one browser profile holds between 6 and 30 depending on the page. A package with 1000 threads and no metering on volume carries roughly 40 heavy browser profiles or 900 scraper threads, and a Dolphin Anty profile routed through Proxifier sits at the heavy end of that count. I plan at 70 percent of the ceiling, because retries and half closed sockets hold slots for a few seconds after the work is done.

Keeping local and internal addresses off the proxy

Every setup needs this rule and half of them are missing it. The symptom is familiar: the moment Proxifier turns on, RDP to the office server hangs, the local database call times out, the network printer disappears. All three are working perfectly. Their traffic is being sent to a remote endpoint that has no route back into your LAN.

The fix is a Direct rule sitting above everything else, with the private ranges in Target hosts:

localhost; 127.0.0.1; ::1; %ComputerName%; *.local; *.lan;
10.0.0.0-10.255.255.255;
172.16.0.0-172.31.255.255;
192.168.0.0-192.168.255.255;
169.254.0.0-169.254.255.255

The field accepts host names with wildcards, single addresses and hyphenated ranges, all separated by semicolons. %ComputerName% expands to your machine name, which matters because some software addresses itself by name over the network stack. The link local range 169.254 covers the address a NIC assigns itself when DHCP fails, and leaving it out gives you a 20 second hang on every network hiccup.

Add Proxifier's own executable as a Direct rule too. The program checks for updates and runs its proxy checker through the same stack it controls, and without that rule you get a connection loop. Proxifier detects most loops and refuses them, printing a loop message in the log, though the clearer path is to keep its own traffic out of the rules from the start.

One more entry worth keeping direct is your monitoring agent. If a Zabbix or Prometheus exporter reports to a server inside the LAN it is already covered by the private ranges, and if it reports to a hosted collector you want its numbers to reflect the machine's own line.

Name resolution, and where DNS actually goes

Open Profile > Name Resolution. The checkbox that decides everything is "Resolve hostnames through proxy".

With it ticked, Proxifier does no lookup locally. It passes the hostname to the endpoint inside the SOCKS5 request as an address of type 3, and the resolution happens at the exit. The target site sees a request whose DNS lookup and TCP connection came from the same place, which is the consistent picture you want.

With it unticked, Windows resolves the name through your own resolver and Proxifier connects to the resulting IP. Two things break quietly here. Your resolver learns every domain your scraper touches, which is a privacy question on a shared network. More practically, large sites answer DNS differently by region: your local resolver hands you an edge node near you, Proxifier then connects to that node from an endpoint somewhere else, and you get slower responses, certificate mismatches on a few CDNs, and occasional redirects to the wrong regional site.

Keep an exclusion list underneath for internal names that only your own resolver knows:

%ComputerName%; *.local; *.lan; *.corp.example; 127.0.0.1

Names in that list are resolved locally even when everything else goes to the exit.

Applications with their own resolver need a second look. Chrome ships an async DNS client and can be configured for DNS over HTTPS. With DoH on, the browser sends lookups as HTTPS requests to a resolver of its own choosing, and those requests are themselves proxified, so nothing leaks to your ISP. The catch is that the resolution now happens at a third party resolver, with the exit node left out of the lookup, so the regional mismatch described above comes back. For any profile I route through a proxy, I turn the browser's secure DNS off and let the SOCKS5 layer carry the name.

You can confirm the setting from the log without any external tool. A line reading api.example.net:443 means the hostname went to the proxy. A line reading 93.184.216.34:443 for the same request means Windows resolved it first.

Reading the connection log

The pane at the bottom of the main window is the only place that tells you the truth about what happened. Everything else is a guess.

Turn on verbose output from the Log menu before you debug anything. Verbose adds the rule name to every entry, which turns a vague failure into a one line answer. A working session looks like this:

[09:41:02] parser.exe *64 - api.example.net:443 matching rule : Parser ; Proxy SOCKS5 203.0.113.10:1080
[09:41:02] parser.exe *64 - api.example.net:443 open through proxy 203.0.113.10:1080 SOCKS5
[09:41:03] parser.exe *64 - api.example.net:443 close, 1841 bytes sent, 24603 bytes received, lifetime 00:01
[09:41:04] outlook.exe *64 - mail.example.com:993 matching rule : Default ; Direct
[09:41:04] outlook.exe *64 - mail.example.com:993 open directly

Five things are worth pulling out of those lines. The process name with its bitness marker, which tells you whether the child process or the launcher owns the socket. The destination as Proxifier saw it, hostname or IP, which answers the DNS question from the previous section. The rule that matched, which proves your ordering. The word directly or through proxy, which is the actual verdict. And the byte counters at close, where zero bytes received means the tunnel came up and the target said nothing, a very different problem from a connection that never opened.

Right clicking the pane gives you a filter and a copy option. On a busy box I filter by process name, because a browser generates 300 lines a minute and buries the one line I need. Log > Write to file keeps a rolling text log, which is what I hand to support when an endpoint behaves oddly for an hour and then stops.

The statistics window, opened from the View menu, shows live connection counts per process. That is the fastest way to see how many slots a program is really holding. I open it whenever a scraper starts reporting timeouts, because seeing 480 live sessions against a 500 slot half of a package explains the timeouts on its own.

Proving the application really went through the proxy

The log says the connection was proxified. I still run two independent checks, because the log describes what Proxifier did and says nothing about what the target received.

Check the socket table first. Every proxified connection from any application terminates at your endpoint, so the machine should show established sessions to the proxy port and none to the target:

netstat -ano | findstr ":1080"
tasklist /fi "pid eq 8124"

PowerShell gives the same picture with process names attached:

Get-NetTCPConnection -State Established |
  Where-Object { $_.RemotePort -eq 1080 } |
  Select-Object RemoteAddress, RemotePort, OwningProcess

If the target's own address shows up in that list for the process you routed, the rule did not match, and the log will name the rule that did.

Then ask the target what it sees. This has to be done from inside the application under test, because a command line check runs as a different process and may hit a different rule. For a browser, open any address echo page in the profile you routed. For a scraper, point one job at an echo endpoint and log the answer. For anything scriptable, a single request tells you the exit address:

curl.exe -s https://api.ipify.org

Run that inside the rule scope and you get the exit. Run it outside and you get your own line. The difference between the two answers is the proof.

The block test is my favourite trick and it takes 10 seconds. Temporarily change your application rule's action to Block, restart the program, and watch it fail to reach anything at all. If it keeps working, the rule never matched it, and you have been reading the wrong log line all along. Set the action back to the proxy afterwards. This one test has saved me more debugging time than every other check combined, because it separates a wrong rule from a wrong endpoint in a single move.

Exit addresses come out of a shared pool of around 12 000 active entries with rotation handled on the service side, so the address in the echo answer will differ between sessions. Steady behaviour comes from the endpoint quality, which is why I keep jobs on exits that show only their own address in the echo and read that answer once per run to confirm the route is live.

Errors you will meet, and what each one points at

Most Proxifier trouble reports fall into a short list. Here are the messages as they appear in the log, with what actually causes them.

Log messageWhat it meansWhere the fix is
Could not connect through proxy ... status code 4 (host unreachable)The endpoint accepted you and failed to reach the targetTarget name wrong, target refusing the exit, or resolution failing at the exit. Retry, then try another target to isolate
status code 5 (connection refused)The target refused the portWrong port in the request, target service down
status code 2 (connection not allowed by ruleset)The endpoint declined this destinationPort or destination outside what the endpoint serves
The proxy server requires authenticationCredentials missing or rejectedBound address changed, or the wrong auth mode is ticked in the server entry
no acceptable authentication methodsThe handshake offered a method the endpoint does not acceptA username went to an endpoint that authorises by bound address, or SOCKS4 was picked for a SOCKS5 port
Could not connect to proxy ... The connection attempt timed outNothing answered on the proxy portLocal firewall, corporate egress filter, wrong port, endpoint down
Connection closed by the proxyThe endpoint dropped an established sessionThread ceiling reached, or the session hit its idle window
Proxy server does not support UDPThe application tried a UDP flowQUIC in a browser, or a client using UDP transport. Disable QUIC or route that app direct
matching rule : Default ; Direct for the app you routedYour rule never matchedExecutable name, rule order, or process account
A connection loop has been detectedProxifier's own traffic entered its own rulesAdd a Direct rule for Proxifier.exe

Three of these deserve more than a table row.

The application ignores the rules. In order of how often I see it: the socket belongs to a child process with a different executable name; the rule sits below a broader rule that matched first; the program runs as a service under SYSTEM with the services option off; the connection was already open before the rule was saved; the program has a proxy setting of its own pointing somewhere else, so Proxifier faithfully routes a connection to a proxy you forgot about. Verbose log plus the block test settles all five.

If the interface confuses you, read the saved profile. It lives under %APPDATA%\Proxifier\Profiles as an XML file, and rule order in the file is rule order in memory:

<RuleList>
  <Rule enabled="true">
    <Name>Local</Name>
    <Targets>localhost; 127.0.0.1; %ComputerName%</Targets>
    <Action type="Direct" />
  </Rule>
  <Rule enabled="true">
    <Name>Parser</Name>
    <Applications>parser.exe; python.exe</Applications>
    <Action type="Proxy">100</Action>
  </Rule>
  <Rule enabled="true">
    <Name>Default</Name>
    <Action type="Direct" />
  </Rule>
</RuleList>

Copying that file is also how I move a working setup between machines in under a minute.

Authentication fails. Two causes cover nearly all cases. The bound address stopped matching, which happens on dynamic home lines, after a VPN client starts, or when the machine switches from ethernet to wireless with a different egress. Rebind in the dashboard and the errors stop. The second cause is a paste with a trailing space in the password field, invisible in the masked box. Retype it by hand once before blaming the endpoint. A third, rarer case: an HTTP endpoint entered as SOCKS5. The port answers, the handshake fails, and the message mentions authentication because the first byte of the HTTP reply is read as a SOCKS version byte.

Name resolution goes around the tunnel. You have the setting from the section above, and the symptom to watch for is a log full of raw IP destinations for a program that clearly works with domain names. That means Windows resolved first. Two extra sources of leaks live outside Proxifier: a browser with secure DNS enabled, and any client that ships its own resolver library, which several scraping frameworks do. For the frameworks, pass the hostname to the request layer and let the SOCKS5 hop resolve it. For browsers, turn secure DNS off in the profile you route, and the same switch sits inside a profile in an antidetect browser, where routing and name lookups belong to the profile itself. Steady exit behaviour under repeated lookups is one reason I keep this work on server side addresses with resolution done at the exit.

Once the log shows the rule you expect, the destination as a hostname, and an echo answer from the exit, the setup is finished and stays finished until you edit the rules or the machine changes networks. If the browser side comes next, the same routing logic applied per profile is covered in the SwitchyOmega guide for Chrome, multi profile work with a fingerprint browser in the AdsPower profiles walkthrough, and the response side of the job in reading block headers. When you have an access line in front of you and no patience for mapping fields by hand, drop it into the connection string parser: it splits address, port, login and password apart and prints them already arranged for Proxifier, curl, Playwright and the other clients you are likely to feed next.