Dockerized egress control

Route app traffic
through one clean
VPN-backed SOCKS5 endpoint.

vpnsocksify runs OpenVPN or WireGuard inside a container, exposes a SOCKS5 proxy, and hardens the path with an iptables kill switch so proxied traffic only leaves through the tunnel.

2 VPN modes OpenVPN and WireGuard auto-detection
Kill switch Traffic drops instead of leaking on failure
~47MB Alpine-based image footprint
Multi-instance Run multiple exits on separate ports
Runtime view
Traffic path Tunnel locked
Ingress Your app Browser, curl, automation, scraper, anything with SOCKS5 support.
Container core Dante + VPN client SOCKS5 listens locally while OpenVPN or WireGuard owns the egress path.
Egress VPN exit IP Internet sees the tunnel endpoint, not your host network.
Kill switch Only VPN endpoints and tunnel interfaces are allowed out.
DNS Resolvers are configured first so hostname lookups stay controlled.
Health Proxy chain can be verified end-to-end through the live tunnel.
$ docker compose up -d [dns] Configuring DNS servers: 1.1.1.1,8.8.8.8 [killswitch] Allowing VPN endpoint: 203.0.113.8:1194/udp [openvpn] Tunnel interface detected: tun0 [ok] SOCKS5 listening on 0.0.0.0:1080 $ curl --proxy socks5h://user:pass@localhost:1080 https://api.ipify.org 198.51.100.23
Main functionality

The container does one job: own the outbound path.

The important part is not that it is a proxy. The important part is that every proxied request is forced through a VPN client that the container controls, while the kill switch blocks anything that tries to escape around it.

1. Detect + prep

Auto-detect the VPN config and lock DNS in first.

On startup, vpnsocksify determines whether your config is OpenVPN or WireGuard, writes the resolver setup, and prepares the container before the tunnel process starts.

  • `wg*.conf` and `[Interface]` sections resolve to WireGuard.
  • `.ovpn` and OpenVPN directives resolve to OpenVPN.
  • DNS setup happens before firewall enforcement and tunnel startup.
2. Enforce

iptables turns failure into a hard stop instead of a leak.

The kill switch parses the actual VPN endpoints where possible, allows only those flows on `eth0`, opens the tunnel interfaces, and blocks IPv6 entirely.

  • Parsed endpoint allow-list beats broad firewall exceptions.
  • Fallback ports cover common OpenVPN and WireGuard defaults.
  • When the tunnel is down, outbound traffic is still denied.
3. Expose

Dante gives your apps one SOCKS5 endpoint to target.

Once the VPN is live, the container generates the Dante config, optionally enables PAM-backed username/password auth, and keeps the proxy in the foreground.

  • Works for browsers, CLI tools, automation agents, and multi-container setups.
  • Bind to `127.0.0.1` for local-only access or `0.0.0.0` when intentional.
  • Health checks verify the actual proxy-to-tunnel-to-internet chain.
Quick start

Pick the runtime shape you want and ship it.

The page now reflects the commands that actually exist in this repo. Use the published image for speed, Compose for local development, or run multiple named instances for separate exits.

Run from GHCR with your VPN config mounted into `/config`.
docker run -d \
  --name vpnsocksify \
  --cap-add=NET_ADMIN \
  --device=/dev/net/tun \
  --sysctl net.ipv4.conf.all.src_valid_mark=1 \
  --sysctl net.ipv6.conf.all.disable_ipv6=1 \
  -p 1080:1080 \
  -v ./config:/config:ro \
  -e SOCKS_USER=myuser \
  -e SOCKS_PASS=mypass \
  ghcr.io/faeton/vpnsocksify:latest

curl --proxy socks5h://myuser:mypass@localhost:1080 https://api.ipify.org
Build locally from this repo and run with Compose.
git clone https://github.com/faeton/vpnsocksify.git
cd vpnsocksify

mkdir -p config
cp /path/to/your-vpn.ovpn config/

docker compose build
docker compose up -d

curl --proxy socks5h://user:pass@localhost:1080 https://api.ipify.org
Run several exits in parallel, each on its own port and config path.
CONTAINER_NAME=vpn-us \
SOCKS_PORT=1080 \
VPN_CONFIG_PATH=./config/us \
docker compose -p vpn-us up -d

CONTAINER_NAME=vpn-uk \
SOCKS_PORT=2080 \
VPN_CONFIG_PATH=./config/uk \
docker compose -p vpn-uk up -d

curl --proxy socks5h://localhost:1080 https://api.ipify.org
curl --proxy socks5h://localhost:2080 https://api.ipify.org
Use cases

Useful when you need network control, not just another proxy.

The value here is operational separation. Your app talks to a local SOCKS5 endpoint, while the container owns VPN configuration, auth, health checks, and leak prevention.

Browser isolation

Run separate local exits for browser profiles, containers, or identities without reconfiguring the host VPN every time.

Good fit for Firefox Multi-Account Containers, QA, and parallel logins.

Geo-testing

Switch application traffic between countries or providers while the rest of the machine keeps its normal network path.

Useful for localization checks, ad verification, and region-bound services.

Automation and agents

Point scripts, CLI tools, or coding agents at a local SOCKS5 proxy instead of teaching each tool how to manage a VPN stack.

Cleaner separation between app logic and network policy.

Multi-exit workloads

Stand up several containers at once, each with its own tunnel and credentials, and steer workloads independently.

Ideal for scraping, task sharding, or split-country test matrices.
Configuration

Small surface area, practical controls.

The runtime does not need a giant dashboard. It needs a short set of environment variables that map cleanly to how the container actually boots, authenticates, binds ports, and validates connectivity.

What matters most

Start with a config directory, decide whether the proxy should be public or local-only, and then layer in credentials and tunnel-specific auth only when needed. The rest of the startup flow is handled by the entrypoint.

SOCKS port Bind address Proxy auth VPN auth DNS servers Kill switch
  • Capabilities: the container requires `NET_ADMIN` and `/dev/net/tun` to manage the tunnel path.
  • WireGuard: works when the host has the kernel support required by `wg-quick`.
  • Access control: use `BIND_ADDR=127.0.0.1` when the proxy should not be reachable off-host.
  • Verification: the health check validates the actual proxy chain instead of just checking whether a process is alive.

Core environment variables

Variable Default Description
SOCKS_PORT 1080 Listen port exposed by Dante inside the container.
SOCKS_USER empty Optional SOCKS5 username. When set with a password, PAM auth is enabled.
SOCKS_PASS empty Password for the generated SOCKS5 user.
VPN_CONFIG empty Specific config filename inside `/config`; auto-detection is used when unset.
VPN_USER empty OpenVPN username for `auth-user-pass` flows.
VPN_PASS empty OpenVPN password for providers that require credentials.
BIND_ADDR 0.0.0.0 Published host bind address when using Compose port mappings.
DNS_SERVERS 1.1.1.1,8.8.8.8 Resolvers written into `/etc/resolv.conf` before tunnel startup.
KILL_SWITCH true Enables iptables rules that restrict egress to the tunnel path.
CONNECTION_TEST_URL https://api.ipify.org Target used by the health check to validate outbound connectivity.