🎁 Sync 2026-07-31 00:21:49

This commit is contained in:
github-actions[bot] committed 2026-07-31 00:21:49 +08:00
1 parent 2660b1fce8
commit ae7b9f4d28
204 files changed
+187145 -10038

No files matched your search

+13 -28
View File
@@ -25,8 +25,8 @@ config homeproxy 'migration'
config homeproxy 'config'
option main_node 'nil'
option main_udp_node 'same'
option dns_server 'https://dns.quad9.net/dns-query'
option china_dns_server 'https://dns.alidns.com/dns-query'
option dns_server '8.8.8.8'
option china_dns_server '223.5.5.5'
option routing_mode 'bypass_mainland_china'
option routing_port 'common'
option proxy_mode 'redirect_tproxy'
@@ -38,36 +38,20 @@ config homeproxy 'control'
option lan_proxy_mode 'disabled'
list wan_proxy_ipv4_ips '91.105.192.0/23'
list wan_proxy_ipv4_ips '91.108.4.0/22'
list wan_proxy_ipv4_ips '91.108.8.0/21'
list wan_proxy_ipv4_ips '91.108.16.0/21'
list wan_proxy_ipv4_ips '91.108.8.0/22'
list wan_proxy_ipv4_ips '91.108.16.0/22'
list wan_proxy_ipv4_ips '91.108.12.0/22'
list wan_proxy_ipv4_ips '91.108.20.0/22'
list wan_proxy_ipv4_ips '91.108.56.0/22'
list wan_proxy_ipv4_ips '95.161.64.0/20'
list wan_proxy_ipv4_ips '149.154.160.0/20'
list wan_proxy_ipv4_ips '185.76.151.0/24'
list wan_proxy_ipv4_ips '203.208.50.66/32'
list wan_proxy_ipv6_ips '2001:67c:4e8::/48'
list wan_proxy_ipv6_ips '2001:b28:f23c::/47'
list wan_proxy_ipv6_ips '2001:b28:f23c::/48'
list wan_proxy_ipv6_ips '2001:b28:f23d::/48'
list wan_proxy_ipv6_ips '2001:b28:f23f::/48'
list wan_proxy_ipv6_ips '2a0a:f280::/32'
config homeproxy 'clash_api'
option external_ui '/etc/homeproxy/run/ui'
option external_ui_download_url 'https://gh-proxy.com/https://github.com/Zephyruso/zashboard/releases/latest/download/dist-cdn-fonts.zip'
option external_ui_download_detour 'direct-out'
option external_controller '0.0.0.0:9095'
option secret 'homeproxy'
option default_mode 'rule'
config homeproxy 'ntp'
option enabled '1'
option server 'ntp.aliyun.com'
option server_port '123'
option interval '30m'
config homeproxy 'cache'
option enabled '1'
option path '/etc/homeproxy/cache.db'
option store_rdrc '1'
config homeproxy 'routing'
option sniff_override '1'
option default_outbound 'direct-out'
@@ -82,12 +66,13 @@ config homeproxy 'dns'
config homeproxy 'subscription'
option auto_update '0'
option allow_insecure '0'
option latency_test_mode 'icmp'
option packet_encoding 'xudp'
option update_via_proxy '0'
option auto_update_time '0 0 * * *'
option filter_nodes 'disabled'
option filter_nodes 'blacklist'
list filter_keywords '重置|到期|过期|剩余|套餐'
list filter_keywords 'Expiration|Remaining'
config homeproxy 'server'
option enabled '0'
option log_level 'warn'
File diff suppressed because it is too large. Load diff
@@ -1 +1 @@
202606132337
20260704060757
@@ -1,8 +1,6 @@
2001:250::/30
2001:254::/33
2001:255::/32
2001:254::/31
2001:256:100::/48
2001:678:53c::/48
2001:c68::/32
2001:cc0::/32
2001:da8::/32
@@ -13,11 +11,8 @@
2001:dc7::/32
2001:dd8:1::/48
2001:dd9::/48
2001:df5:4740::/48
2001:df6:40::/48
2001:4510:400::/40
2001:4510:1480::/41
2001:4511:1480::/41
2400:1160::/32
2400:3200::/32
2400:5280:f803::/48
@@ -25,8 +20,6 @@
2400:6000::/32
2400:6600::/32
2400:6e60:1301::/48
2400:7100::/32
2400:73e0::/32
2400:75aa::/32
2400:7fc0::/40
2400:7fc0:220::/44
@@ -43,14 +36,9 @@
2400:8200::/32
2400:89c0:1010::/44
2400:89c0:1050::/46
2400:89c0:1130::/44
2400:89c0:1150::/48
2400:89c0:2100::/48
2400:89c0:2200::/48
2400:89c0:3010::/44
2400:89c0:6000::/48
2400:89c0:6100::/48
2400:8fc0:571::/48
2400:8fc0::/32
2400:9020:f010::/46
2400:9380:8001::/48
2400:9380:8003::/48
@@ -97,19 +85,15 @@
2400:cb80:e40::/44
2400:da00::/32
2400:dd00::/28
2400:e680::/32
2400:ee00::/32
2400:ee00:ffec::/46
2400:ee00:fff0::/44
2400:f6e0::/32
2400:f720::/32
2400:fe00::/32
2401:20::/40
2401:20:1330::/46
2401:800::/32
2401:1160::/32
2401:1200::/48
2401:1320::/32
2401:1d40::/32
2401:2780::/32
2401:2a00:f000::/43
2401:2e00::/32
2401:3480::/36
@@ -117,39 +101,11 @@
2401:3480:3000::/36
2401:34a0::/31
2401:3800::/32
2401:3880::/32
2401:3980::/32
2401:3a80::/32
2401:3b80::/32
2401:3c80::/32
2401:3d80::/32
2401:3e80::/32
2401:3f80::/32
2401:4180::/32
2401:4280::/32
2401:4380::/32
2401:4480::/32
2401:4580::/32
2401:4680::/32
2401:4780::/32
2401:4880::/32
2401:4a80::/32
2401:5c20:10::/48
2401:71c0::/48
2401:7660::/48
2401:7700::/32
2401:7d40::/32
2401:7e00::/32
2401:8be0::/48
2401:8d00::/47
2401:8d00:3::/48
2401:8d00:4::/47
2401:8d00:7::/48
2401:8d00:8::/47
2401:8d00:b::/48
2401:8d00:c::/48
2401:8d00:f::/48
2401:8d00:12::/48
2401:9a00::/44
2401:9a00:10::/46
2401:a140:1::/48
@@ -165,56 +121,26 @@
2401:c020:6::/48
2401:c020:8::/47
2401:c020:14::/48
2401:ca00::/32
2401:cb80::/32
2401:cc00::/32
2401:ce00::/32
2401:d0e0:3::/48
2401:d180::/46
2401:d180:10::/47
2401:d180:111::/48
2401:d180:2120::/48
2401:d780::/32
2401:d920::/48
2401:de00::/32
2401:ec00::/32
2401:fa00:40::/48
2402:840:d000::/46
2402:840:e000::/46
2402:840:f000::/38
2402:c60::/48
2402:1440::/32
2402:18a0::/32
2402:2000::/32
2402:2e60::/39
2402:34e0::/32
2402:36e0::/44
2402:3c00::/32
2402:3f80:1400::/40
2402:4440:9000::/39
2402:4440:9200::/48
2402:4440:9400::/48
2402:4440:9600::/48
2402:4440:9800::/48
2402:4440:9810::/48
2402:4440:9900::/48
2402:4440:9a00::/48
2402:4440:9b00::/48
2402:4440:9c00::/48
2402:4440:9d00::/48
2402:4440:9e00::/48
2402:4440:a000::/39
2402:4440:a800::/46
2402:4440:a810::/46
2402:4b80::/32
2402:4e00::/32
2402:5e40::/32
2402:5ec0::/32
2402:6e80::/32
2402:6f40::/48
2402:6f40:2::/47
2402:6fc0::/48
2402:7040::/32
2402:7d80::/48
2402:7d80:240::/48
2402:7d80:8888::/48
@@ -236,12 +162,7 @@
2402:dfc0:50::/44
2402:e480::/32
2402:e740::/32
2402:e7c0::/37
2402:e7c0:800::/38
2402:e7c0:1000::/36
2402:e7c0:2000::/35
2402:e7c0:4000::/34
2402:e7c0:8000::/33
2402:e7c0::/32
2402:e880::/48
2402:ef40::/32
2402:f000::/32
@@ -269,7 +190,6 @@
2403:7580::/32
2403:8080:101::/48
2403:8c00::/32
2403:9b00:2000::/48
2403:9b00:2400::/48
2403:9b00:6000::/48
2403:a100::/48
@@ -331,10 +251,6 @@
2404:c940::/48
2404:e280::/47
2404:e8c0::/32
2404:f4c0:f000::/48
2404:f4c0:f003::/48
2404:f4c0:f004::/46
2404:f4c0:f008::/45
2405:80:10::/48
2405:80:13::/48
2405:6c0:2::/48
@@ -354,130 +270,24 @@
2405:6f00:c602::/48
2405:7040:6000::/47
2405:78c0:6e00::/43
2405:8280::/32
2405:8a40::/32
2405:a900:ffee::/48
2405:a900:fffe::/48
2405:ad00::/32
2405:b7c0::/32
2405:d900::/32
2405:e000::/32
2405:e600:2::/48
2405:f940::/32
2406:280::/32
2406:840:8100::/40
2406:840:9178::/48
2406:840:9962::/47
2406:840:9966::/48
2406:840:996c::/48
2406:840:e080::/44
2406:840:e0cf::/48
2406:840:e0e0::/46
2406:840:e0e4::/47
2406:840:e10f::/48
2406:840:e14f::/48
2406:840:e330::/44
2406:840:e600::/44
2406:840:e620::/47
2406:840:e80f::/48
2406:840:eb01::/48
2406:840:eb02::/47
2406:840:eb04::/47
2406:840:eb07::/48
2406:840:eb08::/48
2406:840:eb0b::/48
2406:840:ee40::/47
2406:840:ee44::/48
2406:840:ee4b::/48
2406:840:ee4d::/48
2406:840:eee5::/48
2406:840:f380::/44
2406:840:f44f::/48
2406:840:9680::/44
2406:840:f889::/48
2406:840:fa01::/48
2406:840:fa60::/44
2406:840:fc10::/47
2406:840:fc12::/48
2406:840:fc20::/47
2406:840:fc22::/48
2406:840:fc30::/47
2406:840:fc32::/48
2406:840:fc40::/47
2406:840:fc42::/48
2406:840:fc50::/47
2406:840:fc52::/48
2406:840:fc60::/47
2406:840:fc62::/48
2406:840:fc70::/47
2406:840:fc72::/48
2406:840:fc90::/47
2406:840:fc92::/48
2406:840:fca0::/47
2406:840:fca2::/48
2406:840:fcb0::/47
2406:840:fcb2::/48
2406:840:fcd0::/48
2406:840:fd40::/48
2406:840:fd46::/47
2406:840:fd48::/48
2406:840:fd50::/48
2406:840:fd56::/47
2406:840:fd58::/48
2406:840:fd60::/48
2406:840:fd66::/47
2406:840:fd68::/48
2406:840:fd70::/48
2406:840:fd76::/47
2406:840:fd78::/48
2406:840:fd80::/48
2406:840:fd86::/47
2406:840:fd88::/48
2406:840:fd90::/47
2406:840:fd92::/48
2406:840:fd9f::/48
2406:840:fda0::/48
2406:840:fda7::/48
2406:840:fdb0::/48
2406:840:fdb7::/48
2406:840:fdc0::/48
2406:840:fdc7::/48
2406:840:fe90::/46
2406:840:fe94::/48
2406:840:fe96::/47
2406:840:fe98::/46
2406:840:fe9d::/48
2406:840:fe9e::/48
2406:840:fea2::/47
2406:840:fea4::/46
2406:840:fea8::/48
2406:840:feaa::/47
2406:840:feac::/46
2406:840:fec0::/48
2406:840:fec2::/47
2406:840:fec4::/48
2406:840:feca::/47
2406:840:fecf::/48
2406:840:fed1::/48
2406:840:fed8::/48
2406:840:fedb::/48
2406:840:fedc::/48
2406:840:fef3::/48
2406:840:fef4::/48
2406:840:fef6::/47
2406:840:fef8::/46
2406:840:fefc::/48
2406:840:feff::/48
2406:1080::/48
2406:1e40:f012::/47
2406:2700::/32
2406:3340::/32
2406:3640:1::/48
2406:4d00::/48
2406:52c0::/32
2406:5340:6666::/48
2406:5340:8888::/48
2406:6100::/32
2406:8880::/48
2406:b640:100::/48
2406:b640:4100::/48
2406:cac0::/40
@@ -494,7 +304,6 @@
2407:23c0::/48
2407:2840::/48
2407:37c0::/32
2407:4980::/32
2407:5380::/32
2407:6c40:1100::/48
2407:6c40:1210::/48
@@ -513,51 +322,7 @@
2407:c080:6000::/36
2407:c080:8000::/36
2407:d9c0::/32
2408:4000::/40
2408:4000:100::/47
2408:4000:103::/48
2408:4000:104::/46
2408:4000:108::/45
2408:4000:110::/44
2408:4000:120::/43
2408:4000:140::/42
2408:4000:180::/41
2408:4000:200::/39
2408:4000:400::/38
2408:4000:800::/37
2408:4000:1000::/36
2408:4000:2000::/35
2408:4000:4000::/34
2408:4000:8000::/33
2408:4001::/32
2408:4002::/31
2408:4004::/30
2408:4008::/29
2408:4010::/30
2408:4014::/31
2408:4016:1::/48
2408:4016:2::/47
2408:4016:4::/46
2408:4016:8::/45
2408:4016:10::/44
2408:4016:20::/43
2408:4016:40::/42
2408:4016:80::/41
2408:4016:100::/40
2408:4016:200::/39
2408:4016:400::/38
2408:4016:800::/37
2408:4016:1000::/36
2408:4016:2000::/35
2408:4016:4000::/34
2408:4016:8000::/33
2408:4017::/32
2408:4018::/29
2408:4020::/27
2408:4040::/26
2408:4080::/25
2408:4100::/24
2408:4200::/23
2408:4000::/22
2408:8000::/48
2408:8000:2::/47
2408:8000:1000::/36
@@ -814,86 +579,103 @@
2408:840c:dd00::/40
2408:840c:de00::/40
2408:840d::/42
2408:840d:40::/43
2408:840d:200::/42
2408:840d:400::/42
2408:840d:440::/43
2408:840d:600::/42
2408:840d:d00::/42
2408:840d:d40::/43
2408:840d:f00::/42
2408:840d:1100::/42
2408:840d:1140::/43
2408:840d:1300::/42
2408:840d:1a00::/42
2408:840d:1a40::/43
2408:840d:1c00::/42
2408:840d:1e00::/42
2408:840d:1e40::/43
2408:840d:2000::/42
2408:840d:2700::/42
2408:840d:2740::/43
2408:840d:2900::/42
2408:840d:2b00::/42
2408:840d:2b40::/43
2408:840d:2d00::/42
2408:840d:3400::/42
2408:840d:3440::/43
2408:840d:3600::/42
2408:840d:3800::/42
2408:840d:3840::/43
2408:840d:3a00::/42
2408:840d:4e00::/42
2408:840d:4e40::/43
2408:840d:5000::/42
2408:840d:5200::/42
2408:840d:5240::/43
2408:840d:5400::/42
2408:840d:5b00::/42
2408:840d:5b40::/43
2408:840d:5d00::/42
2408:840d:5f00::/42
2408:840d:5f40::/43
2408:840d:6100::/42
2408:840d:6800::/42
2408:840d:6840::/43
2408:840d:6a00::/42
2408:840d:6c00::/42
2408:840d:6c40::/43
2408:840d:6e00::/42
2408:840d:7500::/42
2408:840d:7540::/43
2408:840d:7700::/42
2408:840d:7900::/42
2408:840d:7940::/43
2408:840d:7b00::/42
2408:840d:8200::/42
2408:840d:8240::/43
2408:840d:8400::/42
2408:840d:8600::/42
2408:840d:8640::/43
2408:840d:8800::/42
2408:840d:8f00::/42
2408:840d:8f40::/43
2408:840d:9100::/42
2408:840d:9300::/42
2408:840d:9340::/43
2408:840d:9500::/42
2408:840d:9c00::/42
2408:840d:9c40::/43
2408:840d:9e00::/42
2408:840d:a000::/42
2408:840d:a040::/43
2408:840d:a200::/42
2408:840d:a900::/42
2408:840d:a940::/43
2408:840d:ab00::/42
2408:840d:ad00::/42
2408:840d:ad40::/43
2408:840d:af00::/42
2408:840d:b600::/42
2408:840d:b640::/43
2408:840d:b800::/42
2408:840d:ba00::/42
2408:840d:ba40::/43
2408:840d:bc00::/42
2408:840d:c300::/42
2408:840d:c340::/43
2408:840d:c500::/42
2408:840d:c700::/42
2408:840d:c740::/43
2408:840d:c900::/42
2408:840d:d000::/42
2408:840d:d040::/43
2408:840d:d200::/42
2408:840d:d400::/42
2408:840d:d440::/43
2408:840d:d600::/42
2408:840d:dd00::/42
2408:840d:dd40::/43
2408:840d:de00::/42
2408:840e:dd00::/40
2408:840e:de00::/40
@@ -1074,6 +856,7 @@
2408:8a06:100::/47
2408:8a07::/40
2408:8a21:4000::/35
2408:8a22::/35
2408:8a23:4000::/34
2408:8a24:4000::/34
2408:8a26:c000::/34
@@ -1087,47 +870,14 @@
2409:27fc::/48
2409:27fe::/33
2409:6100::/44
2409:8000::/21
2409:8800::/22
2409:8c00::/25
2409:8c80::/30
2409:8c84::/32
2409:8c85::/34
2409:8c85:4000::/36
2409:8c85:5000::/38
2409:8c85:5400::/43
2409:8c85:5420::/44
2409:8c85:5430::/47
2409:8c85:5433::/48
2409:8c85:5434::/46
2409:8c85:5438::/45
2409:8c85:5440::/42
2409:8c85:5480::/41
2409:8c85:5500::/40
2409:8c85:5600::/39
2409:8c85:5800::/37
2409:8c85:6000::/35
2409:8c85:8000::/33
2409:8c86::/31
2409:8c88::/29
2409:8c90::/28
2409:8ca0::/27
2409:8cc0::/26
2409:8d00::/24
2409:8e00::/23
2409:8000::/20
240a:2000::/40
240a:2001:100::/40
240a:2001:1000::/36
240a:4002:1b00::/40
240a:4010:8000::/33
240a:4020:83a::/48
240a:4020:883a::/48
240a:4021:83a::/48
240a:4021:883a::/48
240a:4080:8000::/35
240a:4084:2000::/35
240a:4088:a000::/35
240a:408c:2000::/35
240a:4090:50::/48
240a:4090:120::/48
240a:4090:250::/48
@@ -1142,20 +892,11 @@
240a:4090:5200::/40
240a:4090:7000::/39
240a:4090:7200::/40
240a:4090:8000::/34
240a:4093::/35
240a:4094:2000::/35
240a:409c:2000::/35
240a:40a4:2000::/35
240a:40a8:8000::/35
240a:40ac:2000::/35
240a:40b0:83a::/48
240a:40b0:283a::/48
240a:40b0:483a::/48
240a:40b0:683a::/48
240a:40c0:8000::/43
240a:40c0:8200::/48
240a:40c0:8240::/48
240a:40c0:a000::/43
240a:40c0:c000::/43
240a:40c0:e000::/43
@@ -1182,31 +923,10 @@
240a:40c3:8000::/43
240a:40c3:a000::/43
240a:40c3:c000::/43
240a:40c3:c200::/48
240a:40c3:c240::/48
240a:40c3:e000::/43
240a:40c4::/43
240a:40c4:2000::/43
240a:40c4:4000::/43
240a:4172::/31
240a:4180::/31
240a:41b0::/34
240a:41b8:8800::/40
240a:41b8:a000::/40
240a:41b8:d400::/40
240a:41b8:e400::/40
240a:41d6::/31
240a:41f2::/31
240a:4208::/30
240a:4224:9000::/44
240a:4224:a000::/44
240a:4224:c000::/44
240a:4224:d000::/44
240a:4224:e000::/44
240a:4225:1000::/44
240a:4225:3000::/44
240a:4230::/31
240a:4242::/31
240a:4280::/26
240a:42c0::/27
240a:42e0::/28
@@ -1223,69 +943,7 @@
240c:4000::/22
240c:c000::/20
240d:4000::/21
240e::/21
240e:800::/24
240e:900::/26
240e:940::/27
240e:960::/28
240e:970::/29
240e:978::/30
240e:97c::/32
240e:97d::/33
240e:97d:8001::/48
240e:97d:8002::/47
240e:97d:8004::/46
240e:97d:8008::/45
240e:97d:8010::/44
240e:97d:8020::/43
240e:97d:8040::/42
240e:97d:8080::/41
240e:97d:8100::/40
240e:97d:8200::/39
240e:97d:8400::/38
240e:97d:8800::/37
240e:97d:9000::/36
240e:97d:a000::/35
240e:97d:c000::/34
240e:97e::/31
240e:980::/31
240e:982::/32
240e:983::/35
240e:983:2000::/44
240e:983:2011::/48
240e:983:2012::/48
240e:983:2014::/46
240e:983:2018::/45
240e:983:2021::/48
240e:983:2023::/48
240e:983:2024::/46
240e:983:2028::/45
240e:983:2031::/48
240e:983:2032::/47
240e:983:2034::/46
240e:983:2038::/45
240e:983:2040::/42
240e:983:2080::/41
240e:983:2100::/40
240e:983:2200::/39
240e:983:2400::/38
240e:983:2800::/37
240e:983:3000::/36
240e:983:4000::/34
240e:983:8000::/33
240e:984::/30
240e:988::/29
240e:990::/28
240e:9a0::/27
240e:9c0::/26
240e:a00::/23
240e:c00::/22
2602:f92a:a468::/48
2602:f92a:a46d::/48
2602:f92a:a47d::/48
2602:f9ba:a8::/48
2602:f9ba:10c::/48
2602:f9f6:450::/48
240e::/20
2605:9d80:8001::/48
2605:9d80:8011::/48
2605:9d80:8021::/48
@@ -1301,8 +959,6 @@
2605:9d80:9092::/48
2804:1e48:9001::/48
2804:1e48:9002::/48
2a01:e281:a400::/48
2a01:e281:a410::/44
2a04:3e00:1002::/48
2a04:f580:8010::/47
2a04:f580:8090::/48
@@ -1327,163 +983,26 @@
2a04:f580:9270::/48
2a04:f580:9280::/48
2a04:f580:9290::/48
2a05:1087::/32
2a06:3600:e000::/40
2a06:3600:fb00::/40
2a06:3600:fc00::/38
2a06:3605::/32
2a06:3606::/31
2a06:a005:260::/43
2a06:a005:280::/43
2a06:a005:2a0::/44
2a07:54c1:2200::/46
2a07:54c1:2205::/48
2a0a:d681:e000::/40
2a0a:d681:fb00::/40
2a0a:d681:fc00::/38
2a0a:d687:f001::/48
2a0c:b641:571::/48
2a0e:aa06::/40
2a0e:aa06:440::/48
2a0e:aa06:450::/44
2a0e:aa06:490::/44
2a0e:aa06:4e0::/44
2a0e:aa07:e144::/48
2a0e:aa07:e146::/48
2a0e:aa07:e148::/48
2a0e:aa07:e280::/47
2a0e:aa07:e284::/46
2a0e:aa07:e288::/47
2a0e:aa07:e28a::/48
2a0e:aa07:e28d::/48
2a0e:aa07:e28e::/48
2a0e:aa07:f0d0::/46
2a0e:aa07:f0d4::/47
2a0e:aa07:f0d8::/48
2a0e:aa07:f0de::/47
2a0a:d685:1ff::/48
2a0a:d685:300::/40
2a0b:4340:90::/48
2a0b:4340:97::/48
2a0d:c7c7:400::/38
2a0e:aa06:49f::/48
2a0e:b107:740::/44
2a0e:b107:da0::/44
2a0e:b107:14a0::/44
2a0f:1cc5:14::/46
2a0f:1cc5:1f::/48
2a0f:1cc5:40::/48
2a0f:1cc5:110::/44
2a0f:1cc5:130::/44
2a0f:1cc5:140::/42
2a0f:1cc5:600::/47
2a0f:1cc5:603::/48
2a0f:1cc5:642::/48
2a0f:1cc5:661::/48
2a0f:1cc5:662::/48
2a0f:1cc5:6a0::/48
2a0f:1cc5:f01::/48
2a0f:1cc5:f02::/47
2a0f:1cc5:f04::/46
2a0f:1cc5:f09::/48
2a0f:1cc5:fff::/48
2a0f:1cc5:1000::/48
2a0f:1cc5:1010::/44
2a0f:1cc5:1032::/47
2a0f:1cc5:1034::/47
2a0f:1cc5:1c00::/47
2a0f:1cc5:1c02::/48
2a0f:1cc5:1c20::/48
2a0f:1cc5:1c30::/48
2a0f:1cc5:1cc0::/48
2a0f:1cc5:1d10::/47
2a0f:1cc5:2000::/40
2a0f:1cc5:2510::/44
2a0f:1cc5:2520::/44
2a0f:1cc5:25ff::/48
2a0f:1cc5:2600::/41
2a0f:1cc5:2680::/42
2a0f:1cc5:2d01::/48
2a0f:1cc5:2d03::/48
2a0f:1cc5:3200::/46
2a0f:1cc5:3222::/48
2a0f:1cc6:b110::/47
2a0f:1cc6:b210::/47
2a0f:1cc6:b212::/48
2a0f:2706::/32
2a0f:85c1:bfe::/48
2a12:cb41::/44
2a12:cb46::/36
2a12:cb47:ffff::/48
2a13:1800::/48
2a13:1800:10::/48
2a13:1800:80::/44
2a13:1800:300::/44
2a0e:b107:2440::/44
2a0f:1cc5:1600::/44
2a0f:1cc5:4700::/40
2a12:cb41:1200::/44
2a12:cb41:1300::/43
2a12:cb41:13f0::/44
2a13:1801:180::/43
2a13:1801:200::/44
2a13:8c87::/32
2a13:a5c3:ff41::/48
2a13:a5c3:ff50::/44
2a14:67c1:70::/48
2a14:67c1:74::/48
2a14:67c1:a110::/44
2a14:67c1:a123::/48
2a14:67c1:a125::/48
2a14:67c1:a128::/48
2a14:67c1:b500::/48
2a14:67c1:b511::/48
2a14:67c1:b514::/48
2a14:67c1:b530::/44
2a14:67c1:b563::/48
2a14:67c1:b578::/48
2a14:67c1:b586::/47
2a14:67c1:b588::/47
2a14:67c1:b590::/48
2a14:67c1:b599::/48
2a14:67c1:b5e0::/44
2a14:67c1:c300::/40
2a14:67c2:519::/48
2a14:67c2:a10::/47
2a14:67c2:a21::/48
2a14:67c2:a22::/47
2a14:67c2:a2f::/48
2a14:67c2:a30::/48
2a14:67c2:a41::/48
2a14:67c2:a50::/48
2a14:67c2:a70::/47
2a14:67c2:a80::/47
2a14:67c2:a90::/48
2a14:67c3:c0::/48
2a14:67c3:190::/47
2a14:67c3:192::/48
2a14:67c3:1100::/47
2a14:67c3:9990::/44
2a14:7580:740::/44
2a14:7580:fffa::/48
2a14:7581:ffb::/48
2a14:7581:30b6::/48
2a14:7583:f224::/47
2a14:7583:f228::/48
2a14:7583:f22c::/48
2a14:7583:f244::/48
2a14:7583:f264::/48
2a14:7583:f268::/48
2a14:7583:f300::/46
2a14:7583:f304::/47
2a14:7583:f306::/48
2a14:7583:f411::/48
2a14:7583:f4f0::/48
2a14:7583:f4f4::/48
2a14:7583:f4fe::/48
2a14:7583:f701::/48
2a14:7583:f703::/48
2a14:7583:f704::/46
2a14:7583:f708::/46
2a14:7583:f70c::/48
2a14:7583:f743::/48
2a14:7583:f744::/48
2a14:7583:f764::/48
2a14:7586:6100::/47
2a14:7586:6103::/48
2a14:7586:6104::/47
2a14:7586:6110::/48
2a14:7586:6300::/44
2a14:7dc0:506::/48
2a14:ae00:50::/44
2a13:a5c3:f000::/40
2a14:7580:d00::/43
2a14:7580:d20::/46
2a14:7580:d41::/48
2a14:7580:d42::/47
2a14:7580:dff::/48
2c0f:f7a8:8011::/48
2c0f:f7a8:8050::/48
2c0f:f7a8:805f::/48
@@ -1492,5 +1011,4 @@
2c0f:f7a8:8211::/48
2c0f:f7a8:9020::/48
2c0f:f7a8:9041::/48
2c0f:f7a8:9211::/48
2c0f:f7a8:9220::/48
@@ -1 +1 @@
202606132337
20260704060757
File diff suppressed because it is too large. Load diff
@@ -1 +1 @@
202606132337
202607052256
@@ -13,6 +13,7 @@
173ng.com
18board.com
18comic.org
18mh.net
1984bbs.com
1991way.com
1e100.net
@@ -73,6 +74,7 @@
9cache.com
9gag.com
9news.com.au
9oju31.launches.appsflyersdk.com
a-normal-day.com
a248.e.akamai.net
aamacau.com
@@ -87,6 +89,7 @@ about.gitlab.com
about.me
abplive.com
acast.com
accountboy.com
accountkit.com
acevpn.com
acg.mn
@@ -128,6 +131,7 @@ aiosearch.com
aiph.net
airconsole.com
airitilibrary.com
airuniversity.af.edu
airvpn.org
ait.org.tw
aiweiweiblog.com
@@ -207,13 +211,18 @@ aoxvpn.com
apartmentratings.com
apartments.com
apat1989.org
api-gl.lbkrs.com
api-secure.recaptcha.net
api-verify.recaptcha.net
api.ai
api.futunn.com
api.lbkrs.com
api.moomoobull.com
api.palworldgame.com
api.pureapk.com
api.recaptcha.net
api.steampowered.com
api5.futunn.com
apiary.io
apigee.com
apk.support
@@ -391,6 +400,7 @@ bigjapanesesex.com
bignews.org
bigone.com
bild.de
bilinovel.com
biliworld.com
binance.com
binance.org
@@ -655,6 +665,7 @@ cdjp.org
cdn-images.mailchimp.com
cdn-telegram.org
cdn.arstechnica.net
cdn.futustatic.com
cdn.jwplayer.com
cdn.printfriendly.com
cdn.seatguru.com
@@ -678,6 +689,7 @@ centurys.net
certificate-transparency.org
certificate.revocationcheck.com
cfr.org
cg.play-analytics.com
cgdepot.org
change.org
changp.com
@@ -859,6 +871,7 @@ crazypool.org
crazyshit.com
crbug.com
crchina.org
creader.com
creaders.net
creativelab5.com
cristyli.com
@@ -1024,6 +1037,7 @@ dougscripts.com
doujincafe.com
dowjones.io
download.dappcdn.com
download.futunn.com
dpool.top
dpp.org.tw
dpr.info
@@ -1149,6 +1163,7 @@ expatshield.com
expecthim.com
expekt.com
exploader.net
expressnews.com
expressvpn.com
exrates.me
extmatrix.com
@@ -1339,7 +1354,36 @@ funkyimg.com
furbo.org
furinkan.com
furrybar.com
futu.cn
futu.com
futu.link
futu0.com
futu1.com
futu2.com
futu3.com
futu4.com
futu5.com
futu6.com
futu7.com
futu8.com
futu9.com
futuau.com
futubull.cn
futuchain.com
futuesop.com
futufin.com
futuhk.com
futuhk2.com
futuhkapp.com
futuhn.com
futuholdings.com
futuinc.com
futuniuniu.com
futunn.com
futuremessage.org
futustatic.com
fututrade.com
fututrustee.com
fw.cm
fxcm-chinese.com
fxnetworks.com
@@ -1362,6 +1406,7 @@ gaoming.net
gaopi.net
gartlive.com
garudalinux.org
gate.com
gate.io
gatecoin.com
gather.com
@@ -1382,6 +1427,7 @@ generated.photos
genius.com
geph.io
get.app
get.dappcdn.com
get.dev
get.how
get.page
@@ -1739,6 +1785,7 @@ gtv.org
gtv1.org
gu-chu-sum.org
guaguass.com
guangming.com.my
guishan.org
gumroad.com
gunsamerica.com
@@ -1829,6 +1876,7 @@ hkgolden.com
hkgpao.com
hklts.org.hk
hkmap.live
hkong.hk
hkopentv.com
hkpeanut.com
hkreporter.com
@@ -2043,6 +2091,7 @@ itasoftware.com
itch.io
itemfix.com
itiger.com
itigerup.com
itshidden.com
itweet.net
iuhrdf.org
@@ -2132,6 +2181,7 @@ kenengba.com
kepard.com
kex.com
keycdn.com
kfor.com
khatrimaza.org
kichiku-doujinko.com
kik.com
@@ -2181,12 +2231,15 @@ landofhope.tv
lantern.io
laogai.org
laogairesearch.org
laohu8.com
laqingdan.net
larsgeorge.com
lastcombat.com
lastfm.es
lausan.hk
lbank.info
lbctrl.com
lbkrs.com
ldplayer.net
ldplayer.tw
le-vpn.com
@@ -2255,6 +2308,15 @@ localdomain.ws
lockestek.com
login.target.com
logos.com.hk
longbridge.cloud
longbridge.com
longbridge.global
longbridge.hk
longbridge.sg
longbridgeapp.com
longbridgehk.com
longportapp.cn
longportapp.com
longtermly.net
longtoes.com
lookpic.com
@@ -2372,6 +2434,7 @@ mfxmedia.com
mgoon.com
mgstage.com
mh4u.org
mhwindow.org
microvpn.com
mihua.org
mij.rip
@@ -2441,6 +2504,9 @@ monitorchina.org
monocloud.me
monster.com
moodyz.com
moomoo.com
moomooequity.com
moomootrustee.com
moon.fm
moonbbs.com
moonbingo.com
@@ -2681,6 +2747,13 @@ ooni.io
ooni.org
open.firstory.me
openai.com
openapi-quote.longbridge.cn
openapi-quote.longbridge.com
openapi-trade.longbridge.cn
openapi-trade.longbridge.com
openapi.futunn.com
openapi.longbridge.cn
openapi.longbridge.com
openart.ai
opencritic.com
opendemocracy.net
@@ -2746,6 +2819,7 @@ pbs.org
pbworks.com
pbxes.com
pbxes.org
pcgamesn.com
pcgamestorrents.com
pcij.org
pct.org.tw
@@ -2764,6 +2838,7 @@ peoplenews.tw
peopo.org
perfect-privacy.com
periscope.tv
perma.cc
perplexity.ai
pewresearch.org
phayul.com
@@ -2935,12 +3010,15 @@ qmp4.com
qoos.com
qq.co.za
qstatus.com
qtcard.futunn.com
qtcardfthk.futufin.com
qtrac.eu
questvisual.com
quitccp.org
quiz.directory
quora.com
quoracdn.net
quote.longbridge.global
quran.com
qz.com
r-pool.net
@@ -3009,6 +3087,7 @@ rentry.co
renyurenquan.org
resilio.com
resistchina.org
restofworld.org
retweetrank.com
reuters.com
reutersmedia.net
@@ -3082,6 +3161,10 @@ saveuighur.org
sbme.me
sbti.unun.dev
schema.org
schwab.co.uk
schwab.com
schwab.com.cn
schwab.com.hk
scmp.com
scramble.io
scratch.mit.edu
@@ -3120,6 +3203,7 @@ sexinsex.net
sf.net
sfshibao.com
sftuk.org
sgqt0j.launches.appsflyersdk.com
shadeyouvpn.com
shadowsocks.be
shadowsocks.com.hk
@@ -3144,6 +3228,7 @@ shodanhq.com
shooshtime.com
shopee.tw
shopping.yahoo.co.jp
shortconn.im.qcloud.com
showwe.tw
shutterstock.com
shwchurch.org
@@ -3168,6 +3253,7 @@ sinoants.com
sinoca.com
sinocast.com
sinoinsider.com
sinyalee.com
sipml5.org
sis001.com
site.new
@@ -3237,6 +3323,7 @@ southmongolia.org
southnews.com.tw
southpark.cc.com
sowers.org.hk
spaceforce.mil
spaces.hightail.com
spacex.com
spankbang.com
@@ -3327,6 +3414,8 @@ supchina.com
superpages.com
supervpn.net
superzooi.com
support.futunn.com
supremecourt.gov
suprememastertv.com
surfeasy.com
surfeasy.com.au
@@ -3438,6 +3527,7 @@ thehansindia.com
thehindu.com
thehun.net
theinitium.com
theintercept.com
thenewslens.com
thepiratebay.org
theporndude.com
@@ -3516,6 +3606,12 @@ tibettelegraph.com
tibettimes.net
tibettruth.com
tibetwrites.org
tigerbbs.cn
tigerbbs.com
tigerbrokers.com
tigerbrokers.net
tigerbrokers.nz
tigerfintech.com
tigervpn.com
tiktok.com
tiktokcdn-eu.com
@@ -3578,6 +3674,9 @@ totalvpn.com
tou.tv
tpi.org.tw
tracfone.com
trade.futunn.com
trade.longportapp.com
tradeup.com
tradingview.com
translate.goog
transparency.org
@@ -3586,6 +3685,7 @@ trendsmap.com
tronscan.org
trouw.nl
trt.net.tr
trtworld.com
truebuddha-md.org
trustwallet.com
truthsocial.com
@@ -3681,6 +3781,7 @@ twitturk.com
twitturly.com
twkan.com
twreporter.org
twstalker.com
twt.tl
twtkr.com
twttr.com
@@ -3895,6 +3996,7 @@ wanz-factory.com
warroom.org
waselpro.com
washingtonpost.com
washingtontimes.com
watchinese.com
watchmygf.net
watchout.tw
@@ -3903,6 +4005,7 @@ wav.tv
waveprotocol.org
waybig.com
waymo.com
wbrks.com
wd.bible
wealth.com.tw
wearn.com
@@ -3912,6 +4015,7 @@ webmproject.org
webpkgcache.com
webrtc.org
websdr.org
webshare.io
website.new
webwarper.net
wechatlawsuit.com
@@ -4081,6 +4185,7 @@ xgmyd.com
xhamster.com
xianjian.tw
xiaohexie.com
xiaohu8.com
xiaolan.me
xiaoma.org
xiaomi.eu
@@ -4105,6 +4210,7 @@ xn--noss43i.com
xn--oiq.cc
xn--p8j9a0d9c9a.xn--q9jyb4c
xn--u2u927b.com
xn--vuqv2cf7wzyig79c.com
xnpool.com
xnxx.com
xpud.org
@@ -4113,6 +4219,7 @@ xskywalker.com
xt.com
xt.pub
xtube.com
xuan.com.my
xuchao.net
xuchao.org
xuehua.us
@@ -4219,6 +4326,8 @@ zhao.1984.city
zhengjian.org
zhengwunet.org
zhenxiang.biz
zhijianfengyi.cn
zhijianfengyi.com
zhizhu.top
zhongguo.ca
zhongguotese.net
@@ -1 +1 @@
202606132337
202607052256
@@ -7,7 +7,6 @@
'use strict';
import { md5 } from 'digest';
import { readfile, writefile } from 'fs';
import { isnan } from 'math';
import { connect } from 'ubus';
@@ -30,10 +29,7 @@ uci.load(uciconfig);
const uciinfra = 'infra',
ucimain = 'config',
ucicontrol = 'control',
uciclashapi = 'clash_api',
ucintp = 'ntp',
ucicache = 'cache';
ucicontrol = 'control';
const ucidnssetting = 'dns',
ucidnsserver = 'dns_server',
@@ -45,63 +41,23 @@ const uciroutingsetting = 'routing',
const ucinode = 'node';
const uciruleset = 'ruleset';
const RULESET_DIR = HP_DIR + '/ruleset';
const routing_mode = uci.get(uciconfig, ucimain, 'routing_mode') || 'bypass_mainland_china';
function normalize_list(value) {
if (isEmpty(value))
return [];
if (type(value) === 'array')
return value;
return [value];
}
function ruleset_file_name(tag, format) {
let filename = replace(tag || 'ruleset', /[^A-Za-z0-9_.-]+/g, '_');
if (isEmpty(filename))
filename = 'ruleset';
return filename + ((format === 'source') ? '.json' : '.srs');
}
function ruleset_default_path(tag, format) {
return RULESET_DIR + '/' + ruleset_file_name(tag, format);
}
function ruleset_remote_path(path, tag, format) {
if (isEmpty(path))
return ruleset_default_path(tag, format);
if (match(path, /\/$/))
return path + ruleset_file_name(tag, format);
return path;
}
let wan_dns = ubus.call('network.interface', 'status', {'interface': 'wan'})?.['dns-server']?.[0];
if (!wan_dns)
wan_dns = (routing_mode in ['proxy_mainland_china', 'global']) ? '9.9.9.9' : '223.5.5.5';
wan_dns = (routing_mode in ['proxy_mainland_china', 'global']) ? '8.8.8.8' : '223.5.5.5';
const dns_port = uci.get(uciconfig, uciinfra, 'dns_port') || '5333';
let ntp_enabled = uci.get(uciconfig, ucintp, 'enabled'),
ntp_server = uci.get(uciconfig, ucintp, 'server'),
ntp_server_port = uci.get(uciconfig, ucintp, 'server_port'),
ntp_interval = uci.get(uciconfig, ucintp, 'interval');
if (isEmpty(ntp_enabled) && isEmpty(ntp_server)) {
ntp_server = uci.get(uciconfig, uciinfra, 'ntp_server');
ntp_enabled = !isEmpty(ntp_server) ? '1' : '0';
}
const ntp_server = uci.get(uciconfig, uciinfra, 'ntp_server') || 'time.apple.com';
const ipv6_support = uci.get(uciconfig, ucimain, 'ipv6_support') || '0';
let cache_file_enabled, cache_file_path, cache_store_rdrc, cache_rdrc_timeout,
main_node, main_udp_node, dedicated_udp_node, default_outbound, default_outbound_dns,
let main_node, main_udp_node, dedicated_udp_node, default_outbound, default_outbound_dns,
domain_strategy, sniff_override, dns_server, china_dns_server, dns_default_strategy,
dns_default_server, dns_disable_cache, dns_disable_cache_expire, dns_independent_cache,
dns_client_subnet, direct_domain_list,
dns_client_subnet, cache_file_store_rdrc, cache_file_rdrc_timeout, direct_domain_list,
proxy_domain_list;
if (routing_mode !== 'custom') {
@@ -137,6 +93,8 @@ if (routing_mode !== 'custom') {
dns_disable_cache_expire = uci.get(uciconfig, ucidnssetting, 'disable_cache_expire');
dns_independent_cache = uci.get(uciconfig, ucidnssetting, 'independent_cache');
dns_client_subnet = uci.get(uciconfig, ucidnssetting, 'client_subnet');
cache_file_store_rdrc = uci.get(uciconfig, ucidnssetting, 'cache_file_store_rdrc'),
cache_file_rdrc_timeout = uci.get(uciconfig, ucidnssetting, 'cache_file_rdrc_timeout');
/* Routing settings */
default_outbound = uci.get(uciconfig, uciroutingsetting, 'default_outbound') || 'nil';
@@ -152,7 +110,7 @@ const mixed_port = uci.get(uciconfig, uciinfra, 'mixed_port') || '5330';
let self_mark, redirect_port, tproxy_port, tun_name,
tun_addr4, tun_addr6, tun_mtu, tcpip_stack,
udp_timeout;
endpoint_independent_nat, udp_timeout;
if (routing_mode === 'custom')
udp_timeout = uci.get(uciconfig, uciroutingsetting, 'udp_timeout');
@@ -172,18 +130,13 @@ if (match(proxy_mode, /tun/)) {
tun_addr6 = uci.get(uciconfig, uciinfra, 'tun_addr6') || 'fdfe:dcba:9876::1/126';
tun_mtu = uci.get(uciconfig, uciinfra, 'tun_mtu') || '9000';
tcpip_stack = 'system';
if (routing_mode === 'custom')
if (routing_mode === 'custom') {
tcpip_stack = uci.get(uciconfig, uciroutingsetting, 'tcpip_stack') || 'system';
endpoint_independent_nat = uci.get(uciconfig, uciroutingsetting, 'endpoint_independent_nat');
}
}
const log_level = uci.get(uciconfig, ucimain, 'log_level') || 'warn';
cache_file_enabled = uci.get(uciconfig, ucicache, 'enabled');
cache_file_path = uci.get(uciconfig, ucicache, 'path');
cache_store_rdrc = uci.get(uciconfig, ucicache, 'store_rdrc');
cache_rdrc_timeout = uci.get(uciconfig, ucicache, 'rdrc_timeout');
let clash_api = null;
/* UCI config end */
/* Config helper start */
@@ -215,31 +168,6 @@ function parse_dnsserver(server_addr, default_protocol) {
}
}
function parse_custom_dnsserver(cfg) {
let server = cfg.server,
server_port = (cfg.type in ['https', 'h3']) ? null : strToInt(cfg.server_port),
path = cfg.path;
if (!isEmpty(server) && match(server, /:\/\//)) {
const server_url = parseURL(server);
server = server_url.hostname;
if (isEmpty(server_port))
server_port = strToInt(server_url.port);
if ((cfg.type in ['https', 'h3']) && isEmpty(path) && server_url.pathname !== '/')
path = server_url.pathname;
}
if ((cfg.type in ['https', 'h3']) && isEmpty(path))
path = '/dns-query';
return {
type: cfg.type,
server,
server_port,
path
};
}
function parse_dnsquery(strquery) {
if (type(strquery) !== 'array' || isEmpty(strquery))
return null;
@@ -252,149 +180,13 @@ function parse_dnsquery(strquery) {
}
function filter_existing_nodes(nodes) {
if (type(nodes) !== 'array' || isEmpty(nodes))
return [];
return filter(nodes, (k) => {
const node = uci.get_all(uciconfig, k) || {};
return !isEmpty(node);
});
}
function collect_group_nodes(groups, subscription_nodes, nodes, legacy_nodes) {
let result = [];
for (let group in normalize_list(groups))
uci.foreach(uciconfig, ucinode, (cfg) => {
if (cfg.grouphash === group && !~index(result, cfg['.name']))
push(result, cfg['.name']);
});
for (let node in filter_existing_nodes(normalize_list(subscription_nodes)))
if (!~index(result, node))
push(result, node);
for (let node in filter_existing_nodes(normalize_list(nodes)))
if (!~index(result, node))
push(result, node);
for (let node in filter_existing_nodes(normalize_list(legacy_nodes)))
if (!~index(result, node))
push(result, node);
return result;
}
function collect_policy_nodes(nodes, current) {
let result = [];
for (let node in normalize_list(nodes)) {
if (node === current || ~index(result, node))
continue;
const outbound = uci.get_all(uciconfig, node) || {};
if (!isEmpty(outbound) && outbound['.type'] === uciroutingnode && outbound.enabled === '1' && outbound.node in ['urltest', 'selector'])
push(result, node);
}
return result;
}
const reserved_outbound_tags = {
'GLOBAL': true,
'main-out': true,
'main-udp-out': true,
'direct-out': true,
'block-out': true
};
let outbound_tag_map = {},
outbound_tag_used = {};
function normalize_outbound_tag(tag) {
if (isEmpty(tag))
return null;
tag = trim(sprintf('%s', tag));
tag = replace(tag, /[\r\n\t]+/g, ' ');
tag = replace(tag, /[\/\\?#%]+/g, '-');
tag = replace(tag, /\s+/g, ' ');
return tag || null;
}
function section_display_name(section) {
if (type(section) !== 'object' || isEmpty(section))
return null;
let label = normalize_outbound_tag(section.label);
if (!isEmpty(label))
return label;
if (section['.type'] === ucinode) {
const address = trim(section.override_address || section.address || '');
const port = trim(section.override_port || section.port || '');
if (address && port)
return normalize_outbound_tag(`${address}:${port}`);
}
return null;
}
function register_outbound_tag(section_id, display_name) {
if (isEmpty(section_id))
return null;
let tag = outbound_tag_map[section_id];
if (!isEmpty(tag))
return tag;
const fallback_tag = `cfg-${section_id}-out`;
const base_tag = normalize_outbound_tag(display_name) || fallback_tag;
tag = base_tag;
let suffix = 2;
while (reserved_outbound_tags[tag] || outbound_tag_used[tag]) {
tag = `${base_tag} (${suffix})`;
suffix++;
}
outbound_tag_map[section_id] = tag;
outbound_tag_used[tag] = true;
return tag;
}
function get_section_outbound_tag(section_id) {
if (isEmpty(section_id))
return null;
let tag = outbound_tag_map[section_id];
if (!isEmpty(tag))
return tag;
const section = uci.get_all(uciconfig, section_id) || {};
return register_outbound_tag(section_id, section_display_name(section));
}
uci.foreach(uciconfig, ucinode, (cfg) => {
register_outbound_tag(cfg['.name'], section_display_name(cfg));
});
uci.foreach(uciconfig, uciroutingnode, (cfg) => {
if (cfg.enabled === '1')
register_outbound_tag(cfg['.name'], section_display_name(cfg));
});
function generate_endpoint(node) {
if (type(node) !== 'object' || isEmpty(node))
return null;
const endpoint = {
type: node.type,
tag: get_section_outbound_tag(node['.name']),
tag: 'cfg-' + node['.name'] + '-out',
address: node.wireguard_local_address,
mtu: strToInt(node.wireguard_mtu),
private_key: node.wireguard_private_key,
@@ -425,14 +217,13 @@ function generate_outbound(node) {
if (type(node) !== 'object' || isEmpty(node))
return null;
const tls_utls_value = (node.type === 'anytls' && isEmpty(node.tls_utls)) ? 'chrome' : node.tls_utls;
const outbound = {
type: node.type,
tag: get_section_outbound_tag(node['.name']),
tag: 'cfg-' + node['.name'] + '-out',
routing_mark: strToInt(self_mark),
server: (node.type !== 'direct') ? node.address : null,
server_port: (node.type !== 'direct') ? strToInt(node.port) : null,
server: node.address,
server_port: strToInt(node.port),
/* Hysteria(2) */
server_ports: node.hysteria_hopping_port,
@@ -440,6 +231,10 @@ function generate_outbound(node) {
user: (node.type === 'ssh') ? node.username : null,
password: node.password,
/* Direct */
override_address: node.override_address,
override_port: strToInt(node.override_port),
proxy_protocol: strToInt(node.proxy_protocol),
/* AnyTLS */
idle_session_check_interval: strToTime(node.anytls_idle_session_check_interval),
idle_session_timeout: strToTime(node.anytls_idle_session_timeout),
@@ -511,9 +306,9 @@ function generate_outbound(node) {
config: node.tls_ech_config,
config_path: node.tls_ech_config_path
} : null,
utls: !isEmpty(tls_utls_value) ? {
utls: !isEmpty(node.tls_utls) ? {
enabled: true,
fingerprint: tls_utls_value
fingerprint: node.tls_utls
} : null,
reality: (node.tls_reality === '1') ? {
enabled: true,
@@ -569,10 +364,10 @@ function get_outbound(cfg) {
const node = uci.get(uciconfig, cfg, 'node');
if (isEmpty(node))
die(sprintf("%s's node is missing, please check your configuration.", cfg));
else if (node in ['urltest', 'selector'])
return get_section_outbound_tag(cfg);
else if (node === 'urltest')
return 'cfg-' + cfg + '-out';
else
return get_section_outbound_tag(node);
return 'cfg-' + node + '-out';
}
}
}
@@ -595,117 +390,10 @@ function get_ruleset(cfg) {
return null;
let rules = [];
for (let i in cfg) {
if (isEmpty(i)) {
push(rules, null);
continue;
}
const ruleset = uci.get_all(uciconfig, i);
push(rules, !isEmpty(ruleset?.tag) ? ruleset.tag : ('cfg-' + i + '-rule'));
}
for (let i in cfg)
push(rules, isEmpty(i) ? null : 'cfg-' + i + '-rule');
return rules;
}
function subscription_provider_name(name) {
name = trim(name || '');
return name;
}
function unique_provider_name(name, used) {
const base = name;
let suffix = 2;
while (used[name]) {
name = sprintf('%s (%d)', base, suffix);
suffix++;
}
used[name] = true;
return name;
}
function get_subscription_info(group_hash) {
const value = uci.get(uciconfig, 'subscription', 'subinfo_' + substr(group_hash, 0, 16));
if (isEmpty(value))
return null;
try {
const info = json(value);
if (type(info) !== 'object')
return null;
const has_subscription_info = ('upload' in info) || ('download' in info) ||
('total' in info) || ('expire' in info);
return {
updated_at: info.updated_at,
subscription_info: has_subscription_info ? {
upload: info.upload,
download: info.download,
total: info.total,
expire: info.expire
} : null
};
} catch (e) {
return null;
}
}
function build_proxy_providers() {
let providers = [],
used_names = {},
subscription_names = normalize_list(uci.get(uciconfig, 'subscription', 'subscription_name')),
sub_index = 0;
for (let suburl in normalize_list(uci.get(uciconfig, 'subscription', 'subscription_url'))) {
const subscription_name = subscription_names[sub_index];
sub_index++;
if (isEmpty(suburl) || isEmpty(trim(subscription_name || '')))
continue;
const url = replace(suburl, /#.*$/, ''),
group_hash = md5(url);
let proxies = [];
uci.foreach(uciconfig, ucinode, (cfg) => {
if (cfg.grouphash !== group_hash)
return;
const tag = get_section_outbound_tag(cfg['.name']);
if (!isEmpty(tag) && !~index(proxies, tag))
push(proxies, tag);
});
if (isEmpty(proxies))
continue;
const subscription_info = get_subscription_info(group_hash);
push(providers, {
name: unique_provider_name(subscription_provider_name(subscription_name), used_names),
type: 'Proxy',
vehicle_type: 'HTTP',
proxies: proxies,
update_id: (routing_mode === 'custom') ? group_hash : null,
updated_at: subscription_info?.updated_at,
subscription_info: subscription_info?.subscription_info
});
}
return providers;
}
clash_api = {
external_controller: uci.get(uciconfig, uciclashapi, 'external_controller') || '127.0.0.1:9090',
external_ui: uci.get(uciconfig, uciclashapi, 'external_ui'),
external_ui_download_url: uci.get(uciconfig, uciclashapi, 'external_ui_download_url'),
external_ui_download_detour: get_outbound(uci.get(uciconfig, uciclashapi, 'external_ui_download_detour')),
secret: uci.get(uciconfig, uciclashapi, 'secret'),
default_mode: uci.get(uciconfig, uciclashapi, 'default_mode') || 'rule',
proxy_providers: build_proxy_providers()
};
/* Config helper end */
const config = {};
@@ -721,10 +409,8 @@ config.log = {
/* NTP */
if (!isEmpty(ntp_server))
config.ntp = {
enabled: ntp_enabled === '1',
enabled: true,
server: ntp_server,
server_port: strToInt(ntp_server_port),
interval: ntp_interval,
detour: 'direct-out',
domain_resolver: 'default-dns',
};
@@ -834,7 +520,10 @@ if (!isEmpty(main_node)) {
push(config.dns.servers, {
tag: 'cfg-' + cfg['.name'] + '-dns',
...parse_custom_dnsserver(cfg),
type: cfg.type,
server: cfg.server,
server_port: strToInt(cfg.server_port),
path: cfg.path,
headers: cfg.headers,
tls: cfg.tls_sni ? {
enabled: true,
@@ -876,6 +565,7 @@ if (!isEmpty(main_node)) {
user: cfg.user,
rule_set: get_ruleset(cfg.rule_set),
rule_set_ip_cidr_match_source: strToBool(cfg.rule_set_ip_cidr_match_source),
rule_set_ip_cidr_accept_empty: strToBool(cfg.rule_set_ip_cidr_accept_empty),
invert: strToBool(cfg.invert),
outbound: get_outbound(cfg.outbound),
action: cfg.action,
@@ -916,6 +606,8 @@ push(config.inbounds, {
listen: '::',
listen_port: int(mixed_port),
udp_timeout: strToTime(udp_timeout),
sniff: true,
sniff_override_destination: strToBool(sniff_override),
set_system_proxy: false
});
@@ -925,7 +617,9 @@ if (match(proxy_mode, /redirect/))
tag: 'redirect-in',
listen: '::',
listen_port: int(redirect_port)
listen_port: int(redirect_port),
sniff: true,
sniff_override_destination: strToBool(sniff_override)
});
if (match(proxy_mode, /tproxy/))
push(config.inbounds, {
@@ -935,7 +629,9 @@ if (match(proxy_mode, /tproxy/))
listen: '::',
listen_port: int(tproxy_port),
network: 'udp',
udp_timeout: strToTime(udp_timeout)
udp_timeout: strToTime(udp_timeout),
sniff: true,
sniff_override_destination: strToBool(sniff_override)
});
if (match(proxy_mode, /tun/))
push(config.inbounds, {
@@ -946,8 +642,11 @@ if (match(proxy_mode, /tun/))
address: (ipv6_support === '1') ? [tun_addr4, tun_addr6] : [tun_addr4],
mtu: strToInt(tun_mtu),
auto_route: false,
endpoint_independent_nat: strToBool(endpoint_independent_nat),
udp_timeout: strToTime(udp_timeout),
stack: tcpip_stack
stack: tcpip_stack,
sniff: true,
sniff_override_destination: strToBool(sniff_override)
});
/* Inbound end */
@@ -972,16 +671,14 @@ if (!isEmpty(main_node)) {
let urltest_nodes = [];
if (main_node === 'urltest') {
const main_urltest_nodes = filter_existing_nodes(
normalize_list(uci.get(uciconfig, ucimain, 'main_urltest_nodes'))
);
const main_urltest_nodes = uci.get(uciconfig, ucimain, 'main_urltest_nodes') || [];
const main_urltest_interval = uci.get(uciconfig, ucimain, 'main_urltest_interval');
const main_urltest_tolerance = uci.get(uciconfig, ucimain, 'main_urltest_tolerance');
push(config.outbounds, {
type: 'urltest',
tag: 'main-out',
outbounds: map(main_urltest_nodes, (k) => get_section_outbound_tag(k)),
outbounds: map(main_urltest_nodes, (k) => `cfg-${k}-out`),
interval: strToTime(main_urltest_interval),
tolerance: strToInt(main_urltest_tolerance),
idle_timeout: (strToInt(main_urltest_interval) > 1800) ? `${main_urltest_interval * 2}s` : null,
@@ -990,31 +687,23 @@ if (!isEmpty(main_node)) {
} else {
const main_node_cfg = uci.get_all(uciconfig, main_node) || {};
if (main_node_cfg.type === 'wireguard') {
const main_endpoint = generate_endpoint(main_node_cfg);
if (main_endpoint) {
main_endpoint.tag = 'main-out';
push(config.endpoints, main_endpoint);
}
push(config.endpoints, generate_endpoint(main_node_cfg));
config.endpoints[length(config.endpoints)-1].tag = 'main-out';
} else {
const main_outbound = generate_outbound(main_node_cfg);
if (main_outbound) {
main_outbound.tag = 'main-out';
push(config.outbounds, main_outbound);
}
push(config.outbounds, generate_outbound(main_node_cfg));
config.outbounds[length(config.outbounds)-1].tag = 'main-out';
}
}
if (main_udp_node === 'urltest') {
const main_udp_urltest_nodes = filter_existing_nodes(
normalize_list(uci.get(uciconfig, ucimain, 'main_udp_urltest_nodes'))
);
const main_udp_urltest_nodes = uci.get(uciconfig, ucimain, 'main_udp_urltest_nodes') || [];
const main_udp_urltest_interval = uci.get(uciconfig, ucimain, 'main_udp_urltest_interval');
const main_udp_urltest_tolerance = uci.get(uciconfig, ucimain, 'main_udp_urltest_tolerance');
push(config.outbounds, {
type: 'urltest',
tag: 'main-udp-out',
outbounds: map(main_udp_urltest_nodes, (k) => get_section_outbound_tag(k)),
outbounds: map(main_udp_urltest_nodes, (k) => `cfg-${k}-out`),
interval: strToTime(main_udp_urltest_interval),
tolerance: strToInt(main_udp_urltest_tolerance),
idle_timeout: (strToInt(main_udp_urltest_interval) > 1800) ? `${main_udp_urltest_interval * 2}s` : null,
@@ -1023,37 +712,22 @@ if (!isEmpty(main_node)) {
} else if (dedicated_udp_node) {
const main_udp_node_cfg = uci.get_all(uciconfig, main_udp_node) || {};
if (main_udp_node_cfg.type === 'wireguard') {
const main_udp_endpoint = generate_endpoint(main_udp_node_cfg);
if (main_udp_endpoint) {
main_udp_endpoint.tag = 'main-udp-out';
push(config.endpoints, main_udp_endpoint);
}
push(config.endpoints, generate_endpoint(main_udp_node_cfg));
config.endpoints[length(config.endpoints)-1].tag = 'main-udp-out';
} else {
const main_udp_outbound = generate_outbound(main_udp_node_cfg);
if (main_udp_outbound) {
main_udp_outbound.tag = 'main-udp-out';
push(config.outbounds, main_udp_outbound);
}
push(config.outbounds, generate_outbound(main_udp_node_cfg));
config.outbounds[length(config.outbounds)-1].tag = 'main-udp-out';
}
}
for (let i in urltest_nodes) {
const urltest_node = uci.get_all(uciconfig, i) || {};
if (isEmpty(urltest_node))
continue;
if (urltest_node.type === 'wireguard') {
const endpoint = generate_endpoint(urltest_node);
if (endpoint) {
endpoint.tag = get_section_outbound_tag(i);
push(config.endpoints, endpoint);
}
push(config.endpoints, generate_endpoint(urltest_node));
config.endpoints[length(config.endpoints)-1].tag = 'cfg-' + i + '-out';
} else {
const outbound = generate_outbound(urltest_node);
if (outbound) {
outbound.tag = get_section_outbound_tag(i);
push(config.outbounds, outbound);
}
push(config.outbounds, generate_outbound(urltest_node));
config.outbounds[length(config.outbounds)-1].tag = 'cfg-' + i + '-out';
}
}
} else if (!isEmpty(default_outbound)) {
@@ -1065,63 +739,37 @@ if (!isEmpty(main_node)) {
return;
if (cfg.node === 'urltest') {
const legacy_nodes = (isEmpty(cfg.subscription_groups) && isEmpty(cfg.subscription_nodes) && isEmpty(cfg.selected_nodes)) ? cfg.urltest_nodes : null;
const urltest_list = collect_group_nodes(cfg.subscription_groups, cfg.subscription_nodes, cfg.selected_nodes, legacy_nodes);
push(config.outbounds, {
type: 'urltest',
tag: get_section_outbound_tag(cfg['.name']),
outbounds: map(urltest_list, (k) => get_section_outbound_tag(k)),
tag: 'cfg-' + cfg['.name'] + '-out',
outbounds: map(cfg.urltest_nodes, (k) => `cfg-${k}-out`),
url: cfg.urltest_url,
interval: strToTime(cfg.urltest_interval),
tolerance: strToInt(cfg.urltest_tolerance),
idle_timeout: strToTime(cfg.urltest_idle_timeout),
interrupt_exist_connections: strToBool(cfg.urltest_interrupt_exist_connections)
});
urltest_nodes = [...urltest_nodes, ...filter(urltest_list, (l) => !~index(urltest_nodes, l))];
} else if (cfg.node === 'selector') {
const selector_node_list = collect_group_nodes(cfg.subscription_groups, cfg.subscription_nodes, cfg.selected_nodes, null);
const selector_policy_list = collect_policy_nodes(cfg.policy_nodes, cfg['.name']);
const selector_list = [...selector_node_list, ...filter(selector_policy_list, (l) => !~index(selector_node_list, l))];
const selector_default = (!isEmpty(cfg.selector_default) && ~index(selector_list, cfg.selector_default)) ? cfg.selector_default : null;
push(config.outbounds, {
type: 'selector',
tag: get_section_outbound_tag(cfg['.name']),
outbounds: map(selector_list, (k) => get_section_outbound_tag(k)),
default: selector_default ? get_section_outbound_tag(selector_default) : null,
interrupt_exist_connections: strToBool(cfg.selector_interrupt_exist_connections)
});
urltest_nodes = [...urltest_nodes, ...filter(selector_node_list, (l) => !~index(urltest_nodes, l))];
urltest_nodes = [...urltest_nodes, ...filter(cfg.urltest_nodes, (l) => !~index(urltest_nodes, l))];
} else {
const outbound = uci.get_all(uciconfig, cfg.node) || {};
if (isEmpty(outbound))
return;
if (outbound.type === 'wireguard') {
const endpoint = generate_endpoint(outbound);
if (!endpoint)
return;
endpoint.bind_interface = cfg.bind_interface;
endpoint.detour = get_outbound(cfg.outbound);
push(config.endpoints, generate_endpoint(outbound));
config.endpoints[length(config.endpoints)-1].bind_interface = cfg.bind_interface;
config.endpoints[length(config.endpoints)-1].detour = get_outbound(cfg.outbound);
if (cfg.domain_resolver)
endpoint.domain_resolver = {
config.endpoints[length(config.endpoints)-1].domain_resolver = {
server: get_resolver(cfg.domain_resolver),
strategy: cfg.domain_strategy
};
push(config.endpoints, endpoint);
} else {
const routed_outbound = generate_outbound(outbound);
if (!routed_outbound)
return;
routed_outbound.bind_interface = cfg.bind_interface;
routed_outbound.detour = get_outbound(cfg.outbound);
push(config.outbounds, generate_outbound(outbound));
config.outbounds[length(config.outbounds)-1].bind_interface = cfg.bind_interface;
config.outbounds[length(config.outbounds)-1].detour = get_outbound(cfg.outbound);
if (cfg.domain_resolver)
routed_outbound.domain_resolver = {
config.outbounds[length(config.outbounds)-1].domain_resolver = {
server: get_resolver(cfg.domain_resolver),
strategy: cfg.domain_strategy
};
push(config.outbounds, routed_outbound);
}
push(routing_nodes, cfg.node);
}
@@ -1129,18 +777,10 @@ if (!isEmpty(main_node)) {
for (let i in filter(urltest_nodes, (l) => !~index(routing_nodes, l))) {
const urltest_node = uci.get_all(uciconfig, i) || {};
if (isEmpty(urltest_node))
continue;
if (urltest_node.type === 'wireguard') {
const endpoint = generate_endpoint(urltest_node);
if (endpoint)
push(config.endpoints, endpoint);
} else {
const outbound = generate_outbound(urltest_node);
if (outbound)
push(config.outbounds, outbound);
}
if (urltest_node.type === 'wireguard')
push(config.endpoints, generate_endpoint(urltest_node));
else
push(config.outbounds, generate_outbound(urltest_node));
}
}
@@ -1155,10 +795,13 @@ config.route = {
{
inbound: 'dns-in',
action: 'hijack-dns'
},
{
action: 'sniff'
}
/*
* leave for sing-box 1.13.0
* {
* action: 'sniff'
* }
*/
],
rule_set: [],
auto_detect_interface: isEmpty(default_interface) ? true : null,
@@ -1223,7 +866,6 @@ if (!isEmpty(main_node)) {
tag: 'geoip-cn',
format: 'binary',
url: 'https://fastly.jsdelivr.net/gh/1715173329/IPCIDR-CHINA@rule-set/cn.srs',
path: ruleset_default_path('geoip-cn', 'binary'),
download_detour: 'main-out'
});
push(config.route.rule_set, {
@@ -1231,7 +873,6 @@ if (!isEmpty(main_node)) {
tag: 'geosite-cn',
format: 'binary',
url: 'https://fastly.jsdelivr.net/gh/1715173329/sing-geosite@rule-set-unstable/geosite-geolocation-cn.srs',
path: ruleset_default_path('geosite-cn', 'binary'),
download_detour: 'main-out'
});
push(config.route.rule_set, {
@@ -1239,7 +880,6 @@ if (!isEmpty(main_node)) {
tag: 'geosite-noncn',
format: 'binary',
url: 'https://fastly.jsdelivr.net/gh/1715173329/sing-geosite@rule-set-unstable/geosite-geolocation-!cn.srs',
path: ruleset_default_path('geosite-noncn', 'binary'),
download_detour: 'main-out'
});
}
@@ -1284,25 +924,17 @@ if (!isEmpty(main_node)) {
user: cfg.user,
rule_set: get_ruleset(cfg.rule_set),
rule_set_ip_cidr_match_source: strToBool(cfg.rule_set_ip_cidr_match_source),
rule_set_ip_cidr_accept_empty: strToBool(cfg.rule_set_ip_cidr_accept_empty),
invert: strToBool(cfg.invert),
action: cfg.action,
outbound: (cfg.action === 'route') ? get_outbound(cfg.outbound) : null,
server: (cfg.action === 'resolve') ? get_resolver(cfg.resolve_server) : null,
strategy: (cfg.action === 'resolve') ? cfg.resolve_strategy : null,
disable_cache: (cfg.action === 'resolve') ? strToBool(cfg.resolve_disable_cache) : null,
rewrite_ttl: (cfg.action === 'resolve') ? strToInt(cfg.resolve_rewrite_ttl) : null,
client_subnet: (cfg.action === 'resolve') ? cfg.resolve_client_subnet : null,
override_address: (cfg.action in ['route', 'route-options']) ? cfg.override_address : null,
override_port: (cfg.action in ['route', 'route-options']) ? strToInt(cfg.override_port) : null,
udp_disable_domain_unmapping: (cfg.action in ['route', 'route-options']) ? strToBool(cfg.udp_disable_domain_unmapping) : null,
udp_connect: (cfg.action in ['route', 'route-options']) ? strToBool(cfg.udp_connect) : null,
udp_timeout: (cfg.action in ['route', 'route-options']) ? strToTime(cfg.udp_timeout) : null,
tls_fragment: (cfg.action in ['route', 'route-options']) ? strToBool(cfg.tls_fragment) : null,
tls_fragment_fallback_delay: (cfg.action in ['route', 'route-options']) ? strToTime(cfg.tls_fragment_fallback_delay) : null,
tls_record_fragment: (cfg.action in ['route', 'route-options']) ? strToBool(cfg.tls_record_fragment) : null,
method: (cfg.action === 'reject') ? cfg.reject_method : null,
no_drop: (cfg.action === 'reject') ? strToBool(cfg.reject_no_drop) : null
outbound: get_outbound(cfg.outbound),
override_address: cfg.override_address,
override_port: strToInt(cfg.override_port),
udp_disable_domain_unmapping: strToBool(cfg.udp_disable_domain_unmapping),
udp_connect: strToBool(cfg.udp_connect),
udp_timeout: strToTime(cfg.udp_timeout),
tls_fragment: strToBool(cfg.tls_fragment),
tls_fragment_fallback_delay: strToTime(cfg.tls_fragment_fallback_delay),
tls_record_fragment: strToBool(cfg.tls_record_fragment)
});
});
@@ -1313,16 +945,14 @@ if (!isEmpty(main_node)) {
if (cfg.enabled !== '1')
return null;
const tag = !isEmpty(cfg.tag) ? cfg.tag : ('cfg-' + cfg['.name'] + '-rule');
push(config.route.rule_set, {
type: cfg.type,
tag: tag,
tag: 'cfg-' + cfg['.name'] + '-rule',
format: cfg.format,
path: cfg.path,
url: cfg.url,
path: (cfg.type === 'remote') ? ruleset_remote_path(cfg.remote_path || cfg.path, tag, cfg.format) : cfg.path,
download_detour: get_outbound(cfg.outbound),
update_interval: (cfg.type === 'remote') ? '87600h' : null
update_interval: cfg.update_interval
});
});
}
@@ -1331,17 +961,15 @@ if (!isEmpty(main_node)) {
/* Experimental start */
if (routing_mode in ['bypass_mainland_china', 'custom']) {
config.experimental = {
clash_api,
cache_file: {
enabled: cache_file_enabled !== '0',
path: cache_file_path || (HP_DIR + '/cache.db'),
store_rdrc: strToBool(cache_store_rdrc),
rdrc_timeout: strToTime(cache_rdrc_timeout),
enabled: true,
path: RUN_DIR + '/cache.db',
store_rdrc: strToBool(cache_file_store_rdrc),
rdrc_timeout: strToTime(cache_file_rdrc_timeout),
}
};
}
/* Experimental end */
system('mkdir -p ' + RUN_DIR);
system('mkdir -p ' + RULESET_DIR);
writefile(RUN_DIR + '/sing-box-c.json', sprintf('%.J\n', removeBlankAttrs(config)));
@@ -67,7 +67,7 @@ uci.foreach(uciconfig, uciserver, (cfg) => {
password: cfg.hysteria_obfs_password
} : cfg.hysteria_obfs_password,
recv_window_conn: strToInt(cfg.hysteria_recv_window_conn),
recv_window_client: strToInt(cfg.hysteria_recv_window_client),
recv_window_client: strToInt(cfg.hysteria_revc_window_client),
max_conn_client: strToInt(cfg.hysteria_max_conn_client),
disable_mtu_discovery: strToBool(cfg.hysteria_disable_mtu_discovery),
ignore_client_bandwidth: strToBool(cfg.hysteria_ignore_client_bandwidth),
+3 -22
View File
@@ -66,34 +66,15 @@ export function getTime(epoch) {
};
export function wGETResponse(url, ua) {
export function wGET(url, ua) {
if (!url || type(url) !== 'string')
return null;
if (!ua)
ua = 'Wget/1.21 (HomeProxy, like v2rayN)';
const output = executeCommand(`/usr/bin/wget -O- -S --user-agent ${shellQuote(ua)} --timeout=10 ${shellQuote(url)}`) || {};
return {
body: trim(output.stdout),
headers: output.stderr || '',
exitcode: output.exitcode
};
};
export function wGET(url, ua) {
return wGETResponse(url, ua)?.body;
};
export function wGETHeaders(url, ua) {
if (!url || type(url) !== 'string')
return null;
if (!ua)
ua = 'clash.meta';
const output = executeCommand(`/usr/bin/wget -O /dev/null -S --user-agent ${shellQuote(ua)} --timeout=10 ${shellQuote(url)}`) || {};
return output.stderr || '';
const output = executeCommand(`/usr/bin/wget -qO- --user-agent ${shellQuote(ua)} --timeout=10 ${shellQuote(url)}`) || {};
return trim(output.stdout);
};
/* Utilities end */
@@ -7,34 +7,14 @@
'use strict';
import { popen } from 'fs';
import { cursor } from 'uci';
import { isEmpty, parseURL } from 'homeproxy';
import { isEmpty, parseURL, validation } from 'homeproxy';
const uci = cursor();
const uciconfig = 'homeproxy';
uci.load(uciconfig);
function random_secret() {
const fd = popen('tr -dc "A-Za-z0-9" < /dev/urandom 2>/dev/null | head -c 16');
let random = '';
if (fd) {
random = trim(fd.read('all') || '');
fd.close();
}
if (isEmpty(random)) {
const fallback = popen('awk \'BEGIN{srand(); printf "%06d", int(rand() * 1000000)}\'');
if (fallback) {
random = trim(fallback.read('all') || '');
fallback.close();
}
}
return random;
}
const uciinfra = 'infra',
ucimigration = 'migration',
ucimain = 'config',
@@ -45,16 +25,8 @@ const uciinfra = 'infra',
ucirouting = 'routing',
uciroutingnode = 'routing_node',
uciroutingrule = 'routing_rule',
uciclashapi = 'clash_api',
ucintp = 'ntp',
ucicache = 'cache',
uciserver = 'server';
function is_update_cron(value) {
let matched = match(value || '', /^(\d{1,2})\s+(\d{1,2})\s+\*\s+\*\s+([0-7*])$/);
return !isEmpty(matched) && int(matched[1]) <= 59 && int(matched[2]) <= 23;
}
/* chinadns-ng has been removed */
if (uci.get(uciconfig, uciinfra, 'china_dns_port'))
uci.delete(uciconfig, uciinfra, 'china_dns_port');
@@ -64,7 +36,9 @@ const china_dns_server = uci.get(uciconfig, ucimain, 'china_dns_server');
if (type(china_dns_server) === 'array') {
uci.set(uciconfig, ucimain, 'china_dns_server', china_dns_server[0]);
} else {
if (match(china_dns_server, /,/))
if (china_dns_server === 'wan_114')
uci.set(uciconfig, ucimain, 'china_dns_server', '114.114.114.114');
else if (match(china_dns_server, /,/))
uci.set(uciconfig, ucimain, 'china_dns_server', split(china_dns_server, ',')[0]);
}
@@ -83,93 +57,6 @@ if (!uci.get(uciconfig, uciinfra, 'ntp_server'))
if (!isEmpty(uci.get(uciconfig, uciinfra, 'tun_gso')))
uci.delete(uciconfig, uciinfra, 'tun_gso');
/* endpoint_independent_nat was removed in sing-box 1.13 */
if (!isEmpty(uci.get(uciconfig, ucirouting, 'endpoint_independent_nat')))
uci.delete(uciconfig, ucirouting, 'endpoint_independent_nat');
/* direct outbound proxy_protocol was removed in sing-box 1.13 */
uci.foreach(uciconfig, ucinode, (cfg) => {
if (cfg.type === 'direct' && !isEmpty(cfg.proxy_protocol))
uci.delete(uciconfig, cfg['.name'], 'proxy_protocol');
});
const legacy_panel_url = 'https://github.com/Zephyruso/zashboard/releases/latest/download/dist.zip';
const legacy_panel_proxy_url = 'https://gh-proxy.com/https://github.com/Zephyruso/zashboard/releases/latest/download/dist.zip';
const old_panel_url = 'https://github.com/Zephyruso/zashboard/releases/latest/download/dist-cdn-fonts.zip';
const old_panel_proxy_url = 'https://gh-proxy.com/https://github.com/Zephyruso/zashboard/releases/latest/download/dist-cdn-fonts.zip';
const default_panel_url = 'https://gh-proxy.com/https://github.com/Zephyruso/zashboard/releases/latest/download/dist-cdn-fonts.zip';
/* clash api panel options were introduced */
if (!uci.get(uciconfig, uciclashapi))
uci.set(uciconfig, uciclashapi, uciconfig);
if (isEmpty(uci.get(uciconfig, uciclashapi, 'external_ui')))
uci.set(uciconfig, uciclashapi, 'external_ui', '/etc/homeproxy/run/ui');
const panel_url = uci.get(uciconfig, uciclashapi, 'external_ui_download_url');
if (isEmpty(panel_url) || panel_url === legacy_panel_url || panel_url === legacy_panel_proxy_url || panel_url === old_panel_proxy_url)
uci.set(uciconfig, uciclashapi, 'external_ui_download_url', default_panel_url);
if (isEmpty(uci.get(uciconfig, uciclashapi, 'external_ui_download_detour')))
uci.set(uciconfig, uciclashapi, 'external_ui_download_detour', 'direct-out');
if (isEmpty(uci.get(uciconfig, uciclashapi, 'external_controller')))
uci.set(uciconfig, uciclashapi, 'external_controller', '0.0.0.0:9095');
if (isEmpty(uci.get(uciconfig, uciclashapi, 'secret')) || uci.get(uciconfig, uciclashapi, 'secret') === 'homeproxy') {
let random = random_secret();
if (!isEmpty(random))
uci.set(uciconfig, uciclashapi, 'secret', random);
}
if (isEmpty(uci.get(uciconfig, uciclashapi, 'default_mode')))
uci.set(uciconfig, uciclashapi, 'default_mode', 'rule');
/* ntp options were moved into a dedicated section */
if (!uci.get(uciconfig, ucintp))
uci.set(uciconfig, ucintp, uciconfig);
const legacy_ntp_server = uci.get(uciconfig, uciinfra, 'ntp_server');
if (isEmpty(uci.get(uciconfig, ucintp, 'enabled')))
uci.set(uciconfig, ucintp, 'enabled', '1');
if (isEmpty(uci.get(uciconfig, ucintp, 'server')))
uci.set(uciconfig, ucintp, 'server', !isEmpty(legacy_ntp_server) ? legacy_ntp_server : 'ntp.aliyun.com');
if (isEmpty(uci.get(uciconfig, ucintp, 'server_port')))
uci.set(uciconfig, ucintp, 'server_port', '123');
if (isEmpty(uci.get(uciconfig, ucintp, 'interval')))
uci.set(uciconfig, ucintp, 'interval', '30m');
/* cache file options were moved into a dedicated section */
if (!uci.get(uciconfig, ucicache))
uci.set(uciconfig, ucicache, uciconfig);
if (isEmpty(uci.get(uciconfig, ucicache, 'enabled')))
uci.set(uciconfig, ucicache, 'enabled', '1');
const old_cache_path = '/var/run/homeproxy/cache.db';
const default_cache_path = '/etc/homeproxy/cache.db';
const cache_path = uci.get(uciconfig, ucicache, 'path');
if (isEmpty(cache_path) || cache_path === old_cache_path)
uci.set(uciconfig, ucicache, 'path', default_cache_path);
if (!isEmpty(uci.get(uciconfig, ucicache, 'store_fakeip')))
uci.delete(uciconfig, ucicache, 'store_fakeip');
if (isEmpty(uci.get(uciconfig, ucicache, 'store_rdrc')))
uci.set(uciconfig, ucicache, 'store_rdrc', isEmpty(uci.get(uciconfig, ucidns, 'cache_file_store_rdrc')) ? '1' : uci.get(uciconfig, ucidns, 'cache_file_store_rdrc'));
if (isEmpty(uci.get(uciconfig, ucicache, 'rdrc_timeout')) && !isEmpty(uci.get(uciconfig, ucidns, 'cache_file_rdrc_timeout')))
uci.set(uciconfig, ucicache, 'rdrc_timeout', uci.get(uciconfig, ucidns, 'cache_file_rdrc_timeout'));
if (!isEmpty(uci.get(uciconfig, ucidns, 'cache_file_store_rdrc')))
uci.delete(uciconfig, ucidns, 'cache_file_store_rdrc');
if (!isEmpty(uci.get(uciconfig, ucidns, 'cache_file_rdrc_timeout')))
uci.delete(uciconfig, ucidns, 'cache_file_rdrc_timeout');
/* create migration section */
if (!uci.get(uciconfig, ucimigration))
uci.set(uciconfig, ucimigration, uciconfig);
@@ -188,10 +75,6 @@ if (isEmpty(uci.get(uciconfig, ucimain, 'log_level')))
if (isEmpty(uci.get(uciconfig, uciserver, 'log_level')))
uci.set(uciconfig, uciserver, 'log_level', 'warn');
if (!isEmpty(uci.get(uciconfig, 'subscription', 'auto_update_time')) &&
!is_update_cron(uci.get(uciconfig, 'subscription', 'auto_update_time')))
uci.set(uciconfig, 'subscription', 'auto_update_time', '0 0 * * *');
/* empty value defaults to all ports now */
if (uci.get(uciconfig, ucimain, 'routing_port') === 'all')
uci.delete(uciconfig, ucimain, 'routing_port');
@@ -356,47 +239,6 @@ uci.foreach(uciconfig, uciroutingrule, (cfg) => {
}
});
/* routing node options */
uci.foreach(uciconfig, uciroutingnode, (cfg) => {
if (cfg.node === 'urltest' && !isEmpty(cfg.urltest_nodes)) {
let custom_nodes = [],
subscription_nodes = [];
for (let node in (type(cfg.urltest_nodes) === 'array' ? cfg.urltest_nodes : [ cfg.urltest_nodes ])) {
let node_cfg = uci.get_all(uciconfig, node);
if (isEmpty(node_cfg))
continue;
if (!isEmpty(node_cfg.grouphash))
push(subscription_nodes, node);
else
push(custom_nodes, node);
}
if (isEmpty(cfg.selected_nodes) && !isEmpty(custom_nodes))
uci.set(uciconfig, cfg['.name'], 'selected_nodes', custom_nodes);
if (isEmpty(cfg.subscription_nodes) && !isEmpty(subscription_nodes))
uci.set(uciconfig, cfg['.name'], 'subscription_nodes', subscription_nodes);
uci.delete(uciconfig, cfg['.name'], 'urltest_nodes');
}
});
/* rule set options */
uci.foreach(uciconfig, uciruleset, (cfg) => {
if (isEmpty(cfg.tag))
uci.set(uciconfig, cfg['.name'], 'tag', 'cfg-' + cfg['.name'] + '-rule');
if (cfg.type === 'remote') {
if (isEmpty(cfg.auto_update))
uci.set(uciconfig, cfg['.name'], 'auto_update', '1');
if (!is_update_cron(cfg.update_interval))
uci.set(uciconfig, cfg['.name'], 'update_interval', '0 0 * * *');
}
});
/* server options */
/* auto_firewall was moved into server options */
const auto_firewall = uci.get(uciconfig, uciserver, 'auto_firewall');
@@ -404,13 +246,6 @@ if (!isEmpty(auto_firewall))
uci.delete(uciconfig, uciserver, 'auto_firewall');
uci.foreach(uciconfig, uciserver, (cfg) => {
if (!isEmpty(cfg.hysteria_revc_window_client) && isEmpty(cfg.hysteria_recv_window_client)) {
uci.set(uciconfig, cfg['.name'], 'hysteria_recv_window_client', cfg.hysteria_revc_window_client);
}
if (!isEmpty(cfg.hysteria_revc_window_client))
uci.delete(uciconfig, cfg['.name'], 'hysteria_revc_window_client');
/* auto_firewall was moved into server options */
if (auto_firewall === '1')
uci.set(uciconfig, cfg['.name'], 'firewall' , '1');
@@ -1,46 +0,0 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-only
set -eu
NAME="homeproxy"
RUN_DIR="/var/run/$NAME"
REQUEST_FILE="$RUN_DIR/provider-update-id"
LOCK_FILE="$RUN_DIR/provider-update-v2.lock"
LOG_FILE="$RUN_DIR/homeproxy.log"
PROVIDER_ID="${1:-}"
log() {
printf '%s [SUBSCRIBE] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >> "$LOG_FILE"
}
case "$PROVIDER_ID" in
*[!0-9a-f]*|'') exit 1 ;;
esac
[ "${#PROVIDER_ID}" -eq 32 ] || exit 1
mkdir -p "$RUN_DIR"
if ! lock -n "$LOCK_FILE" 2>/dev/null; then
log "Another provider update is running; waiting for it to finish..."
lock "$LOCK_FILE"
fi
umask 077
printf '%s\n' "$PROVIDER_ID" > "$REQUEST_FILE"
cleanup() {
rm -f "$REQUEST_FILE"
lock -u "$LOCK_FILE" 2>/dev/null || true
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
# Give the Clash API response time to reach the panel before HomeProxy restarts.
log "Updating provider $PROVIDER_ID from Clash API..."
sleep 1
if /etc/homeproxy/scripts/update_subscriptions.uc; then
log "Provider $PROVIDER_ID update completed."
else
log "Provider $PROVIDER_ID update failed."
exit 4
fi
@@ -21,65 +21,64 @@ to_upper() {
}
check_list_update() {
local LIST_FILE="$1"
local REPO_NAME="$2"
local REPO_BRANCH="$3"
local REPO_FILE="$4"
local LOCK_FILE="$RUN_DIR/update_resources-$LIST_FILE.lock"
local GITHUB_TOKEN="$(uci -q get homeproxy.config.github_token)"
local listtype="$1"
local listrepo="$2"
local listref="$3"
local listname="$4"
local lock="$RUN_DIR/update_resources-$listtype.lock"
local github_token="$(uci -q get homeproxy.config.github_token)"
local wget="wget --timeout=10 -q"
if ! lock -n "$LOCK_FILE" 2>"/dev/null"; then
log "[$(to_upper "$LIST_FILE")] A task is already running."
exec 200>"$lock"
if ! flock -n 200 &> "/dev/null"; then
log "[$(to_upper "$listtype")] A task is already running."
return 2
fi
local NEW_VER=$(curl -sL ${GITHUB_TOKEN:+-H "Authorization: Bearer $GITHUB_TOKEN"} "https://api.github.com/repos/$REPO_NAME/releases/latest" | jsonfilter -e "@.tag_name")
if [ -z "$NEW_VER" ]; then
log "[$(to_upper "$LIST_FILE")] Failed to get the latest version, please retry later."
[ -z "$github_token" ] || github_token="--header=Authorization: Bearer $github_token"
local list_info="$($wget "${github_token:--q}" -O- "https://api.github.com/repos/$listrepo/commits?sha=$listref&path=$listname&per_page=1")"
local list_sha="$(echo -e "$list_info" | jsonfilter -qe "@[0].sha")"
local list_ver="$(echo -e "$list_info" | jsonfilter -qe "@[0].commit.message" | grep -Eo "[0-9-]+" | tr -d '-')"
if [ -z "$list_sha" ] || [ -z "$list_ver" ]; then
log "[$(to_upper "$listtype")] Failed to get the latest version, please retry later."
return 1
fi
local OLD_VER=$(cat "$RESOURCES_DIR/$LIST_FILE.ver" 2>/dev/null || echo "NOT FOUND")
if [ "$OLD_VER" = "$NEW_VER" ]; then
log "[$(to_upper "$LIST_FILE")] Current version: $NEW_VER."
log "[$(to_upper "$LIST_FILE")] You're already at the latest version."
local local_list_ver="$(cat "$RESOURCES_DIR/$listtype.ver" 2>"/dev/null" || echo "NOT FOUND")"
if [ "$local_list_ver" = "$list_ver" ]; then
log "[$(to_upper "$listtype")] Current version: $list_ver."
log "[$(to_upper "$listtype")] You're already at the latest version."
return 3
else
log "[$(to_upper "$LIST_FILE")] Local version: $OLD_VER, latest version: $NEW_VER."
log "[$(to_upper "$listtype")] Local version: $local_list_ver, latest version: $list_ver."
fi
if ! curl -sL -o "$RUN_DIR/$REPO_FILE" "https://cdn.jsdelivr.net/gh/$REPO_NAME@$REPO_BRANCH/$REPO_FILE" || [ ! -s "$RUN_DIR/$REPO_FILE" ]; then
rm -f "$RUN_DIR/$REPO_FILE"
log "[$(to_upper "$LIST_FILE")] Update failed."
if ! $wget "https://fastly.jsdelivr.net/gh/$listrepo@$list_sha/$listname" -O "$RUN_DIR/$listname" || [ ! -s "$RUN_DIR/$listname" ]; then
rm -f "$RUN_DIR/$listname"
log "[$(to_upper "$listtype")] Update failed."
return 1
fi
mv -f "$RUN_DIR/$REPO_FILE" "$RESOURCES_DIR/$LIST_FILE.${REPO_FILE##*.}"
echo -e "$NEW_VER" > "$RESOURCES_DIR/$LIST_FILE.ver"
log "[$(to_upper "$LIST_FILE")] Successfully updated."
mv -f "$RUN_DIR/$listname" "$RESOURCES_DIR/$listtype.${listname##*.}"
echo -e "$list_ver" > "$RESOURCES_DIR/$listtype.ver"
log "[$(to_upper "$listtype")] Successfully updated."
return 0
}
case "$1" in
"china_ip4")
check_list_update "$1" "Loyalsoldier/surge-rules" "release" "cncidr.txt" && \
sed -i "/IP-CIDR6,/d; s/IP-CIDR,//g" "$RESOURCES_DIR/china_ip4.txt"
check_list_update "$1" "1715173329/IPCIDR-CHINA" "master" "ipv4.txt"
;;
"china_ip6")
check_list_update "$1" "Loyalsoldier/surge-rules" "release" "cncidr.txt" && \
sed -i "/IP-CIDR,/d; s/IP-CIDR6,//g" "$RESOURCES_DIR/china_ip6.txt"
check_list_update "$1" "1715173329/IPCIDR-CHINA" "master" "ipv6.txt"
;;
"gfw_list")
check_list_update "$1" "Loyalsoldier/surge-rules" "release" "gfw.txt" && \
sed -i "s/^\.//g" "$RESOURCES_DIR/gfw_list.txt"
check_list_update "$1" "Loyalsoldier/v2ray-rules-dat" "release" "gfw.txt"
;;
"china_list")
check_list_update "$1" "Loyalsoldier/surge-rules" "release" "direct.txt" && \
sed -i "s/^\.//g" "$RESOURCES_DIR/china_list.txt"
check_list_update "$1" "Loyalsoldier/v2ray-rules-dat" "release" "direct-list.txt" && \
sed -i -e "s/full://g" -e "/:/d" "$RESOURCES_DIR/china_list.txt"
;;
*)
echo -e "Usage: $0 <china_ip4 / china_ip6 / gfw_list / china_list>"
@@ -1,10 +0,0 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2025 ImmortalWrt.org
CACHE_PATH="$(uci -q get homeproxy.cache.path)"
[ -n "$CACHE_PATH" ] || CACHE_PATH="/etc/homeproxy/cache.db"
rm -f "$CACHE_PATH"
/etc/init.d/homeproxy restart
File diff suppressed because it is too large. Load diff
+23 -76
View File
@@ -27,82 +27,13 @@ log() {
echo -e "$(date "+%Y-%m-%d %H:%M:%S") [DAEMON] $*" >> "$LOG_PATH"
}
init_logs() {
mkdir -p "$RUN_DIR"
mkdir -p "$HP_DIR/run/ui"
touch "$LOG_PATH" "$RUN_DIR/sing-box-c.log" "$RUN_DIR/sing-box-s.log"
chown -R sing-box:sing-box "$RUN_DIR" 2>"/dev/null"
chown -R sing-box:sing-box "$HP_DIR/run" 2>"/dev/null"
}
valid_update_cron() {
echo "$1" | grep -Eq '^([0-9]|[0-5][0-9]) ([0-9]|[01][0-9]|2[0-3]) \* \* ([0-7]|\*)$'
}
has_ruleset_cron() {
printf '%s\n' "$ruleset_cron_list" | grep -Fxq -- "$1"
}
add_ruleset_cron() {
local section="$1"
local enabled auto_update type update_time
config_get_bool enabled "$section" "enabled" "0"
config_get_bool auto_update "$section" "auto_update" "1"
config_get type "$section" "type" "local"
config_get update_time "$section" "update_interval" ""
[ "$enabled" = "1" ] || return
[ "$auto_update" = "1" ] || return
[ "$type" = "remote" ] || return
[ -n "$update_time" ] || return
valid_update_cron "$update_time" || return
has_ruleset_cron "$update_time" && return
echo -e "$update_time sh $HP_DIR/scripts/update_rulesets.sh #${CONF}_autosetup" >> "/etc/crontabs/root"
ruleset_cron_list="${ruleset_cron_list}
${update_time}"
cron_reload="1"
}
setup_auto_update_cron() {
local cron_reload="0"
mkdir -p "/etc/crontabs"
touch "/etc/crontabs/root"
grep -q "#${CONF}_autosetup" "/etc/crontabs/root" 2>"/dev/null" && cron_reload="1"
sed -i "/#${CONF}_autosetup/d" "/etc/crontabs/root" 2>"/dev/null"
local auto_update auto_update_time
config_get_bool auto_update "subscription" "auto_update" "0"
if [ "$auto_update" = "1" ]; then
config_get auto_update_time "subscription" "auto_update_time" "0 0 * * *"
if valid_update_cron "$auto_update_time"; then
echo -e "$auto_update_time sh $HP_DIR/scripts/update_crond.sh #${CONF}_autosetup" >> "/etc/crontabs/root"
cron_reload="1"
fi
fi
local ruleset_cron_list=""
config_foreach add_ruleset_cron "ruleset"
[ "$cron_reload" = "1" ] && /etc/init.d/cron restart
}
start_service() {
init_logs
config_load "$CONF"
setup_auto_update_cron
local routing_mode proxy_mode
config_get routing_mode "config" "routing_mode" "bypass_mainland_china"
config_get proxy_mode "config" "proxy_mode" "redirect_tproxy"
local cache_path
config_get cache_path "cache" "path" "$HP_DIR/cache.db"
mkdir -p "$(dirname "$cache_path")"
[ -e "$cache_path" ] || touch "$cache_path"
chown sing-box:sing-box "$cache_path" 2>"/dev/null"
local outbound_node
if [ "$routing_mode" != "custom" ]; then
config_get outbound_node "config" "main_node" "nil"
@@ -117,6 +48,8 @@ start_service() {
return 1
fi
mkdir -p "$RUN_DIR"
if [ "$outbound_node" != "nil" ]; then
# Generate/Validate client config
ucode -S "$HP_DIR/scripts/generate_client.uc" 2>>"$LOG_PATH"
@@ -129,6 +62,16 @@ start_service() {
return 1
fi
# Auto update
local auto_update auto_update_time
config_get_bool auto_update "subscription" "auto_update" "0"
if [ "$auto_update" = "1" ]; then
config_get auto_update_time "subscription" "auto_update_time" "2"
sed -i "/#${CONF}_autosetup/d" "/etc/crontabs/root" 2>"/dev/null"
echo -e "0 $auto_update_time * * * $HP_DIR/scripts/update_crond.sh #${CONF}_autosetup" >> "/etc/crontabs/root"
/etc/init.d/cron restart
fi
# DNSMasq rules
local ipv6_support dns_port
config_get_bool ipv6_support "config" "ipv6_support" "0"
@@ -161,6 +104,8 @@ start_service() {
sed -r -e '/^\s*$/d' -e "s/(.*)/server=\/\1\/127.0.0.1#$dns_port\nnftset=\/\1\\/4#inet#fw4#homeproxy_wan_proxy_addr_v4$wan_nftset_v6/g" \
"$HP_DIR/resources/proxy_list.txt" > "$DNSMASQ_DIR/proxy_list.conf"
fi
/etc/init.d/dnsmasq restart >"/dev/null" 2>&1
# Setup routing table
local table_mark
config_get table_mark "infra" "table_mark" "100"
@@ -211,8 +156,7 @@ start_service() {
procd_add_jail "sing-box-c" log procfs
procd_add_jail_mount "$RUN_DIR/sing-box-c.json"
procd_add_jail_mount_rw "$RUN_DIR/sing-box-c.log"
procd_add_jail_mount_rw "$cache_path"
procd_add_jail_mount_rw "$HP_DIR/run/"
[ "$routing_mode" != "bypass_mainland_china" ] || procd_add_jail_mount_rw "$RUN_DIR/cache.db"
procd_add_jail_mount "$HP_DIR/certs/"
procd_add_jail_mount "/etc/ssl/"
procd_add_jail_mount "/etc/localtime"
@@ -282,15 +226,19 @@ start_service() {
procd_close_instance
case "$routing_mode" in
"bypass_mainland_china")
# Prepare cache db
[ -e "$RUN_DIR/cache.db" ] || touch "$RUN_DIR/cache.db"
;;
"custom")
# Prepare ruleset directory
[ -d "$HP_DIR/ruleset" ] || mkdir -p "$HP_DIR/ruleset"
;;
esac
[ "$outbound_node" = "nil" ] || : > "$RUN_DIR/sing-box-c.log"
[ "$outbound_node" = "nil" ] || echo > "$RUN_DIR/sing-box-c.log"
if [ "$server_enabled" = "1" ]; then
: > "$RUN_DIR/sing-box-s.log"
echo > "$RUN_DIR/sing-box-s.log"
mkdir -p "$HP_DIR/certs"
fi
@@ -301,7 +249,6 @@ start_service() {
ucode "$HP_DIR/scripts/firewall_pre.uc"
[ "$outbound_node" = "nil" ] || utpl -S "$HP_DIR/scripts/firewall_post.ut" > "$RUN_DIR/fw4_post.nft"
fw4 reload >"/dev/null" 2>&1
/etc/init.d/dnsmasq restart >"/dev/null" 2>&1
log "sing-box $(sing-box version -n) started."
}
@@ -361,8 +308,8 @@ stop_service() {
rm -rf "$DNSMASQ_DIR/../dnsmasq-homeproxy.conf" "$DNSMASQ_DIR"
/etc/init.d/dnsmasq restart >"/dev/null" 2>&1
rm -f "$RUN_DIR/sing-box-c.json" "$RUN_DIR/sing-box-s.json"
init_logs
rm -f "$RUN_DIR/sing-box-c.json" "$RUN_DIR/sing-box-c.log" \
"$RUN_DIR/sing-box-s.json" "$RUN_DIR/sing-box-s.log"
log "Service stopped."
}
-30
View File
@@ -3,36 +3,6 @@
[ -f "/www/luci-static/resources/icons/loading.gif" ] && \
sed -i "s,/loading.svg,/loading.gif,g" "/www/luci-static/resources/view/homeproxy/status.js"
uci -q set luci.main.lang='zh_cn'
uci -q commit luci
api_secret="$(uci -q get homeproxy.clash_api.secret)"
if [ -z "$api_secret" ] || [ "$api_secret" = "homeproxy" ]; then
api_secret="$(tr -dc 'A-Za-z0-9' < /dev/urandom 2>"/dev/null" | head -c 16)"
[ -n "$api_secret" ] || api_secret="$(awk 'BEGIN{srand(); printf "%06d", int(rand() * 1000000)}')"
uci -q set homeproxy.clash_api.secret="$api_secret"
uci -q commit homeproxy
fi
legacy_panel_url="https://github.com/Zephyruso/zashboard/releases/latest/download/dist.zip"
legacy_panel_proxy_url="https://gh-proxy.com/https://github.com/Zephyruso/zashboard/releases/latest/download/dist.zip"
old_panel_url="https://github.com/Zephyruso/zashboard/releases/latest/download/dist-cdn-fonts.zip"
old_panel_proxy_url="https://gh-proxy.com/https://github.com/Zephyruso/zashboard/releases/latest/download/dist-cdn-fonts.zip"
default_panel_url="https://gh-proxy.com/https://github.com/Zephyruso/zashboard/releases/latest/download/dist-cdn-fonts.zip"
panel_url="$(uci -q get homeproxy.clash_api.external_ui_download_url)"
if [ -z "$panel_url" ] || [ "$panel_url" = "$legacy_panel_url" ] || [ "$panel_url" = "$legacy_panel_proxy_url" ] || [ "$panel_url" = "$old_panel_proxy_url" ]; then
uci -q set homeproxy.clash_api.external_ui_download_url="$default_panel_url"
uci -q commit homeproxy
fi
rm -f /tmp/luci-indexcache /tmp/luci-modulecache/* 2>"/dev/null"
mkdir -p /var/run/homeproxy
touch /var/run/homeproxy/homeproxy.log \
/var/run/homeproxy/sing-box-c.log \
/var/run/homeproxy/sing-box-s.log
chown -R sing-box:sing-box /var/run/homeproxy 2>"/dev/null"
uci -q batch <<-EOF >"/dev/null"
delete firewall.homeproxy_pre
View File
File mode changed.