1

I have a Linux VPS, and want to route only a single application through a commercial VPN (Mullvad). I do not want to connect to the VPN as a network interface and route all traffic through it. The application supports local SOCKS5 proxies. How can this be done without costly and cumbersome solutions such as virtual machines or separate servers?

user234683
  • 161
  • 7

2 Answers2

1

You can't use SOCKS as it works at a different OSI level to a VPN (ie at the TCP level). Per their help page, Mullvad VPN "only" offer VPN service over Wireguard and OpenVPN (nothing wrong with that, but stating it helps define the limits we are dealing with).

The easiest way to handle this - if allowed by your application - is to set up the VPN so it does not honor a default gateway, and you only push the IP addresses associated with the application through it.

If you can't route based on IP address the alternatives are a lot more complex and depend on the specifics/implementation of the application in question - and the Virtual machine you don't want will likely be the easiest way of doing it, and leave the least chance for future breakage. To do this without a VM or the like you will need to get into policy based routing, and work out how you would identify the packets to be routed through the VPN gateway, for example you could use policy based routing and NAT and the "owner" module in iptables - which can apparently allow you to select rules based on UID, GID, PID, SID command. This is fairly advanced routing. (I'm a seasoned Linux sysadmin by trade, and I believe I could do it, but I expect it would take me a while to get it "just so") https://stackoverflow.com/questions/4314163/create-iptables-rule-per-process-service#4314473 provides some useful hints, but does not get into the policy routing side of the problem. https://serverfault.com/questions/699481/route-ip-traffic-based-on-process-to-different-default-routes-interfaces also hints at possible solutions to the routing side of the problem by using namespaces or policy routing.

davidgo
  • 68,623
  • 13
  • 106
  • 163
  • The application is SearXNG and it seems they do [offer an option](https://docs.searxng.org/admin/engines/settings.html#outgoing) to use different network interfaces. So just to make sure I understand, Mulvad gave me a WireGuard .conf with Address = 10.66.223.77/32,fc00:bbbb:bbbb:bb01::3:df4c/128 for the interface. I assume that source IPs in this subnet will go through that interface, so I would just put this conf into /etc/wireguard, giving me a new interface, and then set the source_ips to 10.66.223.77/32 in the application config? – user234683 Jul 01 '22 at 03:35
  • I've not used Wireguard (only OpenVPN), so can only be of limited help, but if this SearXNG does what I understand it to do (ie hit multiple search engines, then aggregate the results and runs on your side), its likely to be more complex then you envisage from your comment as you will need policy based routing. – davidgo Jul 01 '22 at 05:10
  • I see SearXNG has a docker image associated with it. I expect you can use that image and the process described at https://www.linuxserver.io/blog/routing-docker-host-and-container-traffic-through-wireguard to route the docker images traffic through wireguard. (Docker is close to a lightweight VM, so not sure if this is an option) – davidgo Jul 01 '22 at 05:12
  • I was able to get policy based routing to work relatively easily since I can filter it by the source_ip and searxng lets you set the source_ip Routing by owner also works. However, the problem is that DNS is not routed, and it appears impossible to route DNS requests differently without patching system libraries: https://unix.stackexchange.com/q/224682 But it turns out there is already an answer to my original SOCKS5 method: https://superuser.com/q/1307743 So I will have to try that in order to get DNS routed as well – user234683 Jul 04 '22 at 20:25
0

For Cisco AnyConnect, Juniper SSL VPN and some other proprietary protocols there is OpenConnect with ocproxy / tunsocks support, which expose VPN as a SOCKS/HTTP proxy.

For WireGuard, there's wghttp, wg-http-proxy, wireproxy, onetun

For OpenVPN, there's a patch for ocproxy support, but it's outdated (for 2.3.x branch). I've ported it to the recent 2.5, but this is PoC (Windows not supported, yet).

On Linux, you can use network namespaces, bring up VPN and setup a proxy server in each. This is a generic universal method but it's a bit messy to maintain.

ValdikSS
  • 94
  • 1
  • 4