Третьего дня ко мне таки приехал мой долгожданный роутер с OpenWRT на борту и я моментально приступил к жесточайшему пердолингу. Пердолинг оказался совсем не жесточайший, и все получилось настолько быстро и просто, что я даже немного расстроился.
Итак, первым делом настраиваем наш свеженький роутер как обычно. Ставим там логины, пароли, настраиваем wi-fi, сети и т.д. Дальше ломимся на него по ssh
ssh root@192.168.1.1
и начинаем делать грязь.
Первым делом нужно отключить обход блокировок ютуба если он у вас есть.
# отключим встроенный обход блокирокки ютуба. Мы же ничего не хотим обходить, помните?
service youtubeUnblock disable
service youtubeUnblock stop
rm /usr/share/nftables.d/ruleset-post/537-youtubeUnblock.nft
Затем ставим sing-box
# обновим пакеты и поставим сингбокс
opkg update
opkg install sing-box
# Настроим sing-box от root (необходимый костыль)
uci set sing-box.main.enabled='1'
uci set sing-box.main.user='root'
uci commit sing-box
Ну а дальше правим конфиг sing-box с помощью nano /etc/sing-box/config.json
и пишем туда что-нибудь такое
{
"log": {
"level": "warn"
},
"dns": {
"servers": [
{
"tag": "local-dns",
"address": "local",
"detour": "direct-out"
},
{
"tag": "cloudflare-dns",
"address": "https://1.1.1.1/dns-query",
"address_resolver": "local-dns",
"detour": "proxy"
}
],
"rules": [
{
"rule_set": [
"antizapret",
"geosite-youtube",
"geosite-openai",
"geosite-anthropic",
"geosite-jetbrains",
"geosite-jetbrains-ai",
"geosite-x",
"geosite-discord"
],
"server": "cloudflare-dns"
},
{
"domain_suffix": [
"lucid.app",
"lucid.co",
"qodana.cloud",
"habr.com"
],
"server": "cloudflare-dns"
}
]
},
"inbounds": [
{
"type": "tproxy",
"tag": "proxy",
"listen": "::",
"listen_port": 1602,
"sniff": true,
"domain_strategy": "prefer_ipv4"
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct-out"
},
{
"domain_strategy": "ipv4_only",
"flow": "",
"packet_encoding": "",
"server": "YOUR_SERVER",
"server_port": 443,
"tag": "proxy",
"tls": {
"enabled": true,
"reality": {
"enabled": true,
"public_key": "YOUR_KEY",
"short_id": "YOUR_ID"
},
"server_name": "YOUR_SERVER_NAME",
"utls": {
"enabled": true,
"fingerprint": "chrome"
}
},
"type": "vless",
"uuid": "YOUR_UUID"
}
],
"route": {
"rules": [
{
"ip_cidr": [
"104.16.0.0/12",
"13.24.0.0/13",
"13.32.0.0/12",
"13.48.0.0/13",
"13.56.0.0/14",
"143.204.0.0/16",
"162.158.0.0/15",
"172.64.0.0/13",
"18.128.0.0/9",
"18.32.0.0/11",
"18.64.0.0/10",
"188.114.96.0/22",
"204.11.56.0/23",
"23.227.32.0/19",
"3.128.0.0/9",
"138.128.136.0/21",
"34.0.0.0/15",
"34.2.0.0/16",
"34.3.0.0/23",
"34.3.2.0/24",
"35.192.0.0/12",
"35.208.0.0/12",
"35.224.0.0/12",
"35.240.0.0/13",
"5.200.14.128/25",
"66.22.192.0/18"
],
"outbound": "proxy"
},
{
"rule_set": "antizapret",
"outbound": "proxy"
},
{
"rule_set": [
"geosite-youtube",
"geosite-openai",
"geosite-anthropic",
"geosite-jetbrains",
"geosite-jetbrains-ai",
"geosite-x",
"geosite-discord",
"geo-block"
],
"outbound": "proxy"
},
{
"domain_suffix": [
"lucid.app",
"lucid.co",
"qodana.cloud",
"habr.com",
"ntc.party"
],
"outbound": "proxy"
}
],
"rule_set": [
{
"tag": "antizapret",
"type": "remote",
"format": "binary",
"url": "https://github.com/savely-krasovsky/antizapret-sing-box/releases/latest/download/antizapret.srs",
"download_detour": "proxy"
},
{
"tag": "geosite-youtube",
"type": "remote",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-youtube.srs",
"download_detour": "proxy"
},
{
"tag": "geosite-openai",
"type": "remote",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-openai.srs",
"download_detour": "proxy"
},
{
"tag": "geosite-anthropic",
"type": "remote",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-anthropic.srs",
"download_detour": "proxy"
},
{
"tag": "geosite-jetbrains",
"type": "remote",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-jetbrains.srs",
"download_detour": "proxy"
},
{
"tag": "geosite-jetbrains-ai",
"type": "remote",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-jetbrains-ai.srs",
"download_detour": "proxy"
},
{
"tag": "geosite-x",
"type": "remote",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-x.srs",
"download_detour": "proxy"
},
{
"tag": "geosite-discord",
"type": "remote",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-discord.srs",
"download_detour": "proxy"
},
{
"tag": "geo-block",
"type": "remote",
"format": "binary",
"url": "https://github.com/itdoginfo/allow-domains/releases/latest/download/geoblock.srs",
"download_detour": "proxy"
}
],
"auto_detect_interface": true
},
"experimental": {
"cache_file": {
"enabled": true
}
}
}
Данный конфиг поднимем sing-box в режиме прокси, теперь надо зароутить туда трафик, для этого добавляем “сервис” который будет настраивать форвардинг трафика.
touch /etc/init.d/proxyroute
chmod +x /etc/init.d/proxyroute
запихиваем в файл /etc/init.d/proxyroute скрипт ниже
#!/bin/sh /etc/rc.common
START=99
STOP=15
USE_PROCD=1
NAME="proxyroute"
NFT_TABLE_NAME="ProxyRouteTable"
RT_TABLE_NAME="proxyroute"
RT_TABLE_NUM="106"
FWMARK="0x105"
TPROXY_PORT="1602"
SRC_INTERFACE="br-lan" # Ваш LAN-интерфейс
YOUR_LAN_SUBNET="192.168.1.0/24" # Ваша LAN-подсеть
start_service() {
logger "Starting $NAME service"
# 1. Настройка таблицы роутинга и правила ip rule
# Добавляем запись в /etc/iproute2/rt_tables, если ее нет
if ! grep -q "$RT_TABLE_NUM $RT_TABLE_NAME" /etc/iproute2/rt_tables; then
echo "$RT_TABLE_NUM $RT_TABLE_NAME" >> /etc/iproute2/rt_tables
logger "Added route table entry to /etc/iproute2/rt_tables"
fi
# Создаем таблицу маршрутизации, если ее нет
if ! ip route show table "$RT_TABLE_NAME" >/dev/null 2>&1; then
ip route add local 0.0.0.0/0 dev lo table "$RT_TABLE_NAME"
logger "Created routing table: $RT_TABLE_NAME"
fi
# Добавляем локальный маршрут, если его нет
if ! ip route list table "$RT_TABLE_NAME" | grep -q "local default dev lo"; then
ip route add local 0.0.0.0/0 dev lo table "$RT_TABLE_NAME"
logger "Added local route to table: $RT_TABLE_NAME"
fi
# Добавляем правило ip rule, если его нет
if ! ip rule list | grep -q "fwmark $FWMARK lookup $RT_TABLE_NAME"; then
ip -4 rule add fwmark "$FWMARK" table "$RT_TABLE_NAME" priority "$RT_TABLE_NUM"
logger "Added ip rule fwmark $FWMARK lookup $RT_TABLE_NAME"
fi
# 2. Настройка nftables
# Создать таблицу, если не существует
nft list table inet "$NFT_TABLE_NAME" >/dev/null 2>&1 || {
nft add table inet "$NFT_TABLE_NAME"
logger "Created nftables table: $NFT_TABLE_NAME"
}
# Создать цепочки, если не существуют
nft list chain inet "$NFT_TABLE_NAME" mangle >/dev/null 2>&1 || {
nft add chain inet "$NFT_TABLE_NAME" mangle { type filter hook prerouting priority -150 \; policy accept \; }
logger "Created nftables chain: $NFT_TABLE_NAME mangle"
}
nft list chain inet "$NFT_TABLE_NAME" proxy >/dev/null 2>&1 || {
nft add chain inet "$NFT_TABLE_NAME" proxy { type filter hook prerouting priority -100 \; policy accept \; }
logger "Created nftables chain: $NFT_TABLE_NAME proxy"
}
# Создать и заполнить сет localv4 для исключений
if ! nft list set inet "$NFT_TABLE_NAME" localv4 >/dev/null 2>&1; then
nft add set inet "$NFT_TABLE_NAME" localv4 { type ipv4_addr\; flags interval\; }
nft add element inet "$NFT_TABLE_NAME" localv4 { \
0.0.0.0/8, \
10.0.0.0/8, \
127.0.0.0/8, \
169.254.0.0/16, \
172.16.0.0/12, \
192.0.0.0/24, \
192.0.2.0/24, \
192.88.99.0/24, \
192.168.0.0/16, \
198.51.100.0/24, \
203.0.113.0/24, \
224.0.0.0/4, \
240.0.0.0-255.255.255.255 }
logger "Created and populated nftables set: $NFT_TABLE_NAME localv4"
fi
# Правила маркировки в цепочке mangle
# ПРАВИЛО 1: Исключить локальный трафик (ВАЖНО: должно быть до общего правила маркировки)
if ! nft -a list chain inet "$NFT_TABLE_NAME" mangle | grep -q "ip saddr $YOUR_LAN_SUBNET ip daddr @localv4 return"; then
nft insert rule inet "$NFT_TABLE_NAME" mangle position 0 iifname "$SRC_INTERFACE" ip saddr "$YOUR_LAN_SUBNET" ip daddr @localv4 return comment "Exclude_local_traffic"
logger "Added nftables rule to mangle chain: Exclude_local_traffic"
fi
# ПРАВИЛО 2: Маркировка ВСЕГО TCP/UDP трафика, идущего из LAN
if ! nft -a list chain inet "$NFT_TABLE_NAME" mangle | grep -q "ip saddr $YOUR_LAN_SUBNET meta l4proto { tcp, udp } meta mark set $FWMARK"; then
nft add rule inet "$NFT_TABLE_NAME" mangle iifname "$SRC_INTERFACE" ip saddr "$YOUR_LAN_SUBNET" meta l4proto { tcp, udp } meta mark set "$FWMARK" counter comment "Mark_ALL_LAN_Traffic"
logger "Added nftables rule to mangle chain: Mark_ALL_LAN_Traffic"
fi
# Правила TProxy в цепочке proxy
if ! nft -a list chain inet "$NFT_TABLE_NAME" proxy | grep -q "meta mark $FWMARK meta l4proto tcp tproxy ip to :$TPROXY_PORT"; then
nft add rule inet "$NFT_TABLE_NAME" proxy meta mark "$FWMARK" meta l4proto tcp tproxy ip to ":$TPROXY_PORT" counter comment "TPROXY_TCP_to_$TPROXY_PORT"
logger "Added nftables rule to proxy chain: TPROXY_TCP_to_$TPROXY_PORT"
fi
if ! nft -a list chain inet "$NFT_TABLE_NAME" proxy | grep -q "meta mark $FWMARK meta l4proto udp tproxy ip to :$TPROXY_PORT"; then
nft add rule inet "$NFT_TABLE_NAME" proxy meta mark "$FWMARK" meta l4proto udp tproxy ip to ":$TPROXY_PORT" counter comment "TPROXY_UDP_to_$TPROXY_PORT"
logger "Added nftables rule to proxy chain: TPROXY_UDP_to_$TPROXY_PORT"
fi
}
stop_service() {
logger "Stopping $NAME service and uninstalling rules"
# 1. Удаляем nftables правила и таблицы
nft delete table inet "$NFT_TABLE_NAME" &>/dev/null
logger "Deleted nftables table: $NFT_TABLE_NAME"
# 2. Удаляем ip rule
ip -4 rule del fwmark "$FWMARK" table "$RT_TABLE_NAME" priority "$RT_TABLE_NUM" &>/dev/null
logger "Deleted ip rule fwmark $FWMARK lookup $RT_TABLE_NAME"
# 3. Удаляем таблицу маршрутизации и запись в /etc/iproute2/rt_tables
ip route flush table "$RT_TABLE_NAME" &>/dev/null
ip route del local 0.0.0.0/0 dev lo table "$RT_TABLE_NAME" &>/dev/null
logger "Deleted routing table: $RT_TABLE_NAME"
sed -i "/$RT_TABLE_NUM $RT_TABLE_NAME/d" /etc/iproute2/rt_tables
logger "Removed route table entry from /etc/iproute2/rt_tables"
}
remove() {
stop
rm -f /etc/init.d/$NAME
logger "Removed service init file"
}
включаем sing-box и наш серис по роутингу
service sing-box enable
service sing-box start
service proxyroute enable
service proxyroute start