My thoughts are like this:

I have this external vpn service that I am connecting to. But Is it possible for me to set up a local proxy server that uses that vpn connection, so applications that connects throu that proxy uses the vpn? This is applies to a Linux system.

Hints and links are welcome!

EDIT: Use case: Perhaps there is another way to do this.

Router #1 - Connects by the default net provided by ISP
Router #2 - Connects by PPTP VPN to another 'ISP'

Clients in network are by the default connected to the normal router #1 and all traffic gets handled by that. Client have a different browser (opera) that connects via a proxy on router #2 and ends up at the end of the VPN tunnel.

Does this clearify?

4 Answers 4


Although the situation you have described is not possible (running application can not override system routing table) you may have a couble of options:

  • setting up a proxy on the network you are reaching by VPN and get your applications use that proxy as default. There are several proxies you can choose from depending on the protocol your application is using
  • ssh to a host on the given network and exploit ssh-s service called as Dynamic Forwarding. This is basically a SOCKS proxy made out of your ssh client. You can then set your application up using this proxy or tweak it with tsocks (Transparent Socks)

man ssh_config

             Specifies that a TCP port on the local machine be forwarded over the
             secure channel, and the application protocol is then used to determine
             where to connect to from the remote machine.

             The argument must be [bind_address:]port.  IPv6 addresses can be specified
             by enclosing addresses in square brackets or by using an alternative syn‐
             tax: [bind_address/]port.  By default, the local port is bound in accor‐
             dance with the GatewayPorts setting.  However, an explicit bind_address
             may be used to bind the connection to a specific address.  The
             bind_address of “localhost” indicates that the listening port be bound for
             local use only, while an empty address or ‘*’ indicates that the port
             should be available from all interfaces.

             Currently the SOCKS4 and SOCKS5 protocols are supported, and ssh(1) will
             act as a SOCKS server.  Multiple forwardings may be specified, and addi‐
             tional forwardings can be given on the command line.  Only the superuser
             can forward privileged ports.
  • I appreciate all the answers, and I hate start looking for solutions without knowing if it's possible. Making ssh tunnels seems like the most uncomplicated ways. Thanks to you all.
    – Stojg
    Jul 20, 2009 at 14:28

Six year later I came to this question and almost let it down based on the accepted answer. As of today, it is not complicated, using policy routing. All the details are available on this same site, at https://serverfault.com/a/389004/70774.

In my case, I had first to make sure that the vpn was not the default route. How you will achieve that depends on what kind of connection manager you are using.

The proxy (tinyproxy) is running with its own user, so I mark all the packages coming from this user with the command

iptables -t mangle -A OUTPUT -m owner --uid-owner 125 -j MARK --set-mark 2

where 125 is the uid of the tinyproxy user and 2 is an arbitrary number, to be matched later.

Then I instruct the routing system to use a specific table to route all requests marked with 2.

ip rule add fwmark 2 table 3

Again, the 3 is just an arbitrary number. Just pray attention to choose an unused table (just see if there is something on the table with you choose with ip route list table 3 ).

Then I populate the table 3 with my default route:

ip route add default dev ppp0 via proto static scope link metric 1024

The last step was making a masquerading rule, of which I do not fully understand the necessity:

iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

Et voilà!

  • 4
    Some useful information to understand this answer: - ppp0 is the tunneled interface, usually it is named tun0 ; - "ip route add default dev ppp0 via proto static scope link metric 1024" is wrong. You should remove the "via" keyword and you should add "table 3" at the end to avoid changing the default route for all your system. Jan 20, 2019 at 14:05

This becomes quite easy with Squid and its tcp_outgoing_address xxx parameter:

apt install squid
nano /etc/squid/conf.d/proxy2vpn
# put this in: tcp_outgoing_address YOUR_VPN_NIC_IP (check ifconfig)
systemctl restart squid.service

Squid is listening on port 3128 by default.

Usage example:

curl --proxy https://ipinfo.io

The request will first go through Squid proxy and then through the VPN.


Maybe i didn't understand your question, but try this:

  • Setup an Server, connect to your VPN Server (what kind of VPN? OpenVpn, PPTP? IPSec?).
  • Make the default GW the VPN Endpoint
  • Enable IP Forwarding, something like this: "echo 1 > /proc/sys/net/ipv4/ip_forward"
  • On the Clients use your Server as Default GW.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.