-
Notifications
You must be signed in to change notification settings - Fork 35
Redirecting dumbproxy into a tunnel or other network interface
There is a quite common need for a proxy to have its outgoing connection redirected somewhere else via some tunnel or other network interface without affecting all other connections from the system. For example you might want to forward connections via your proxy into some VPN connection, but you don't want this VPN connection to affect all your system traffic. For such cases I suggest use of Linux VRF feature to create multiple forwarding domains.
Let's say we have upstream wireguard VPN connection defined by /etc/wireguard/proton.conf
configuration file like this:
[Interface]
PrivateKey = xxxxxxxxxxxxxxx
Address = 10.2.0.2/32
DNS = 10.2.0.1
[Peer]
# NL-FREE#381133
PublicKey = xxxxxxxxxx
AllowedIPs = 0.0.0.0/0
Endpoint = xxx.xxx.xxx.xx:xxxxx
Let's modify it in a way to attach it to a separate forwarding domain. First, we need to define separate name routing table for it. Add following line to /etc/iproute2/rt_tables
:
1000 proton
Next, let's make connection scripts to create and setup VRF for wireguard interface:
[Interface]
PrivateKey = xxxxxxxxxxxxxxx
Address = 10.2.0.2/32
DNS = 1.1.1.1
Table = proton
PreUp = ip link add dev %i-vrf type vrf table proton
PreUp = ip link set dev %i-vrf up
PostUp = ip link set dev %i master %i-vrf
PostUp = ip -4 route add default dev proton vrf %i-vrf
PostDown = ip link del dev %i-vrf
[Peer]
# NL-FREE#381133
PublicKey = xxxxxxxxxx
AllowedIPs = 0.0.0.0/0
Endpoint = xxx.xxx.xxx.xx:xxxxx
Scripts do the following:
- Create a VRF domain.
- Activate it.
- Enslave wireguard interface to VRF domain.
- Re-populate default route to VRF route table (local routes of enslaved interface are getting migrated to VRF table, other routes vanish).
Now we can start VPN connection with wg-quick up proton
or systemctl start wg-quick@proton
. It should bring up all interfaces, but won't affect actual routing. We can check that both default VRF and proton-vrf
are usable.
Request with usual direct connection:
user@hp:~> curl -4 ifconfig.co
89.251.30.210
Using VRF domain with wireguard VPN hooked into it:
user@hp:~> curl -4 --interface proton-vrf ifconfig.co
169.150.218.57
Next, we need to operate dumbproxy
inside that new VRF, but having its listen socket in default VRF to accept connections from outside normally. systemd socket activation can help us with that.
Create separate dumbproxy user to run daemon with low privileges: adduser --system --home /var/lib/dumbproxy --shell /bin/false --group --disabled-login dumbproxy
Put following systemd units.
/etc/systemd/system/dumbproxy.socket
:
[Socket]
ListenStream=443
[Install]
WantedBy=sockets.target
/etc/systemd/system/dumbproxy.service
:
[Unit]
Description=Dumb Proxy
Documentation=https://github.com/Snawoot/dumbproxy/
After=network.target network-online.target
Requires=network-online.target
[Service]
EnvironmentFile=/etc/default/dumbproxy
Environment=HOME=/var/lib/dumbproxy
User=root
Group=root
ExecStart=/usr/sbin/ip vrf exec proton-vrf \
/usr/bin/setpriv --reuid dumbproxy --regid dumbproxy --clear-groups -- \
/usr/local/bin/dumbproxy --bind-address='' $OPTIONS
TimeoutStopSec=5s
PrivateTmp=true
ProtectSystem=full
[Install]
WantedBy=default.target
/etc/default/dumbproxy
:
OPTIONS=-auth basicfile://?path=/var/lib/dumbproxy/dumbproxy.htpasswd \
-autocert
Finally, lets enable it and start!
systemctl daemon-reload
systemctl enable dumbproxy.socket
systemctl start dumbproxy.socket
Socket unit will invoke service automatically on first connection to it. That's it, it should work and forward incoming connections into VPN. If it doesn't, check logs with journalctl -u dumbproxy -n 100
. Also make sure if DNS in /etc/resolv.conf
file is reachable from that VRF. Try some public ones like 1.1.1.1
or 8.8.8.8
if in doubt.
Alternatively, it is possible to run dumbproxy with socket activation and custom VRF from command line like this:
sudo systemd-socket-activate -E HOME=/var/lib/dumbproxy -l 0.0.0.0:443 \
ip vrf exec proton-vrf \
setpriv --reuid dumbproxy --regid dumbproxy --clear-groups \
/usr/local/bin/dumbproxy --bind-address=''