OpenWRT as a SOCKS5 gateway to VPN

OpenWRT as a SOCKS5 gateway to VPN

Currently I use gluetun in a container to connect to VPN. I expose HTTP(S) proxy for my LAN and have a qBittorrent instance connected to it through network_mode.

This works fine enough, but I would prefer my router keeping the connection through VPN and exposing it through SOCKS5. I’ve tried running microsocks bound to VPN IP, but I can’t get it to route correctly, all the traffic goes to whatever is set as default route at the moment.

I do NOT want to route all the LAN traffic through a VPN or SOCKS5. I want specific apps to connect to VPN through SOCKS5

My current config:

# uci show network.vpn0
network.vpn0=interface
network.vpn0.proto='wireguard'
network.vpn0.private_key='justmyprivatekeyheremovealong='
network.vpn0.addresses='10.666.666.666/32'
network.vpn0.dns='10.64.0.1'

# uci show network.@wireguard_vpn0[0]
network.cfg0b1892=wireguard_vpn0
network.cfg0b1892.description='Zurich-02'
network.cfg0b1892.public_key='qcvI02LwBnTb7aFrOyZSWvg4kb7zNW9/+rS6alnWyFE='
network.cfg0b1892.allowed_ips='0.0.0.0/0'
network.cfg0b1892.endpoint_host='193.32.127.67'

# uci show firewall.@zone[3]
firewall.cfg1adc81=zone
firewall.cfg1adc81.name='vpn'
firewall.cfg1adc81.input='REJECT'
firewall.cfg1adc81.output='ACCEPT'
firewall.cfg1adc81.forward='REJECT'
firewall.cfg1adc81.masq='1'
firewall.cfg1adc81.mtu_fix='1'
firewall.cfg1adc81.network='vpn0'

VPN connection works, but I do not set “Route Allowed IPs” in the peer configuration as I only want microsocks (or whatever piece software that will expose it as SOCKS5) to use it.

# curl ifconfig.me
(my home IP, trust me)

# curl --interface vpn0 ifconfig.me
193.32.127.219

# uci show microsocks
microsocks.config=microsocks
microsocks.config.enabled='1'
microsocks.config.listenip='10.0.0.1'
microsocks.config.port='1080'
microsocks.config.auth_once='1'
microsocks.config.bindaddr='10.666.666.666'
microsocks.config.user='abc'
microsocks.config.password='abc'

# curl --socks5 abc:[email protected] ifconfig.me
(still my home IP, not VPN)

Is it a network configuration or microsocks problem?

Has to be an issue with microsocks not binding to the address specified for whatever reason. Maybe strace it to see what it’s doing?

1 Like

I did some more digging, microsocks doesn’t use provided external IP, same as sockd. They just use the default WAN interface. Interestingly, hev-socks5-server does work and forwards traffic to the VPN interface. But unfortunately UDP doesn’t at least when connecting to UDP trackers in qBittorrent.

I did some checks with sockd and this minimal config, 10.666.666.666 is my IP on VPN’s WireGuard interface.

logoutput: syslog stdout /mnt/data/sockd.log
user.privileged: root
user.unprivileged: nobody

internal: 10.0.0.1 port=1080
external: 10.666.666.666

socksmethod: none
clientmethod: none

debug: 0

client pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0
}

socks pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0
}

But when running strace -e trace=network -o /tmp/strace.txt sockd I can only see those calls and no further use of this descriptor when running curl. Built in debug of sockd also isn’t very helpful.

socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 7
bind(7, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("10.666.666.666")}, 16) = 0
getsockname(7, {sa_family=AF_INET, sin_port=htons(59201), sin_addr=inet_addr("10.666.666.666")}, [128 => 16]) = 0

Any hints? I will check hev-socks5-server with strace when I find some spare time. Or just compile and debug sockd myself.

In case of multithreaded programs, you need to use: strace -f

UDP support in SOCKS (both client and server side) is not very common and not always interoperable.

2 Likes

I’ve been down a similar path when trying to set up my router to manage VPN traffic for specific apps. I once set up a proxy server to handle some tasks without affecting the whole network. It took some tweaking, but using best mobile proxies helped streamline the connection for my mobile devices without rerouting everything through the VPN.

For your setup, make sure the routing tables are correctly configured. It sounds like you’ve done most of the heavy lifting already. Have you checked the firewall rules? Sometimes, a small adjustment there can make a huge difference. If you’re still hitting roadblocks, consider posting on a forum specifically for OpenWRT users—they can be super helpful.

Just for completness I’ll mention that I’ve abandoned the attempts to make a selective proxy to VPN on my router.

I have many self-hosted apps I want to exclusively use the VPN, not all of them natively support running through a proxy. So instead I created a separate VM, installed Mullvad CLI and put all the apps there. And for things like VPN for private browsing in Firefox I set up the simplest possible Dante (sockd) service on this VM:

logoutput: /var/log/sockd.log
internal: 10.0.0.5 port = 8888
external: wg0-mullvad
method: none
user.privileged: root
user.notprivileged: sockd

client pass {
    from: 10.0.0.0/16 to: 0.0.0.0/0
    log: connect disconnect error
}

socks pass {
    from: 10.0.0.0/16 to: 0.0.0.0/0
    log: connect disconnect error
}

This approach has some benefits, like simpler setup than running a gluetun container and VPN management. The only drawback is that it’s more resource intensive, but I can live with that.

2 Likes

This is also the approach I took, but I used LXC. Using the Mullvad app also has the benefit of automatically connecting you to another peer if the one you’re connected to goes down.

2 Likes