Shadowsocks + Hardware switch

Hello! I'd like to share my solution for setting up Shadowsocks with the hardware switch, similar to how TOR, WireGuard, and OpenVPN are handled.

!!! This guide involves modifying system files. Your configuration may be lost after a firmware update. Proceed at your own risk — I take no responsibility for bricked devices, even though the changes are minor.

I’m using the GL-E750 (4G LTE) router.
Firmware version: 4.0
Kernel version: 5.10.176
OpenWRT version: 22.03.4
Required packages

Run:

opkg update
opkg install \
  luci-app-shadowsocks-libev \
  shadowsocks-libev-ss-redir \
  shadowsocks-libev-config

UCI configuration for Shadowsocks server and ss-redir instance

SERVER_NAME='Bulgaria'
SERVER_ADDRESS='1.1.1.1'
SERVER_PORT=38583
SERVER_PROTO='chacha20-ietf-poly1305'
SERVER_PASS='YoUr_pASS'
LOCAL_PORT=12345

uci set shadowsocks-libev.$SERVER_NAME=server
uci set shadowsocks-libev.$SERVER_NAME.server="$SERVER_ADDRESS"
uci set shadowsocks-libev.$SERVER_NAME.server_port="$SERVER_PORT"
uci set shadowsocks-libev.$SERVER_NAME.method="$SERVER_PROTO"
uci set shadowsocks-libev.$SERVER_NAME.password="$SERVER_PASS"

uci set shadowsocks-libev.VPN_redir=ss_redir
uci set shadowsocks-libev.VPN_redir.disabled='0'
uci set shadowsocks-libev.VPN_redir.mode='tcp_and_udp'
uci set shadowsocks-libev.VPN_redir.fast_open='1'
uci set shadowsocks-libev.VPN_redir.no_delay='1'
uci set shadowsocks-libev.VPN_redir.reuse_port='1'
uci set shadowsocks-libev.VPN_redir.server="$SERVER_NAME"
uci set shadowsocks-libev.VPN_redir.local_port="$LOCAL_PORT"

# Enable Shadowsocks option for hardware switch
uci set switch-button.@main[0].func='shadowsocks'
uci commit

Create /etc/gl-switch.d/shadowsocks.sh that will be executed on switch turn on\off.

#!/bin/sh
action=$1
port=12345
chain=SHADOWSOCKS

if [ "$action" = "on" ]; then
    # Start ss-redir service
    /etc/init.d/shadowsocks-libev start

    # Add iptables rules
    iptables -t nat -N $chain 2>/dev/null
    iptables -t nat -F $chain
    iptables -t nat -A $chain -d 192.168.0.0/16 -j RETURN
    iptables -t nat -A $chain -p tcp -j REDIRECT --to-ports $port
    iptables -t nat -A PREROUTING -i br-lan -p tcp -j $chain

    # Drop existing connections
    conntrack -F
else
    # Delete iptables rules
    iptables -t nat -D PREROUTING -i br-lan -p tcp -j $chain
    iptables -t nat -F $chain
    iptables -t nat -X $chain

    # Stop ss-redir service
    /etc/init.d/shadowsocks-libev stop
fi

Then make it executable:

chmod +x /etc/gl-switch.d/shadowsocks.sh

Now you can toggle Shadowsocks VPN using the router's hardware switch.
You can also manually start/stop the VPN using:

/etc/gl-switch.d/shadowsocks.sh on
/etc/gl-switch.d/shadowsocks.sh off

Hope this helps someone!