Skip to content

Commit

Permalink
[openwrt] add sing-box utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
lirundong committed Nov 27, 2023
1 parent c061c7f commit cbb4927
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 0 deletions.
4 changes: 4 additions & 0 deletions conf-gen/rule/ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ class GeoIP(IRBase):
_clash_prefix = "GEOIP"
_quantumult_prefix = "geoip"

@property
def clash_rule(self):
return f"{super().clash_rule},no-resolve"


@_IR_REGISTRY.register()
class IPCIDR(IRBase):
Expand Down
92 changes: 92 additions & 0 deletions openwrt-builder/files/etc/init.d/sing-box
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/bin/sh /etc/rc.common

USE_PROCD=1
START=99
STOP=01

start_service() {
local sing_box_root=/tmp/.config/sing-box
local sing_box_config=${sing_box_root}/config.json

procd_open_instance "sing-box-daemon"
procd_set_param command /tmp/bin/sing-box run -c ${sing_box_config}
procd_set_param file ${sing_box_config}
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param user root
procd_close_instance
}

reload_service() {
local sing_box_root=/tmp/.config/sing-box
local sing_box_config=${sing_box_root}/config.json
local clash_secret=@secret:CLASH_SECRET

curl -X PUT \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${clash_secret}" \
-d "{\"path\":\"${sing_box_config}\"}" \
http://127.0.0.1:9090/configs
}

service_started() {
# Handle TUN traffic for IPv4.
local tun_dev=${TUN_DEV:-"tun0"}
local tun_mark=${TUN_MARK:-"0x02"}
local tun_table=${TUN_TABLE:-"101"}
# Wait until TUN device is up.
ip addr list dev ${tun_dev} >/dev/null 2>&1
while [[ $? -ne 0 ]]; do
sleep 1s
ip addr list dev ${tun_dev} >/dev/null 2>&1
done

# Add routing policy.
ip route replace default dev ${tun_dev} table ${tun_table}
ip rule add fwmark ${tun_mark} table ${tun_table}
ip -6 route replace default dev ${tun_dev} table ${tun_table}
ip -6 rule add fwmark ${tun_mark} table ${tun_table}

# Instruct nftables to mark routable packets.
local nft_config=/etc/nftables.d/99-sing-box.nft
if test -f ${nft_config}.skip; then
mv ${nft_config}.skip ${nft_config}
fi
fw4 reload

# Add interface IP addresses into corresponding sets.
local interface_ipv4=$(ifconfig | grep 'inet addr' | cut -d: -f2 | awk '{print $1}')
local interface_ipv6=$(ifconfig | grep 'inet6 addr' | awk '{print $3}' 2>/dev/null)
for ipv4 in ${interface_ipv4}; do
if ! $(nft get element inet fw4 local_ipv4 { ${ipv4} } &> /dev/null); then
nft add element inet fw4 local_ipv4 { ${ipv4} }
fi
done
for ipv6 in ${interface_ipv6}; do
if ! $(nft get element inet fw4 local_ipv6 { ${ipv6} } &> /dev/null); then
nft add element inet fw4 local_ipv6 { ${ipv6} }
fi
done
}
service_stopped() {
# Cleanup TUN routes and rules.
local tun_dev=${TUN_DEV:-"tun0"}
local tun_mark=${TUN_MARK:-"0x02"}
local tun_table=${TUN_TABLE:-"101"}
ip rule delete fwmark ${tun_mark} table ${tun_table}
ip route flush table ${tun_table}
ip -6 rule delete fwmark ${tun_mark} table ${tun_table}
ip -6 route flush table ${tun_table}
# Clear packet fileting rules from nftables.
local nft_config=/etc/nftables.d/99-sing-box.nft
if test -f ${nft_config}; then
mv ${nft_config} ${nft_config}.skip
fi
fw4 reload
# Flush interface IP addresses from corresponding sets.
nft flush set inet fw4 local_ipv4
nft flush set inet fw4 local_ipv6
}
71 changes: 71 additions & 0 deletions openwrt-builder/files/etc/nftables.d/99-sing-box.nft
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/sbin/nft -f

# Available fw4 constants: (Note that *_subnets contains both ip and ip6 addresses.)
# lan_devices, lan_subnets
# wan_devices, wan_subnets
define tun_mark = 0x02
define tun_device = tun0

set direct_macs {
type ether_addr
elements = {
00:11:32:ac:77:2e, # synonas eth0
64:ff:0a:4b:8c:c1, # Sony-TV WiFi
00:e4:21:6a:eb:a3, # PS5 WiFi
00:e4:21:fd:9f:0b, # PS5 Ethernet
16:43:4b:30:19:84, # qemu-win10-compute
a6:3e:aa:1f:1d:57, # win-11-nv-work
9c:fc:e8:de:d3:de, # davidli-lt
54:ef:44:34:35:86, # Living room camera
54:ef:44:2e:b1:62, # Bedroom gateway
1a:07:10:1f:ab:50, # TrueNAS
1a:0d:d3:c5:27:27 # Plex-GPU
}
}

set local_ipv4 {
type ipv4_addr
flags interval
auto-merge
elements = {
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.168.0.0/16,
224.0.0.0/4,
240.0.0.0/4
}
}

set local_ipv6 {
type ipv6_addr
flags interval
auto-merge
elements = {
::/128,
::1/128,
::ffff:0:0/96,
::ffff:0:0:0/96,
64:ff9b::/96,
100::/64,
2001::/32,
2001:20::/28,
2001:db8::/32,
2002::/16,
fc00::/7,
fe80::/10,
ff00::/8
}
}

chain mangle_prerouting_custom {
type filter hook prerouting priority mangle - 1; policy accept;
# 1. Do not touch packets from direct-to-wan devices or packets designated to local network.
ether saddr @direct_macs counter return
ip daddr @local_ipv4 counter return
ip6 daddr @local_ipv6 counter return
# 2. Handle all remaining TCP and UDP packets by TProxy and route to lo later.
iifname $lan_devices counter meta mark set $tun_mark
}

0 comments on commit cbb4927

Please sign in to comment.