How to Route Local Proxy Server Traffic Through VPN on Linux Systems


2 views

The scenario describes a dual-router setup where:

  • Router #1 handles default ISP connection
  • Router #2 establishes PPTP VPN connection to alternative ISP

Clients normally connect through Router #1, but we want specific applications (like Opera browser) to route through Router #2's VPN tunnel via a proxy.

We'll implement this using:

1. VPN client configuration
2. Squid proxy server
3. Network namespace isolation (optional for advanced setups)
4. Routing table modifications

1. VPN Connection Setup

First establish your VPN connection using NetworkManager or CLI:

sudo nmcli connection import type vpn file /path/to/vpn-config.ovpn
sudo nmcli connection up vpn-connection-name

2. Install and Configure Squid Proxy

sudo apt install squid
sudo nano /etc/squid/squid.conf

Key configuration parameters:

http_port 3128
acl localnet src 192.168.1.0/24 # Your local network
http_access allow localnet
forwarded_for off
request_header_access Via deny all

3. Create Custom Routing Table

Add a new routing table for VPN traffic:

echo "200 vpnrt" >> /etc/iproute2/rt_tables
ip rule add from 192.168.1.100 table vpnrt # Proxy server IP
ip route add default via 192.168.1.2 table vpnrt # Router #2 IP

4. Force Proxy Traffic Through VPN

Mark and route Squid traffic:

iptables -t mangle -A OUTPUT -p tcp --dport 3128 -j MARK --set-mark 1
ip rule add fwmark 1 table vpnrt

For more isolation, create a dedicated network namespace:

sudo ip netns add vpnspace
sudo ip netns exec vpnspace ip link set dev lo up
sudo ip netns exec vpnspace squid

Check routing with:

curl --proxy http://proxy-server:3128 ifconfig.me
traceroute --proxy http://proxy-server:3128 example.com
  • Verify VPN tunnel is active: ip route show table vpnrt
  • Check Squid access logs: tail -f /var/log/squid/access.log
  • Test basic connectivity: sudo ip netns exec vpnspace ping 8.8.8.8

In this scenario, we have two distinct network paths:

Router #1 - Default ISP connection (main gateway)
Router #2 - PPTP VPN connection to external network

The challenge is to create a proxy server that exclusively uses Router #2's VPN connection while regular traffic flows through Router #1. This setup is particularly useful when you need application-level control over which traffic uses the VPN.

There are several ways to achieve this:

Method 1: Using Squid with Policy Routing

First, install Squid proxy server:

sudo apt-get install squid

Then configure routing tables to force Squid traffic through VPN:

# Create new routing table
echo "200 vpnrt" >> /etc/iproute2/rt_tables

# Add VPN interface to new table
ip rule add from [VPN_IP] table vpnrt
ip route add default via [VPN_GATEWAY] dev [VPN_INTERFACE] table vpnrt

# Mark Squid traffic
iptables -t mangle -A OUTPUT -p tcp --dport 3128 -j MARK --set-mark 1
ip rule add fwmark 1 table vpnrt

Method 2: Dockerized Proxy with VPN

Create a Docker container running both Squid and OpenVPN:

version: '3'
services:
  vpn-proxy:
    image: ubuntu/squid
    volumes:
      - ./squid.conf:/etc/squid/squid.conf
      - ./vpn-config.ovpn:/etc/openvpn/client/config.ovpn
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
    command: bash -c "openvpn --config /etc/openvpn/client/config.ovpn && squid -N"
    ports:
      - "3128:3128"

To implement your specific use case with Opera:

opera --proxy-server="http://[ROUTER2_IP]:3128" --no-proxy-server

Or configure manually in Opera settings:

  1. Go to Settings → Advanced → System
  2. Enable "Use proxy server"
  3. Enter your Router #2's IP and port 3128

For more granular control:

# Create VPN routing table
ip route add default via [VPN_GATEWAY] dev [VPN_INTERFACE] table vpnrt

# Mark packets from specific users
iptables -t mangle -A OUTPUT -m owner --uid-owner [squid_user] -j MARK --set-mark 1

# Apply routing to marked packets
ip rule add fwmark 1 table vpnrt
  • Check VPN connectivity: ping [VPN_GATEWAY]
  • Verify proxy accessibility: curl --proxy http://[PROXY_IP]:3128 ifconfig.me
  • Inspect routing: ip route show table vpnrt
  • Check marked packets: iptables -t mangle -L -v