Shadowsocks-Windows Forward Proxy Feature and Privoxy Integration: Complete Technical Guide
The forward proxy feature in shadowsocks-windows embeds a Privoxy instance that converts the Shadowsocks SOCKS5 listener into an HTTP-compatible forward proxy, allowing local applications to tunnel traffic through the encrypted Shadowsocks connection without native SOCKS5 support.
shadowsocks-windows v4 includes a built-in forward proxy component that exposes the Shadowsocks client as both HTTP and SOCKS5 endpoints for local applications. When enabled, the client automatically extracts and launches a bundled ss_privoxy.exe process that listens for HTTP requests and forwards them to the local Shadowsocks SOCKS5 port, effectively creating a transparent bridge for legacy applications that require standard HTTP proxy connectivity.
Architecture of the Forward Proxy System
The forward proxy implementation consists of three coordinated layers that handle configuration, user interface, and process management.
Configuration Model (ForwardProxyConfig.cs)
At the core of the system lies the ForwardProxyConfig class defined in shadowsocks-csharp/Model/ForwardProxyConfig.cs. This data model stores the operational parameters including the selected proxy type (PROXY_SOCKS5 or PROXY_HTTP), the local listening port, and the autoStart boolean flag that determines whether the proxy launches automatically when Shadowsocks connects.
UI and ViewModel Layer
User interaction flows through ForwardProxyViewModel.cs and ForwardProxyView.xaml.cs in the ViewModels and Views directories respectively. The ViewModel handles validation logic and exposes a SaveCommand that invokes ShadowsocksController.SaveProxy() to persist configuration changes. The WPF view binds the Enable checkbox directly to config.autoStart, providing immediate control over automatic startup behavior.
The PrivoxyRunner Service
The PrivoxyRunner class in Controller/Service/PrivoxyRunner.cs serves as the execution engine. This service manages the entire lifecycle of the embedded Privoxy process, from binary extraction to configuration generation and process monitoring. When ShadowsocksController initializes a connection, it checks proxy.autoStart and invokes privoxyRunner.Start(_config) to activate the forward proxy.
How PrivoxyRunner Manages the Embedded Proxy
The PrivoxyRunner.Start() method orchestrates a sophisticated setup process that prepares the Privoxy environment without requiring manual installation.
First, the runner decompresses privoxy.exe.gz from embedded resources into a temporary directory as ss_privoxy.exe. It then generates a unique configuration file by reading the template from Data/privoxy_conf.txt and replacing the placeholders __SOCKS_PORT__ and __PRIVOXY_BIND_PORT__ with the actual Shadowsocks SOCKS5 port and the desired Privoxy listening port. Finally, it launches the process as a background job, monitors its Process ID (PID), and registers cleanup handlers for graceful shutdown.
// Simplified logic from PrivoxyRunner.Start(ShadowsocksConfig cfg)
string privoxyTemplate = Resources.privoxy_conf; // from privoxy_conf.txt
privoxyTemplate = privoxyTemplate.Replace("__SOCKS_PORT__", cfg.localPort.ToString());
privoxyTemplate = privoxyTemplate.Replace("__PRIVOXY_BIND_PORT__", _runningPort.ToString());
// Write to temporary file: privoxy_<uid>.conf
// Launch: ss_privoxy.exe -c <tmpConf>
Enabling the Forward Proxy
You can activate the forward proxy feature either through the graphical settings interface or programmatically via the controller API.
Through the Settings Interface
Navigate to the Settings dialog and select the Forward Proxy section. The ForwardProxyView.xaml.cs binds to ForwardProxyViewModel, allowing you to select the proxy mode (SOCKS5 or HTTP), specify the local port, and check the Enable box to set autoStart to true. Clicking Save triggers ShadowsocksController.SaveProxy(), which persists the configuration to the main Shadowsocks configuration file.
// From ForwardProxyView.xaml.cs (simplified)
public ForwardProxyView()
{
InitializeComponent();
ViewModel = new ForwardProxyViewModel();
}
// Save button handler
_viewModel.SaveCommand.Execute(null);
// Internally calls: _controller.SaveProxy(GetForwardProxyConfig());
Programmatic Configuration
For automated deployments or custom clients, instantiate ForwardProxyConfig directly and pass it to the controller:
var controller = ShadowsocksController.Instance;
var proxyConfig = new ForwardProxyConfig
{
mode = ForwardProxyConfig.PROXY_HTTP,
localPort = 8118,
autoStart = true
};
controller.SaveProxy(proxyConfig); // Persists configuration
controller.Start(); // Launches Shadowsocks + Privoxy
Traffic Flow and Protocol Handling
Once active, the forward proxy creates a multi-hop data path. Local applications connect to the Privoxy HTTP port (or directly to the SOCKS5 port depending on configuration). Controller/Service/TCPRelay.cs handles the protocol-specific logic for both PROXY_SOCKS5 and PROXY_HTTP modes, ensuring that incoming connections are properly formatted and forwarded to the remote Shadowsocks server.
A typical HTTP request flows as follows:
# Application sends HTTP request to Privoxy
curl -x http://127.0.0.1:8118 http://example.com
# Privoxy (ss_privoxy.exe) forwards to Shadowsocks SOCKS5
# Shadowsocks encrypts and transmits to remote server
Summary
- ForwardProxyConfig stores the proxy mode (SOCKS5/HTTP), local port, and auto-start preferences in
Model/ForwardProxyConfig.cs. - PrivoxyRunner extracts
ss_privoxy.exefrom embedded resources, generates runtime configuration fromData/privoxy_conf.txt, and manages the process lifecycle. - ShadowsocksController coordinates activation, calling
PrivoxyRunner.Start()whenautoStartis enabled and the client connects. - TCPRelay.cs implements the underlying data forwarding logic for both SOCKS5 and HTTP proxy protocols.
- The bundled Privoxy binary eliminates external dependencies, automatically configuring itself to point to the dynamic Shadowsocks SOCKS5 port.
Frequently Asked Questions
What is the difference between SOCKS5 and HTTP mode in the forward proxy feature?
SOCKS5 mode exposes a native SOCKS5 proxy that applications can connect to directly for TCP traffic. HTTP mode utilizes the embedded Privoxy instance to provide an HTTP/1.1 compatible proxy endpoint, which is necessary for applications that do not support SOCKS5 but can be configured to use a standard HTTP proxy. Both modes ultimately tunnel traffic through the same encrypted Shadowsocks connection.
How does shadowsocks-windows handle the Privoxy executable without requiring a separate installation?
The project embeds privoxy.exe.gz as a compressed resource within the assembly. The PrivoxyRunner class decompresses this resource into a temporary directory as ss_privoxy.exe at runtime, generates a configuration file specific to the current Shadowsocks session, and launches the process. This self-contained approach ensures Privoxy functionality without requiring users to install or configure Privoxy separately.
Can I use the forward proxy feature with applications that only support HTTP proxies?
Yes, this is the primary use case for the Privoxy integration. By selecting HTTP mode in ForwardProxyConfig and configuring your application to use http://127.0.0.1:<port> (default 8118), the application can route traffic through Shadowsocks even though it lacks native SOCKS5 support. Privoxy handles the protocol conversion from HTTP to SOCKS5 automatically.
Where is the Privoxy configuration file stored during runtime?
PrivoxyRunner generates a unique temporary configuration file named privoxy_<uid>.conf in the system's temp directory for each instance. This file is created from the privoxy_conf.txt template with placeholders replaced by actual port numbers. The configuration file and the extracted ss_privoxy.exe are cleaned up automatically when the Shadowsocks client shuts down or when PrivoxyRunner.Stop() is invoked.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →