
Forward all your traffic with RedSocks
April 30, 2024
VPNs can be used in different ways based on the desired objective. If the goal is to reach some specific web pages served only within a network, using a proxy will probably do the trick. Another common use for VPNs is to ensure the confidentiality of data transferred between a remote system and a safe site. In this case, we might want to ensure that all traffic from the remote system reaches the safe site via the VPN.
RedSocks is a tool for redirecting any TCP connection to a SOCKS or HTTPS proxy. The aspect I like the most about RedSocks is that it does not do the TCP redirect natively, but it expects a firewall to be properly configured to redirect all TCP traffic to the RedSocks socket. RedSocks redirects the traffic from his socket to the remote proxy. The best solution would be to leverage a VPN feature directly. Still, in my case, I use Nebula, which does not support this use, so I leverage RedSocks (in addition to Dante and Nebula as previously described) to mimic this feature.
To use RedSocks this way, we will need to perform a few steps in addition to configuring an HTTP or SOCKS proxy (like Dante).
The first step is to install RedSocks.
If you are on Fedora, you will only need to install the redsocks
package, which is already available in the official repositories.
If you are not on Fedora, look in your distribution’s repositories; there are good chances it is there, too.
If your distribution does not distribute it, you will need to download, build, and install it from the project’s GitHub page.
Once you have RedSocks installed, you can proceed at configuring it by changing the /etc/redsocks.conf
file.
A simple configuration will look like this one:
base {
log_debug = on;
log_info = on;
log = stderr;
daemon = on;
redirector = iptables;
}
redsocks {
local_ip = 0.0.0.0;
local_port = 12345;
ip = 192.168.1.1;
port = 3128;
type = socks5;
}
This configuration will ensure that RedSocks binds itself on 0.0.0.0:12345
and redirects all traffic to the proxy socks5://192.168.1.1:3128
.
In my case, I use Dante, so I used the socks5
protocol, but other supported types are: socks4
, http-connect
, and http-relay
.
An important thing to notice is that the redirector = iptables
also works for nft, so if you are using it, there is no need to change it.
Now that RedSocks is installed and configured, we can run it.
The first step is to start the RedSocks service with sudo systemctl start redsocks
.
We can then ensure that the nfd_redir
kernel module is loaded with sudo modprobe nft_redir
and therefore configure it to redirect all traffic except the one for the local network to the RedSocks’ socket with:
sudo nft -f - <<EOF
table ip nat {
chain REDSOCKS {
# hook to the output
type nat hook output priority 0; policy accept;
# skip if the user is not uid 1000
ip protocol tcp skuid != 1000 return
# skip for local ip ranges
ip daddr 0.0.0.0/8 return
ip daddr 10.0.0.0/8 return
ip daddr 100.64.0.0/10 return
ip daddr 127.0.0.0/8 return
ip daddr 169.254.0.0/16 return
ip daddr 172.16.0.0/12 return
ip daddr 192.168.0.0/16 return
ip daddr 198.18.0.0/15 return
ip daddr 224.0.0.0/4 return
ip daddr 240.0.0.0/4 return
# everything else tcp = redirect to redsocks
ip protocol tcp redirect to 12345
}
}
EOF
All traffic by user 1000 addressed to the public Internet will go through RedSocks and, therefore, the configured proxy.
To stop the redirection, we must first flush the nft rules with sudo nft flush ruleset
and then stop the RedSocks service with sudo systemctl stop redsocks
.
To make it easier to start and stop RedSocks, I use the following script:
#!/bin/bash
sudo systemctl start redsocks
sudo modprobe nft_redir
sudo nft -f - <<EOF
table ip nat {
chain REDSOCKS {
# hook to the output
type nat hook output priority 0; policy accept;
# skip if the user is not uid 1000
ip protocol tcp skuid != 1000 return
# skip for local ip ranges
ip daddr 0.0.0.0/8 return
ip daddr 10.0.0.0/8 return
ip daddr 100.64.0.0/10 return
ip daddr 127.0.0.0/8 return
ip daddr 169.254.0.0/16 return
ip daddr 172.16.0.0/12 return
ip daddr 192.168.0.0/16 return
ip daddr 198.18.0.0/15 return
ip daddr 224.0.0.0/4 return
ip daddr 240.0.0.0/4 return
# everything else tcp = redirect to redsocks
ip protocol tcp redirect to 12345
}
}
EOF
echo "All traffic should now be proxied :)"
# wait for Ctrl-C
( trap exit SIGINT ; read -r -d '' _ </dev/tty )
sudo nft flush ruleset
sudo systemctl stop redsocks
Many RedSocks documentation and examples are fairly ancient, so they use different firewalls. I hope this can help some more people use RedSocks within modern setups.