Skip to content

Instantly share code, notes, and snippets.

@wonderbeyond
Last active March 12, 2024 13:43
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wonderbeyond/3289a073c26e5b5c8ee56dc459f91dd9 to your computer and use it in GitHub Desktop.
Save wonderbeyond/3289a073c26e5b5c8ee56dc459f91dd9 to your computer and use it in GitHub Desktop.
Apply system-wide proxy settings dynamically using ipset, iptables, redsocks and socks5.

References:


NOTE 1: To eliminate the interference of existing rules, you can try clear the nat table (iptables -t nat -F).

NOTE 2: After updating iptables rules, the redsocks may require to be restarted to function as expected.

Simple Configuration (Example 1)

Proxy all http(s) packets by 3 commands.

I assume the behind socks5 service is not listening on port 80/443, otherwise we'll run into infinite loop.

# Add new chain if not exists
sudo iptables -t nat -L REDSOCKS > /dev/null || sudo iptables -t nat -N REDSOCKS
sudo iptables -t nat -A OUTPUT -j REDSOCKS -p tcp
sudo iptables -t nat -A REDSOCKS -j REDIRECT -p tcp -m multiport --dports 80,443 --to-ports 12345

To revert above proxy effect, we only need flush rules in REDSOCKS chain:

sudo iptables -t nat -F REDSOCKS
# Or flush all rules in *nat* table
# sudo iptables -t nat -F

Proxy All Packets Except a Bypass List (Example 2)

First add the global redirect rules:

sudo iptables -t nat -L REDSOCKS > /dev/null || sudo iptables -t nat -N REDSOCKS
sudo iptables -t nat -A OUTPUT -p tcp -j REDSOCKS
sudo iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-ports 12345

Then add some bypass rules:

REMOTE_PROXY_SERVER=35.220.151.63
sudo iptables -t nat -I REDSOCKS -d $REMOTE_PROXY_SERVER -j RETURN

sudo iptables -t nat -I REDSOCKS -d 0.0.0.0/8 -j RETURN
sudo iptables -t nat -I REDSOCKS -d 10.0.0.0/8 -j RETURN
sudo iptables -t nat -I REDSOCKS -d 100.64.0.0/10 -j RETURN
sudo iptables -t nat -I REDSOCKS -d 127.0.0.0/8 -j RETURN
sudo iptables -t nat -I REDSOCKS -d 169.254.0.0/16 -j RETURN
sudo iptables -t nat -I REDSOCKS -d 172.16.0.0/12 -j RETURN
sudo iptables -t nat -I REDSOCKS -d 192.168.0.0/16 -j RETURN
sudo iptables -t nat -I REDSOCKS -d 198.18.0.0/15 -j RETURN
sudo iptables -t nat -I REDSOCKS -d 224.0.0.0/4 -j RETURN
sudo iptables -t nat -I REDSOCKS -d 240.0.0.0/4 -j RETURN

⭐ Dynamic iptables rules (Example 3) (Reimplementation of Example 2)

An IP set may store IP(v4/v6) addresses, (TCP/UDP) port numbers, IP and MAC address pairs, IP address and port number pairs, etc.

sudo apt install ipset

sudo iptables -t nat -L REDSOCKS > /dev/null || sudo iptables -t nat -N REDSOCKS
sudo iptables -t nat -I OUTPUT -p tcp -j REDSOCKS

Create an ipset to contains IP addresses that should bypass redsocks, including the remote proxy server addresses.

sudo ipset create redsocks_bypass hash:net

# Add remote proxy server address(es) to ipset:
sudo ipset add redsocks_bypass 35.220.151.63
sudo ipset add redsocks_bypass 34.139.140.49
sudo ipset add redsocks_bypass 168.138.205.175

sudo ipset add redsocks_bypass 0.0.0.0/8
sudo ipset add redsocks_bypass 10.0.0.0/8
sudo ipset add redsocks_bypass 100.64.0.0/10
sudo ipset add redsocks_bypass 127.0.0.0/8
sudo ipset add redsocks_bypass 169.254.0.0/16
sudo ipset add redsocks_bypass 172.16.0.0/12
sudo ipset add redsocks_bypass 192.168.0.0/16
sudo ipset add redsocks_bypass 198.18.0.0/15
sudo ipset add redsocks_bypass 224.0.0.0/4
sudo ipset add redsocks_bypass 240.0.0.0/4

Create an iptables rule that references the redsocks_bypass set.

sudo iptables -t nat -I REDSOCKS -m set --match-set redsocks_bypass dst -j RETURN

Now, add below rule to let all other packets go through redsocks.

sudo iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-ports 12345

We can also add new IP addresses to redsocks_bypass to bypass these destinations automatically.

sudo ipset add redsocks_bypass www.baidu.com

Make Persistant

sudo apt install iptables-persistent ipset-persistent

sudo ipset save | sudo tee /etc/iptables/ipsets
sudo iptables-save | sudo tee /etc/iptables/rules.v4

Make a Toggle Command

We can easily toggle the proxy effect off and on, each by a single command.

sudo iptables -t nat -I REDSOCKS -j RETURN -m comment --comment "off-redsocks"  # toggle off
sudo iptables -t nat -D REDSOCKS -j RETURN -m comment --comment "off-redsocks"  # toggle on again

Also we can make a toggle script.

~/bin/toggle-redsocks.sh

toggle_redsocks_func () {
    if sudo iptables -t nat -nL | grep "off-redsocks"; then
        sudo iptables -t nat -D REDSOCKS -j RETURN -m comment --comment "off-redsocks"
        echo "Toggled on redsocks ..."
    else
        echo "Toggled off redsocks ..."
        sudo iptables -t nat -I REDSOCKS -j RETURN -m comment --comment "off-redsocks"
    fi
}

toggle_redsocks_func "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment