31 KiB
title, created, updated, tags
| title | created | updated | tags | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Rasputin OpenWrt router | 2026-07-22 | 2026-09-17 |
|
Rasputin R5S OpenWrt router
Status as of 2026-09-17: Rasputin is the OpenWrt edge/LAN router, routing normal LAN traffic through a VLESS/Xray tunnel via
tun0, with explicit direct-WAN exceptions for upstream LAN access and MaccloudflaredQUIC traffic. ⚠️ WAN переехал наeth0(192.168.2.157/24, gw192.168.2.2) — см. раздел «WAN-интерфейс изменился» ниже. Транзит в GPON-сегмент192.168.0.0/24сломан — см. одноимённый раздел.
Identity
| Field | Value |
|---|---|
| Hostname | Rasputin |
| Hardware | FriendlyElec NanoPi R5S |
| Board | friendlyarm,nanopi-r5s |
| CPU | ARMv8 Processor rev 0 |
| OpenWrt | 24.10.2, revision r28739-d9340319c6 |
| Target | rockchip/armv8 |
| Kernel | 6.6.93 |
| Rootfs | squashfs |
| LAN IP | 192.168.6.1/24 |
| IPv6 ULA prefix | fd3b:153e:9be9::/48 |
Network Topology
LAN clients
-> br-lan / 192.168.6.0/24
-> policy routing
-> most LAN traffic: table vpn -> tun0 -> badvpn-tun2socks -> Xray SOCKS -> VLESS
-> selected exceptions: table main -> WAN device
WAN devices are eth0 and usb0 in the wan firewall zone. As of 2026-09-17 eth0 is the active WAN (it carries the default route); usb0 is idle. At the 2026-07-22 capture this was inverted — eth0 had no carrier and usb0 held the default route.
Default route at the 2026-07-22 capture (historical, no longer active):
default via 10.252.240.133 dev usb0 src 10.252.240.230
Current default route (2026-09-17):
default via 192.168.2.2 dev eth0 proto static src 192.168.2.157
That is, Rasputin gets 192.168.2.157/24 from the upstream router 192.168.2.2 and reaches the internet through it; 192.168.2.2 in turn sits behind GPON 192.168.0.1.
VPN table:
default dev tun0 scope link
Interfaces
LAN
br-lan bridges:
eth1
eth2
phy0-ap0
LAN config:
network.lan=interface
network.lan.device='br-lan'
network.lan.proto='static'
network.lan.ipaddr='192.168.6.1'
network.lan.netmask='255.255.255.0'
network.lan.ip6assign='60'
network.lan.dns='8.8.8.8'
WAN
eth0:
network.wan=interface
network.wan.device='eth0'
network.wan.proto='dhcp'
network.wan.peerdns='0'
network.wan.type='bridge'
usb0:
network.usbwan=interface
network.usbwan.proto='dhcp'
network.usbwan.device='usb0'
Firewall wan zone includes:
wan
wan6
wwan
usbwan
VPN
tun0 is declared as an unmanaged interface:
network.vpn=interface
network.vpn.proto='none'
network.vpn.device='tun0'
tun0 is created/used by badvpn-tun2socks, launched from /etc/init.d/tunvpn.
DHCP And Static Leases
DHCP server:
dhcp.lan=dhcp
dhcp.lan.interface='lan'
dhcp.lan.start='100'
dhcp.lan.limit='150'
dhcp.lan.leasetime='12h'
dhcp.lan.dhcp_option='6,1.1.1.1,1.0.0.1'
dhcp.lan.dhcpv4='server'
dhcp.lan.dhcpv6='server'
dhcp.lan.ra='server'
dhcp.lan.ra_slaac='1'
dhcp.lan.ra_flags='managed-config' 'other-config'
Static DHCP reservations added 2026-07-14 for the Mac:
dhcp.@host[0].name='mbp-black-eth'
dhcp.@host[0].mac='00:e0:4c:68:04:88'
dhcp.@host[0].ip='192.168.6.104'
dhcp.@host[1].name='mbp-black-wifi'
dhcp.@host[1].mac='66:02:b1:8b:2f:94'
dhcp.@host[1].ip='192.168.6.173'
Backup made before this change:
/etc/config/dhcp.bak.20260714-195408
VLESS / Xray Stack
Packages present include:
badvpn
xray-core
v2ray-core
v2ray-extra
v2ray-geoip
v2ray-geosite
v2raya
luci-app-v2raya
sing-box
nftables-json
iptables-nft
Runtime processes:
badvpn-tun2socks --tundev tun0 --netif-ipaddr 10.99.0.2 --netif-netmask 255.255.255.252 --socks-server-addr 127.0.0.1:1080 --loglevel none
/usr/bin/xray run -confdir /etc/xray -config /etc/xray/config.json -format json
v2raya is installed, but the observed UCI service config previously had enabled='0'. The active traffic path is the custom tunvpn service plus direct Xray config.
Xray Config
File:
/etc/xray/config.json
Structure:
{
"log": {
"loglevel": "debug",
"access": "/tmp/xray-access.log",
"error": "/tmp/xray-error.log"
},
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 1080,
"protocol": "socks"
}
],
"outbounds": [
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "188.239.191.235",
"port": 443,
"users": [
{
"id": "<redacted-vless-user-id>",
"flow": "xtls-rprx-vision",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"serverName": "node3.sysnx.net",
"publicKey": "<redacted-reality-public-key>",
"shortId": "<redacted-reality-short-id>",
"fingerprint": "qq"
}
}
}
],
"routing": {
"rules": [
{ "type": "field", "outboundTag": "proxy", "network": "tcp,udp" }
]
}
}
Secrets are intentionally redacted in this note. The live file on the router contains the actual VLESS UUID and REALITY parameters.
tunvpn Service
File:
/etc/init.d/tunvpn
Purpose:
- Start
badvpn-tun2socks. - Populate routing table
vpnwith default route throughtun0. - Add policy rules so LAN traffic uses the VPN table.
- Add explicit Cloudflare Tunnel QUIC bypass rules for the Mac.
Current script:
#!/bin/sh /etc/rc.common
START=95
STOP=10
start() {
badvpn-tun2socks --tundev tun0 --netif-ipaddr 10.99.0.2 --netif-netmask 255.255.255.252 --socks-server-addr 127.0.0.1:1080 --loglevel none &
sleep 2
ip route replace default dev tun0 table vpn
# cloudflared QUIC direct bypass for Mac Ethernet/Wi-Fi
ip rule add priority 98 from 192.168.6.173 ipproto udp dport 7844 lookup main 2>/dev/null
ip rule add priority 99 from 192.168.6.104 ipproto udp dport 7844 lookup main 2>/dev/null
ip rule add iif br-lan lookup vpn priority 101
}
stop() {
killall badvpn-tun2socks
ip rule del priority 98 2>/dev/null
ip rule del priority 99 2>/dev/null
ip rule del iif br-lan lookup vpn 2>/dev/null
ip route flush table vpn
}
Backup made before the Cloudflare direct-bypass update:
/etc/init.d/tunvpn.bak.20260714-195530
Policy Routing
Current rules:
0: from all lookup local
98: from 192.168.6.173 ipproto udp dport 7844 lookup main
99: from 192.168.6.104 ipproto udp dport 7844 lookup main
100: from all to 192.168.2.0/24 lookup main
101: from all iif br-lan lookup vpn
32766: from all lookup main
32767: from all lookup default
Meaning:
- Mac Wi-Fi
192.168.6.173UDP/7844 goes direct throughmain. - Mac Ethernet
192.168.6.104UDP/7844 goes direct throughmain. - Traffic to upstream LAN
192.168.2.0/24goes direct throughmain. - 🔴 Traffic to the GPON segment
192.168.0.0/24is NOT covered by rule100(2026-09-17) → falls through to rule101→table vpn→tun0. Доступ к GPON-сегменту из LAN192.168.6.0/24не работает. See the «🔴 Транзит Rasputin → 192.168.0.0/24» section. - All other traffic entering from LAN bridge
br-lanusestable vpn. table vpnsends default traffic throughtun0.
/etc/rc.local adds the upstream-LAN bypass:
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
ip rule add to 192.168.2.0/24 lookup main priority 100
exit 0
⚠️ Здесь только 192.168.2.0/24. Строки для 192.168.0.0/24 нет — это и есть корневая причина сломанного транзита в GPON-сегмент. После ребута текущий ip rule 100 пересоздаётся именно из этого файла.
Firewall Model
Default firewall policy:
input: REJECT
output: ACCEPT
forward: REJECT
Zones:
lan
name='lan'
input='ACCEPT'
output='ACCEPT'
forward='REJECT'
masq='1'
network='lan'
wan
name='wan'
input='REJECT'
output='ACCEPT'
forward='REJECT'
masq='1'
mtu_fix='1'
network='wan' 'wan6' 'wwan' 'usbwan'
vpn
name='vpn'
input='ACCEPT'
output='ACCEPT'
forward='ACCEPT'
masq='1'
network='vpn'
Forwarding:
lan -> vpn
There is no general lan -> wan forwarding. Instead, selected lan -> wan traffic is allowed before a LAN-to-WAN killswitch.
Important Firewall Rules
Cloudflare Tunnel QUIC Direct Bypass
Added 2026-07-14:
firewall.@rule[8].name='Allow-Mac-cloudflared-QUIC-direct'
firewall.@rule[8].src='lan'
firewall.@rule[8].dest='wan'
firewall.@rule[8].src_ip='192.168.6.104' '192.168.6.173'
firewall.@rule[8].proto='udp'
firewall.@rule[8].dest_port='7844'
firewall.@rule[8].target='ACCEPT'
The nft realization appears in forward_lan before the killswitch:
ip saddr { 192.168.6.104, 192.168.6.173 } udp dport 7844 jump accept_to_wan comment "!fw4: Allow-Mac-cloudflared-QUIC-direct"
At capture time, this rule had matched traffic:
counter packets 19 bytes 27636
This confirms that Mac cloudflared QUIC traffic was hitting the direct-WAN exception.
Upstream LAN Bypass (Allow-upstream-LAN)
firewall.@rule[10].name='Allow-upstream-LAN'
firewall.@rule[10].src='lan'
firewall.@rule[10].dest='wan'
firewall.@rule[10].target='ACCEPT'
firewall.@rule[10].dest_ip='192.168.2.0/24' '192.168.0.1'
⚠️ Порядковый номер изменился (2026-09-17). Актуальное правило — firewall.@rule[0].name='Allow-upstream-LAN', и dest_ip расширен до GPON-сегмента. Его nft-реализация в forward_lan — две отдельные строки, tcp и udp, без icmp:
meta l4proto tcp ip daddr { 192.168.0.1, 192.168.0.50, 192.168.2.0/24 } counter packets 19 bytes 1216 jump accept_to_wan comment "!fw4: Allow-upstream-LAN"
meta l4proto udp ip daddr { 192.168.0.1, 192.168.0.50, 192.168.2.0/24 } counter packets 0 bytes 0 jump accept_to_wan comment "!fw4: Allow-upstream-LAN"
Практическое следствие: forward в GPON-сегмент разрешён, но без NAT ответ не вернётся, а ICMP вообще не проходит. Полный разбор — в разделе «🔴 Транзит Rasputin → 192.168.0.0/24» ниже.
🔴 ICMP к недоступному хосту в 192.168.2.0/24 отдаёт Destination Port Unreachable от САМОГО роутера
Наблюдение 2026-09-15 (подтверждено дважды в одной сессии). С Mac (192.168.6.104) при пинге выключенного хоста верхнего сегмента:
$ /sbin/ping -c 3 192.168.2.176
92 bytes from rasputin.lan (192.168.6.1): Destination Port Unreachable
Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
4 5 00 5400 a0a3 0 0000 3f 01 509d 192.168.6.104 192.168.2.176
--- 192.168.2.176 ping statistics ---
3 packets transmitted, 0 packets received, 100.0% packet loss
Как это читать (и как НЕ читать):
| Признак | Значение |
|---|---|
Request timeout for icmp_seq N |
нормальный признак «хост выключен» |
Destination Port Unreachable от rasputin.lan (192.168.6.1) |
это роутер отбивает попытку, а не ответ хоста |
Полный дамп IP-заголовка (Vr HL TOS … Src/Dst) |
ответ сгенерирован ICMP-модулем роутера, а не удалённой машиной |
100.0% packet loss |
хост не ответил |
/usr/sbin/arp -an | grep 176
? (192.168.6.176) at (incomplete) on en8 ifscope [ethernet]
(incomplete) = ARP-запрос ушёл, ответа нет → L2-ответа нет вообще, хост мёртв или вне сети. Это правильный признак для вывода «машина недоступна».
⚠️ ПИТФОЛЛ ДИАГНОСТИКИ: строка
Destination Port Unreachableот роутера легко читается как «порт закрыт, машина жива». Это НЕВЕРНО. Она одинаково выглядит и для хоста, который выключен, и для хоста, который висит в kernel lockup без сетевого стека. Опираться нужно наarp (incomplete)+ 100% loss, а не на текст ICMP-ошибки.
⚠️ Проверять достижимость узлов
192.168.2.0/24из192.168.6.0/24надёжнее всего тем же каналом, которым потом будете работать: SSH по ключу.ssh -o ConnectTimeout=10 -o BatchMode=yes root@192.168.2.176 'uptime'— если отвечает, хост жив, и всё дальнейшее снимается через него. Пинг/веб-порты могут врать (см.Reject to LANниже), SSH — нет.
🔴 Проверка 2026-09-17: 5 из 5 ICMP-попыток к
192.168.2.2отбиты роутером (Destination Port Unreachableот192.168.6.1), при том что с самого Rasputin192.168.2.2пингуется 0% loss, 0.75–0.84 ms. То есть эхо-запрос из LAN до шлюза не доходит вообще — отбой происходит локально. Практический вывод: отсутствие пинга к192.168.2.xНЕ говорит о том, что хост/шлюз недоступен. Единственный вывод — «ICMP из LAN до этого адреса зарезан». Никогда не строить на пинге вывод о состоянии аплинка; проверять TCP-каналом, которым будете работать.
⚠️ Ещё один контр-пример к пингу как индикатору (2026-09-17,
192.168.0.50): с Мака — 100% loss и безDestination Port Unreachable(обычный timeout), а с Rasputin — 0% loss. Здесь пинг отражает реальную поломку policy routing, но не показывает, жив ли хост. Различить «хост мёртв» и «транзит сломан» можно одним дешёвым шагом: пингануть ту же цель с самого Rasputin. Роутер видит, клиент — нет ⇒ проблема в транзите, не в хосте.
Границы прав внутри сегментов (напоминание):
- Router transit
192.168.6.0/24 ↔ 192.168.2.0/24— разрешён правилами выше. - Между сегментами есть санитарный
Reject to LANвforward_lan→ произвольные порты не пройдут, ICMP-эхо тоже. - Порты HA (
8123) и SSH (22) через транзит роутера не проверять как индикатор живости — индикатор это сам факт ответа SSH-сессии.
🔴 Транзит Rasputin → 192.168.0.0/24 (GPON-сегмент) НЕ РАБОТАЕТ
Наблюдение 2026-09-17. Симптом: с Мака (LAN 192.168.6.0/24) трафик на 192.168.0.50 и 192.168.0.1 (80 порт) не проходит.
Что подтверждено фактами
| Тест | Результат |
|---|---|
ping -c2 192.168.0.50 с Мака (192.168.6.173, en8) |
100% loss |
ping -c2 192.168.0.50 с самого Rasputin |
✅ 0% loss, 2.11–2.79 ms, ttl=63 |
ping -c2 192.168.2.2 с Мака |
100% loss + Destination Port Unreachable от 192.168.6.1 |
Вывод из таблицы: L2/L3 от Rasputin до 192.168.0.50 живой (ttl=63 — один хоп). Ломается только транзит из LAN 192.168.6.0/24.
Три причины
1. ip rule 100 покрывает только 192.168.2.0/24.
Фактические правила на роутере (2026-09-17):
0: from all lookup local
98: from 192.168.6.173 ipproto udp dport 7844 lookup main
99: from 192.168.6.104 ipproto udp dport 7844 lookup main
100: from all to 192.168.2.0/24 lookup main
101: from all iif br-lan lookup vpn
32766: from all lookup main
32767: from all lookup default
Для 192.168.0.50 правило 100 не матчится → пакет попадает в 101 → table vpn → tun0 (VLESS). Трафик уходит в туннель вместо WAN.
2. NAT/masq для зоны wan не покрывает 192.168.0.0/24.
Правило firewall уже расширено до GPON-сегмента:
meta l4proto tcp ip daddr { 192.168.0.1, 192.168.0.50, 192.168.2.0/24 } counter packets 19 bytes 1216 jump accept_to_wan comment "!fw4: Allow-upstream-LAN"
meta l4proto udp ip daddr { 192.168.0.1, 192.168.0.50, 192.168.2.0/24 } counter packets 0 bytes 0 jump accept_to_wan comment "!fw4: Allow-upstream-LAN"
То есть forward разрешён, но пакет уходит с source 192.168.6.x, а GPON-сегмент не знает обратного маршрута в 192.168.6.0/24. Ответ вернуться не может. В forward_lan нет NAT-правила для этого направления.
3. ICMP зарезан отдельно.
Allow-upstream-LAN в nft создан в двух вариантах — tcp и udp, без icmp — и стоит выше KillSwitch. Остальной ICMP из LAN падает в KillSwitch (packets 71 bytes 6192). Отсюда Destination Port Unreachable от самого роутера (см. раздел про ICMP ниже).
⚠️ Из-за п.3 пинг не является индикатором доступности
192.168.0.0/24из LAN. Проверять только тем каналом, которым будете работать (SSH/TCP).
WAN-интерфейс изменился (факт 2026-09-17)
Ранее (capture 2026-07-22) WAN был usb0 с адресом 10.252.240.230. Сейчас WAN = eth0:
inet 192.168.2.157/24 scope global eth0
default via 192.168.2.2 dev eth0 proto static src 192.168.2.157
То есть Rasputin получает адрес 192.168.2.157 от роутера 192.168.2.2 и выходит в интернет через него, а 192.168.2.2 — через GPON 192.168.0.1. Топология запроса подтверждена: rasputin → 192.168.2.2 → 192.168.0.1 (GPON) → 192.168.0.50.
✅ ЧТО СДЕЛАНО (2026-09-17) — правило ip rule добавлено и работает
Применено и проверено Alex руками (80 порт на 192.168.0.50 открылся):
# на живом роутере
ip rule add to 192.168.0.0/24 lookup main priority 100
# и то же записано в /etc/rc.local (чтобы выжило ребут)
Бэкап до правки: /etc/rc.local.bak.20260917-132639
Правила после правки (две строки priority 100 — это нормально):
100: from all to 192.168.2.0/24 lookup main
100: from all to 192.168.0.0/24 lookup main
101: from all iif br-lan lookup vpn
🔴 Правка файлов на роутере — через скачивание → локальную правку → заливку.
sed -iпо живому конфигу запрещён (и был заблокирован в этой сессии). Порядок:scpвниз →patchлокально →scpнаверх →catдля проверки.
⚠️ Что ОСТАЛОСЬ не сделано (осознанно, по объёму команды «ip rule»)
Alex дал команду только на ip rule. Следующие два пункта не трогались:
- NAT/masq для
192.168.0.0/24— нет. Пакет уходит с source192.168.6.x. Проверка показала, что 80 порт всё равно отвечает (GPON, судя по всему, маршрутизирует обратно), поэтому это не блокер, но и не гарантия. - ICMP —
Allow-upstream-LANв nft по-прежнему толькоtcp+udp, безicmp. Значит пинг из LAN в192.168.0.0/24не работает до сих пор, хотя TCP/UDP проходит. Не путать «не пингуется» с «не работает».
План ремонта (исходный, для истории)
# 1. ip rule — расширить bypass на GPON-сегмент ← СДЕЛАНО
ip rule add to 192.168.0.0/24 lookup main priority 100
# 2. та же строка в /etc/rc.local ← СДЕЛАНО
# 3. firewall: Allow-upstream-LAN dest_ip += 192.168.0.0/24, добавить proto icmp ← НЕ сделано
# 4. проверить, что masq зоны wan покрывает 192.168.0.0/24 ← НЕ сделано
Порядок работ по боевому конфигу: коммит ДО → правка → заливка → проверка Алекса руками → коммит ПОСЛЕ.
Downstream LAN Access
firewall.@rule[11].name='Allow-downstream-LAN'
firewall.@rule[11].src='wan'
firewall.@rule[11].dest='lan'
firewall.@rule[11].target='ACCEPT'
firewall.@rule[11].src_ip='192.168.2.0/24' '192.168.0.1'
KillSwitch
firewall.@rule[12].name='KillSwitch'
firewall.@rule[12].src='lan'
firewall.@rule[12].dest='wan'
firewall.@rule[12].proto='all'
firewall.@rule[12].target='REJECT'
In nft forward_lan, ordering is important:
1. Allow-Mac-cloudflared-QUIC-direct
2. Allow-upstream-LAN
3. KillSwitch
4. Accept lan to vpn forwarding
5. Accept DNAT port forwards
6. Reject to LAN
This ordering means only explicit lan -> wan exceptions escape; everything else either goes through VPN routing or is rejected from WAN.
Backup made before the Cloudflare firewall change:
/etc/config/firewall.bak.20260714-195530
Port Forwarding
There is a port-forward named LocalSend-to-mbp-black-eth:
firewall.@redirect[0].name='LocalSend-to-mbp-black-eth'
firewall.@redirect[0].src='wan'
firewall.@redirect[0].dest='lan'
firewall.@redirect[0].src_ip='192.168.2.0/24'
firewall.@redirect[0].proto='tcp udp'
firewall.@redirect[0].src_dport='53317'
firewall.@redirect[0].dest_ip='192.168.6.104'
firewall.@redirect[0].dest_port='53317'
firewall.@redirect[0].target='DNAT'
Reflection rules exist for LAN clients hitting the router WAN IP on port 53317, redirecting to 192.168.6.104:53317.
Cloudflare Tunnel / Mac Bypass Context
Problem addressed:
- Mac runs
cloudflaredforzulip.qentra.top. - Router routes normal LAN traffic through VLESS via
tun0. - Cloudflare Tunnel connector traffic should go direct to WAN rather than through VLESS.
Chosen solution:
- Mac
cloudflaredshould use QUIC, not HTTP/2. - Cloudflare Tunnel QUIC is UDP destination port
7844. - Router sends only Mac UDP/7844 through
maintable. - Firewall allows only Mac UDP/7844 from LAN to WAN before the KillSwitch.
Mac-side LaunchDaemon observed earlier:
/Library/LaunchDaemons/com.cloudflare.cloudflared.plist
Original args observed before the change:
cloudflared tunnel --protocol http2 run --token <redacted-cloudflare-tunnel-token>
Target Mac-side args:
cloudflared tunnel --protocol quic run --token <redacted-cloudflare-tunnel-token>
Manual Mac commands provided for that change:
sudo cp /Library/LaunchDaemons/com.cloudflare.cloudflared.plist \
/Library/LaunchDaemons/com.cloudflare.cloudflared.plist.bak.$(date +%Y%m%d-%H%M%S)
sudo /usr/libexec/PlistBuddy \
-c "Set :ProgramArguments:3 quic" \
/Library/LaunchDaemons/com.cloudflare.cloudflared.plist
sudo launchctl bootout system /Library/LaunchDaemons/com.cloudflare.cloudflared.plist
sudo launchctl bootstrap system /Library/LaunchDaemons/com.cloudflare.cloudflared.plist
Verify on Mac:
plutil -p /Library/LaunchDaemons/com.cloudflare.cloudflared.plist
tail -50 /Library/Logs/com.cloudflare.cloudflared.err.log
Expected log clue:
protocol=quic
Router-side counters can verify traffic is hitting the bypass:
nft list chain inet fw4 forward_lan
Look for increasing counters on:
Allow-Mac-cloudflared-QUIC-direct
Current Effective Traffic Behavior
Mac 192.168.6.104 UDP/7844 -> main routing table -> WAN direct
Mac 192.168.6.173 UDP/7844 -> main routing table -> WAN direct
Any LAN client -> 192.168.2.0/24 -> main routing table -> WAN/upstream LAN
Other LAN traffic -> vpn routing table -> tun0 -> Xray/VLESS
LAN -> WAN not explicitly allowed -> rejected by KillSwitch
Operational Commands
Restart VPN tunnel policy:
/etc/init.d/tunvpn restart
Restart firewall:
/etc/init.d/firewall restart
Show policy routing:
ip rule show
ip route show table vpn
ip route show table all
Show Cloudflare direct firewall counter:
nft list chain inet fw4 forward_lan
Show Xray logs:
tail -100 /tmp/xray-access.log
tail -100 /tmp/xray-error.log
Show active proxy processes:
ps w | grep -Ei 'xray|badvpn|tun2socks' | grep -v grep
Show current DHCP static leases:
uci show dhcp | grep -E 'mbp-black|192.168.6.104|192.168.6.173|00:e0:4c:68:04:88|66:02:b1:8b:2f:94'
Recovery / Rollback
DHCP backup from Mac static lease change:
/etc/config/dhcp.bak.20260714-195408
Routing service backup from Cloudflare direct-bypass change:
/etc/init.d/tunvpn.bak.20260714-195530
Firewall backup from Cloudflare direct-bypass change:
/etc/config/firewall.bak.20260714-195530
Роутинг через туннель (tunvpn) — 2026-07-14.
Firewall/Cloudflare bypass — 2026-07-14.
GPON-транзит (ip rule на 192.168.0.0/24) — 2026-09-17.
Rollback example:
cp /etc/init.d/tunvpn.bak.20260714-195530 /etc/init.d/tunvpn
chmod +x /etc/init.d/tunvpn
cp /etc/config/firewall.bak.20260714-195530 /etc/config/firewall
/etc/init.d/tunvpn restart
/etc/init.d/firewall restart
Rollback DHCP static leases:
cp /etc/config/dhcp.bak.20260714-195408 /etc/config/dhcp
uci commit dhcp
/etc/init.d/dnsmasq restart
Rollback GPON-транзита (2026-09-17):
# живая система
ip rule del to 192.168.0.0/24 lookup main priority 100
# постоянство
cp /etc/rc.local.bak.20260917-132639 /etc/rc.local
⚠️ Правки
/etc/rc.localна роутере делать только черезscp-вниз →patchлокально →scp-наверх.sed -iпо живому конфигу запрещён.
Notes And Pitfalls
- The Cloudflare bypass depends on Mac
cloudflaredusing QUIC. If the Mac falls back to HTTP/2/TCP/443, the router exception will not match. - There are two Mac source IPs because the Mac can use Ethernet or Wi-Fi.
- Both Mac IPs are now static DHCP reservations on Rasputin.
ip rulecan matchipproto udp dport 7844on this OpenWrt build; this was tested and confirmed before making the persistent change.- The firewall allow alone would not be sufficient, because policy routing rule
101sends LAN ingress totable vpn. The directip rules at priorities98and99must remain before priority101. - Rule order in
forward_lanmatters: Cloudflare direct allow must stay aboveKillSwitch. eth0is the active WAN as of 2026-09-17 (192.168.2.157/24, gw192.168.2.2);usb0is idle. At the 2026-07-22 capture this was inverted (eth0down,usb0carrying the default route). Do not trust the old banner — re-readip routebefore assuming which WAN is live.- 🔴 Транзит из LAN
192.168.6.0/24в GPON-сегмент192.168.0.0/24— ЧАСТИЧНО ПОЧИНЕН (2026-09-17).ip ruleдобавлено (живая система +/etc/rc.local), Alex проверил 80 порт на192.168.0.50— работает. Было три причины:ip rule 100не покрывал192.168.0.0/24(✅ исправлено); нет NAT/masq для этого направления (❌ не сделано, не блокер); ICMP не разрешён вAllow-upstream-LAN(❌ не сделано). Подробности — в разделе «Транзит Rasputin → 192.168.0.0/24». - 🔴 ICMP по-прежнему не индикатор доступности
192.168.0.0/24.Allow-upstream-LANсоздан только дляtcp+udp, поэтому эхо-запросы из LAN падают вKillSwitchи роутер отвечаетDestination Port Unreachableот себя. Пинг в GPON-сегмент не работает даже после починкиip rule— TCP/UDP при этом проходит. Проверять TCP-портом (nc -zv 192.168.0.50 80) или SSH. - Различай два похожих симптома:
Destination Port Unreachableот роутера192.168.6.1= локальное отбивание ICMP/firewall-ом, а не закрытый порт на хосте. Признак живости — ответ на TCP/SSH, а не текст ICMP-ошибки. - 🔴 Ping from Mac to an unreachable
192.168.2.xhost returnsDestination Port Unreachablefromrasputin.lan (192.168.6.1), NOT a plain timeout. This is the router rejecting the attempt — it does not mean the host is up with a closed port. Usearp (incomplete)+100% packet lossas the liveness signal. Confirmed 2026-09-15 (see the dedicated section above). - Liveness of
192.168.2.0/24hosts is best verified with the channel you intend to work through: key-based SSH (ssh -o BatchMode=yes root@192.168.2.176 'uptime'). Ping and web ports can mislead; an answered SSH session cannot. - Дешёвый способ развести «хост мёртв» и «транзит сломан»: пингануть цель с самого Rasputin (
ssh root@192.168.6.1 'ping -c2 <target>'). Если роутер видит хост, а LAN-клиент — нет, проблема в policy routing/firewall, а не в хосте. Именно так 2026-09-17 локализовали GPON-проблему. - Secrets are redacted here intentionally. Consult the live router files only when the actual VLESS or Cloudflare credentials are needed.