Summary
I use a VPN to route all of my traffic through. Until recently, I used OpenVPN, but then switched to Wireguard. Unfortunately, this broke my redsocks setup, and I can't figure out why.
I'm using redsocks because I'm using a command-line program that doesn't support using a SOCKS proxy - but I need that program to go through a SOCKS SSH tunnel.
Setup
Overview:
no-socks-program -> iptables nat -> redsocks -> ssh -> destination
- The non-socks-capable program is launched with group 1001
- Iptables matches on the group and REDIRECTs to port 1533 where redsocks is listening
- Redsocks socksifies and redirects to 1533 where SSH is listening
- SSH uses
DynamicForward
to forward to target server
Details:
- Match group
1001
and internal destinations (I launch the program I want to socksify with this group, and the destinations are in 10/8):
iptables -t nat -A OUTPUT -d 10.0.0.0/8 -m owner --gid-owner 1001 -j REDSOCKS
- Then in the redsocks chain, filter out the usual stuff and 10.2/16 because that's where the wireguard gateway is, then redirect to port 59375, where redsocks is listening:
iptables -t nat -A REDSOCKS -d 0.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -d 100.64.0.0/10 -j RETURN
iptables -t nat -A REDSOCKS -d 127.0.0.0/8 -j RETURN
iptables -t nat -A REDSOCKS -d 169.254.0.0/16 -j RETURN
iptables -t nat -A REDSOCKS -d 172.16.0.0/12 -j RETURN
iptables -t nat -A REDSOCKS -d 192.168.0.0/16 -j RETURN
iptables -t nat -A REDSOCKS -d 198.18.0.0/15 -j RETURN
iptables -t nat -A REDSOCKS -d 224.0.0.0/4 -j RETURN
iptables -t nat -A REDSOCKS -d 240.0.0.0/4 -j RETURN
iptables -t nat -A REDSOCKS -d 10.2.0.0/16 -j RETURN
iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-ports 59375
- Redsocks config, listens on 59375, redirects to 1533, where SSH listens:
redsocks {
local_ip = 127.0.0.1;
local_port = 59375;
ip = 127.0.0.1;
port = 1533;
type = socks5;
}
- SSH config for listening on 1533:
Host socksify
User me
Hostname intermediate
DynamicForward 1533
And this works when using OpenVPN, but it breaks when using Wireguard, and I'm too stupid to figure out why.
The only difference I can make out between the two is the routing and the kernel parameter net.ipv4.conf.all.src_valid_mark
which is set to 1
by wg-quick
but not by OpenVPN.
Routing for Wireguard (redsocks not working):
> sudo ip rule
0: from all lookup local
32764: from all lookup main suppress_prefixlength 0
32765: not from all fwmark 0xca6c lookup 51820
32766: from all lookup main
32767: from all lookup default
> sudo ip route show table all
default dev wg0 table 51820 scope link
default via 192.168.1.1 dev wlp3s0 proto dhcp metric 600
192.168.1.0/24 dev wlp3s0 proto kernel scope link src 192.168.1.205 metric 600
local 10.2.0.2 dev wg0 table local proto kernel scope host src 10.2.0.2
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1
local 192.168.1.205 dev wlp3s0 table local proto kernel scope host src 192.168.1.205
broadcast 192.168.1.255 dev wlp3s0 table local proto kernel scope link src 192.168.1.205
> ip route get 10.89.2.21
10.89.2.21 dev wg0 table 51820 src 10.2.0.2 uid 1000
cache
Routing for OpenVPN (redsocks is working):
> sudo ip rule
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
> sudo ip route show table all
0.0.0.0/1 via 10.30.0.1 dev tun0
default via 192.168.1.1 dev wlp3s0 proto dhcp metric 600
10.30.0.0/16 dev tun0 proto kernel scope link src 10.30.0.14
128.0.0.0/1 via 10.30.0.1 dev tun0
192.168.1.0/24 dev wlp3s0 proto kernel scope link src 192.168.1.205 metric 600
local 10.30.0.14 dev tun0 table local proto kernel scope host src 10.30.0.14
broadcast 10.30.255.255 dev tun0 table local proto kernel scope link src 10.30.0.14
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1
local 192.168.1.205 dev wlp3s0 table local proto kernel scope host src 192.168.1.205
broadcast 192.168.1.255 dev wlp3s0 table local proto kernel scope link src 192.168.1.205
> ip route get 10.89.2.21
10.89.2.21 via 10.39.0.1 dev tun0 src 10.39.0.13 uid 1000
cache
Troubleshooting steps taken
- I tried replacing
redsocks
withtun2socks
from badvpn, but it's the exact same problem. So it isn'tredsocks
who is broken. - I turned on iptables tracing like this:
sudo iptables -t raw -A OUTPUT -d 10.89.0.0/16 -p tcp -m tcp --dport 443 -j TRACE
and I see SYN
, SYN-ACK
, ACK
when using OpenVPN, but only SYN
when using Wireguard. No ACK
.
- I used Wireshark for OpenVPN and for Wireguard and compared them. In the OpenVPN traffic, I see the same thing as in the iptables trace, a normal
SYN
,SYN-ACK
,ACK
. But, and that's the interesting thing, when using Wireguard, I seeSYN
,RST-ACK
:
OpenVPN normal TCP:
Wireguard SYN
then RST
:
(10.2.0.2
is my wg0
IP, and 10.89.2.21
is my tun0
IP.)
Question
Why is redsocks working with OpenVPN and not with Wireguard, and what do I need to do to make it work?
I am happy to provide additional information.
Update
I found another difference between OpenVPN and Wireguard. I am using wg-quick
to set up the Wireguard connection, and that utility uses nftables
to set some rules. Here they are:
table ip wg-quick-wg0 {
chain preraw {
type filter hook prerouting priority raw; policy accept;
iifname != "wg0" ip daddr 10.2.0.2 fib saddr type != local drop
}
chain premangle {
type filter hook prerouting priority mangle; policy accept;
meta l4proto udp meta mark set ct mark
}
chain postmangle {
type filter hook postrouting priority mangle; policy accept;
meta l4proto udp meta mark 0x0000ca6c ct mark set meta mark
}
}
I have zero knowledge of nftables
and I don't know what they mean, but this could very well be the problem.
Setting 0/1 route
Setting 0.0.0.0/1, 128.0.0.0/1
as AllowedIPs
in Wireguard, to match the route with OpenVPN, resulted in no internet access at all. Here is the routing table with that setting:
> sudo ip route show table all
0.0.0.0/1 dev wg0 scope link
default via 192.168.1.1 dev wlp3s0 proto dhcp metric 600
128.0.0.0/1 dev wg0 scope link
192.168.1.0/24 dev wlp3s0 proto kernel scope link src 192.168.1.205 metric 600
local 10.2.0.2 dev wg0 table local proto kernel scope host src 10.2.0.2
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1
local 192.168.1.205 dev wlp3s0 table local proto kernel scope host src 192.168.1.205
broadcast 192.168.1.255 dev wlp3s0 table local proto kernel scope link src 192.168.1.205
> ip route get 10.89.2.21
10.89.2.21 dev wg0 src 10.2.0.2 uid 1000
cache