update 2025-08-09 09:24:33

This commit is contained in:
actions-user 2025-08-09 09:24:33 +08:00
parent 2b6140d46a
commit 1c7821d1b0
42 changed files with 1694 additions and 1808 deletions

View File

@ -63,7 +63,6 @@
14.204.0.0/15 14.204.0.0/15
14.208.0.0/12 14.208.0.0/12
16.2.142.0/23 16.2.142.0/23
23.140.100.0/24
27.0.128.0/24 27.0.128.0/24
27.0.130.0/23 27.0.130.0/23
27.0.132.0/22 27.0.132.0/22
@ -75,7 +74,6 @@
27.36.0.0/14 27.36.0.0/14
27.40.0.0/13 27.40.0.0/13
27.50.128.0/17 27.50.128.0/17
27.54.224.0/19
27.98.224.0/19 27.98.224.0/19
27.106.128.0/18 27.106.128.0/18
27.106.204.0/22 27.106.204.0/22
@ -90,6 +88,7 @@
27.192.0.0/11 27.192.0.0/11
27.224.0.0/14 27.224.0.0/14
31.56.124.0/24 31.56.124.0/24
31.57.10.0/24
36.1.0.0/16 36.1.0.0/16
36.4.0.0/14 36.4.0.0/14
36.16.0.0/12 36.16.0.0/12
@ -127,7 +126,6 @@
36.255.128.0/22 36.255.128.0/22
36.255.164.0/24 36.255.164.0/24
36.255.192.0/24 36.255.192.0/24
36.255.194.0/24
38.111.220.0/23 38.111.220.0/23
39.64.0.0/11 39.64.0.0/11
39.96.0.0/13 39.96.0.0/13
@ -205,11 +203,16 @@
42.242.0.0/15 42.242.0.0/15
42.244.0.0/14 42.244.0.0/14
42.248.0.0/15 42.248.0.0/15
43.102.128.0/21
43.102.136.0/22
43.102.144.0/20
43.136.0.0/13 43.136.0.0/13
43.144.0.0/15 43.144.0.0/15
43.192.0.0/16 43.192.0.0/16
43.193.0.0/18 43.193.0.0/18
43.193.64.0/24 43.193.64.0/24
43.194.0.0/20
43.195.0.0/20
43.196.0.0/16 43.196.0.0/16
43.224.12.0/22 43.224.12.0/22
43.224.23.0/24 43.224.23.0/24
@ -250,7 +253,7 @@
43.228.204.0/22 43.228.204.0/22
43.228.240.0/22 43.228.240.0/22
43.229.48.0/22 43.229.48.0/22
43.229.184.0/22 43.229.184.0/23
43.229.216.0/22 43.229.216.0/22
43.230.72.0/22 43.230.72.0/22
43.230.136.0/22 43.230.136.0/22
@ -271,6 +274,7 @@
43.240.124.0/22 43.240.124.0/22
43.240.128.0/22 43.240.128.0/22
43.240.133.0/24 43.240.133.0/24
43.240.136.0/22
43.240.156.0/22 43.240.156.0/22
43.240.192.0/21 43.240.192.0/21
43.240.200.0/23 43.240.200.0/23
@ -280,11 +284,13 @@
43.241.16.0/22 43.241.16.0/22
43.241.48.0/24 43.241.48.0/24
43.241.50.0/23 43.241.50.0/23
43.241.76.0/22
43.241.180.0/22 43.241.180.0/22
43.241.208.0/20 43.241.208.0/20
43.241.224.0/20 43.241.224.0/20
43.241.240.0/22 43.241.240.0/22
43.242.72.0/22 43.242.72.0/22
43.242.84.0/22
43.242.96.0/22 43.242.96.0/22
43.242.152.0/21 43.242.152.0/21
43.242.164.0/22 43.242.164.0/22
@ -312,6 +318,7 @@
43.247.196.0/22 43.247.196.0/22
43.247.244.0/22 43.247.244.0/22
43.247.248.0/22 43.247.248.0/22
43.248.0.0/22
43.248.48.0/22 43.248.48.0/22
43.248.76.0/22 43.248.76.0/22
43.248.96.0/21 43.248.96.0/21
@ -340,7 +347,6 @@
43.251.4.0/22 43.251.4.0/22
43.251.8.0/22 43.251.8.0/22
43.251.36.0/22 43.251.36.0/22
43.251.100.0/22
43.251.244.0/22 43.251.244.0/22
43.252.48.0/24 43.252.48.0/24
43.254.0.0/22 43.254.0.0/22
@ -373,6 +379,7 @@
43.255.212.0/22 43.255.212.0/22
43.255.224.0/21 43.255.224.0/21
44.30.15.0/24 44.30.15.0/24
44.30.28.0/24
44.31.42.0/24 44.31.42.0/24
44.31.81.0/24 44.31.81.0/24
44.31.96.0/24 44.31.96.0/24
@ -398,8 +405,6 @@
45.116.152.0/22 45.116.152.0/22
45.116.208.0/22 45.116.208.0/22
45.117.8.0/22 45.117.8.0/22
45.117.68.0/24
45.117.70.0/23
45.119.60.0/22 45.119.60.0/22
45.119.68.0/22 45.119.68.0/22
45.119.105.0/24 45.119.105.0/24
@ -430,6 +435,7 @@
45.151.47.0/24 45.151.47.0/24
45.157.88.0/24 45.157.88.0/24
45.195.6.0/24 45.195.6.0/24
45.202.64.0/22
45.202.209.0/24 45.202.209.0/24
45.202.210.0/23 45.202.210.0/23
45.202.212.0/24 45.202.212.0/24
@ -515,7 +521,6 @@
49.112.0.0/13 49.112.0.0/13
49.120.0.0/14 49.120.0.0/14
49.128.203.0/24 49.128.203.0/24
49.128.220.0/24
49.128.223.0/24 49.128.223.0/24
49.140.0.0/15 49.140.0.0/15
49.208.0.0/14 49.208.0.0/14
@ -627,7 +632,8 @@
59.111.96.0/21 59.111.96.0/21
59.111.104.0/23 59.111.104.0/23
59.111.107.0/24 59.111.107.0/24
59.111.108.0/22 59.111.109.0/24
59.111.111.0/24
59.111.112.0/21 59.111.112.0/21
59.111.128.0/20 59.111.128.0/20
59.111.144.0/24 59.111.144.0/24
@ -651,7 +657,9 @@
59.111.232.0/23 59.111.232.0/23
59.111.236.0/24 59.111.236.0/24
59.111.238.0/23 59.111.238.0/23
59.111.240.0/20 59.111.240.0/22
59.111.244.0/24
59.111.248.0/21
59.151.0.0/17 59.151.0.0/17
59.152.32.0/24 59.152.32.0/24
59.152.36.0/24 59.152.36.0/24
@ -727,18 +735,17 @@
72.163.240.0/23 72.163.240.0/23
72.163.248.0/22 72.163.248.0/22
74.114.51.0/24 74.114.51.0/24
77.107.118.0/24
79.133.176.0/24 79.133.176.0/24
81.23.208.0/20 81.23.208.0/20
81.68.0.0/14 81.68.0.0/14
81.173.18.0/23 81.173.18.0/23
81.173.20.0/22 81.173.20.0/22
81.173.28.0/24 81.173.28.0/24
82.26.131.0/24
82.156.0.0/15 82.156.0.0/15
84.54.2.0/23 84.54.2.0/23
85.237.205.0/24 85.237.205.0/24
87.254.207.0/24 87.254.207.0/24
89.144.2.0/24
93.183.14.0/24 93.183.14.0/24
93.183.18.0/24 93.183.18.0/24
94.191.0.0/17 94.191.0.0/17
@ -761,7 +768,6 @@
101.50.56.0/22 101.50.56.0/22
101.52.4.0/24 101.52.4.0/24
101.52.6.0/24 101.52.6.0/24
101.52.52.0/24
101.52.112.0/21 101.52.112.0/21
101.52.124.0/22 101.52.124.0/22
101.52.128.0/20 101.52.128.0/20
@ -833,6 +839,7 @@
101.237.128.0/20 101.237.128.0/20
101.240.0.0/14 101.240.0.0/14
101.245.0.0/22 101.245.0.0/22
101.245.8.0/23
101.245.16.0/22 101.245.16.0/22
101.245.32.0/19 101.245.32.0/19
101.245.64.0/18 101.245.64.0/18
@ -906,7 +913,9 @@
103.24.176.0/22 103.24.176.0/22
103.24.228.0/22 103.24.228.0/22
103.24.248.0/22 103.24.248.0/22
103.25.20.0/22
103.25.24.0/22 103.25.24.0/22
103.25.36.0/22
103.25.64.0/23 103.25.64.0/23
103.25.156.0/24 103.25.156.0/24
103.26.0.0/22 103.26.0.0/22
@ -952,12 +961,14 @@
103.37.160.0/21 103.37.160.0/21
103.37.172.0/22 103.37.172.0/22
103.38.40.0/22 103.38.40.0/22
103.38.76.0/22
103.38.84.0/22 103.38.84.0/22
103.38.92.0/23 103.38.92.0/23
103.38.116.0/22 103.38.116.0/22
103.38.224.0/22 103.38.224.0/22
103.38.232.0/22 103.38.232.0/22
103.38.252.0/23 103.38.252.0/23
103.39.64.0/22
103.39.200.0/21 103.39.200.0/21
103.39.208.0/20 103.39.208.0/20
103.39.224.0/21 103.39.224.0/21
@ -1005,6 +1016,7 @@
103.49.196.0/24 103.49.196.0/24
103.49.198.0/23 103.49.198.0/23
103.50.36.0/22 103.50.36.0/22
103.50.253.0/24
103.51.62.0/23 103.51.62.0/23
103.52.104.0/23 103.52.104.0/23
103.52.172.0/22 103.52.172.0/22
@ -1023,7 +1035,6 @@
103.56.152.0/22 103.56.152.0/22
103.56.184.0/22 103.56.184.0/22
103.57.12.0/22 103.57.12.0/22
103.57.136.0/23
103.57.139.0/24 103.57.139.0/24
103.59.112.0/22 103.59.112.0/22
103.59.124.0/22 103.59.124.0/22
@ -1068,7 +1079,6 @@
103.73.204.0/22 103.73.204.0/22
103.74.24.0/21 103.74.24.0/21
103.74.48.0/22 103.74.48.0/22
103.74.126.0/24
103.75.104.0/22 103.75.104.0/22
103.75.152.0/22 103.75.152.0/22
103.76.60.0/22 103.76.60.0/22
@ -1078,16 +1088,17 @@
103.77.72.0/22 103.77.72.0/22
103.77.92.0/22 103.77.92.0/22
103.77.132.0/22 103.77.132.0/22
103.78.60.0/22
103.78.126.0/23 103.78.126.0/23
103.78.228.0/22 103.78.228.0/22
103.79.24.0/22 103.79.24.0/22
103.79.120.0/22
103.79.200.0/22 103.79.200.0/22
103.81.4.0/22 103.81.4.0/22
103.81.48.0/22 103.81.48.0/22
103.81.72.0/22 103.81.72.0/22
103.81.123.0/24 103.81.123.0/24
103.81.200.0/22 103.81.200.0/22
103.82.52.0/22
103.82.224.0/22 103.82.224.0/22
103.83.44.0/22 103.83.44.0/22
103.83.64.0/22 103.83.64.0/22
@ -1098,7 +1109,6 @@
103.85.164.0/22 103.85.164.0/22
103.85.168.0/21 103.85.168.0/21
103.85.176.0/22 103.85.176.0/22
103.85.224.0/22
103.87.132.0/22 103.87.132.0/22
103.87.180.0/22 103.87.180.0/22
103.88.32.0/21 103.88.32.0/21
@ -1130,6 +1140,7 @@
103.97.60.0/24 103.97.60.0/24
103.97.62.0/23 103.97.62.0/23
103.97.112.0/24 103.97.112.0/24
103.97.144.0/22
103.98.0.0/24 103.98.0.0/24
103.98.15.0/24 103.98.15.0/24
103.98.28.0/23 103.98.28.0/23
@ -1171,11 +1182,13 @@
103.110.132.0/22 103.110.132.0/22
103.110.136.0/22 103.110.136.0/22
103.111.64.0/24 103.111.64.0/24
103.111.172.0/22
103.113.4.0/22 103.113.4.0/22
103.114.100.0/22 103.114.100.0/22
103.114.158.0/23 103.114.158.0/23
103.114.212.0/23 103.114.212.0/23
103.114.236.0/22 103.114.236.0/22
103.115.92.0/22
103.115.120.0/22 103.115.120.0/22
103.115.248.0/22 103.115.248.0/22
103.116.76.0/22 103.116.76.0/22
@ -1193,6 +1206,7 @@
103.119.104.0/22 103.119.104.0/22
103.119.224.0/22 103.119.224.0/22
103.120.72.0/22 103.120.72.0/22
103.120.88.0/22
103.120.224.0/22 103.120.224.0/22
103.121.52.0/22 103.121.52.0/22
103.121.164.0/23 103.121.164.0/23
@ -1214,6 +1228,7 @@
103.132.80.0/23 103.132.80.0/23
103.132.212.0/23 103.132.212.0/23
103.133.128.0/23 103.133.128.0/23
103.134.136.0/22
103.135.160.0/22 103.135.160.0/22
103.135.192.0/21 103.135.192.0/21
103.135.236.0/24 103.135.236.0/24
@ -1238,7 +1253,6 @@
103.145.92.0/24 103.145.92.0/24
103.146.126.0/23 103.146.126.0/23
103.147.124.0/24 103.147.124.0/24
103.149.110.0/23
103.149.181.0/24 103.149.181.0/24
103.149.242.0/24 103.149.242.0/24
103.149.244.0/22 103.149.244.0/22
@ -1247,7 +1261,6 @@
103.150.164.0/23 103.150.164.0/23
103.150.212.0/24 103.150.212.0/24
103.151.148.0/23 103.151.148.0/23
103.151.178.0/23
103.152.28.0/23 103.152.28.0/23
103.152.56.0/23 103.152.56.0/23
103.152.76.0/23 103.152.76.0/23
@ -1290,7 +1303,7 @@
103.183.66.0/23 103.183.66.0/23
103.183.122.0/23 103.183.122.0/23
103.183.124.0/23 103.183.124.0/23
103.183.218.0/24 103.183.218.0/23
103.184.46.0/23 103.184.46.0/23
103.186.4.0/23 103.186.4.0/23
103.186.108.0/23 103.186.108.0/23
@ -1395,7 +1408,6 @@
103.227.80.0/22 103.227.80.0/22
103.227.120.0/22 103.227.120.0/22
103.227.136.0/22 103.227.136.0/22
103.227.228.0/22
103.228.12.0/22 103.228.12.0/22
103.228.136.0/22 103.228.136.0/22
103.228.160.0/22 103.228.160.0/22
@ -1408,7 +1420,6 @@
103.229.216.0/21 103.229.216.0/21
103.229.236.0/22 103.229.236.0/22
103.230.110.0/23 103.230.110.0/23
103.230.128.0/23
103.230.200.0/22 103.230.200.0/22
103.230.212.0/22 103.230.212.0/22
103.230.236.0/22 103.230.236.0/22
@ -1458,13 +1469,16 @@
103.239.68.0/22 103.239.68.0/22
103.239.152.0/22 103.239.152.0/22
103.239.184.0/24 103.239.184.0/24
103.239.187.0/24
103.239.192.0/22 103.239.192.0/22
103.239.204.0/22 103.239.204.0/22
103.239.224.0/22 103.239.224.0/22
103.239.244.0/22 103.239.244.0/22
103.240.16.0/22
103.240.36.0/22 103.240.36.0/22
103.240.84.0/22 103.240.84.0/22
103.240.124.0/22 103.240.124.0/22
103.240.244.0/22
103.241.95.0/24 103.241.95.0/24
103.241.208.0/23 103.241.208.0/23
103.242.128.0/24 103.242.128.0/24
@ -1541,7 +1555,6 @@
106.2.100.0/22 106.2.100.0/22
106.2.104.0/21 106.2.104.0/21
106.2.112.0/21 106.2.112.0/21
106.2.122.0/24
106.2.124.0/22 106.2.124.0/22
106.2.128.0/19 106.2.128.0/19
106.2.224.0/24 106.2.224.0/24
@ -1853,8 +1866,7 @@
114.112.160.0/21 114.112.160.0/21
114.112.200.0/21 114.112.200.0/21
114.112.208.0/20 114.112.208.0/20
114.113.16.0/20 114.113.63.0/24
114.113.32.0/19
114.113.64.0/18 114.113.64.0/18
114.113.144.0/20 114.113.144.0/20
114.113.196.0/22 114.113.196.0/22
@ -1884,6 +1896,8 @@
115.28.0.0/15 115.28.0.0/15
115.31.64.0/22 115.31.64.0/22
115.32.0.0/19 115.32.0.0/19
115.32.32.0/21
115.32.56.0/21
115.44.0.0/14 115.44.0.0/14
115.48.0.0/12 115.48.0.0/12
115.84.0.0/18 115.84.0.0/18
@ -1940,7 +1954,7 @@
116.85.0.0/22 116.85.0.0/22
116.85.13.0/24 116.85.13.0/24
116.85.14.0/23 116.85.14.0/23
116.85.16.0/24 116.85.16.0/23
116.85.64.0/20 116.85.64.0/20
116.85.240.0/20 116.85.240.0/20
116.90.80.0/20 116.90.80.0/20
@ -1994,14 +2008,12 @@
116.198.0.0/18 116.198.0.0/18
116.198.64.0/21 116.198.64.0/21
116.198.72.0/22 116.198.72.0/22
116.198.80.0/21
116.198.144.0/20 116.198.144.0/20
116.198.160.0/20 116.198.160.0/20
116.198.176.0/21 116.198.176.0/21
116.198.192.0/18 116.198.192.0/18
116.199.0.0/17 116.199.0.0/17
116.204.0.0/17 116.204.0.0/17
116.204.132.0/22
116.205.0.0/16 116.205.0.0/16
116.207.0.0/16 116.207.0.0/16
116.208.0.0/14 116.208.0.0/14
@ -2039,7 +2051,10 @@
117.48.216.0/23 117.48.216.0/23
117.48.218.0/24 117.48.218.0/24
117.48.220.0/22 117.48.220.0/22
117.48.224.0/20 117.48.224.0/21
117.48.232.0/23
117.48.234.0/24
117.48.236.0/22
117.50.0.0/16 117.50.0.0/16
117.51.0.0/17 117.51.0.0/17
117.51.128.0/19 117.51.128.0/19
@ -2055,9 +2070,9 @@
117.72.16.0/23 117.72.16.0/23
117.72.32.0/19 117.72.32.0/19
117.72.64.0/18 117.72.64.0/18
117.72.144.0/20
117.72.160.0/19 117.72.160.0/19
117.72.192.0/19 117.72.192.0/19
117.72.224.0/20
117.72.255.0/24 117.72.255.0/24
117.73.0.0/20 117.73.0.0/20
117.73.16.0/21 117.73.16.0/21
@ -2136,6 +2151,21 @@
118.145.192.0/18 118.145.192.0/18
118.178.0.0/16 118.178.0.0/16
118.180.0.0/14 118.180.0.0/14
118.184.0.0/22
118.184.30.0/24
118.184.40.0/21
118.184.48.0/22
118.184.52.0/24
118.184.64.0/24
118.184.66.0/23
118.184.69.0/24
118.184.76.0/22
118.184.81.0/24
118.184.82.0/23
118.184.84.0/22
118.184.92.0/22
118.184.96.0/22
118.184.104.0/22
118.184.128.0/17 118.184.128.0/17
118.186.0.0/19 118.186.0.0/19
118.186.32.0/24 118.186.32.0/24
@ -2174,6 +2204,15 @@
118.192.70.0/24 118.192.70.0/24
118.192.96.0/19 118.192.96.0/19
118.193.96.0/19 118.193.96.0/19
118.193.128.0/23
118.193.138.0/24
118.193.144.0/23
118.193.152.0/22
118.193.160.0/23
118.193.162.0/24
118.193.164.0/22
118.193.176.0/24
118.193.188.0/22
118.194.32.0/19 118.194.32.0/19
118.194.128.0/21 118.194.128.0/21
118.194.240.0/21 118.194.240.0/21
@ -2386,7 +2425,11 @@
120.136.128.0/21 120.136.128.0/21
120.136.140.0/22 120.136.140.0/22
120.136.144.0/20 120.136.144.0/20
120.136.160.0/19 120.136.160.0/20
120.136.176.0/21
120.136.184.0/22
120.136.188.0/23
120.136.190.0/24
120.192.0.0/10 120.192.0.0/10
121.0.16.0/20 121.0.16.0/20
121.4.0.0/15 121.4.0.0/15
@ -2442,7 +2485,8 @@
122.10.160.0/24 122.10.160.0/24
122.11.32.0/19 122.11.32.0/19
122.13.0.0/16 122.13.0.0/16
122.14.0.0/18 122.14.44.0/22
122.14.62.0/24
122.14.192.0/18 122.14.192.0/18
122.48.0.0/16 122.48.0.0/16
122.49.8.0/21 122.49.8.0/21
@ -2466,7 +2510,11 @@
122.112.0.0/20 122.112.0.0/20
122.112.32.0/19 122.112.32.0/19
122.112.64.0/19 122.112.64.0/19
122.112.128.0/17 122.112.132.0/22
122.112.136.0/21
122.112.144.0/20
122.112.160.0/19
122.112.192.0/18
122.114.0.0/16 122.114.0.0/16
122.115.0.0/20 122.115.0.0/20
122.115.32.0/19 122.115.32.0/19
@ -2531,8 +2579,9 @@
123.4.0.0/14 123.4.0.0/14
123.8.0.0/13 123.8.0.0/13
123.49.192.0/23 123.49.192.0/23
123.49.194.0/24
123.49.224.0/24
123.49.229.0/24 123.49.229.0/24
123.49.230.0/24
123.49.232.0/24 123.49.232.0/24
123.49.240.0/24 123.49.240.0/24
123.49.242.0/23 123.49.242.0/23
@ -2585,7 +2634,7 @@
123.103.40.0/21 123.103.40.0/21
123.103.48.0/20 123.103.48.0/20
123.103.64.0/18 123.103.64.0/18
123.108.89.0/24 123.108.88.0/24
123.108.208.0/22 123.108.208.0/22
123.108.212.0/23 123.108.212.0/23
123.108.220.0/22 123.108.220.0/22
@ -2641,7 +2690,6 @@
124.151.0.0/17 124.151.0.0/17
124.151.128.0/18 124.151.128.0/18
124.151.193.0/24 124.151.193.0/24
124.151.194.0/24
124.151.224.0/19 124.151.224.0/19
124.152.0.0/16 124.152.0.0/16
124.160.0.0/13 124.160.0.0/13
@ -2857,6 +2905,14 @@
154.8.128.0/17 154.8.128.0/17
154.19.43.0/24 154.19.43.0/24
154.38.104.0/22 154.38.104.0/22
154.48.226.0/24
154.48.231.0/24
154.48.235.0/24
154.48.236.0/22
154.48.240.0/24
154.48.247.0/24
154.48.248.0/24
154.48.250.0/23
154.72.42.0/24 154.72.42.0/24
154.72.44.0/24 154.72.44.0/24
154.72.47.0/24 154.72.47.0/24
@ -2871,7 +2927,6 @@
154.208.160.0/21 154.208.160.0/21
154.208.172.0/23 154.208.172.0/23
154.213.4.0/23 154.213.4.0/23
154.213.189.0/24
155.102.0.0/23 155.102.0.0/23
155.102.2.0/24 155.102.2.0/24
155.102.4.0/23 155.102.4.0/23
@ -2882,13 +2937,9 @@
155.102.20.0/24 155.102.20.0/24
155.102.22.0/23 155.102.22.0/23
155.102.24.0/24 155.102.24.0/24
155.102.27.0/24 155.102.26.0/23
155.102.28.0/22 155.102.28.0/22
155.102.32.0/22 155.102.32.0/19
155.102.36.0/23
155.102.39.0/24
155.102.40.0/21
155.102.48.0/20
155.102.111.0/24 155.102.111.0/24
155.102.112.0/21 155.102.112.0/21
155.102.120.0/23 155.102.120.0/23
@ -2913,6 +2964,7 @@
155.102.220.0/23 155.102.220.0/23
155.102.247.0/24 155.102.247.0/24
155.102.248.0/23 155.102.248.0/23
155.102.253.0/24
155.126.176.0/23 155.126.176.0/23
156.59.108.0/24 156.59.108.0/24
156.59.202.0/23 156.59.202.0/23
@ -2968,7 +3020,6 @@
161.163.28.0/23 161.163.28.0/23
161.189.0.0/16 161.189.0.0/16
161.207.0.0/16 161.207.0.0/16
161.248.136.0/23
162.14.0.0/16 162.14.0.0/16
162.105.0.0/16 162.105.0.0/16
163.0.0.0/16 163.0.0.0/16
@ -2980,6 +3031,7 @@
163.53.128.0/22 163.53.128.0/22
163.53.168.0/22 163.53.168.0/22
163.61.202.0/23 163.61.202.0/23
163.61.214.0/24
163.125.0.0/16 163.125.0.0/16
163.142.0.0/16 163.142.0.0/16
163.177.0.0/16 163.177.0.0/16
@ -3045,7 +3097,7 @@
163.181.196.0/22 163.181.196.0/22
163.181.200.0/21 163.181.200.0/21
163.181.209.0/24 163.181.209.0/24
163.181.210.0/24 163.181.210.0/23
163.181.212.0/23 163.181.212.0/23
163.181.214.0/24 163.181.214.0/24
163.181.216.0/21 163.181.216.0/21
@ -3099,7 +3151,6 @@
175.44.0.0/16 175.44.0.0/16
175.46.0.0/15 175.46.0.0/15
175.102.0.0/19 175.102.0.0/19
175.102.32.0/22
175.102.128.0/21 175.102.128.0/21
175.102.178.0/23 175.102.178.0/23
175.102.180.0/22 175.102.180.0/22
@ -3145,6 +3196,7 @@
180.160.0.0/12 180.160.0.0/12
180.178.208.0/20 180.178.208.0/20
180.178.224.0/21 180.178.224.0/21
180.178.232.0/22
180.178.248.0/21 180.178.248.0/21
180.184.0.0/21 180.184.0.0/21
180.184.8.0/23 180.184.8.0/23
@ -3185,6 +3237,7 @@
182.48.112.0/21 182.48.112.0/21
182.50.8.0/21 182.50.8.0/21
182.50.112.0/20 182.50.112.0/20
182.51.117.0/24
182.51.118.0/24 182.51.118.0/24
182.51.122.0/23 182.51.122.0/23
182.51.124.0/24 182.51.124.0/24
@ -3230,6 +3283,7 @@
183.192.0.0/10 183.192.0.0/10
185.75.173.0/24 185.75.173.0/24
185.75.174.0/24 185.75.174.0/24
185.78.105.0/24
185.234.212.0/24 185.234.212.0/24
188.131.128.0/17 188.131.128.0/17
192.55.46.0/24 192.55.46.0/24
@ -3313,6 +3367,7 @@
202.61.88.0/22 202.61.88.0/22
202.62.112.0/22 202.62.112.0/22
202.63.160.0/20 202.63.160.0/20
202.65.96.0/24
202.67.3.0/24 202.67.3.0/24
202.69.4.0/23 202.69.4.0/23
202.69.16.0/20 202.69.16.0/20
@ -3554,7 +3609,7 @@
203.76.216.0/22 203.76.216.0/22
203.76.240.0/22 203.76.240.0/22
203.78.48.0/20 203.78.48.0/20
203.79.0.0/20 203.79.0.0/23
203.80.57.0/24 203.80.57.0/24
203.80.144.0/20 203.80.144.0/20
203.82.0.0/23 203.82.0.0/23
@ -3592,15 +3647,12 @@
203.95.0.0/23 203.95.0.0/23
203.95.2.0/24 203.95.2.0/24
203.95.4.0/22 203.95.4.0/22
203.95.96.0/22
203.95.104.0/21
203.95.128.0/23 203.95.128.0/23
203.99.20.0/22 203.99.20.0/22
203.99.24.0/21 203.99.24.0/21
203.100.50.0/23 203.100.50.0/23
203.100.54.0/24 203.100.54.0/24
203.100.92.0/22 203.100.92.0/22
203.100.96.0/19
203.100.192.0/20 203.100.192.0/20
203.104.32.0/20 203.104.32.0/20
203.107.1.0/24 203.107.1.0/24
@ -3613,9 +3665,6 @@
203.107.72.0/21 203.107.72.0/21
203.107.80.0/21 203.107.80.0/21
203.107.96.0/23 203.107.96.0/23
203.107.100.0/22
203.107.104.0/22
203.107.108.0/23
203.107.116.0/22 203.107.116.0/22
203.110.160.0/19 203.110.160.0/19
203.110.208.0/20 203.110.208.0/20
@ -3628,7 +3677,6 @@
203.119.33.0/24 203.119.33.0/24
203.119.80.0/23 203.119.80.0/23
203.119.83.0/24 203.119.83.0/24
203.119.85.0/24
203.119.114.0/23 203.119.114.0/23
203.119.128.0/19 203.119.128.0/19
203.119.160.0/24 203.119.160.0/24
@ -3722,7 +3770,8 @@
203.223.21.0/24 203.223.21.0/24
204.13.175.0/24 204.13.175.0/24
205.198.19.0/24 205.198.19.0/24
206.52.0.0/23 206.52.0.0/22
206.52.4.0/23
206.54.1.128/25 206.54.1.128/25
206.54.9.0/24 206.54.9.0/24
206.54.10.0/23 206.54.10.0/23
@ -3978,7 +4027,8 @@
211.161.0.0/20 211.161.0.0/20
211.161.24.0/22 211.161.24.0/22
211.161.32.0/20 211.161.32.0/20
211.161.60.0/22 211.161.60.0/23
211.161.62.0/24
211.161.97.0/24 211.161.97.0/24
211.161.101.0/24 211.161.101.0/24
211.161.102.0/23 211.161.102.0/23
@ -4096,7 +4146,8 @@
219.233.0.0/16 219.233.0.0/16
219.234.0.0/21 219.234.0.0/21
219.234.16.0/20 219.234.16.0/20
219.234.64.0/18 219.234.80.0/20
219.234.96.0/19
219.234.128.0/17 219.234.128.0/17
219.235.0.0/20 219.235.0.0/20
219.235.32.0/19 219.235.32.0/19
@ -4135,7 +4186,10 @@
220.113.154.0/24 220.113.154.0/24
220.114.250.0/23 220.114.250.0/23
220.152.128.0/17 220.152.128.0/17
220.154.0.0/20
220.154.16.0/22
220.154.128.0/22 220.154.128.0/22
220.154.140.0/24
220.154.144.0/24 220.154.144.0/24
220.160.0.0/12 220.160.0.0/12
220.176.0.0/14 220.176.0.0/14
@ -4196,6 +4250,7 @@
221.13.0.0/16 221.13.0.0/16
221.14.0.0/15 221.14.0.0/15
221.122.0.0/16 221.122.0.0/16
221.123.112.0/20
221.123.128.0/17 221.123.128.0/17
221.129.0.0/16 221.129.0.0/16
221.130.0.0/15 221.130.0.0/15
@ -4246,8 +4301,7 @@
222.126.140.0/22 222.126.140.0/22
222.126.144.0/20 222.126.144.0/20
222.126.160.0/20 222.126.160.0/20
222.126.178.0/23 222.126.176.0/21
222.126.180.0/22
222.126.184.0/22 222.126.184.0/22
222.126.192.0/22 222.126.192.0/22
222.126.196.0/23 222.126.196.0/23

View File

@ -1 +1 @@
20250718035513 20250808035959

View File

@ -1,6 +1,7 @@
2001:250::/30 2001:250::/30
2001:254::/31 2001:254::/31
2001:256:100::/48 2001:256:100::/48
2001:678:120::/48
2001:67c:ebc::/48 2001:67c:ebc::/48
2001:7fa:5::/48 2001:7fa:5::/48
2001:c68::/32 2001:c68::/32
@ -12,7 +13,6 @@
2001:daa:6::/48 2001:daa:6::/48
2001:dc7::/32 2001:dc7::/32
2001:dd8:1::/48 2001:dd8:1::/48
2001:dd8:5::/48
2001:dd9::/48 2001:dd9::/48
2001:df0:ac40::/48 2001:df0:ac40::/48
2001:df3:3a80::/48 2001:df3:3a80::/48
@ -151,7 +151,8 @@
2401:b400::/45 2401:b400::/45
2401:b400:8::/47 2401:b400:8::/47
2401:b400:11::/48 2401:b400:11::/48
2401:b400:14::/46 2401:b400:14::/48
2401:b400:16::/47
2401:b400:20::/47 2401:b400:20::/47
2401:b680::/32 2401:b680::/32
2401:be00::/32 2401:be00::/32
@ -170,6 +171,7 @@
2401:f860:88::/47 2401:f860:88::/47
2401:f860:90::/47 2401:f860:90::/47
2401:f860:93::/48 2401:f860:93::/48
2401:f860:94::/48
2401:f860:100::/40 2401:f860:100::/40
2401:f860:f100::/40 2401:f860:f100::/40
2401:fa00:40::/43 2401:fa00:40::/43
@ -337,7 +339,6 @@
2404:2280:1f0::/45 2404:2280:1f0::/45
2404:2280:1f8::/46 2404:2280:1f8::/46
2404:2280:1fd::/48 2404:2280:1fd::/48
2404:2280:1fe::/48
2404:2280:202::/47 2404:2280:202::/47
2404:2280:204::/46 2404:2280:204::/46
2404:2280:208::/46 2404:2280:208::/46
@ -350,6 +351,7 @@
2404:2280:21a::/48 2404:2280:21a::/48
2404:2280:221::/48 2404:2280:221::/48
2404:2280:271::/48 2404:2280:271::/48
2404:2280:27a::/48
2404:2280:27c::/48 2404:2280:27c::/48
2404:3700::/48 2404:3700::/48
2404:4dc0::/32 2404:4dc0::/32
@ -405,8 +407,6 @@
2405:3140:21::/48 2405:3140:21::/48
2405:3140:31::/48 2405:3140:31::/48
2405:3140:3a::/48 2405:3140:3a::/48
2405:57c0::/47
2405:57c0:100::/48
2405:66c0::/32 2405:66c0::/32
2405:68c0:21::/48 2405:68c0:21::/48
2405:6940::/48 2405:6940::/48
@ -440,11 +440,10 @@
2406:840:e201::/48 2406:840:e201::/48
2406:840:e230::/44 2406:840:e230::/44
2406:840:e260::/48 2406:840:e260::/48
2406:840:e2cb::/48 2406:840:e2cf::/48
2406:840:e500::/47 2406:840:e500::/47
2406:840:e621::/48 2406:840:e621::/48
2406:840:e666::/47 2406:840:e666::/47
2406:840:e720::/44
2406:840:e80f::/48 2406:840:e80f::/48
2406:840:eb00::/46 2406:840:eb00::/46
2406:840:eb04::/47 2406:840:eb04::/47
@ -533,6 +532,7 @@
2407:c080:5000::/37 2407:c080:5000::/37
2407:c080:6000::/36 2407:c080:6000::/36
2407:c080:8000::/36 2407:c080:8000::/36
2407:d9c0::/32
2408:4000::/22 2408:4000::/22
2408:8000::/48 2408:8000::/48
2408:8000:2::/47 2408:8000:2::/47
@ -653,104 +653,151 @@
2408:8374::/30 2408:8374::/30
2408:8378::/31 2408:8378::/31
2408:837a::/32 2408:837a::/32
2408:8406::/40 2408:8406::/42
2408:8406:40::/43
2408:8406:c0::/42
2408:8406:100::/41 2408:8406:100::/41
2408:8406:180::/42 2408:8406:180::/42
2408:8406:c00::/40 2408:8406:c00::/42
2408:8406:c40::/43
2408:8406:cc0::/42
2408:8406:d00::/41 2408:8406:d00::/41
2408:8406:d80::/42 2408:8406:d80::/42
2408:8406:1800::/40 2408:8406:1800::/42
2408:8406:1840::/43
2408:8406:18c0::/42
2408:8406:1900::/41 2408:8406:1900::/41
2408:8406:1980::/42 2408:8406:1980::/42
2408:8406:2400::/40 2408:8406:2400::/42
2408:8406:2440::/43
2408:8406:24c0::/42
2408:8406:2500::/41 2408:8406:2500::/41
2408:8406:2580::/42 2408:8406:2580::/42
2408:8406:3000::/40 2408:8406:3000::/42
2408:8406:3040::/43
2408:8406:30c0::/42
2408:8406:3100::/41 2408:8406:3100::/41
2408:8406:3180::/42 2408:8406:3180::/42
2408:8406:3c00::/40 2408:8406:3c00::/42
2408:8406:3c40::/43
2408:8406:3cc0::/42
2408:8406:3d00::/41 2408:8406:3d00::/41
2408:8406:3d80::/42 2408:8406:3d80::/42
2408:8406:4800::/40 2408:8406:4800::/42
2408:8406:4840::/43
2408:8406:48c0::/42
2408:8406:4900::/41 2408:8406:4900::/41
2408:8406:4980::/42 2408:8406:4980::/42
2408:8406:5400::/40 2408:8406:5400::/42
2408:8406:5440::/43
2408:8406:54c0::/42
2408:8406:5500::/41 2408:8406:5500::/41
2408:8406:5580::/42 2408:8406:5580::/42
2408:8406:6000::/40 2408:8406:6000::/42
2408:8406:6040::/43
2408:8406:60c0::/42
2408:8406:6100::/41 2408:8406:6100::/41
2408:8406:6180::/42 2408:8406:6180::/42
2408:8406:6c00::/40 2408:8406:6c00::/42
2408:8406:6c40::/43
2408:8406:6cc0::/42
2408:8406:6d00::/41 2408:8406:6d00::/41
2408:8406:6d80::/42 2408:8406:6d80::/42
2408:8406:7800::/40 2408:8406:7800::/42
2408:8406:7840::/43
2408:8406:78c0::/42
2408:8406:7900::/41 2408:8406:7900::/41
2408:8406:7980::/42 2408:8406:7980::/42
2408:8406:8400::/40 2408:8406:8400::/42
2408:8406:8440::/43
2408:8406:84c0::/42
2408:8406:8500::/41 2408:8406:8500::/41
2408:8406:8580::/42 2408:8406:8580::/42
2408:8406:9000::/40 2408:8406:9000::/42
2408:8406:9040::/43
2408:8406:90c0::/42
2408:8406:9100::/41 2408:8406:9100::/41
2408:8406:9180::/42 2408:8406:9180::/42
2408:8406:9c00::/40 2408:8406:9c00::/42
2408:8406:9c40::/43
2408:8406:9cc0::/42
2408:8406:9d00::/41 2408:8406:9d00::/41
2408:8406:9d80::/42 2408:8406:9d80::/42
2408:8406:a800::/40 2408:8406:a800::/42
2408:8406:a840::/43
2408:8406:a8c0::/42
2408:8406:a900::/41 2408:8406:a900::/41
2408:8406:a980::/42 2408:8406:a980::/42
2408:8406:b400::/40 2408:8406:b400::/42
2408:8406:b440::/43
2408:8406:b4c0::/42
2408:8406:b500::/41 2408:8406:b500::/41
2408:8406:b580::/42 2408:8406:b580::/42
2408:8407:500::/43 2408:8407:500::/43
2408:8409::/40 2408:8409::/40
2408:8409:120::/43 2408:8409:100::/41
2408:8409:140::/42
2408:8409:180::/42 2408:8409:180::/42
2408:8409:1c0::/43
2408:8409:c00::/40 2408:8409:c00::/40
2408:8409:d00::/41 2408:8409:d00::/41
2408:8409:d80::/42 2408:8409:d80::/42
2408:8409:dc0::/43
2408:8409:1800::/40 2408:8409:1800::/40
2408:8409:1900::/41 2408:8409:1900::/41
2408:8409:1980::/42 2408:8409:1980::/42
2408:8409:19c0::/43
2408:8409:2400::/40 2408:8409:2400::/40
2408:8409:2500::/41 2408:8409:2500::/41
2408:8409:2580::/42 2408:8409:2580::/42
2408:8409:25c0::/43
2408:8409:3000::/40 2408:8409:3000::/40
2408:8409:3100::/41 2408:8409:3100::/41
2408:8409:3180::/42 2408:8409:3180::/42
2408:8409:31c0::/43
2408:8409:3c00::/40 2408:8409:3c00::/40
2408:8409:3d00::/41 2408:8409:3d00::/41
2408:8409:3d80::/42 2408:8409:3d80::/42
2408:8409:3dc0::/43
2408:8409:4800::/40 2408:8409:4800::/40
2408:8409:4900::/41 2408:8409:4900::/41
2408:8409:4980::/42 2408:8409:4980::/42
2408:8409:49c0::/43
2408:8409:5400::/40 2408:8409:5400::/40
2408:8409:5500::/41 2408:8409:5500::/41
2408:8409:5580::/42 2408:8409:5580::/42
2408:8409:55c0::/43
2408:8409:6000::/40 2408:8409:6000::/40
2408:8409:6100::/41 2408:8409:6100::/41
2408:8409:6180::/42 2408:8409:6180::/42
2408:8409:61c0::/43
2408:8409:6c00::/40 2408:8409:6c00::/40
2408:8409:6d00::/41 2408:8409:6d00::/41
2408:8409:6d80::/42 2408:8409:6d80::/42
2408:8409:6dc0::/43
2408:8409:7800::/40 2408:8409:7800::/40
2408:8409:7900::/41 2408:8409:7900::/41
2408:8409:7980::/42 2408:8409:7980::/42
2408:8409:79c0::/43
2408:8409:8400::/40 2408:8409:8400::/40
2408:8409:8500::/41 2408:8409:8500::/41
2408:8409:8580::/42 2408:8409:8580::/42
2408:8409:85c0::/43
2408:8409:9000::/40 2408:8409:9000::/40
2408:8409:9100::/41 2408:8409:9100::/41
2408:8409:9180::/42 2408:8409:9180::/42
2408:8409:91c0::/43
2408:8409:9c00::/40 2408:8409:9c00::/40
2408:8409:9d00::/41 2408:8409:9d00::/41
2408:8409:9d80::/42 2408:8409:9d80::/42
2408:8409:9dc0::/43
2408:8409:a800::/40 2408:8409:a800::/40
2408:8409:a900::/41 2408:8409:a900::/41
2408:8409:a980::/42 2408:8409:a980::/42
2408:8409:a9c0::/43
2408:8409:b400::/40 2408:8409:b400::/40
2408:8409:b500::/41 2408:8409:b500::/41
2408:8409:b580::/42 2408:8409:b580::/42
2408:8409:b5c0::/43
2408:840c::/40 2408:840c::/40
2408:840c:200::/40 2408:840c:200::/40
2408:840c:400::/40 2408:840c:400::/40
@ -1140,7 +1187,6 @@
2602:f93b:400::/38 2602:f93b:400::/38
2602:f9ba:a8::/48 2602:f9ba:a8::/48
2602:f9ba:10c::/48 2602:f9ba:10c::/48
2602:fd92:cc0::/44
2602:feda:182::/47 2602:feda:182::/47
2602:feda:1bf::/48 2602:feda:1bf::/48
2602:feda:1d1::/48 2602:feda:1d1::/48
@ -1191,9 +1237,8 @@
2a06:1180:1000::/48 2a06:1180:1000::/48
2a06:3605::/32 2a06:3605::/32
2a06:3606::/31 2a06:3606::/31
2a06:9f81:4600::/44 2a06:9f81:4600::/43
2a06:9f81:4640::/44 2a06:9f81:4640::/44
2a06:9f81:4660::/44
2a06:a005:260::/43 2a06:a005:260::/43
2a06:a005:280::/43 2a06:a005:280::/43
2a06:a005:2a0::/44 2a06:a005:2a0::/44
@ -1206,9 +1251,10 @@
2a09:b280:ff81::/48 2a09:b280:ff81::/48
2a09:b280:ff83::/48 2a09:b280:ff83::/48
2a09:b280:ff84::/47 2a09:b280:ff84::/47
2a0a:2840::/30 2a0a:2840:20::/43
2a0a:2840:2000::/48
2a0a:2842::/32
2a0a:2845:aab8::/46 2a0a:2845:aab8::/46
2a0a:2845:d647::/48
2a0a:2846::/48 2a0a:2846::/48
2a0a:6040:ec00::/40 2a0a:6040:ec00::/40
2a0a:6044:6600::/40 2a0a:6044:6600::/40
@ -1216,10 +1262,8 @@
2a0b:2542::/48 2a0b:2542::/48
2a0b:4340:a6::/48 2a0b:4340:a6::/48
2a0b:4e07:b8::/47 2a0b:4e07:b8::/47
2a0c:9a40:84e0::/48
2a0c:9a40:9e00::/43 2a0c:9a40:9e00::/43
2a0c:b641:571::/48 2a0c:b641:571::/48
2a0e:97c0:550::/44
2a0e:97c0:83f::/48 2a0e:97c0:83f::/48
2a0e:9b00::/29 2a0e:9b00::/29
2a0e:aa01:1fff::/48 2a0e:aa01:1fff::/48
@ -1236,6 +1280,7 @@
2a0e:aa07:e039::/48 2a0e:aa07:e039::/48
2a0e:aa07:e044::/48 2a0e:aa07:e044::/48
2a0e:aa07:e151::/48 2a0e:aa07:e151::/48
2a0e:aa07:e155::/48
2a0e:aa07:e160::/47 2a0e:aa07:e160::/47
2a0e:aa07:e162::/48 2a0e:aa07:e162::/48
2a0e:aa07:e16a::/48 2a0e:aa07:e16a::/48
@ -1256,7 +1301,6 @@
2a0e:b107:740::/44 2a0e:b107:740::/44
2a0e:b107:c10::/48 2a0e:b107:c10::/48
2a0e:b107:dce::/48 2a0e:b107:dce::/48
2a0e:b107:16b0::/44
2a0e:b107:178d::/48 2a0e:b107:178d::/48
2a0e:b107:178e::/48 2a0e:b107:178e::/48
2a0f:5707:ac00::/47 2a0f:5707:ac00::/47
@ -1274,8 +1318,6 @@
2a0f:7803:fe81::/48 2a0f:7803:fe81::/48
2a0f:7803:fe82::/48 2a0f:7803:fe82::/48
2a0f:7d07::/32 2a0f:7d07::/32
2a0f:85c1:816::/48
2a0f:85c1:b3a::/48
2a0f:85c1:ba5::/48 2a0f:85c1:ba5::/48
2a0f:9400:6110::/48 2a0f:9400:6110::/48
2a0f:9400:7700::/48 2a0f:9400:7700::/48
@ -1283,8 +1325,12 @@
2a10:2f00:15a::/48 2a10:2f00:15a::/48
2a10:cc40:190::/48 2a10:cc40:190::/48
2a10:ccc0:d00::/46 2a10:ccc0:d00::/46
2a10:ccc0:d0a::/48 2a10:ccc0:d0a::/47
2a10:ccc0:d0c::/47 2a10:ccc0:d0c::/47
2a10:ccc6:66c6::/48
2a10:ccc6:66c9::/48
2a10:ccc6:66ca::/48
2a10:ccc6:66cd::/48
2a12:f8c3::/36 2a12:f8c3::/36
2a13:1800::/48 2a13:1800::/48
2a13:1800:10::/48 2a13:1800:10::/48
@ -1296,16 +1342,15 @@
2a13:a5c7:1800::/40 2a13:a5c7:1800::/40
2a13:a5c7:2100::/48 2a13:a5c7:2100::/48
2a13:a5c7:2102::/48 2a13:a5c7:2102::/48
2a13:a5c7:2110::/48
2a13:a5c7:2121::/48 2a13:a5c7:2121::/48
2a13:a5c7:2803::/48 2a13:a5c7:2803::/48
2a13:a5c7:3100::/43 2a13:a5c7:3100::/43
2a13:a5c7:31a0::/43
2a13:aac4:f000::/44 2a13:aac4:f000::/44
2a14:7c0:4a01::/48 2a14:7c0:4a01::/48
2a14:4c41::/32 2a14:4c41::/32
2a14:67c1:20::/44 2a14:67c1:20::/44
2a14:67c1:70::/47 2a14:67c1:70::/47
2a14:67c1:73::/48
2a14:67c1:74::/48 2a14:67c1:74::/48
2a14:67c1:702::/47 2a14:67c1:702::/47
2a14:67c1:704::/48 2a14:67c1:704::/48
@ -1315,12 +1360,11 @@
2a14:67c1:a024::/48 2a14:67c1:a024::/48
2a14:67c1:a02a::/48 2a14:67c1:a02a::/48
2a14:67c1:a02f::/48 2a14:67c1:a02f::/48
2a14:67c1:a040::/48 2a14:67c1:a040::/47
2a14:67c1:a061::/48 2a14:67c1:a061::/48
2a14:67c1:a064::/48 2a14:67c1:a064::/48
2a14:67c1:a090::/48 2a14:67c1:a090::/46
2a14:67c1:a092::/47 2a14:67c1:a094::/47
2a14:67c1:a095::/48
2a14:67c1:a099::/48 2a14:67c1:a099::/48
2a14:67c1:a100::/43 2a14:67c1:a100::/43
2a14:67c1:b000::/48 2a14:67c1:b000::/48
@ -1332,14 +1376,15 @@
2a14:67c1:b107::/48 2a14:67c1:b107::/48
2a14:67c1:b130::/47 2a14:67c1:b130::/47
2a14:67c1:b132::/48 2a14:67c1:b132::/48
2a14:67c1:b4d0::/44 2a14:67c1:b4c0::/45
2a14:67c1:b4e0::/43 2a14:67c1:b4e0::/43
2a14:67c1:b500::/48 2a14:67c1:b500::/48
2a14:67c1:b561::/48 2a14:67c1:b561::/48
2a14:67c1:b563::/48 2a14:67c1:b563::/48
2a14:67c1:b566::/48 2a14:67c1:b566::/48
2a14:67c1:b582::/48 2a14:67c1:b582::/48
2a14:67c5:1100::/40 2a14:67c1:b588::/47
2a14:67c1:b590::/48
2a14:67c5:1900::/40 2a14:67c5:1900::/40
2a14:7580:9200::/40 2a14:7580:9200::/40
2a14:7580:9400::/39 2a14:7580:9400::/39
@ -1349,7 +1394,6 @@
2a14:7580:fe00::/40 2a14:7580:fe00::/40
2a14:7581:3100::/40 2a14:7581:3100::/40
2a14:7581:9010::/44 2a14:7581:9010::/44
2a14:7584:9000::/36
2c0f:f7a8:8011::/48 2c0f:f7a8:8011::/48
2c0f:f7a8:8050::/48 2c0f:f7a8:8050::/48
2c0f:f7a8:805f::/48 2c0f:f7a8:805f::/48

View File

@ -1 +1 @@
20250718035513 20250808035959

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
202507172215 202508072216

View File

@ -3086,6 +3086,7 @@ lsmwebcast.com
lsxszzg.com lsxszzg.com
ltn.com.tw ltn.com.tw
luckydesigner.space luckydesigner.space
ludepress.com
luke54.com luke54.com
luke54.org luke54.org
lupm.org lupm.org
@ -5376,6 +5377,7 @@ waffle1999.com
wahas.com wahas.com
waikeung.org waikeung.org
wainao.me wainao.me
walletconnect.com
wallmama.com wallmama.com
wallpapercasa.com wallpapercasa.com
wallproxy.com wallproxy.com
@ -5609,6 +5611,8 @@ www1.biz
www2.ohchr.org www2.ohchr.org
www2.rocketbbs.com www2.rocketbbs.com
wwwhost.biz wwwhost.biz
wxw.cat
wxw.moe
wzyboy.im wzyboy.im
x-art.com x-art.com
x-berry.com x-berry.com
@ -5707,6 +5711,7 @@ yam.com
yam.org.tw yam.org.tw
yande.re yande.re
yanghengjun.com yanghengjun.com
yangzhi.org
yasni.co.uk yasni.co.uk
yasukuni.or.jp yasukuni.or.jp
yayabay.com yayabay.com

View File

@ -1 +1 @@
202507172215 202508072216

View File

@ -128,7 +128,6 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Shadow_TLS
config PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs config PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs
bool "Include Simple-Obfs (Shadowsocks Plugin)" bool "Include Simple-Obfs (Shadowsocks Plugin)"
select PACKAGE_simple-obfs
select PACKAGE_simple-obfs-client select PACKAGE_simple-obfs-client
default y default y

View File

@ -779,6 +779,18 @@ o.rmempty = false
o = s2:option(ListValue, "node", translate("Socks Node")) o = s2:option(ListValue, "node", translate("Socks Node"))
o = s2:option(DummyValue, "now_node", translate("Current Node"))
o.rawhtml = true
o.cfgvalue = function(_, n)
local current_node = api.get_cache_var("socks_" .. n)
if current_node then
local node = m:get(current_node)
if node then
return (api.get_node_remarks(node) or ""):gsub("()%[", "%1<br>[")
end
end
end
local n = 1 local n = 1
m.uci:foreach(appname, "socks", function(s) m.uci:foreach(appname, "socks", function(s)
if s[".name"] == section then if s[".name"] == section then
@ -793,7 +805,7 @@ o.datatype = "port"
o.rmempty = false o.rmempty = false
if has_singbox or has_xray then if has_singbox or has_xray then
o = s2:option(Value, "http_port", "HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use")) o = s2:option(Value, "http_port", "HTTP " .. translate("Listen Port"))
o.default = 0 o.default = 0
o.datatype = "port" o.datatype = "port"
end end

View File

@ -100,6 +100,9 @@ msgstr "Socks 配置"
msgid "Socks Node" msgid "Socks Node"
msgstr "Socks 节点" msgstr "Socks 节点"
msgid "Current Node"
msgstr "当前节点"
msgid "Listen Port" msgid "Listen Port"
msgstr "监听端口" msgstr "监听端口"

View File

@ -31,7 +31,7 @@ test_url() {
if /usr/bin/curl --help all | grep -q "\-\-retry-all-errors"; then if /usr/bin/curl --help all | grep -q "\-\-retry-all-errors"; then
extra_params="--retry-all-errors ${extra_params}" extra_params="--retry-all-errors ${extra_params}"
fi fi
status=$(/usr/bin/curl -I -o /dev/null -skL ${extra_params} --connect-timeout ${timeout} --retry ${try} -w %{http_code} "$url") local status=$(/usr/bin/curl -I -o /dev/null -skL ${extra_params} --connect-timeout ${timeout} --retry ${try} -w %{http_code} "$url")
case "$status" in case "$status" in
204) 204)
status=200 status=200
@ -41,12 +41,12 @@ test_url() {
} }
test_proxy() { test_proxy() {
result=0 local result=0
status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x socks5h://127.0.0.1:${socks_port}") local status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x socks5h://127.0.0.1:${socks_port}")
if [ "$status" = "200" ]; then if [ "$status" = "200" ]; then
result=0 result=0
else else
status2=$(test_url "https://www.baidu.com" ${retry_num} ${connect_timeout}) local status2=$(test_url "https://www.baidu.com" ${retry_num} ${connect_timeout})
if [ "$status2" = "200" ]; then if [ "$status2" = "200" ]; then
result=1 result=1
else else
@ -68,7 +68,7 @@ test_node() {
/usr/share/${CONFIG}/app.sh run_socks flag="test_node_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=test_node_${node_id}.json /usr/share/${CONFIG}/app.sh run_socks flag="test_node_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=test_node_${node_id}.json
local curlx="socks5h://127.0.0.1:${_tmp_port}" local curlx="socks5h://127.0.0.1:${_tmp_port}"
sleep 1s sleep 1s
_proxy_status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x $curlx") local _proxy_status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x $curlx")
# 结束 SS 插件进程 # 结束 SS 插件进程
local pid_file="/tmp/etc/${CONFIG}/test_node_${node_id}_plugin.pid" local pid_file="/tmp/etc/${CONFIG}/test_node_${node_id}_plugin.pid"
[ -s "$pid_file" ] && kill -9 "$(head -n 1 "$pid_file")" >/dev/null 2>&1 [ -s "$pid_file" ] && kill -9 "$(head -n 1 "$pid_file")" >/dev/null 2>&1
@ -82,14 +82,14 @@ test_node() {
} }
test_auto_switch() { test_auto_switch() {
flag=$(expr $flag + 1) flag=$((flag + 1))
local b_nodes=$1 local b_nodes=$1
local now_node=$2 local now_node=$2
[ -z "$now_node" ] && { [ -z "$now_node" ] && {
if [ -n "$(/usr/share/${CONFIG}/app.sh get_cache_var "socks_${id}")" ]; then if [ -n "$(/usr/share/${CONFIG}/app.sh get_cache_var "socks_${id}")" ]; then
now_node=$(/usr/share/${CONFIG}/app.sh get_cache_var "socks_${id}") now_node=$(/usr/share/${CONFIG}/app.sh get_cache_var "socks_${id}")
else else
#echolog "自动切换检测:未知错误" #echolog "Socks切换检测:未知错误"
return 1 return 1
fi fi
} }
@ -98,58 +98,59 @@ test_auto_switch() {
main_node=$now_node main_node=$now_node
} }
status=$(test_proxy) local status=$(test_proxy)
if [ "$status" == 2 ]; then if [ "$status" = "2" ]; then
echolog "自动切换检测:无法连接到网络,请检查网络是否正常!" echolog "Socks切换检测:无法连接到网络,请检查网络是否正常!"
return 2 return 2
fi fi
#检测主节点是否能使用 #检测主节点是否能使用
if [ "$restore_switch" == "1" ] && [ -n "$main_node" ] && [ "$now_node" != "$main_node" ]; then if [ "$restore_switch" = "1" ] && [ -n "$main_node" ] && [ "$now_node" != "$main_node" ]; then
test_node ${main_node} test_node ${main_node}
[ $? -eq 0 ] && { [ $? -eq 0 ] && {
#主节点正常,切换到主节点 #主节点正常,切换到主节点
echolog "自动切换检测:${id}主节点【$(config_n_get $main_node type)[$(config_n_get $main_node remarks)]】正常,切换到主节点!" echolog "Socks切换检测:${id}主节点【$(config_n_get $main_node type)[$(config_n_get $main_node remarks)]】正常,切换到主节点!"
/usr/share/${CONFIG}/app.sh socks_node_switch flag=${id} new_node=${main_node} /usr/share/${CONFIG}/app.sh socks_node_switch flag=${id} new_node=${main_node}
[ $? -eq 0 ] && { [ $? -eq 0 ] && {
echolog "自动切换检测:${id}节点切换完毕!" echolog "Socks切换检测:${id}节点切换完毕!"
} }
return 0 return 0
} }
fi fi
if [ "$status" == 0 ]; then if [ "$status" = "0" ]; then
#echolog "自动切换检测:${id}【$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】正常。" #echolog "Socks切换检测:${id}【$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】正常。"
return 0 return 0
elif [ "$status" == 1 ]; then elif [ "$status" = "1" ]; then
echolog "自动切换检测:${id}$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】异常,切换到下一个备用节点检测!" local new_node msg
local new_node if [ "$backup_node_num" -gt 1 ]; then
in_backup_nodes=$(echo $b_nodes | grep $now_node) # 有多个后备节点时
# 判断当前节点是否存在于备用节点列表里 local first_node found node
if [ -z "$in_backup_nodes" ]; then for node in $b_nodes; do
# 如果不存在,设置第一个节点为新的节点 [ -z "$first_node" ] && first_node="$node" # 记录第一个节点
new_node=$(echo $b_nodes | awk -F ' ' '{print $1}') [ "$found" = "1" ] && { new_node="$node"; break; } # 找到当前节点后取下一个
[ "$node" = "$now_node" ] && found=1 # 标记找到当前节点
done
# 如果没找到当前节点,或者当前节点是最后一个,就取第一个节点
[ -z "$new_node" ] && new_node="$first_node"
msg="切换到$([ "$now_node" = "$main_node" ] && echo 备用节点 || echo 下一个备用节点)检测!"
else else
# 如果存在,设置下一个备用节点为新的节点 # 只有一个后备节点时,与主节点轮询
#local count=$(expr $(echo $b_nodes | grep -o ' ' | wc -l) + 1) new_node=$([ "$now_node" = "$main_node" ] && echo "$b_nodes" || echo "$main_node")
local next_node=$(echo $b_nodes | awk -F "$now_node" '{print $2}' | awk -F " " '{print $1}') msg="切换到$([ "$now_node" = "$main_node" ] && echo 备用节点 || echo 主节点)检测!"
if [ -z "$next_node" ]; then
new_node=$(echo $b_nodes | awk -F ' ' '{print $1}')
else
new_node=$next_node
fi
fi fi
echolog "Socks切换检测${id}$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】异常,$msg"
test_node ${new_node} test_node ${new_node}
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
[ "$restore_switch" == "0" ] && { # [ "$restore_switch" = "0" ] && {
uci set $CONFIG.${id}.node=$new_node # uci set $CONFIG.${id}.node=$new_node
[ -z "$(echo $b_nodes | grep $main_node)" ] && uci add_list $CONFIG.${id}.autoswitch_backup_node=$main_node # [ -z "$(echo $b_nodes | grep $main_node)" ] && uci add_list $CONFIG.${id}.autoswitch_backup_node=$main_node
uci commit $CONFIG # uci commit $CONFIG
} # }
echolog "自动切换检测:${id}$(config_n_get $new_node type)[$(config_n_get $new_node remarks)]】正常,切换到此节点!" echolog "Socks切换检测:${id}$(config_n_get $new_node type)[$(config_n_get $new_node remarks)]】正常,切换到此节点!"
/usr/share/${CONFIG}/app.sh socks_node_switch flag=${id} new_node=${new_node} /usr/share/${CONFIG}/app.sh socks_node_switch flag=${id} new_node=${new_node}
[ $? -eq 0 ] && { [ $? -eq 0 ] && {
echolog "自动切换检测:${id}节点切换完毕!" echolog "Socks切换检测:${id}节点切换完毕!"
} }
return 0 return 0
else else
@ -166,12 +167,20 @@ start() {
main_node=$(config_n_get $id node) main_node=$(config_n_get $id node)
socks_port=$(config_n_get $id port 0) socks_port=$(config_n_get $id port 0)
delay=$(config_n_get $id autoswitch_testing_time 30) delay=$(config_n_get $id autoswitch_testing_time 30)
sleep 5s
connect_timeout=$(config_n_get $id autoswitch_connect_timeout 3) connect_timeout=$(config_n_get $id autoswitch_connect_timeout 3)
retry_num=$(config_n_get $id autoswitch_retry_num 1) retry_num=$(config_n_get $id autoswitch_retry_num 1)
restore_switch=$(config_n_get $id autoswitch_restore_switch 0) restore_switch=$(config_n_get $id autoswitch_restore_switch 0)
probe_url=$(config_n_get $id autoswitch_probe_url "https://www.google.com/generate_204") probe_url=$(config_n_get $id autoswitch_probe_url "https://www.google.com/generate_204")
backup_node=$(config_n_get $id autoswitch_backup_node) backup_node=$(config_n_get $id autoswitch_backup_node)
if [ -n "$backup_node" ]; then
backup_node=$(echo "$backup_node" | tr -s ' ' '\n' | uniq | tr -s '\n' ' ')
backup_node_num=$(printf "%s\n" "$backup_node" | wc -w)
if [ "$backup_node_num" -eq 1 ]; then
[ "$main_node" = "$backup_node" ] && return
fi
else
return
fi
while [ -n "$backup_node" ]; do while [ -n "$backup_node" ]; do
[ -f "$LOCK_FILE" ] && { [ -f "$LOCK_FILE" ] && {
sleep 6s sleep 6s
@ -183,7 +192,6 @@ start() {
continue continue
} }
touch $LOCK_FILE touch $LOCK_FILE
backup_node=$(echo $backup_node | tr -s ' ' '\n' | uniq | tr -s '\n' ' ')
test_auto_switch "$backup_node" test_auto_switch "$backup_node"
rm -f $LOCK_FILE rm -f $LOCK_FILE
sleep ${delay} sleep ${delay}
@ -191,4 +199,3 @@ start() {
} }
start $@ start $@

View File

@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall2 PKG_NAME:=luci-app-passwall2
PKG_VERSION:=25.7.15 PKG_VERSION:=25.8.9
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_CONFIG_DEPENDS:= \ PKG_CONFIG_DEPENDS:= \
@ -123,7 +123,7 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server
config PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs config PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs
bool "Include Simple-Obfs (Shadowsocks Plugin)" bool "Include Simple-Obfs (Shadowsocks Plugin)"
select PACKAGE_simple-obfs select PACKAGE_simple-obfs-client
default y default y
config PACKAGE_$(PKG_NAME)_INCLUDE_SingBox config PACKAGE_$(PKG_NAME)_INCLUDE_SingBox

View File

@ -81,6 +81,8 @@ function index()
entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true
entry({"admin", "services", appname, "subscribe_del_node"}, call("subscribe_del_node")).leaf = true entry({"admin", "services", appname, "subscribe_del_node"}, call("subscribe_del_node")).leaf = true
entry({"admin", "services", appname, "subscribe_del_all"}, call("subscribe_del_all")).leaf = true entry({"admin", "services", appname, "subscribe_del_all"}, call("subscribe_del_all")).leaf = true
entry({"admin", "services", appname, "subscribe_manual"}, call("subscribe_manual")).leaf = true
entry({"admin", "services", appname, "subscribe_manual_all"}, call("subscribe_manual_all")).leaf = true
--[[Components update]] --[[Components update]]
entry({"admin", "services", appname, "check_passwall2"}, call("app_check")).leaf = true entry({"admin", "services", appname, "check_passwall2"}, call("app_check")).leaf = true
@ -416,6 +418,27 @@ function delete_select_nodes()
uci:delete(appname, t[".name"], "to_node") uci:delete(appname, t[".name"], "to_node")
uci:delete(appname, t[".name"], "chain_proxy") uci:delete(appname, t[".name"], "chain_proxy")
end end
local list_name = t["urltest_node"] and "urltest_node" or (t["balancing_node"] and "balancing_node")
if list_name then
local nodes = uci:get_list(appname, t[".name"], list_name)
if nodes then
local changed = false
local new_nodes = {}
for _, node in ipairs(nodes) do
if node ~= w then
table.insert(new_nodes, node)
else
changed = true
end
end
if changed then
uci:set_list(appname, t[".name"], list_name, new_nodes)
end
end
end
if t["fallback_node"] == w then
uci:delete(appname, t[".name"], "fallback_node")
end
end) end)
if (uci:get(appname, w, "add_mode") or "0") == "2" then if (uci:get(appname, w, "add_mode") or "0") == "2" then
local add_from = uci:get(appname, w, "add_from") or "" local add_from = uci:get(appname, w, "add_from") or ""
@ -619,3 +642,51 @@ function subscribe_del_all()
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua truncate > /dev/null 2>&1") luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua truncate > /dev/null 2>&1")
http.status(200, "OK") http.status(200, "OK")
end end
function subscribe_manual()
local section = http.formvalue("section") or ""
local current_url = http.formvalue("url") or ""
if section == "" or current_url == "" then
http_write_json({ success = false, msg = "Missing section or URL, skip." })
return
end
local uci_url = api.sh_uci_get(appname, section, "url")
if not uci_url or uci_url == "" then
http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") })
return
end
if uci_url ~= current_url then
api.sh_uci_set(appname, section, "url", current_url, true)
end
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start " .. section .. " manual >/dev/null 2>&1 &")
http_write_json({ success = true, msg = "Subscribe triggered." })
end
function subscribe_manual_all()
local sections = http.formvalue("sections") or ""
local urls = http.formvalue("urls") or ""
if sections == "" or urls == "" then
http_write_json({ success = false, msg = "Missing section or URL, skip." })
return
end
local section_list = util.split(sections, ",")
local url_list = util.split(urls, ",")
-- 检查是否存在未保存配置
for i, section in ipairs(section_list) do
local uci_url = api.sh_uci_get(appname, section, "url")
if not uci_url or uci_url == "" then
http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") })
return
end
end
-- 保存有变动的url
for i, section in ipairs(section_list) do
local current_url = url_list[i] or ""
local uci_url = api.sh_uci_get(appname, section, "url")
if current_url ~= "" and uci_url ~= current_url then
api.sh_uci_set(appname, section, "url", current_url, true)
end
end
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start all manual >/dev/null 2>&1 &")
http_write_json({ success = true, msg = "Subscribe triggered." })
end

View File

@ -419,6 +419,18 @@ o.rmempty = false
o = s2:option(ListValue, "node", translate("Socks Node")) o = s2:option(ListValue, "node", translate("Socks Node"))
o = s2:option(DummyValue, "now_node", translate("Current Node"))
o.rawhtml = true
o.cfgvalue = function(_, n)
local current_node = api.get_cache_var("socks_" .. n)
if current_node then
local node = m:get(current_node)
if node then
return (api.get_node_remarks(node) or ""):gsub("()%[", "%1<br>[")
end
end
end
local n = 1 local n = 1
m.uci:foreach(appname, "socks", function(s) m.uci:foreach(appname, "socks", function(s)
if s[".name"] == section then if s[".name"] == section then

View File

@ -53,6 +53,37 @@ function s.remove(e, t)
m:set(s[".name"], "node", "default") m:set(s[".name"], "node", "default")
end end
end) end)
m.uci:foreach(appname, "nodes", function(s)
if s["preproxy_node"] == t then
m:del(s[".name"], "preproxy_node")
m:del(s[".name"], "chain_proxy")
end
if s["to_node"] == t then
m:del(s[".name"], "to_node")
m:del(s[".name"], "chain_proxy")
end
local list_name = s["urltest_node"] and "urltest_node" or (s["balancing_node"] and "balancing_node")
if list_name then
local nodes = m.uci:get_list(appname, s[".name"], list_name)
if nodes then
local changed = false
local new_nodes = {}
for _, node in ipairs(nodes) do
if node ~= t then
table.insert(new_nodes, node)
else
changed = true
end
end
if changed then
m.uci:set_list(appname, s[".name"], list_name, new_nodes)
end
end
end
if s["fallback_node"] == t then
m:del(s[".name"], "fallback_node")
end
end)
if (m:get(t, "add_mode") or "0") == "2" then if (m:get(t, "add_mode") or "0") == "2" then
local add_from = m:get(t, "add_from") or "" local add_from = m:get(t, "add_from") or ""
if add_from ~= "" then if add_from ~= "" then

View File

@ -51,6 +51,11 @@ if api.is_js_luci() then
end end
end end
m.render = function(self, ...)
Map.render(self, ...)
api.optimize_cbi_ui()
end
-- [[ Subscribe Settings ]]-- -- [[ Subscribe Settings ]]--
s = m:section(TypedSection, "global_subscribe", "") s = m:section(TypedSection, "global_subscribe", "")
s.anonymous = true s.anonymous = true
@ -136,15 +141,15 @@ function o.cfgvalue(self, section)
translate("Delete All Subscribe Node")) translate("Delete All Subscribe Node"))
end end
o = s:option(Button, "_update", translate("Manual subscription All")) o = s:option(DummyValue, "_update", translate("Manual subscription All"))
o.inputstyle = "apply" o.rawhtml = true
function o.write(t, n) o.cfgvalue = function(self, section)
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start > /dev/null 2>&1 &") return string.format([[
m.no_commit = true <button type="button" class="cbi-button cbi-button-apply" onclick="ManualSubscribeAll()">%s</button>]],
luci.http.redirect(api.url("log")) translate("Manual subscription All"))
end end
s = m:section(TypedSection, "subscribe_list", "", "<font color='red'>" .. translate("Please input the subscription url first, save and submit before manual subscription.") .. "</font>") s = m:section(TypedSection, "subscribe_list", "", "<font color='red'>" .. translate("When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically.") .. "</font>")
s.addremove = true s.addremove = true
s.anonymous = true s.anonymous = true
s.sortable = true s.sortable = true
@ -205,12 +210,12 @@ function o.cfgvalue(self, section)
remark, translate("Delete the subscribed node")) remark, translate("Delete the subscribed node"))
end end
o = s:option(Button, "_update", translate("Manual subscription")) o = s:option(DummyValue, "_update", translate("Manual subscription"))
o.inputstyle = "apply" o.rawhtml = true
function o.write(t, n) o.cfgvalue = function(self, section)
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start " .. n .. " > /dev/null 2>&1 &") return string.format([[
m.no_commit = true <button type="button" class="cbi-button cbi-button-apply" onclick="ManualSubscribe('%s')">%s</button>]],
luci.http.redirect(api.url("log")) section, translate("Manual subscription"))
end end
s:append(Template(appname .. "/node_subscribe/js")) s:append(Template(appname .. "/node_subscribe/js"))

View File

@ -9,6 +9,11 @@ if not arg[1] or not m:get(arg[1]) then
luci.http.redirect(m.redirect) luci.http.redirect(m.redirect)
end end
m.render = function(self, ...)
Map.render(self, ...)
api.optimize_cbi_ui()
end
local has_ss = api.is_finded("ss-redir") local has_ss = api.is_finded("ss-redir")
local has_ss_rust = api.is_finded("sslocal") local has_ss_rust = api.is_finded("sslocal")
local has_singbox = api.finded_com("sing-box") local has_singbox = api.finded_com("sing-box")

View File

@ -234,6 +234,9 @@ if has_xray then
end end
if has_singbox then if has_singbox then
local version = api.get_app_version("sing-box"):match("[^v]+")
local version_ge_1_12_0 = api.compare_versions(version, ">=", "1.12.0")
s = m:section(TypedSection, "global_singbox", "Sing-Box " .. translate("Settings")) s = m:section(TypedSection, "global_singbox", "Sing-Box " .. translate("Settings"))
s.anonymous = true s.anonymous = true
s.addremove = false s.addremove = false
@ -243,6 +246,7 @@ if has_singbox then
o.rmempty = false o.rmempty = false
o.description = translate("Override the connection destination address with the sniffed domain.<br />When enabled, traffic will match only by domain, ignoring IP rules.<br />If using shunt nodes, configure the domain shunt rules correctly.") o.description = translate("Override the connection destination address with the sniffed domain.<br />When enabled, traffic will match only by domain, ignoring IP rules.<br />If using shunt nodes, configure the domain shunt rules correctly.")
if not version_ge_1_12_0 then
o = s:option(Value, "geoip_path", translate("Custom geoip Path")) o = s:option(Value, "geoip_path", translate("Custom geoip Path"))
o.default = "/usr/share/singbox/geoip.db" o.default = "/usr/share/singbox/geoip.db"
o.rmempty = false o.rmempty = false
@ -281,4 +285,15 @@ if has_singbox then
end end
end end
if version_ge_1_12_0 then
o = s:option(Flag, "record_fragment", "TLS Record " .. translate("Fragment"),
translate("Split handshake data into multiple TLS records for better censorship evasion. Low overhead. Recommended to enable first."))
o.default = 0
o = s:option(Flag, "fragment", "TLS TCP " .. translate("Fragment"),
translate("Split handshake into multiple TCP segments. Enhances obfuscation. May increase delay. Use only if needed."))
o.default = 0
end
end
return m return m

View File

@ -136,6 +136,11 @@ domain_list.validate = function(self, value)
flag = 0 flag = 0
elseif host:find("ext:") and host:find("ext:") == 1 then elseif host:find("ext:") and host:find("ext:") == 1 then
flag = 0 flag = 0
elseif host:find("rule-set:", 1, true) == 1 or host:find("rs:") == 1 then
local w = host:sub(host:find(":") + 1, #host)
if w:find("local:") == 1 or w:find("remote:") == 1 then
flag = 0
end
elseif host:find("#") and host:find("#") == 1 then elseif host:find("#") and host:find("#") == 1 then
flag = 0 flag = 0
end end
@ -147,13 +152,21 @@ domain_list.validate = function(self, value)
end end
return value return value
end end
domain_list.description = "<br /><ul><li>" .. translate("Plaintext: If this string matches any part of the targeting domain, this rule takes effet. Example: rule 'sina.com' matches targeting domain 'sina.com', 'sina.com.cn' and 'www.sina.com', but not 'sina.cn'.") domain_list.description = "<br /><ul>"
.. "</li><li>" .. translate("Regular expression: Begining with 'regexp:', the rest is a regular expression. When the regexp matches targeting domain, this rule takes effect. Example: rule 'regexp:\\.goo.*\\.com$' matches 'www.google.com' and 'fonts.googleapis.com', but not 'google.com'.") .. "<li>" .. translate("Plaintext: If this string matches any part of the targeting domain, this rule takes effet. Example: rule 'sina.com' matches targeting domain 'sina.com', 'sina.com.cn' and 'www.sina.com', but not 'sina.cn'.") .. "</li>"
.. "</li><li>" .. translate("Subdomain (recommended): Begining with 'domain:' and the rest is a domain. When the targeting domain is exactly the value, or is a subdomain of the value, this rule takes effect. Example: rule 'domain:v2ray.com' matches 'www.v2ray.com', 'v2ray.com', but not 'xv2ray.com'.") .. "<li>" .. translate("Regular expression: Begining with 'regexp:', the rest is a regular expression. When the regexp matches targeting domain, this rule takes effect. Example: rule 'regexp:\\.goo.*\\.com$' matches 'www.google.com' and 'fonts.googleapis.com', but not 'google.com'.") .. "</li>"
.. "</li><li>" .. translate("Full domain: Begining with 'full:' and the rest is a domain. When the targeting domain is exactly the value, the rule takes effect. Example: rule 'domain:v2ray.com' matches 'v2ray.com', but not 'www.v2ray.com'.") .. "<li>" .. translate("Subdomain (recommended): Begining with 'domain:' and the rest is a domain. When the targeting domain is exactly the value, or is a subdomain of the value, this rule takes effect. Example: rule 'domain:v2ray.com' matches 'www.v2ray.com', 'v2ray.com', but not 'xv2ray.com'.") .. "</li>"
.. "</li><li>" .. translate("Pre-defined domain list: Begining with 'geosite:' and the rest is a name, such as geosite:google or geosite:cn.") .. "<li>" .. translate("Full domain: Begining with 'full:' and the rest is a domain. When the targeting domain is exactly the value, the rule takes effect. Example: rule 'domain:v2ray.com' matches 'v2ray.com', but not 'www.v2ray.com'.") .. "</li>"
.. "</li><li>" .. translate("Annotation: Begining with #") .. "<li>" .. translate("Pre-defined domain list: Begining with 'geosite:' and the rest is a name, such as geosite:google or geosite:cn.") .. "</li>"
.. "</li></ul>" .. "<li>"
.. translate("Sing-Box rule-set: Begining with 'rule-set:remote:' or 'rule-set:local:'")
.. "<ul>"
.. "<li>" .. translate("Such as:") .. "'rule-set:remote:https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-cn.srs'" .. "</li>"
.. "<li>" .. translate("Such as:") .. "'rule-set:local:/usr/share/sing-box/geosite-cn.srs'" .. "</li>"
.. "</ul>"
.. "</li>"
.. "<li>" .. translate("Annotation: Begining with #") .. "</li>"
.. "</ul>"
ip_list = s:option(TextValue, "ip_list", "IP") ip_list = s:option(TextValue, "ip_list", "IP")
ip_list.rows = 10 ip_list.rows = 10
ip_list.wrap = "off" ip_list.wrap = "off"
@ -164,6 +177,11 @@ ip_list.validate = function(self, value)
for index, ipmask in ipairs(ipmasks) do for index, ipmask in ipairs(ipmasks) do
if ipmask:find("geoip:") and ipmask:find("geoip:") == 1 and not ipmask:find("%s") then if ipmask:find("geoip:") and ipmask:find("geoip:") == 1 and not ipmask:find("%s") then
elseif ipmask:find("ext:") and ipmask:find("ext:") == 1 and not ipmask:find("%s") then elseif ipmask:find("ext:") and ipmask:find("ext:") == 1 and not ipmask:find("%s") then
elseif ipmask:find("rule-set:", 1, true) == 1 or ipmask:find("rs:") == 1 then
local w = ipmask:sub(ipmask:find(":") + 1, #ipmask)
if w:find("local:") == 1 or w:find("remote:") == 1 then
flag = 0
end
elseif ipmask:find("#") and ipmask:find("#") == 1 then elseif ipmask:find("#") and ipmask:find("#") == 1 then
else else
if not (datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask)) then if not (datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask)) then
@ -173,10 +191,18 @@ ip_list.validate = function(self, value)
end end
return value return value
end end
ip_list.description = "<br /><ul><li>" .. translate("IP: such as '127.0.0.1'.") ip_list.description = "<br /><ul>"
.. "</li><li>" .. translate("CIDR: such as '127.0.0.0/8'.") .. "<li>" .. translate("IP: such as '127.0.0.1'.") .. "</li>"
.. "</li><li>" .. translate("GeoIP: such as 'geoip:cn'. It begins with geoip: (lower case) and followed by two letter of country code.") .. "<li>" .. translate("CIDR: such as '127.0.0.0/8'.") .. "</li>"
.. "</li><li>" .. translate("Annotation: Begining with #") .. "<li>" .. translate("GeoIP: such as 'geoip:cn'. It begins with geoip: (lower case) and followed by two letter of country code.") .. "</li>"
.. "</li></ul>" .. "<li>"
.. translate("Sing-Box rule-set: Begining with 'rule-set:remote:' or 'rule-set:local:'")
.. "<ul>"
.. "<li>" .. translate("Such as:") .. "'rule-set:remote:https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs'" .. "</li>"
.. "<li>" .. translate("Such as:") .. "'rule-set:local:/usr/share/sing-box/geoip-cn.srs'" .. "</li>"
.. "</ul>"
.. "</li>"
.. "<li>" .. translate("Annotation: Begining with #") .. "</li>"
.. "</ul>"
return m return m

View File

@ -135,7 +135,7 @@ if api.compare_versions(xray_version, ">=", "1.8.10") then
end end
-- 探测地址 -- 探测地址
local ucpu = s:option(Flag, _n("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL.")) local ucpu = s:option(Flag, _n("useCustomProbeUrl"), translate("Use Custom Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
ucpu:depends({ [_n("balancingStrategy")] = "leastPing" }) ucpu:depends({ [_n("balancingStrategy")] = "leastPing" })
ucpu:depends({ [_n("balancingStrategy")] = "leastLoad" }) ucpu:depends({ [_n("balancingStrategy")] = "leastLoad" })
@ -379,6 +379,19 @@ o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translat
o.default = "0" o.default = "0"
o:depends({ [_n("tls")] = true, [_n("reality")] = false }) o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o = s:option(Flag, _n("ech"), translate("ECH"))
o.default = "0"
o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
o = s:option(TextValue, _n("ech_config"), translate("ECH Config"))
o.default = ""
o.rows = 5
o.wrap = "soft"
o:depends({ [_n("ech")] = true })
o.validate = function(self, value)
return api.trim(value:gsub("[\r\n]", ""))
end
-- [[ REALITY部分 ]] -- -- [[ REALITY部分 ]] --
o = s:option(Value, _n("reality_publicKey"), translate("Public Key")) o = s:option(Value, _n("reality_publicKey"), translate("Public Key"))
o:depends({ [_n("tls")] = true, [_n("reality")] = true }) o:depends({ [_n("tls")] = true, [_n("reality")] = true })
@ -409,6 +422,19 @@ o.default = "chrome"
o:depends({ [_n("tls")] = true, [_n("utls")] = true }) o:depends({ [_n("tls")] = true, [_n("utls")] = true })
o:depends({ [_n("tls")] = true, [_n("reality")] = true }) o:depends({ [_n("tls")] = true, [_n("reality")] = true })
o = s:option(Flag, _n("use_mldsa65Verify"), translate("ML-DSA-65"))
o.default = "0"
o:depends({ [_n("tls")] = true, [_n("reality")] = true })
o = s:option(TextValue, _n("reality_mldsa65Verify"), "ML-DSA-65 " .. translate("Public key"))
o.default = ""
o.rows = 5
o.wrap = "soft"
o:depends({ [_n("use_mldsa65Verify")] = true })
o.validate = function(self, value)
return api.trim(value:gsub("[\r\n]", ""))
end
o = s:option(ListValue, _n("transport"), translate("Transport")) o = s:option(ListValue, _n("transport"), translate("Transport"))
o:value("raw", "RAW (TCP)") o:value("raw", "RAW (TCP)")
o:value("mkcp", "mKCP") o:value("mkcp", "mKCP")

View File

@ -43,17 +43,29 @@ o = s:option(ListValue, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), t
o:value("false") o:value("false")
o:value("true") o:value("true")
o = s:option(ListValue, _n("plugin"), translate("plugin")) o = s:option(Flag, _n("plugin_enabled"), translate("plugin"))
o.default = 0
o = s:option(Value, _n("plugin"), "SIP003 " .. translate("plugin"), translate("Supports custom SIP003 plugins, Make sure the plugin is installed."))
o.default = "none"
o:value("none", translate("none")) o:value("none", translate("none"))
if api.is_finded("xray-plugin") then o:value("xray-plugin") end if api.is_finded("xray-plugin") then o:value("xray-plugin") end
if api.is_finded("v2ray-plugin") then o:value("v2ray-plugin") end if api.is_finded("v2ray-plugin") then o:value("v2ray-plugin") end
if api.is_finded("obfs-local") then o:value("obfs-local") end if api.is_finded("obfs-local") then o:value("obfs-local") end
if api.is_finded("shadow-tls") then o:value("shadow-tls") end if api.is_finded("shadow-tls") then o:value("shadow-tls") end
o:depends({ [_n("plugin_enabled")] = true })
o.validate = function(self, value, t)
if value and value ~= "" and value ~= "none" then
if not api.is_finded(value) then
return nil, value .. ": " .. translate("Can't find this file!")
else
return value
end
end
return nil
end
o = s:option(Value, _n("plugin_opts"), translate("opts")) o = s:option(Value, _n("plugin_opts"), translate("opts"))
o:depends({ [_n("plugin")] = "xray-plugin"}) o:depends({ [_n("plugin_enabled")] = true })
o:depends({ [_n("plugin")] = "v2ray-plugin"})
o:depends({ [_n("plugin")] = "obfs-local"})
o:depends({ [_n("plugin")] = "shadow-tls"})
api.luci_types(arg[1], m, s, type_name, option_prefix) api.luci_types(arg[1], m, s, type_name, option_prefix)

View File

@ -44,15 +44,18 @@ o = s:option(ListValue, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), t
o:value("false") o:value("false")
o:value("true") o:value("true")
o = s:option(ListValue, _n("plugin"), translate("plugin")) o = s:option(Flag, _n("plugin_enabled"), translate("plugin"))
o.default = 0
o = s:option(ListValue, _n("plugin"), "SIP003 " .. translate("plugin"))
o.default = "none"
o:value("none", translate("none")) o:value("none", translate("none"))
if api.is_finded("xray-plugin") then o:value("xray-plugin") end if api.is_finded("xray-plugin") then o:value("xray-plugin") end
if api.is_finded("v2ray-plugin") then o:value("v2ray-plugin") end if api.is_finded("v2ray-plugin") then o:value("v2ray-plugin") end
if api.is_finded("obfs-local") then o:value("obfs-local") end if api.is_finded("obfs-local") then o:value("obfs-local") end
o:depends({ [_n("plugin_enabled")] = true })
o = s:option(Value, _n("plugin_opts"), translate("opts")) o = s:option(Value, _n("plugin_opts"), translate("opts"))
o:depends({ [_n("plugin")] = "xray-plugin"}) o:depends({ [_n("plugin_enabled")] = true })
o:depends({ [_n("plugin")] = "v2ray-plugin"})
o:depends({ [_n("plugin")] = "obfs-local"})
api.luci_types(arg[1], m, s, type_name, option_prefix) api.luci_types(arg[1], m, s, type_name, option_prefix)

View File

@ -187,6 +187,19 @@ o:value("h2")
o:value("http/1.1") o:value("http/1.1")
o:depends({ [_n("tls")] = true }) o:depends({ [_n("tls")] = true })
o = s:option(Flag, _n("use_mldsa65Seed"), translate("ML-DSA-65"))
o.default = "0"
o:depends({ [_n("reality")] = true })
o = s:option(TextValue, _n("reality_mldsa65Seed"), "ML-DSA-65 " .. translate("Private Key"))
o.default = ""
o.rows = 5
o.wrap = "soft"
o:depends({ [_n("use_mldsa65Seed")] = true })
o.validate = function(self, value)
return api.trim(value:gsub("[\r\n]", ""))
end
-- o = s:option(Value, _n("minversion"), translate("minversion")) -- o = s:option(Value, _n("minversion"), translate("minversion"))
-- o.default = "1.3" -- o.default = "1.3"
-- o:value("1.3") -- o:value("1.3")
@ -223,6 +236,19 @@ o.validate = function(self, value, t)
return nil return nil
end end
o = s:option(Flag, _n("ech"), translate("ECH"))
o.default = "0"
o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
o = s:option(TextValue, _n("ech_key"), translate("ECH Key"))
o.default = ""
o.rows = 5
o.wrap = "soft"
o:depends({ [_n("ech")] = true })
o.validate = function(self, value)
return api.trim(value:gsub("[\r\n]", ""))
end
o = s:option(ListValue, _n("transport"), translate("Transport")) o = s:option(ListValue, _n("transport"), translate("Transport"))
o:value("raw", "RAW") o:value("raw", "RAW")
o:value("mkcp", "mKCP") o:value("mkcp", "mKCP")

View File

@ -55,7 +55,8 @@ function uci_save(cursor, config, commit, apply)
end end
function sh_uci_get(config, section, option) function sh_uci_get(config, section, option)
exec_call(string.format("uci -q get %s.%s.%s", config, section, option)) local _, val = exec_call(string.format("uci -q get %s.%s.%s", config, section, option))
return val
end end
function sh_uci_set(config, section, option, val, commit) function sh_uci_set(config, section, option, val, commit)
@ -1208,6 +1209,9 @@ function is_js_luci()
end end
function set_apply_on_parse(map) function set_apply_on_parse(map)
if not map then
return
end
if is_js_luci() == true then if is_js_luci() == true then
map.apply_on_parse = false map.apply_on_parse = false
map.on_after_apply = function(self) map.on_after_apply = function(self)
@ -1217,6 +1221,10 @@ function set_apply_on_parse(map)
end end
end end
end end
map.render = function(self, ...)
getmetatable(self).__index.render(self, ...) -- 保持原渲染流程
optimize_cbi_ui()
end
end end
function luci_types(id, m, s, type_name, option_prefix) function luci_types(id, m, s, type_name, option_prefix)
@ -1320,3 +1328,27 @@ function format_go_time(input)
if s > 0 or result == "" then result = result .. s .. "s" end if s > 0 or result == "" then result = result .. s .. "s" end
return result return result
end end
function optimize_cbi_ui()
luci.http.write([[
<script type="text/javascript">
//
document.querySelectorAll("input.btn.cbi-button.cbi-button-up").forEach(function(btn) {
btn.value = "]] .. i18n.translate("Move up") .. [[";
});
document.querySelectorAll("input.btn.cbi-button.cbi-button-down").forEach(function(btn) {
btn.value = "]] .. i18n.translate("Move down") .. [[";
});
//
document.querySelectorAll("div.cbi-value-description").forEach(function(descDiv) {
var prev = descDiv.previousSibling;
while (prev && prev.nodeType === Node.TEXT_NODE && prev.textContent.trim() === "") {
prev = prev.previousSibling;
}
if (prev && prev.nodeType === Node.ELEMENT_NODE && prev.tagName === "BR") {
prev.remove();
}
});
</script>
]])
end

View File

@ -1,11 +1,13 @@
local _M = {} local _M = {}
local function gh_release_url(self) local function gh_release_url(self)
return "https://api.github.com/repos/" .. self.repo .. "/releases/latest" --return "https://api.github.com/repos/" .. self.repo .. "/releases/latest"
return "https://github.com/xiaorouji/openwrt-passwall-packages/releases/download/api-cache/" .. string.lower(self.name) .. "-release-api.json"
end end
local function gh_pre_release_url(self) local function gh_pre_release_url(self)
return "https://api.github.com/repos/" .. self.repo .. "/releases?per_page=1" --return "https://api.github.com/repos/" .. self.repo .. "/releases?per_page=1"
return "https://github.com/xiaorouji/openwrt-passwall-packages/releases/download/api-cache/" .. string.lower(self.name) .. "-pre-release-api.json"
end end
_M.hysteria = { _M.hysteria = {

View File

@ -28,6 +28,7 @@ function gen_config_server(node)
return config return config
end end
local plugin_sh, plugin_bin
function gen_config(var) function gen_config(var)
local node_id = var["-node"] local node_id = var["-node"]
@ -55,6 +56,13 @@ function gen_config(var)
end end
local server = server_host local server = server_host
local plugin_file
if node.plugin and node.plugin ~= "" and node.plugin ~= "none" then
plugin_sh = var["-plugin_sh"] or ""
plugin_file = (plugin_sh ~="") and plugin_sh or node.plugin
plugin_bin = node.plugin
end
local config = { local config = {
server = server, server = server,
server_port = tonumber(server_port), server_port = tonumber(server_port),
@ -68,10 +76,8 @@ function gen_config(var)
} }
if node.type == "SS" then if node.type == "SS" then
if node.plugin and node.plugin ~= "none" then config.plugin = plugin_file or nil
config.plugin = node.plugin config.plugin_opts = (plugin_file) and node.plugin_opts or nil
config.plugin_opts = node.plugin_opts or nil
end
config.mode = mode config.mode = mode
elseif node.type == "SSR" then elseif node.type == "SSR" then
config.protocol = node.protocol config.protocol = node.protocol
@ -87,8 +93,8 @@ function gen_config(var)
method = node.method, method = node.method,
password = node.password, password = node.password,
timeout = tonumber(node.timeout), timeout = tonumber(node.timeout),
plugin = (node.plugin and node.plugin ~= "none") and node.plugin or nil, plugin = plugin_file or nil,
plugin_opts = (node.plugin and node.plugin ~= "none") and node.plugin_opts or nil plugin_opts = (plugin_file) and node.plugin_opts or nil
} }
}, },
locals = {}, locals = {},
@ -119,5 +125,15 @@ if arg[1] then
local func =_G[arg[1]] local func =_G[arg[1]]
if func then if func then
print(func(api.get_function_args(arg))) print(func(api.get_function_args(arg)))
if plugin_sh and plugin_sh ~="" and plugin_bin then
local f = io.open(plugin_sh, "w")
f:write("#!/bin/sh\n")
f:write("export PATH=/usr/sbin:/usr/bin:/sbin:/bin:/root/bin:$PATH\n")
f:write(plugin_bin .. " $@ &\n")
f:write("echo $! > " .. plugin_sh:gsub("%.sh$", ".pid") .. "\n")
f:write("wait\n")
f:close()
luci.sys.call("chmod +x " .. plugin_sh)
end
end end
end end

View File

@ -8,8 +8,9 @@ local fs = api.fs
local CACHE_PATH = api.CACHE_PATH local CACHE_PATH = api.CACHE_PATH
local split = api.split local split = api.split
local local_version = api.get_app_version("sing-box") local local_version = api.get_app_version("sing-box"):match("[^v]+")
local version_ge_1_11_0 = api.compare_versions(local_version:match("[^v]+"), ">=", "1.11.0") local version_ge_1_11_0 = api.compare_versions(local_version, ">=", "1.11.0")
local version_ge_1_12_0 = api.compare_versions(local_version, ">=", "1.12.0")
local new_port local new_port
@ -31,9 +32,13 @@ function gen_outbound(flag, node, tag, proxy_table)
end end
local proxy_tag = nil local proxy_tag = nil
local fragment = nil
local record_fragment = nil
local run_socks_instance = true local run_socks_instance = true
if proxy_table ~= nil and type(proxy_table) == "table" then if proxy_table ~= nil and type(proxy_table) == "table" then
proxy_tag = proxy_table.tag or nil proxy_tag = proxy_table.tag or nil
fragment = proxy_table.fragment or nil
record_fragment = proxy_table.record_fragment or nil
run_socks_instance = proxy_table.run_socks_instance run_socks_instance = proxy_table.run_socks_instance
end end
@ -98,6 +103,8 @@ function gen_outbound(flag, node, tag, proxy_table)
alpn = alpn, --支持的应用层协议协商列表,按优先顺序排列。如果两个对等点都支持 ALPN则选择的协议将是此列表中的一个如果没有相互支持的协议则连接将失败。 alpn = alpn, --支持的应用层协议协商列表,按优先顺序排列。如果两个对等点都支持 ALPN则选择的协议将是此列表中的一个如果没有相互支持的协议则连接将失败。
--min_version = "1.2", --min_version = "1.2",
--max_version = "1.3", --max_version = "1.3",
fragment = fragment,
record_fragment = record_fragment,
ech = { ech = {
enabled = (node.ech == "1") and true or false, enabled = (node.ech == "1") and true or false,
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {}, config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {},
@ -327,6 +334,8 @@ function gen_outbound(flag, node, tag, proxy_table)
enabled = true, enabled = true,
server_name = node.tls_serverName, server_name = node.tls_serverName,
insecure = (node.tls_allowInsecure == "1") and true or false, insecure = (node.tls_allowInsecure == "1") and true or false,
fragment = fragment,
record_fragment = record_fragment,
alpn = (node.hysteria_alpn and node.hysteria_alpn ~= "") and { alpn = (node.hysteria_alpn and node.hysteria_alpn ~= "") and {
node.hysteria_alpn node.hysteria_alpn
} or nil, } or nil,
@ -361,6 +370,8 @@ function gen_outbound(flag, node, tag, proxy_table)
enabled = true, enabled = true,
server_name = node.tls_serverName, server_name = node.tls_serverName,
insecure = (node.tls_allowInsecure == "1") and true or false, insecure = (node.tls_allowInsecure == "1") and true or false,
fragment = fragment,
record_fragment = record_fragment,
alpn = (node.tuic_alpn and node.tuic_alpn ~= "") and { alpn = (node.tuic_alpn and node.tuic_alpn ~= "") and {
node.tuic_alpn node.tuic_alpn
} or nil, } or nil,
@ -398,6 +409,8 @@ function gen_outbound(flag, node, tag, proxy_table)
enabled = true, enabled = true,
server_name = node.tls_serverName, server_name = node.tls_serverName,
insecure = (node.tls_allowInsecure == "1") and true or false, insecure = (node.tls_allowInsecure == "1") and true or false,
fragment = fragment,
record_fragment = record_fragment,
ech = { ech = {
enabled = (node.ech == "1") and true or false, enabled = (node.ech == "1") and true or false,
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {}, config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {},
@ -856,6 +869,7 @@ function gen_config(var)
local dns = nil local dns = nil
local inbounds = {} local inbounds = {}
local outbounds = {} local outbounds = {}
local rule_set_table = {}
local COMMON = {} local COMMON = {}
local CACHE_TEXT_FILE = CACHE_PATH .. "/cache_" .. flag .. ".txt" local CACHE_TEXT_FILE = CACHE_PATH .. "/cache_" .. flag .. ".txt"
@ -878,6 +892,45 @@ function gen_config(var)
local experimental = nil local experimental = nil
function rule_set_add(w)
local result = nil
if w and #w > 0 then
if w:find("local:") == 1 or w:find("remote:") == 1 then
local _type = w:sub(1, w:find(":") - 1)
w = w:sub(w:find(":") + 1, #w)
local format = nil
local filename = w:sub(-w:reverse():find("/") + 1)
local suffix = ""
local find_doc = filename:reverse():find("%.")
if find_doc then
suffix = filename:sub(-find_doc + 1)
end
if suffix == "srs" then
format = "binary"
elseif suffix == "json" then
format = "source"
end
if format then
local rule_set_tag = filename:sub(1, filename:find("%.") - 1)
if not rule_set_table[rule_set_tag] then
local t = {
type = _type,
tag = rule_set_tag,
format = format,
path = format == "source" and w or nil,
url = format == "binary" and w or nil,
--download_detour = format == "binary" and "",
--update_interval = format == "binary" and "",
}
rule_set_table[rule_set_tag] = t
result = t
end
end
end
end
return result
end
local node = nil local node = nil
if node_id then if node_id then
node = uci:get_all(appname, node_id) node = uci:get_all(appname, node_id)
@ -978,7 +1031,7 @@ function gen_config(var)
end end
if is_new_ut_node then if is_new_ut_node then
local ut_node = uci:get_all(appname, ut_node_id) local ut_node = uci:get_all(appname, ut_node_id)
local outbound = gen_outbound(flag, ut_node, ut_node_tag, { run_socks_instance = not no_run }) local outbound = gen_outbound(flag, ut_node, ut_node_tag, { fragment = singbox_settings.fragment == "1" or nil, record_fragment = singbox_settings.record_fragment == "1" or nil, run_socks_instance = not no_run })
if outbound then if outbound then
outbound.tag = outbound.tag .. ":" .. ut_node.remarks outbound.tag = outbound.tag .. ":" .. ut_node.remarks
table.insert(outbounds, outbound) table.insert(outbounds, outbound)
@ -1144,8 +1197,19 @@ function gen_config(var)
}) })
end end
end end
local proxy_table = {
local _outbound = gen_outbound(flag, _node, rule_name, { tag = use_proxy and preproxy_tag or nil, run_socks_instance = not no_run}) tag = use_proxy and preproxy_tag or nil,
run_socks_instance = not no_run
}
if not proxy_table.tag then
if singbox_settings.fragment == "1" then
proxy_table.fragment = true
end
if singbox_settings.record_fragment == "1" then
proxy_table.record_fragment = true
end
end
local _outbound = gen_outbound(flag, _node, rule_name, proxy_table)
if _outbound then if _outbound then
_outbound.tag = _outbound.tag .. ":" .. _node.remarks _outbound.tag = _outbound.tag .. ":" .. _node.remarks
rule_outboundTag, last_insert_outbound = set_outbound_detour(_node, _outbound, outbounds, rule_name) rule_outboundTag, last_insert_outbound = set_outbound_detour(_node, _outbound, outbounds, rule_name)
@ -1274,6 +1338,8 @@ function gen_config(var)
rule.port_range = #port_range > 0 and port_range or nil rule.port_range = #port_range > 0 and port_range or nil
end end
local rule_set = {}
if e.domain_list then if e.domain_list then
local domain_table = { local domain_table = {
outboundTag = outboundTag, outboundTag = outboundTag,
@ -1282,6 +1348,7 @@ function gen_config(var)
domain_keyword = {}, domain_keyword = {},
domain_regex = {}, domain_regex = {},
geosite = {}, geosite = {},
rule_set = {},
} }
string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w) string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w)
if w:find("#") == 1 then return end if w:find("#") == 1 then return end
@ -1293,6 +1360,13 @@ function gen_config(var)
table.insert(domain_table.domain, w:sub(1 + #"full:")) table.insert(domain_table.domain, w:sub(1 + #"full:"))
elseif w:find("domain:") == 1 then elseif w:find("domain:") == 1 then
table.insert(domain_table.domain_suffix, w:sub(1 + #"domain:")) table.insert(domain_table.domain_suffix, w:sub(1 + #"domain:"))
elseif w:find("rule-set:", 1, true) == 1 or w:find("rs:") == 1 then
w = w:sub(w:find(":") + 1, #w)
local t = rule_set_add(w)
if t then
table.insert(rule_set, t.tag)
table.insert(domain_table.rule_set, t.tag)
end
else else
table.insert(domain_table.domain_keyword, w) table.insert(domain_table.domain_keyword, w)
end end
@ -1302,6 +1376,7 @@ function gen_config(var)
rule.domain_keyword = #domain_table.domain_keyword > 0 and domain_table.domain_keyword or nil rule.domain_keyword = #domain_table.domain_keyword > 0 and domain_table.domain_keyword or nil
rule.domain_regex = #domain_table.domain_regex > 0 and domain_table.domain_regex or nil rule.domain_regex = #domain_table.domain_regex > 0 and domain_table.domain_regex or nil
rule.geosite = #domain_table.geosite > 0 and domain_table.geosite or nil rule.geosite = #domain_table.geosite > 0 and domain_table.geosite or nil
rule.rule_set = #domain_table.rule_set > 0 and domain_table.rule_set or nil
if outboundTag then if outboundTag then
table.insert(dns_domain_rules, api.clone(domain_table)) table.insert(dns_domain_rules, api.clone(domain_table))
@ -1315,6 +1390,12 @@ function gen_config(var)
if w:find("#") == 1 then return end if w:find("#") == 1 then return end
if w:find("geoip:") == 1 then if w:find("geoip:") == 1 then
table.insert(geoip, w:sub(1 + #"geoip:")) table.insert(geoip, w:sub(1 + #"geoip:"))
elseif w:find("rule-set:", 1, true) == 1 or w:find("rs:") == 1 then
w = w:sub(w:find(":") + 1, #w)
local t = rule_set_add(w)
if t then
table.insert(rule_set, t.tag)
end
else else
table.insert(ip_cidr, w) table.insert(ip_cidr, w)
end end
@ -1323,6 +1404,7 @@ function gen_config(var)
rule.ip_cidr = #ip_cidr > 0 and ip_cidr or nil rule.ip_cidr = #ip_cidr > 0 and ip_cidr or nil
rule.geoip = #geoip > 0 and geoip or nil rule.geoip = #geoip > 0 and geoip or nil
end end
rule.rule_set = #rule_set > 0 and rule_set or nil
table.insert(rules, rule) table.insert(rules, rule)
end end
@ -1348,7 +1430,7 @@ function gen_config(var)
sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.iface)) sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.iface))
end end
else else
local outbound = gen_outbound(flag, node, nil, { run_socks_instance = not no_run }) local outbound = gen_outbound(flag, node, nil, { fragment = singbox_settings.fragment == "1" or nil, record_fragment = singbox_settings.record_fragment == "1" or nil, run_socks_instance = not no_run })
if outbound then if outbound then
outbound.tag = outbound.tag .. ":" .. node.remarks outbound.tag = outbound.tag .. ":" .. node.remarks
COMMON.default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds) COMMON.default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds)
@ -1488,7 +1570,7 @@ function gen_config(var)
--按分流顺序DNS --按分流顺序DNS
if dns_domain_rules and #dns_domain_rules > 0 then if dns_domain_rules and #dns_domain_rules > 0 then
for index, value in ipairs(dns_domain_rules) do for index, value in ipairs(dns_domain_rules) do
if value.outboundTag and (value.domain or value.domain_suffix or value.domain_keyword or value.domain_regex or value.geosite) then if value.outboundTag and (value.domain or value.domain_suffix or value.domain_keyword or value.domain_regex or value.geosite or value.rule_set) then
local dns_rule = { local dns_rule = {
server = value.outboundTag, server = value.outboundTag,
domain = (value.domain and #value.domain > 0) and value.domain or nil, domain = (value.domain and #value.domain > 0) and value.domain or nil,
@ -1496,6 +1578,7 @@ function gen_config(var)
domain_keyword = (value.domain_keyword and #value.domain_keyword > 0) and value.domain_keyword or nil, domain_keyword = (value.domain_keyword and #value.domain_keyword > 0) and value.domain_keyword or nil,
domain_regex = (value.domain_regex and #value.domain_regex > 0) and value.domain_regex or nil, domain_regex = (value.domain_regex and #value.domain_regex > 0) and value.domain_regex or nil,
geosite = (value.geosite and #value.geosite > 0) and value.geosite or nil, geosite = (value.geosite and #value.geosite > 0) and value.geosite or nil,
rule_set = (value.rule_set and #value.rule_set > 0) and value.rule_set or nil,
disable_cache = false, disable_cache = false,
} }
if value.outboundTag ~= "block" and value.outboundTag ~= "direct" then if value.outboundTag ~= "block" and value.outboundTag ~= "direct" then
@ -1590,6 +1673,13 @@ function gen_config(var)
end end
end end
if next(rule_set_table) then
route.rule_set = {}
for k, v in pairs(rule_set_table) do
table.insert(route.rule_set, v)
end
end
if inbounds or outbounds then if inbounds or outbounds then
local config = { local config = {
log = { log = {
@ -1713,6 +1803,24 @@ function gen_config(var)
}) })
end end
end end
if version_ge_1_12_0 then
-- removed geo in version 1.12
config.route.geoip = nil
config.route.geosite = nil
if config.route and config.route.rules then
for i = #config.route.rules, 1, -1 do
local value = config.route.rules[i]
value.geoip = nil
value.geosite = nil
end
end
if config.dns and config.dns.rules then
for i = #config.dns.rules, 1, -1 do
local value = config.dns.rules[i]
value.geosite = nil
end
end
end
return jsonc.stringify(config, 1) return jsonc.stringify(config, 1)
end end
end end

View File

@ -154,14 +154,16 @@ function gen_outbound(flag, node, tag, proxy_table)
tlsSettings = (node.stream_security == "tls") and { tlsSettings = (node.stream_security == "tls") and {
serverName = node.tls_serverName, serverName = node.tls_serverName,
allowInsecure = (node.tls_allowInsecure == "1") and true or false, allowInsecure = (node.tls_allowInsecure == "1") and true or false,
fingerprint = (node.type == "Xray" and node.utls == "1" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil fingerprint = (node.type == "Xray" and node.utls == "1" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil,
echConfigList = (node.ech == "1") and node.ech_config or nil
} or nil, } or nil,
realitySettings = (node.stream_security == "reality") and { realitySettings = (node.stream_security == "reality") and {
serverName = node.tls_serverName, serverName = node.tls_serverName,
publicKey = node.reality_publicKey, publicKey = node.reality_publicKey,
shortId = node.reality_shortId or "", shortId = node.reality_shortId or "",
spiderX = node.reality_spiderX or "/", spiderX = node.reality_spiderX or "/",
fingerprint = (node.type == "Xray" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or "chrome" fingerprint = (node.type == "Xray" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or "chrome",
mldsa65Verify = (node.use_mldsa65Verify == "1") and node.reality_mldsa65Verify or nil
} or nil, } or nil,
rawSettings = ((node.transport == "raw" or node.transport == "tcp") and node.protocol ~= "socks" and (node.tcp_guise and node.tcp_guise ~= "none")) and { rawSettings = ((node.transport == "raw" or node.transport == "tcp") and node.protocol ~= "socks" and (node.tcp_guise and node.tcp_guise ~= "none")) and {
header = { header = {
@ -460,7 +462,8 @@ function gen_config_server(node)
certificateFile = node.tls_certificateFile, certificateFile = node.tls_certificateFile,
keyFile = node.tls_keyFile keyFile = node.tls_keyFile
} }
} },
echServerKeys = (node.ech == "1") and node.ech_key or nil
} or nil, } or nil,
rawSettings = (node.transport == "raw" or node.transport == "tcp") and { rawSettings = (node.transport == "raw" or node.transport == "tcp") and {
header = { header = {
@ -545,7 +548,8 @@ function gen_config_server(node)
dest = node.reality_dest, dest = node.reality_dest,
serverNames = node.reality_serverNames or {}, serverNames = node.reality_serverNames or {},
privateKey = node.reality_private_key, privateKey = node.reality_private_key,
shortIds = node.reality_shortId or "" shortIds = node.reality_shortId or "",
mldsa65Seed = (node.use_mldsa65Seed == "1") and node.reality_mldsa65Seed or nil
} or nil } or nil
end end
end end
@ -1152,7 +1156,7 @@ function gen_config(var)
sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.iface)) sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.iface))
end end
else else
local outbound = gen_outbound(flag, node, nil, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.fragment == "1" or nil, run_socks_instance = not no_run }) local outbound = gen_outbound(flag, node, nil, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.noise == "1" or nil, run_socks_instance = not no_run })
if outbound then if outbound then
outbound.tag = outbound.tag .. ":" .. node.remarks outbound.tag = outbound.tag .. ":" .. node.remarks
COMMON.default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds) COMMON.default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds)

View File

@ -282,6 +282,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("pbk", dom_prefix + "reality_publicKey"); params += opt.query("pbk", dom_prefix + "reality_publicKey");
params += opt.query("sid", dom_prefix + "reality_shortId"); params += opt.query("sid", dom_prefix + "reality_shortId");
params += opt.query("spx", dom_prefix + "reality_spiderX"); params += opt.query("spx", dom_prefix + "reality_spiderX");
params += opt.query("pqv", dom_prefix + "reality_mldsa65Verify");
} }
if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) { if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) {
let v_flow = opt.get(dom_prefix + "flow").value; let v_flow = opt.get(dom_prefix + "flow").value;
@ -290,6 +291,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += "&security=" + v_security; params += "&security=" + v_security;
params += opt.query("alpn", dom_prefix + "alpn"); params += opt.query("alpn", dom_prefix + "alpn");
params += opt.query("sni", dom_prefix + "tls_serverName"); params += opt.query("sni", dom_prefix + "tls_serverName");
params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure");
params += opt.query("ech", dom_prefix + "ech_config");
} }
if (opt.get(dom_prefix + "shadowtls")?.checked) { if (opt.get(dom_prefix + "shadowtls")?.checked) {
@ -404,7 +407,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("path", dom_prefix + "ws_path"); params += opt.query("path", dom_prefix + "ws_path");
if (v_type == "sing-box" && opt.get(dom_prefix + "ws_enableEarlyData").checked) { if (v_type == "sing-box" && opt.get(dom_prefix + "ws_enableEarlyData").checked) {
var ws_maxEarlyData = opt.get(dom_prefix + "ws_maxEarlyData").value; var ws_maxEarlyData = opt.get(dom_prefix + "ws_maxEarlyData").value;
params += "?ed=" + ws_maxEarlyData; params += encodeURIComponent("?ed=" + ws_maxEarlyData);
} }
} else if (v_transport === "h2") { } else if (v_transport === "h2") {
v_transport = "http"; v_transport = "http";
@ -440,7 +443,11 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
} }
params += "&type=" + v_transport; params += "&type=" + v_transport;
if (v_type === "sing-box") {
params += "&encryption=none";
} else {
params += opt.query("encryption", dom_prefix + "encryption"); params += opt.query("encryption", dom_prefix + "encryption");
}
if (opt.get(dom_prefix + "tls").checked) { if (opt.get(dom_prefix + "tls").checked) {
var v_security = "tls"; var v_security = "tls";
@ -453,6 +460,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("pbk", dom_prefix + "reality_publicKey"); params += opt.query("pbk", dom_prefix + "reality_publicKey");
params += opt.query("sid", dom_prefix + "reality_shortId"); params += opt.query("sid", dom_prefix + "reality_shortId");
params += opt.query("spx", dom_prefix + "reality_spiderX"); params += opt.query("spx", dom_prefix + "reality_spiderX");
params += opt.query("pqv", dom_prefix + "reality_mldsa65Verify");
} }
if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) { if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) {
let v_flow = opt.get(dom_prefix + "flow").value; let v_flow = opt.get(dom_prefix + "flow").value;
@ -461,6 +469,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += "&security=" + v_security; params += "&security=" + v_security;
params += opt.query("alpn", dom_prefix + "alpn"); params += opt.query("alpn", dom_prefix + "alpn");
params += opt.query("sni", dom_prefix + "tls_serverName"); params += opt.query("sni", dom_prefix + "tls_serverName");
params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure");
params += opt.query("ech", dom_prefix + "ech_config");
} }
params += "#" + encodeURI(v_alias.value); params += "#" + encodeURI(v_alias.value);
@ -520,6 +530,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("pbk", dom_prefix + "reality_publicKey"); params += opt.query("pbk", dom_prefix + "reality_publicKey");
params += opt.query("sid", dom_prefix + "reality_shortId"); params += opt.query("sid", dom_prefix + "reality_shortId");
params += opt.query("spx", dom_prefix + "reality_spiderX"); params += opt.query("spx", dom_prefix + "reality_spiderX");
params += opt.query("pqv", dom_prefix + "reality_mldsa65Verify");
} }
if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) { if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) {
let v_flow = opt.get(dom_prefix + "flow").value; let v_flow = opt.get(dom_prefix + "flow").value;
@ -528,6 +539,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += "&security=" + v_security; params += "&security=" + v_security;
params += opt.query("alpn", dom_prefix + "alpn"); params += opt.query("alpn", dom_prefix + "alpn");
params += opt.query("sni", dom_prefix + "tls_serverName"); params += opt.query("sni", dom_prefix + "tls_serverName");
params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure");
params += opt.query("ech", dom_prefix + "ech_config");
} }
params += "#" + encodeURI(v_alias.value); params += "#" + encodeURI(v_alias.value);
if (params[0] == "&") { if (params[0] == "&") {
@ -958,6 +971,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
opt.set(dom_prefix + 'utls', true); opt.set(dom_prefix + 'utls', true);
opt.set(dom_prefix + 'fingerprint', queryParam.fp); opt.set(dom_prefix + 'fingerprint', queryParam.fp);
} }
opt.set(dom_prefix + 'ech', !!queryParam.ech);
opt.set(dom_prefix + 'ech_config', queryParam.ech || '');
} }
if (queryParam.security == "reality") { if (queryParam.security == "reality") {
@ -973,6 +988,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
opt.set(dom_prefix + 'reality_publicKey', queryParam.pbk || ''); opt.set(dom_prefix + 'reality_publicKey', queryParam.pbk || '');
opt.set(dom_prefix + 'reality_shortId', queryParam.sid || ''); opt.set(dom_prefix + 'reality_shortId', queryParam.sid || '');
opt.set(dom_prefix + 'reality_spiderX', queryParam.spx || ''); opt.set(dom_prefix + 'reality_spiderX', queryParam.spx || '');
opt.set(dom_prefix + 'use_mldsa65Verify', !!queryParam.pqv);
opt.set(dom_prefix + 'reality_mldsa65Verify', queryParam.pqv || '');
} }
} }
@ -1061,6 +1078,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
} }
} }
if (dom_prefix === "ssrust_") { if (dom_prefix === "ssrust_") {
opt.set(dom_prefix + 'plugin_enabled', true);
opt.set(dom_prefix + 'plugin', "shadow-tls"); opt.set(dom_prefix + 'plugin', "shadow-tls");
let shadowtlsOpt = parseShadowTLSParams(queryParam["shadow-tls"]); let shadowtlsOpt = parseShadowTLSParams(queryParam["shadow-tls"]);
opt.set(dom_prefix + 'plugin_opts', shadowtlsOpt || ""); opt.set(dom_prefix + 'plugin_opts', shadowtlsOpt || "");
@ -1335,6 +1353,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
opt.set(dom_prefix + 'utls', true); opt.set(dom_prefix + 'utls', true);
opt.set(dom_prefix + 'fingerprint', queryParam.fp); opt.set(dom_prefix + 'fingerprint', queryParam.fp);
} }
opt.set(dom_prefix + 'ech', !!queryParam.ech);
opt.set(dom_prefix + 'ech_config', queryParam.ech || '');
} }
if (queryParam.security == "reality") { if (queryParam.security == "reality") {
@ -1350,6 +1370,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
opt.set(dom_prefix + 'reality_publicKey', queryParam.pbk || ''); opt.set(dom_prefix + 'reality_publicKey', queryParam.pbk || '');
opt.set(dom_prefix + 'reality_shortId', queryParam.sid || ''); opt.set(dom_prefix + 'reality_shortId', queryParam.sid || '');
opt.set(dom_prefix + 'reality_spiderX', queryParam.spx || ''); opt.set(dom_prefix + 'reality_spiderX', queryParam.spx || '');
opt.set(dom_prefix + 'use_mldsa65Verify', !!queryParam.pqv);
opt.set(dom_prefix + 'reality_mldsa65Verify', queryParam.pqv || '');
} }
} }
@ -1550,6 +1572,9 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || ''); queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
} }
} }
if ((!queryParam.security || queryParam.security == "") && queryParam.sni && queryParam.sni != "") {
queryParam.security = "tls";
}
if (queryParam.security) { if (queryParam.security) {
if (queryParam.security == "tls") { if (queryParam.security == "tls") {
opt.set(dom_prefix + 'tls', true); opt.set(dom_prefix + 'tls', true);

View File

@ -3,6 +3,8 @@ local api = require "luci.passwall2.api"
-%> -%>
<script type="text/javascript"> <script type="text/javascript">
//<![CDATA[ //<![CDATA[
var appname = "<%= api.appname %>"
function confirmDeleteNode(remark) { function confirmDeleteNode(remark) {
if (!confirm("<%:Delete the subscribed node%>: " + remark + " ?")) if (!confirm("<%:Delete the subscribed node%>: " + remark + " ?"))
return false; return false;
@ -34,5 +36,76 @@ local api = require "luci.passwall2.api"
}); });
return false; return false;
} }
function ManualSubscribe(sectionId) {
var urlInput = document.querySelector("input[name='cbid." + appname + "." + sectionId + ".url']");
var currentUrl = urlInput ? urlInput.value.trim() : "";
if (!currentUrl) {
alert("<%:Subscribe URL cannot be empty.%>");
return;
}
fetch('<%= api.url("subscribe_manual") %>?section='
+ encodeURIComponent(sectionId)
+ '&url='
+ encodeURIComponent(currentUrl))
.then(response => response.json())
.then(data => {
if (!data.success) {
alert(data.msg || "Operation failed");
} else {
window.location.href = '<%= api.url("log") %>'
}
});
}
function ManualSubscribeAll() {
var sectionIds = [];
var urls = [];
var table = document.getElementById("cbi-" + appname + "-subscribe_list");
var editBtns = table ? table.getElementsByClassName("cbi-button cbi-button-edit") : [];
for (var i = 0; i < editBtns.length; i++) {
var btn = editBtns[i];
var onclickStr = btn.getAttribute("onclick");
if (!onclickStr) continue;
var id = onclickStr.substring(onclickStr.lastIndexOf('/') + 1, onclickStr.length - 1);
if (!id) continue;
var urlInput = document.querySelector("input[name='cbid." + appname + "." + id + ".url']");
var currentUrl = urlInput ? urlInput.value.trim() : "";
if (!currentUrl) {
alert("<%:Subscribe URL cannot be empty.%>");
return;
}
sectionIds.push(id);
urls.push(currentUrl);
}
if (sectionIds.length === 0) {
//alert("No subscriptions found.");
return;
}
var params = new URLSearchParams();
params.append("sections", sectionIds.join(","));
params.append("urls", urls.join(","));
fetch('<%= api.url("subscribe_manual_all") %>', {
method: 'POST',
body: params
})
.then(response => response.json())
.then(data => {
if (!data.success) {
alert(data.msg || "Operation failed");
} else {
window.location.href = '<%= api.url("log") %>'
}
});
}
//]]> //]]>
</script> </script>

View File

@ -103,6 +103,9 @@ msgstr "Socks配置"
msgid "Socks Node" msgid "Socks Node"
msgstr "Socks 节点" msgstr "Socks 节点"
msgid "Current Node"
msgstr "当前节点"
msgid "Listen Port" msgid "Listen Port"
msgstr "监听端口" msgstr "监听端口"
@ -343,7 +346,7 @@ msgstr "负载均衡策略"
msgid "Fallback Node" msgid "Fallback Node"
msgstr "后备节点" msgstr "后备节点"
msgid "Use Custome Probe URL" msgid "Use Custom Probe URL"
msgstr "使用自定义探测网址" msgstr "使用自定义探测网址"
msgid "By default the built-in probe URL will be used, enable this option to use a custom probe URL." msgid "By default the built-in probe URL will be used, enable this option to use a custom probe URL."
@ -940,8 +943,14 @@ msgstr "订阅网址"
msgid "Subscribe URL Access Method" msgid "Subscribe URL Access Method"
msgstr "订阅网址访问方式" msgstr "订阅网址访问方式"
msgid "Please input the subscription url first, save and submit before manual subscription." msgid "When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically."
msgstr "请输入订阅网址保存应用后再手动订阅。" msgstr "新增订阅请先保存并应用后再手动订阅;如仅修改订阅地址,可直接手动订阅,系统将自动保存。"
msgid "Please save and apply before manually subscribing."
msgstr "请先保存并应用后再手动订阅。"
msgid "Subscribe URL cannot be empty."
msgstr "订阅网址不能为空。"
msgid "Subscribe via proxy" msgid "Subscribe via proxy"
msgstr "通过代理订阅" msgstr "通过代理订阅"
@ -1087,6 +1096,12 @@ msgstr "子域名 (推荐): 由'domain:'开始,余下部分是一个域名。
msgid "Full domain: Begining with 'full:' and the rest is a domain. When the targeting domain is exactly the value, the rule takes effect. Example: rule 'domain:v2ray.com' matches 'v2ray.com', but not 'www.v2ray.com'." msgid "Full domain: Begining with 'full:' and the rest is a domain. When the targeting domain is exactly the value, the rule takes effect. Example: rule 'domain:v2ray.com' matches 'v2ray.com', but not 'www.v2ray.com'."
msgstr "完整匹配: 由'full:'开始,余下部分是一个域名。当此域名完整匹配目标域名时,该规则生效。例如'full:v2ray.com'匹配'v2ray.com'但不匹配'www.v2ray.com'。" msgstr "完整匹配: 由'full:'开始,余下部分是一个域名。当此域名完整匹配目标域名时,该规则生效。例如'full:v2ray.com'匹配'v2ray.com'但不匹配'www.v2ray.com'。"
msgid "Sing-Box rule-set: Begining with 'rule-set:remote:' or 'rule-set:local:'"
msgstr "Sing-Box 规则集: 由 'rule-set:remote:' 或 'rule-set:local:' 开始"
msgid "Such as:"
msgstr "例如:"
msgid "Pre-defined domain list: Begining with 'geosite:' and the rest is a name, such as geosite:google or geosite:cn." msgid "Pre-defined domain list: Begining with 'geosite:' and the rest is a name, such as geosite:google or geosite:cn."
msgstr "预定义域名列表:由'geosite:'开头余下部分是一个名称如geosite:google或者geosite:cn。" msgstr "预定义域名列表:由'geosite:'开头余下部分是一个名称如geosite:google或者geosite:cn。"
@ -1126,6 +1141,9 @@ msgstr "快速打开"
msgid "plugin" msgid "plugin"
msgstr "插件" msgstr "插件"
msgid "Supports custom SIP003 plugins, Make sure the plugin is installed."
msgstr "支持自定义 SIP003 插件,请确保插件已安装。"
msgid "opts" msgid "opts"
msgstr "插件选项" msgstr "插件选项"
@ -1547,10 +1565,10 @@ msgid "Protocol parameter. Enable length block encryption."
msgstr "协议参数。启用长度块加密。" msgstr "协议参数。启用长度块加密。"
msgid "ECH Config" msgid "ECH Config"
msgstr "ECH 密钥" msgstr "ECH 配置"
msgid "ECH Key" msgid "ECH Key"
msgstr "ECH 配置" msgstr "ECH 密钥"
msgid "PQ signature schemes" msgid "PQ signature schemes"
msgstr "后量子对等证书签名方案" msgstr "后量子对等证书签名方案"
@ -1585,6 +1603,12 @@ msgstr "分片间隔"
msgid "Fragmentation interval (ms)" msgid "Fragmentation interval (ms)"
msgstr "分片间隔ms" msgstr "分片间隔ms"
msgid "Split handshake data into multiple TLS records for better censorship evasion. Low overhead. Recommended to enable first."
msgstr "将握手数据拆分为多个 TLS 记录,提升抗封锁能力,几乎不增加延迟,建议优先启用。"
msgid "Split handshake into multiple TCP segments. Enhances obfuscation. May increase delay. Use only if needed."
msgstr "将 TLS 握手数据分为多个 TCP 包发送,提高伪装性,可能增加延迟,仅在封锁严重时使用。"
msgid "Noise" msgid "Noise"
msgstr "噪声" msgstr "噪声"

View File

@ -51,7 +51,7 @@ config global_rules
config global_app config global_app
option xray_file '/usr/bin/xray' option xray_file '/usr/bin/xray'
option hysteria_file '/usr/bin/hysteria' option hysteria_file '/usr/bin/hysteria'
option singbox_file '/usr/bin/sing-box' option sing_box_file '/usr/bin/sing-box'
config global_subscribe config global_subscribe
option filter_keyword_mode '1' option filter_keyword_mode '1'
@ -112,6 +112,7 @@ alibaba.cdn.steampipe.steamcontent.com
# 国内游戏geosite域名 # 国内游戏geosite域名
geosite:category-games@cn geosite:category-games@cn
rule-set:remote:https://raw.githubusercontent.com/lyc8503/sing-box-rules/rule-set-geosite/geosite-category-games%40cn.srs
' '
option ip_list '# steam直连IP option ip_list '# steam直连IP
@ -181,13 +182,13 @@ steamcloud-sydney.storage.googleapis.com
steamcloud-taiwan.storage.googleapis.com steamcloud-taiwan.storage.googleapis.com
steamcloud-eu.storage.googleapis.com steamcloud-eu.storage.googleapis.com
geosite:category-games' geosite:category-games
rule-set:remote:https://raw.githubusercontent.com/lyc8503/sing-box-rules/rule-set-geosite/geosite-category-games.srs'
config shunt_rules 'Direct' config shunt_rules 'Direct'
option network 'tcp,udp' option network 'tcp,udp'
option remarks 'Direct' option remarks 'Direct'
option ip_list 'geoip:private option ip_list '114.114.114.114
114.114.114.114
114.114.115.115 114.114.115.115
223.5.5.5 223.5.5.5
223.6.6.6 223.6.6.6
@ -219,17 +220,20 @@ domain:xn--ngstr-lra8j.com'
config shunt_rules 'Netflix' config shunt_rules 'Netflix'
option remarks 'Netflix' option remarks 'Netflix'
option network 'tcp,udp' option network 'tcp,udp'
option domain_list 'geosite:netflix' option domain_list 'geosite:netflix
rule-set:remote:https://raw.githubusercontent.com/lyc8503/sing-box-rules/rule-set-geosite/geosite-netflix.srs'
config shunt_rules 'OpenAI' config shunt_rules 'OpenAI'
option remarks 'OpenAI' option remarks 'OpenAI'
option network 'tcp,udp' option network 'tcp,udp'
option domain_list 'geosite:openai' option domain_list 'geosite:openai
rule-set:remote:https://raw.githubusercontent.com/lyc8503/sing-box-rules/rule-set-geosite/geosite-openai.srs'
config shunt_rules 'Proxy' config shunt_rules 'Proxy'
option network 'tcp,udp' option network 'tcp,udp'
option remarks 'Proxy' option remarks 'Proxy'
option domain_list 'geosite:geolocation-!cn' option domain_list 'geosite:geolocation-!cn
rule-set:remote:https://raw.githubusercontent.com/lyc8503/sing-box-rules/rule-set-geosite/geosite-geolocation-!cn.srs'
option ip_list '149.154.160.0/20 option ip_list '149.154.160.0/20
91.108.4.0/22 91.108.4.0/22
91.108.56.0/24 91.108.56.0/24
@ -258,8 +262,10 @@ config shunt_rules 'Proxy'
config shunt_rules 'China' config shunt_rules 'China'
option remarks 'China' option remarks 'China'
option network 'tcp,udp' option network 'tcp,udp'
option ip_list 'geoip:cn' option ip_list 'geoip:cn
option domain_list 'geosite:cn' rule-set:remote:https://raw.githubusercontent.com/lyc8503/sing-box-rules/rule-set-geoip/geoip-cn.srs'
option domain_list 'geosite:cn
rule-set:remote:https://raw.githubusercontent.com/lyc8503/sing-box-rules/rule-set-geosite/geosite-cn.srs'
config shunt_rules 'QUIC' config shunt_rules 'QUIC'
option remarks 'QUIC' option remarks 'QUIC'

View File

@ -297,11 +297,11 @@ get_singbox_geoip() {
local geoip_code="$1" local geoip_code="$1"
local geoip_path=$(config_t_get global_singbox geoip_path) local geoip_path=$(config_t_get global_singbox geoip_path)
[ -e "$geoip_path" ] || { echo ""; return; } [ -e "$geoip_path" ] || { echo ""; return; }
local has_geoip_tools=$($(first_type $(config_t_get global_app singbox_file) sing-box) geoip | grep "GeoIP tools") local has_geoip_tools=$($(first_type $(config_t_get global_app sing_box_file) sing-box) geoip | grep "GeoIP tools")
if [ -n "${has_geoip_tools}" ]; then if [ -n "${has_geoip_tools}" ]; then
[ -f "${geoip_path}" ] && local geoip_md5=$(md5sum ${geoip_path} | awk '{print $1}') [ -f "${geoip_path}" ] && local geoip_md5=$(md5sum ${geoip_path} | awk '{print $1}')
local output_file="${TMP_PATH2}/geoip-${geoip_md5}-${geoip_code}.json" local output_file="${TMP_PATH2}/geoip-${geoip_md5}-${geoip_code}.json"
[ ! -f ${output_file} ] && $(first_type $(config_t_get global_app singbox_file) sing-box) geoip -f "${geoip_path}" export "${geoip_code}" -o "${output_file}" [ ! -f ${output_file} ] && $(first_type $(config_t_get global_app sing_box_file) sing-box) geoip -f "${geoip_path}" export "${geoip_code}" -o "${output_file}"
case "$2" in case "$2" in
ipv4) ipv4)
cat ${output_file} | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | awk -F '"' '{print $2}' | sed -e "/^$/d" cat ${output_file} | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | awk -F '"' '{print $2}' | sed -e "/^$/d"
@ -468,7 +468,7 @@ run_singbox() {
[ "$loglevel" = "warning" ] && loglevel="warn" [ "$loglevel" = "warning" ] && loglevel="warn"
_extra_param="${_extra_param} -loglevel $loglevel" _extra_param="${_extra_param} -loglevel $loglevel"
_extra_param="${_extra_param} -tags $($(first_type $(config_t_get global_app singbox_file) sing-box) version | grep 'Tags:' | awk '{print $2}')" _extra_param="${_extra_param} -tags $($(first_type $(config_t_get global_app sing_box_file) sing-box) version | grep 'Tags:' | awk '{print $2}')"
[ -n "$flag" ] && pgrep -af "$TMP_BIN_PATH" | awk -v P1="${flag}" 'BEGIN{IGNORECASE=1}$0~P1{print $1}' | xargs kill -9 >/dev/null 2>&1 [ -n "$flag" ] && pgrep -af "$TMP_BIN_PATH" | awk -v P1="${flag}" 'BEGIN{IGNORECASE=1}$0~P1{print $1}' | xargs kill -9 >/dev/null 2>&1
[ -n "$flag" ] && _extra_param="${_extra_param} -flag $flag" [ -n "$flag" ] && _extra_param="${_extra_param} -flag $flag"
@ -552,7 +552,7 @@ run_singbox() {
} }
lua $UTIL_SINGBOX gen_config -node $node ${_extra_param} > $config_file lua $UTIL_SINGBOX gen_config -node $node ${_extra_param} > $config_file
ln_run "$(first_type $(config_t_get global_app singbox_file) sing-box)" "sing-box" "${log_file}" run -c "$config_file" ln_run "$(first_type $(config_t_get global_app sing_box_file) sing-box)" "sing-box" "${log_file}" run -c "$config_file"
} }
run_socks() { run_socks() {
@ -604,7 +604,7 @@ run_socks() {
sing-box) sing-box)
[ "$http_port" != "0" ] && { [ "$http_port" != "0" ] && {
http_flag=1 http_flag=1
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g") config_file="${config_file//SOCKS/HTTP_SOCKS}"
local _extra_param="-local_http_address $bind -local_http_port $http_port" local _extra_param="-local_http_address $bind -local_http_port $http_port"
} }
[ -n "$relay_port" ] && _extra_param="${_extra_param} -server_host $server_host -server_port $server_port" [ -n "$relay_port" ] && _extra_param="${_extra_param} -server_host $server_host -server_port $server_port"
@ -615,12 +615,12 @@ run_socks() {
} }
[ -n "$no_run" ] && _extra_param="${_extra_param} -no_run 1" [ -n "$no_run" ] && _extra_param="${_extra_param} -no_run 1"
lua $UTIL_SINGBOX gen_config -flag SOCKS_$flag -node $node -local_socks_address $bind -local_socks_port $socks_port ${_extra_param} > $config_file lua $UTIL_SINGBOX gen_config -flag SOCKS_$flag -node $node -local_socks_address $bind -local_socks_port $socks_port ${_extra_param} > $config_file
[ -n "$no_run" ] || ln_run "$(first_type $(config_t_get global_app singbox_file) sing-box)" "sing-box" /dev/null run -c "$config_file" [ -n "$no_run" ] || ln_run "$(first_type $(config_t_get global_app sing_box_file) sing-box)" "sing-box" /dev/null run -c "$config_file"
;; ;;
xray) xray)
[ "$http_port" != "0" ] && { [ "$http_port" != "0" ] && {
http_flag=1 http_flag=1
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g") config_file="${config_file//SOCKS/HTTP_SOCKS}"
local _extra_param="-local_http_address $bind -local_http_port $http_port" local _extra_param="-local_http_address $bind -local_http_port $http_port"
} }
[ -n "$relay_port" ] && _extra_param="${_extra_param} -server_host $server_host -server_port $server_port" [ -n "$relay_port" ] && _extra_param="${_extra_param} -server_host $server_host -server_port $server_port"
@ -637,14 +637,23 @@ run_socks() {
[ -n "$no_run" ] || ln_run "$(first_type ssr-local)" "ssr-local" $log_file -c "$config_file" -v -u [ -n "$no_run" ] || ln_run "$(first_type ssr-local)" "ssr-local" $log_file -c "$config_file" -v -u
;; ;;
ss) ss)
lua $UTIL_SS gen_config -node $node -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $server_port -mode tcp_and_udp > $config_file [ -n "$no_run" ] || {
local plugin_sh="${config_file%.json}_plugin.sh"
local _extra_param="-plugin_sh $plugin_sh"
}
lua $UTIL_SS gen_config -node $node -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $server_port -mode tcp_and_udp ${_extra_param} > $config_file
[ -n "$no_run" ] || ln_run "$(first_type ss-local)" "ss-local" $log_file -c "$config_file" -v [ -n "$no_run" ] || ln_run "$(first_type ss-local)" "ss-local" $log_file -c "$config_file" -v
;; ;;
ss-rust) ss-rust)
local _extra_param
[ "$http_port" != "0" ] && { [ "$http_port" != "0" ] && {
http_flag=1 http_flag=1
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g") config_file="${config_file//SOCKS/HTTP_SOCKS}"
local _extra_param="-local_http_address $bind -local_http_port $http_port" _extra_param="-local_http_address $bind -local_http_port $http_port"
}
[ -n "$no_run" ] || {
local plugin_sh="${config_file%.json}_plugin.sh"
_extra_param="${_extra_param:+$_extra_param }-plugin_sh $plugin_sh"
} }
lua $UTIL_SS gen_config -node $node -local_socks_address $bind -local_socks_port $socks_port -server_host $server_host -server_port $server_port ${_extra_param} > $config_file lua $UTIL_SS gen_config -node $node -local_socks_address $bind -local_socks_port $socks_port -server_host $server_host -server_port $server_port ${_extra_param} > $config_file
[ -n "$no_run" ] || ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v [ -n "$no_run" ] || ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v
@ -652,7 +661,7 @@ run_socks() {
hysteria2) hysteria2)
[ "$http_port" != "0" ] && { [ "$http_port" != "0" ] && {
http_flag=1 http_flag=1
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g") config_file="${config_file//SOCKS/HTTP_SOCKS}"
local _extra_param="-local_http_address $bind -local_http_port $http_port" local _extra_param="-local_http_address $bind -local_http_port $http_port"
} }
lua $UTIL_HYSTERIA2 gen_config -node $node -local_socks_address $bind -local_socks_port $socks_port -server_host $server_host -server_port $server_port ${_extra_param} > $config_file lua $UTIL_HYSTERIA2 gen_config -node $node -local_socks_address $bind -local_socks_port $socks_port -server_host $server_host -server_port $server_port ${_extra_param} > $config_file
@ -666,7 +675,7 @@ run_socks() {
# http to socks # http to socks
[ -z "$http_flag" ] && [ "$http_port" != "0" ] && [ -n "$http_config_file" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && [ "$type" != "socks" ] && { [ -z "$http_flag" ] && [ "$http_port" != "0" ] && [ -n "$http_config_file" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && [ "$type" != "socks" ] && {
local bin=$(first_type $(config_t_get global_app singbox_file) sing-box) local bin=$(first_type $(config_t_get global_app sing_box_file) sing-box)
if [ -n "$bin" ]; then if [ -n "$bin" ]; then
type="sing-box" type="sing-box"
lua $UTIL_SINGBOX gen_proto_config -local_http_port $http_port -server_proto socks -server_address "127.0.0.1" -server_port $socks_port -server_username $_username -server_password $_password > $http_config_file lua $UTIL_SINGBOX gen_proto_config -local_http_port $http_port -server_proto socks -server_address "127.0.0.1" -server_port $socks_port -server_username $_username -server_password $_password > $http_config_file
@ -688,9 +697,17 @@ socks_node_switch() {
local flag new_node local flag new_node
eval_set_val $@ eval_set_val $@
[ -n "$flag" ] && [ -n "$new_node" ] && { [ -n "$flag" ] && [ -n "$new_node" ] && {
local prefix pf filename
# 结束 SS 插件进程
for prefix in "" "HTTP_"; do
pf="$TMP_PATH/${prefix}SOCKS_${flag}_plugin.pid"
[ -s "$pf" ] && kill -9 "$(head -n1 "$pf")" >/dev/null 2>&1
done
pgrep -af "$TMP_BIN_PATH" | awk -v P1="${flag}" 'BEGIN{IGNORECASE=1}$0~P1 && !/acl\/|acl_/{print $1}' | xargs kill -9 >/dev/null 2>&1 pgrep -af "$TMP_BIN_PATH" | awk -v P1="${flag}" 'BEGIN{IGNORECASE=1}$0~P1 && !/acl\/|acl_/{print $1}' | xargs kill -9 >/dev/null 2>&1
rm -rf $TMP_PATH/SOCKS_${flag}* for prefix in "" "HTTP_" "HTTP2"; do
rm -rf $TMP_PATH/HTTP2SOCKS_${flag}* rm -rf "$TMP_PATH/${prefix}SOCKS_${flag}"*
done
for filename in $(ls ${TMP_SCRIPT_FUNC_PATH}); do for filename in $(ls ${TMP_SCRIPT_FUNC_PATH}); do
cmd=$(cat ${TMP_SCRIPT_FUNC_PATH}/${filename}) cmd=$(cat ${TMP_SCRIPT_FUNC_PATH}/${filename})
@ -1312,7 +1329,15 @@ stop() {
eval_cache_var eval_cache_var
[ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh stop [ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh stop
delete_ip2route delete_ip2route
kill_all xray-plugin v2ray-plugin obfs-local shadow-tls # 结束 SS 插件进程
# kill_all xray-plugin v2ray-plugin obfs-local shadow-tls
local pid_file pid
find "$TMP_PATH" -type f -name '*_plugin.pid' | while read -r pid_file; do
read -r pid < "$pid_file"
if [ -n "$pid" ]; then
kill -9 "$pid" >/dev/null 2>&1
fi
done
pgrep -f "sleep.*(6s|9s|58s)" | xargs kill -9 >/dev/null 2>&1 pgrep -f "sleep.*(6s|9s|58s)" | xargs kill -9 >/dev/null 2>&1
pgrep -af "${CONFIG}/" | awk '! /app\.sh|subscribe\.lua|rule_update\.lua|tasks\.sh|ujail/{print $1}' | xargs kill -9 >/dev/null 2>&1 pgrep -af "${CONFIG}/" | awk '! /app\.sh|subscribe\.lua|rule_update\.lua|tasks\.sh|ujail/{print $1}' | xargs kill -9 >/dev/null 2>&1
unset V2RAY_LOCATION_ASSET unset V2RAY_LOCATION_ASSET
@ -1402,7 +1427,7 @@ get_config() {
set_cache_var GLOBAL_DNSMASQ_CONF_PATH ${GLOBAL_ACL_PATH}/dnsmasq.d set_cache_var GLOBAL_DNSMASQ_CONF_PATH ${GLOBAL_ACL_PATH}/dnsmasq.d
XRAY_BIN=$(first_type $(config_t_get global_app xray_file) xray) XRAY_BIN=$(first_type $(config_t_get global_app xray_file) xray)
SINGBOX_BIN=$(first_type $(config_t_get global_app singbox_file) sing-box) SINGBOX_BIN=$(first_type $(config_t_get global_app sing_box_file) sing-box)
} }
arg1=$1 arg1=$1

View File

@ -1,13 +1,19 @@
#!/bin/sh #!/bin/sh
export PATH=/usr/sbin:/usr/bin:/sbin:/bin:/root/bin export PATH=/usr/sbin:/usr/bin:/sbin:/bin:/root/bin
CONFIG=passwall2
listen_address=$1 listen_address=$1
listen_port=$2 listen_port=$2
server_address=$3 server_address=$3
server_port=$4 server_port=$4
probe_file="/tmp/etc/passwall2/haproxy/Probe_URL" pgrep -af "${CONFIG}/" | awk '/app\.sh.*(start|stop)/ || /nftables\.sh/ || /iptables\.sh/ { found = 1 } END { exit !found }' && {
# 特定任务执行中不检测
exit 0
}
probe_file="/tmp/etc/${CONFIG}/haproxy/Probe_URL"
probeUrl="https://www.google.com/generate_204" probeUrl="https://www.google.com/generate_204"
if [ -f "$probe_file" ]; then if [ -f "$probe_file" ]; then
firstLine=$(head -n 1 "$probe_file" | tr -d ' \t\n') firstLine=$(head -n 1 "$probe_file" | tr -d ' \t\n')
@ -19,7 +25,7 @@ if /usr/bin/curl --help all | grep -q "\-\-retry-all-errors"; then
extra_params="${extra_params} --retry-all-errors" extra_params="${extra_params} --retry-all-errors"
fi fi
status=$(/usr/bin/curl -I -o /dev/null -skL ${extra_params} --connect-timeout 3 --retry 1 --max-time 10 -w "%{http_code}" "${probeUrl}") status=$(/usr/bin/curl -I -o /dev/null -skL ${extra_params} --connect-timeout 3 --retry 2 --max-time 10 -w "%{http_code}" "${probeUrl}")
case "$status" in case "$status" in
200|204) 200|204)

View File

@ -27,7 +27,7 @@ test_url() {
if /usr/bin/curl --help all | grep -q "\-\-retry-all-errors"; then if /usr/bin/curl --help all | grep -q "\-\-retry-all-errors"; then
extra_params="--retry-all-errors ${extra_params}" extra_params="--retry-all-errors ${extra_params}"
fi fi
status=$(/usr/bin/curl -I -o /dev/null -skL ${extra_params} --connect-timeout ${timeout} --retry ${try} -w %{http_code} "$url") local status=$(/usr/bin/curl -I -o /dev/null -skL ${extra_params} --connect-timeout ${timeout} --retry ${try} -w %{http_code} "$url")
case "$status" in case "$status" in
204) 204)
status=200 status=200
@ -37,12 +37,12 @@ test_url() {
} }
test_proxy() { test_proxy() {
result=0 local result=0
status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x socks5h://127.0.0.1:${socks_port}") local status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x socks5h://127.0.0.1:${socks_port}")
if [ "$status" = "200" ]; then if [ "$status" = "200" ]; then
result=0 result=0
else else
status2=$(test_url "https://www.baidu.com" ${retry_num} ${connect_timeout}) local status2=$(test_url "https://www.baidu.com" ${retry_num} ${connect_timeout})
if [ "$status2" = "200" ]; then if [ "$status2" = "200" ]; then
result=1 result=1
else else
@ -64,9 +64,12 @@ test_node() {
/usr/share/${CONFIG}/app.sh run_socks flag="test_node_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=test_node_${node_id}.json /usr/share/${CONFIG}/app.sh run_socks flag="test_node_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=test_node_${node_id}.json
local curlx="socks5h://127.0.0.1:${_tmp_port}" local curlx="socks5h://127.0.0.1:${_tmp_port}"
sleep 1s sleep 1s
_proxy_status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x $curlx") local _proxy_status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x $curlx")
# 结束 SS 插件进程
local pid_file="/tmp/etc/${CONFIG}/test_node_${node_id}_plugin.pid"
[ -s "$pid_file" ] && kill -9 "$(head -n 1 "$pid_file")" >/dev/null 2>&1
pgrep -af "test_node_${node_id}" | awk '! /socks_auto_switch\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1 pgrep -af "test_node_${node_id}" | awk '! /socks_auto_switch\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1
rm -rf "/tmp/etc/${CONFIG}/test_node_${node_id}.json" rm -rf /tmp/etc/${CONFIG}/test_node_${node_id}*.*
if [ "${_proxy_status}" -eq 200 ]; then if [ "${_proxy_status}" -eq 200 ]; then
return 0 return 0
fi fi
@ -75,14 +78,14 @@ test_node() {
} }
test_auto_switch() { test_auto_switch() {
flag=$(expr $flag + 1) flag=$((flag + 1))
local b_nodes=$1 local b_nodes=$1
local now_node=$2 local now_node=$2
[ -z "$now_node" ] && { [ -z "$now_node" ] && {
if [ -n "$(/usr/share/${CONFIG}/app.sh get_cache_var "socks_${id}")" ]; then if [ -n "$(/usr/share/${CONFIG}/app.sh get_cache_var "socks_${id}")" ]; then
now_node=$(/usr/share/${CONFIG}/app.sh get_cache_var "socks_${id}") now_node=$(/usr/share/${CONFIG}/app.sh get_cache_var "socks_${id}")
else else
#echolog "自动切换检测:未知错误" #echolog "Socks切换检测:未知错误"
return 1 return 1
fi fi
} }
@ -91,58 +94,59 @@ test_auto_switch() {
main_node=$now_node main_node=$now_node
} }
status=$(test_proxy) local status=$(test_proxy)
if [ "$status" == 2 ]; then if [ "$status" = "2" ]; then
echolog "自动切换检测:无法连接到网络,请检查网络是否正常!" echolog "Socks切换检测:无法连接到网络,请检查网络是否正常!"
return 2 return 2
fi fi
#检测主节点是否能使用 #检测主节点是否能使用
if [ "$restore_switch" == "1" ] && [ -n "$main_node" ] && [ "$now_node" != "$main_node" ]; then if [ "$restore_switch" = "1" ] && [ -n "$main_node" ] && [ "$now_node" != "$main_node" ]; then
test_node ${main_node} test_node ${main_node}
[ $? -eq 0 ] && { [ $? -eq 0 ] && {
#主节点正常,切换到主节点 #主节点正常,切换到主节点
echolog "自动切换检测:${id}主节点【$(config_n_get $main_node type)[$(config_n_get $main_node remarks)]】正常,切换到主节点!" echolog "Socks切换检测:${id}主节点【$(config_n_get $main_node type)[$(config_n_get $main_node remarks)]】正常,切换到主节点!"
/usr/share/${CONFIG}/app.sh socks_node_switch flag=${id} new_node=${main_node} /usr/share/${CONFIG}/app.sh socks_node_switch flag=${id} new_node=${main_node}
[ $? -eq 0 ] && { [ $? -eq 0 ] && {
echolog "自动切换检测:${id}节点切换完毕!" echolog "Socks切换检测:${id}节点切换完毕!"
} }
return 0 return 0
} }
fi fi
if [ "$status" == 0 ]; then if [ "$status" = "0" ]; then
#echolog "自动切换检测:${id}【$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】正常。" #echolog "Socks切换检测:${id}【$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】正常。"
return 0 return 0
elif [ "$status" == 1 ]; then elif [ "$status" = "1" ]; then
echolog "自动切换检测:${id}$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】异常,切换到下一个备用节点检测!" local new_node msg
local new_node if [ "$backup_node_num" -gt 1 ]; then
in_backup_nodes=$(echo $b_nodes | grep $now_node) # 有多个后备节点时
# 判断当前节点是否存在于备用节点列表里 local first_node found node
if [ -z "$in_backup_nodes" ]; then for node in $b_nodes; do
# 如果不存在,设置第一个节点为新的节点 [ -z "$first_node" ] && first_node="$node" # 记录第一个节点
new_node=$(echo $b_nodes | awk -F ' ' '{print $1}') [ "$found" = "1" ] && { new_node="$node"; break; } # 找到当前节点后取下一个
[ "$node" = "$now_node" ] && found=1 # 标记找到当前节点
done
# 如果没找到当前节点,或者当前节点是最后一个,就取第一个节点
[ -z "$new_node" ] && new_node="$first_node"
msg="切换到$([ "$now_node" = "$main_node" ] && echo 备用节点 || echo 下一个备用节点)检测!"
else else
# 如果存在,设置下一个备用节点为新的节点 # 只有一个后备节点时,与主节点轮询
#local count=$(expr $(echo $b_nodes | grep -o ' ' | wc -l) + 1) new_node=$([ "$now_node" = "$main_node" ] && echo "$b_nodes" || echo "$main_node")
local next_node=$(echo $b_nodes | awk -F "$now_node" '{print $2}' | awk -F " " '{print $1}') msg="切换到$([ "$now_node" = "$main_node" ] && echo 备用节点 || echo 主节点)检测!"
if [ -z "$next_node" ]; then
new_node=$(echo $b_nodes | awk -F ' ' '{print $1}')
else
new_node=$next_node
fi
fi fi
echolog "Socks切换检测${id}$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】异常,$msg"
test_node ${new_node} test_node ${new_node}
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
[ "$restore_switch" == "0" ] && { # [ "$restore_switch" = "0" ] && {
uci set $CONFIG.${id}.node=$new_node # uci set $CONFIG.${id}.node=$new_node
[ -z "$(echo $b_nodes | grep $main_node)" ] && uci add_list $CONFIG.${id}.autoswitch_backup_node=$main_node # [ -z "$(echo $b_nodes | grep $main_node)" ] && uci add_list $CONFIG.${id}.autoswitch_backup_node=$main_node
uci commit $CONFIG # uci commit $CONFIG
} # }
echolog "自动切换检测:${id}$(config_n_get $new_node type)[$(config_n_get $new_node remarks)]】正常,切换到此节点!" echolog "Socks切换检测:${id}$(config_n_get $new_node type)[$(config_n_get $new_node remarks)]】正常,切换到此节点!"
/usr/share/${CONFIG}/app.sh socks_node_switch flag=${id} new_node=${new_node} /usr/share/${CONFIG}/app.sh socks_node_switch flag=${id} new_node=${new_node}
[ $? -eq 0 ] && { [ $? -eq 0 ] && {
echolog "自动切换检测:${id}节点切换完毕!" echolog "Socks切换检测:${id}节点切换完毕!"
} }
return 0 return 0
else else
@ -157,19 +161,31 @@ start() {
main_node=$(config_n_get $id node) main_node=$(config_n_get $id node)
socks_port=$(config_n_get $id port 0) socks_port=$(config_n_get $id port 0)
delay=$(config_n_get $id autoswitch_testing_time 30) delay=$(config_n_get $id autoswitch_testing_time 30)
sleep 5s
connect_timeout=$(config_n_get $id autoswitch_connect_timeout 3) connect_timeout=$(config_n_get $id autoswitch_connect_timeout 3)
retry_num=$(config_n_get $id autoswitch_retry_num 1) retry_num=$(config_n_get $id autoswitch_retry_num 1)
restore_switch=$(config_n_get $id autoswitch_restore_switch 0) restore_switch=$(config_n_get $id autoswitch_restore_switch 0)
probe_url=$(config_n_get $id autoswitch_probe_url "https://www.google.com/generate_204") probe_url=$(config_n_get $id autoswitch_probe_url "https://www.google.com/generate_204")
backup_node=$(config_n_get $id autoswitch_backup_node) backup_node=$(config_n_get $id autoswitch_backup_node)
if [ -n "$backup_node" ]; then
backup_node=$(echo "$backup_node" | tr -s ' ' '\n' | uniq | tr -s '\n' ' ')
backup_node_num=$(printf "%s\n" "$backup_node" | wc -w)
if [ "$backup_node_num" -eq 1 ]; then
[ "$main_node" = "$backup_node" ] && return
fi
else
return
fi
while [ -n "$backup_node" ]; do while [ -n "$backup_node" ]; do
[ -f "$LOCK_FILE" ] && { [ -f "$LOCK_FILE" ] && {
sleep 6s sleep 6s
continue continue
} }
pgrep -af "${CONFIG}/" | awk '/app\.sh.*(start|stop)/ || /nftables\.sh/ || /iptables\.sh/ { found = 1 } END { exit !found }' && {
# 特定任务执行中不检测
sleep 6s
continue
}
touch $LOCK_FILE touch $LOCK_FILE
backup_node=$(echo $backup_node | tr -s ' ' '\n' | uniq | tr -s '\n' ' ')
test_auto_switch "$backup_node" test_auto_switch "$backup_node"
rm -f $LOCK_FILE rm -f $LOCK_FILE
sleep ${delay} sleep ${delay}
@ -177,4 +193,3 @@ start() {
} }
start $@ start $@

View File

@ -23,6 +23,7 @@ uci:revert(appname)
local has_ss = api.is_finded("ss-redir") local has_ss = api.is_finded("ss-redir")
local has_ss_rust = api.is_finded("sslocal") local has_ss_rust = api.is_finded("sslocal")
local has_ssr = api.is_finded("ssr-local") and api.is_finded("ssr-redir")
local has_singbox = api.finded_com("sing-box") local has_singbox = api.finded_com("sing-box")
local has_xray = api.finded_com("xray") local has_xray = api.finded_com("xray")
local has_hysteria2 = api.finded_com("hysteria") local has_hysteria2 = api.finded_com("hysteria")
@ -273,7 +274,7 @@ do
if node.balancing_node then if node.balancing_node then
for k, node in pairs(node.balancing_node) do for k, node in pairs(node.balancing_node) do
currentNodes[#currentNodes + 1] = { currentNodes[#currentNodes + 1] = {
log = false, log = true,
node = node, node = node,
currentNode = node and uci:get_all(appname, node) or nil, currentNode = node and uci:get_all(appname, node) or nil,
remarks = node, remarks = node,
@ -321,7 +322,7 @@ do
if node.urltest_node then if node.urltest_node then
for k, node in pairs(node.urltest_node) do for k, node in pairs(node.urltest_node) do
currentNodes[#currentNodes + 1] = { currentNodes[#currentNodes + 1] = {
log = false, log = true,
node = node, node = node,
currentNode = node and uci:get_all(appname, node) or nil, currentNode = node and uci:get_all(appname, node) or nil,
remarks = node, remarks = node,
@ -440,6 +441,10 @@ local function processData(szType, content, add_mode, add_from)
} }
--ssr://base64(host:port:protocol:method:obfs:base64pass/?obfsparam=base64param&protoparam=base64param&remarks=base64remarks&group=base64group&udpport=0&uot=0) --ssr://base64(host:port:protocol:method:obfs:base64pass/?obfsparam=base64param&protoparam=base64param&remarks=base64remarks&group=base64group&udpport=0&uot=0)
if szType == 'ssr' then if szType == 'ssr' then
if not has_ssr then
log("跳过 SSR 节点,因未安装 SSR 核心程序 shadowsocksr-libev。")
return nil
end
result.type = "SSR" result.type = "SSR"
local dat = split(content, "/%?") local dat = split(content, "/%?")
@ -466,17 +471,13 @@ local function processData(szType, content, add_mode, add_from)
result.remarks = base64Decode(params.remarks) result.remarks = base64Decode(params.remarks)
elseif szType == 'vmess' then elseif szType == 'vmess' then
local info = jsonParse(content) local info = jsonParse(content)
if has_singbox then
result.type = 'sing-box'
end
if has_xray then
result.type = 'Xray'
end
if vmess_type_default == "sing-box" and has_singbox then if vmess_type_default == "sing-box" and has_singbox then
result.type = 'sing-box' result.type = 'sing-box'
end elseif vmess_type_default == "xray" and has_xray then
if vmess_type_default == "xray" and has_xray then
result.type = "Xray" result.type = "Xray"
else
log("跳过 VMess 节点,因未适配到 VMess 核心程序,或未正确设置节点使用类型。")
return nil
end end
result.alter_id = info.aid result.alter_id = info.aid
result.address = info.add result.address = info.add
@ -593,7 +594,21 @@ local function processData(szType, content, add_mode, add_from)
return nil return nil
end end
elseif szType == "ss" then elseif szType == "ss" then
if ss_type_default == "shadowsocks-libev" and has_ss then
result.type = "SS" result.type = "SS"
elseif ss_type_default == "shadowsocks-rust" and has_ss_rust then
result.type = 'SS-Rust'
elseif ss_type_default == "xray" and has_xray then
result.type = 'Xray'
result.protocol = 'shadowsocks'
result.transport = 'raw'
elseif ss_type_default == "sing-box" and has_singbox then
result.type = 'sing-box'
result.protocol = 'shadowsocks'
else
log("跳过 SS 节点,因未适配到 SS 核心程序,或未正确设置节点使用类型。")
return nil
end
--SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ] --SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ]
--userinfo = websafe-base64-encode-utf8(method ":" password) --userinfo = websafe-base64-encode-utf8(method ":" password)
@ -623,8 +638,7 @@ local function processData(szType, content, add_mode, add_from)
local idx_pn = plugin_info:find(";") local idx_pn = plugin_info:find(";")
if idx_pn then if idx_pn then
result.plugin = plugin_info:sub(1, idx_pn - 1) result.plugin = plugin_info:sub(1, idx_pn - 1)
result.plugin_opts = result.plugin_opts = plugin_info:sub(idx_pn + 1, #plugin_info)
plugin_info:sub(idx_pn + 1, #plugin_info)
else else
result.plugin = plugin_info result.plugin = plugin_info
end end
@ -681,19 +695,6 @@ local function processData(szType, content, add_mode, add_from)
result.method = method result.method = method
result.password = password result.password = password
if ss_type_default == "shadowsocks-rust" and has_ss_rust then
result.type = 'SS-Rust'
end
if ss_type_default == "xray" and has_xray then
result.type = 'Xray'
result.protocol = 'shadowsocks'
result.transport = 'raw'
end
if ss_type_default == "sing-box" and has_singbox then
result.type = 'sing-box'
result.protocol = 'shadowsocks'
end
if result.type ~= "Xray" then if result.type ~= "Xray" then
result.method = (method:lower() == "chacha20-poly1305" and "chacha20-ietf-poly1305") or result.method = (method:lower() == "chacha20-poly1305" and "chacha20-ietf-poly1305") or
(method:lower() == "xchacha20-poly1305" and "xchacha20-ietf-poly1305") or method (method:lower() == "xchacha20-poly1305" and "xchacha20-ietf-poly1305") or method
@ -722,8 +723,7 @@ local function processData(szType, content, add_mode, add_from)
result.plugin = nil result.plugin = nil
result.plugin_opts = nil result.plugin_opts = nil
end end
end else
if result.type == "sing-box" then
result.plugin_enabled = "1" result.plugin_enabled = "1"
end end
end end
@ -822,11 +822,17 @@ local function processData(szType, content, add_mode, add_from)
result.utls = "1" result.utls = "1"
result.fingerprint = params.fp result.fingerprint = params.fp
end end
if params.ech and params.ech ~= "" then
result.ech = "1"
result.ech_config = params.ech
end
if params.security == "reality" then if params.security == "reality" then
result.reality = "1" result.reality = "1"
result.reality_publicKey = params.pbk or nil result.reality_publicKey = params.pbk or nil
result.reality_shortId = params.sid or nil result.reality_shortId = params.sid or nil
result.reality_spiderX = params.spx or nil result.reality_spiderX = params.spx or nil
result.use_mldsa65Verify = (params.pqv and params.pqv ~= "") and "1" or nil
result.reality_mldsa65Verify = params.pqv or nil
end end
end end
params.allowinsecure = params.allowinsecure or params.insecure params.allowinsecure = params.allowinsecure or params.insecure
@ -863,6 +869,7 @@ local function processData(szType, content, add_mode, add_from)
end end
if result.type == "SS-Rust" then if result.type == "SS-Rust" then
result.plugin_enabled = "1"
result.plugin = "shadow-tls" result.plugin = "shadow-tls"
result.plugin_opts = parseShadowTLSParams(params["shadow-tls"]) result.plugin_opts = parseShadowTLSParams(params["shadow-tls"])
elseif result.type == "sing-box" then elseif result.type == "sing-box" then
@ -885,10 +892,15 @@ local function processData(szType, content, add_mode, add_from)
elseif szType == "trojan" then elseif szType == "trojan" then
if trojan_type_default == "sing-box" and has_singbox then if trojan_type_default == "sing-box" and has_singbox then
result.type = 'sing-box' result.type = 'sing-box'
result.protocol = 'trojan'
elseif trojan_type_default == "xray" and has_xray then elseif trojan_type_default == "xray" and has_xray then
result.type = 'Xray' result.type = 'Xray'
end
result.protocol = 'trojan' result.protocol = 'trojan'
else
log("跳过 Trojan 节点,因未适配到 Trojan 核心程序,或未正确设置节点使用类型。")
return nil
end
local alias = "" local alias = ""
if content:find("#") then if content:find("#") then
local idx_sp = content:find("#") local idx_sp = content:find("#")
@ -1049,17 +1061,13 @@ local function processData(szType, content, add_mode, add_from)
result.group = content.airport result.group = content.airport
result.remarks = content.remarks result.remarks = content.remarks
elseif szType == "vless" then elseif szType == "vless" then
if has_singbox then
result.type = 'sing-box'
end
if has_xray then
result.type = 'Xray'
end
if vless_type_default == "sing-box" and has_singbox then if vless_type_default == "sing-box" and has_singbox then
result.type = 'sing-box' result.type = 'sing-box'
end elseif vless_type_default == "xray" and has_xray then
if vless_type_default == "xray" and has_xray then
result.type = "Xray" result.type = "Xray"
else
log("跳过 VLESS 节点,因未适配到 VLESS 核心程序,或未正确设置节点使用类型。")
return nil
end end
result.protocol = "vless" result.protocol = "vless"
local alias = "" local alias = ""
@ -1197,11 +1205,17 @@ local function processData(szType, content, add_mode, add_from)
result.utls = "1" result.utls = "1"
result.fingerprint = params.fp result.fingerprint = params.fp
end end
if params.ech and params.ech ~= "" then
result.ech = "1"
result.ech_config = params.ech
end
if params.security == "reality" then if params.security == "reality" then
result.reality = "1" result.reality = "1"
result.reality_publicKey = params.pbk or nil result.reality_publicKey = params.pbk or nil
result.reality_shortId = params.sid or nil result.reality_shortId = params.sid or nil
result.reality_spiderX = params.spx or nil result.reality_spiderX = params.spx or nil
result.use_mldsa65Verify = (params.pqv and params.pqv ~= "") and "1" or nil
result.reality_mldsa65Verify = params.pqv or nil
end end
end end
@ -1220,6 +1234,14 @@ local function processData(szType, content, add_mode, add_from)
end end
end end
elseif szType == 'hysteria' then elseif szType == 'hysteria' then
if has_singbox then
result.type = 'sing-box'
result.protocol = "hysteria"
else
log("跳过 Hysteria 节点,因未安装 Hysteria 核心程序 Sing-box。")
return nil
end
local alias = "" local alias = ""
if content:find("#") then if content:find("#") then
local idx_sp = content:find("#") local idx_sp = content:find("#")
@ -1267,10 +1289,6 @@ local function processData(szType, content, add_mode, add_from)
result.hysteria_down_mbps = params.downmbps result.hysteria_down_mbps = params.downmbps
result.hysteria_hop = params.mport result.hysteria_hop = params.mport
if has_singbox then
result.type = 'sing-box'
result.protocol = "hysteria"
end
elseif szType == 'hysteria2' or szType == 'hy2' then elseif szType == 'hysteria2' or szType == 'hy2' then
local alias = "" local alias = ""
if content:find("#") then if content:find("#") then
@ -1330,8 +1348,19 @@ local function processData(szType, content, add_mode, add_from)
if params["obfs-password"] or params["obfs_password"] then if params["obfs-password"] or params["obfs_password"] then
result.hysteria2_obfs = params["obfs-password"] or params["obfs_password"] result.hysteria2_obfs = params["obfs-password"] or params["obfs_password"]
end end
else
log("跳过 Hysteria2 节点,因未适配到 Hysteria2 核心程序,或未正确设置节点使用类型。")
return nil
end end
elseif szType == 'tuic' then elseif szType == 'tuic' then
if has_singbox then
result.type = 'sing-box'
result.protocol = "tuic"
else
log("跳过 Tuic 节点,因未安装 Tuic 核心程序 Sing-box。")
return nil
end
local alias = "" local alias = ""
if content:find("#") then if content:find("#") then
local idx_sp = content:find("#") local idx_sp = content:find("#")
@ -1384,11 +1413,15 @@ local function processData(szType, content, add_mode, add_from)
else else
result.tls_allowInsecure = allowInsecure_default and "1" or "0" result.tls_allowInsecure = allowInsecure_default and "1" or "0"
end end
result.type = 'sing-box'
result.protocol = "tuic"
elseif szType == "anytls" then elseif szType == "anytls" then
if has_singbox then
result.type = 'sing-box' result.type = 'sing-box'
result.protocol = "anytls" result.protocol = "anytls"
else
log("跳过 AnyTLS 节点,因未安装 AnyTLS 核心程序 Sing-box 1.12。")
return nil
end
local alias = "" local alias = ""
if content:find("#") then if content:find("#") then
local idx_sp = content:find("#") local idx_sp = content:find("#")
@ -1422,9 +1455,12 @@ local function processData(szType, content, add_mode, add_from)
result.address = host_port result.address = host_port
end end
result.tls = "0" result.tls = "0"
if (not params.security or params.security == "") and params.sni and params.sni ~= "" then
params.security = "tls"
end
if params.security == "tls" or params.security == "reality" then if params.security == "tls" or params.security == "reality" then
result.tls = "1" result.tls = "1"
result.tls_serverName = (params.sni and params.sni ~= "") and params.sni or params.host result.tls_serverName = params.sni
result.alpn = params.alpn result.alpn = params.alpn
if params.fp and params.fp ~= "" then if params.fp and params.fp ~= "" then
result.utls = "1" result.utls = "1"
@ -1536,7 +1572,9 @@ local function select_node(nodes, config, parentConfig)
if config.currentNode[".name"] then if config.currentNode[".name"] then
for index, node in pairs(nodes) do for index, node in pairs(nodes) do
if node[".name"] == config.currentNode[".name"] then if node[".name"] == config.currentNode[".name"] then
if config.log == nil or config.log == true then
log('更新【' .. config.remarks .. '】匹配节点:' .. node.remarks) log('更新【' .. config.remarks .. '】匹配节点:' .. node.remarks)
end
server = node[".name"] server = node[".name"]
break break
end end
@ -1704,6 +1742,9 @@ local function update_node(manual)
for _, config in pairs(CONFIG) do for _, config in pairs(CONFIG) do
if config.currentNodes and #config.currentNodes > 0 then if config.currentNodes and #config.currentNodes > 0 then
if config.remarks and config.currentNodes[1].log ~= false then
log('----【' .. config.remarks .. '】----')
end
for kk, vv in pairs(config.currentNodes) do for kk, vv in pairs(config.currentNodes) do
select_node(nodes, vv, config) select_node(nodes, vv, config)
end end
@ -1816,7 +1857,7 @@ local execute = function()
do do
local subscribe_list = {} local subscribe_list = {}
local fail_list = {} local fail_list = {}
if arg[2] then if arg[2] ~= "all" then
string.gsub(arg[2], '[^' .. "," .. ']+', function(w) string.gsub(arg[2], '[^' .. "," .. ']+', function(w)
subscribe_list[#subscribe_list + 1] = uci:get_all(appname, w) or {} subscribe_list[#subscribe_list + 1] = uci:get_all(appname, w) or {}
end) end)
@ -1826,6 +1867,8 @@ local execute = function()
end) end)
end end
local manual_sub = arg[3] == "manual"
for index, value in ipairs(subscribe_list) do for index, value in ipairs(subscribe_list) do
local cfgid = value[".name"] local cfgid = value[".name"]
local remark = value.remark local remark = value.remark
@ -1893,8 +1936,7 @@ local execute = function()
local raw_data = api.trim(stdout) local raw_data = api.trim(stdout)
local old_md5 = value.md5 or "" local old_md5 = value.md5 or ""
local new_md5 = luci.sys.exec("md5sum " .. tmp_file .. " 2>/dev/null | awk '{print $1}'"):gsub("\n", "") local new_md5 = luci.sys.exec("md5sum " .. tmp_file .. " 2>/dev/null | awk '{print $1}'"):gsub("\n", "")
os.remove(tmp_file) if not manual_sub and old_md5 == new_md5 then
if old_md5 == new_md5 then
log('订阅:【' .. remark .. '】没有变化,无需更新。') log('订阅:【' .. remark .. '】没有变化,无需更新。')
else else
parse_link(raw_data, "2", remark, cfgid) parse_link(raw_data, "2", remark, cfgid)
@ -1905,6 +1947,7 @@ local execute = function()
end end
end end
allowInsecure_default = true allowInsecure_default = true
luci.sys.call("rm -f " .. tmp_file)
filter_keyword_mode_default = uci:get(appname, "@global_subscribe[0]", "filter_keyword_mode") or "0" filter_keyword_mode_default = uci:get(appname, "@global_subscribe[0]", "filter_keyword_mode") or "0"
filter_keyword_discard_list_default = uci:get(appname, "@global_subscribe[0]", "filter_discard_list") or {} filter_keyword_discard_list_default = uci:get(appname, "@global_subscribe[0]", "filter_discard_list") or {}
filter_keyword_keep_list_default = uci:get(appname, "@global_subscribe[0]", "filter_keep_list") or {} filter_keyword_keep_list_default = uci:get(appname, "@global_subscribe[0]", "filter_keep_list") or {}
@ -1932,7 +1975,7 @@ if arg[1] then
log(debug.traceback()) log(debug.traceback())
log('发生错误, 正在恢复服务') log('发生错误, 正在恢复服务')
end) end)
log('订阅完毕...') log('订阅完毕...\n')
elseif arg[1] == "add" then elseif arg[1] == "add" then
local f = assert(io.open("/tmp/links.conf", 'r')) local f = assert(io.open("/tmp/links.conf", 'r'))
local raw = f:read('*all') local raw = f:read('*all')

View File

@ -367,6 +367,10 @@ o = s:option(Value, "fragment_interval", translate("Fragment Interval"), transla
o.default = "10-20" o.default = "10-20"
o:depends("fragment", true) o:depends("fragment", true)
o = s:option(Value, "fragment_maxsplit", translate("Fragment maxSplit"), translate("Fragmented maxSplit (byte)"))
o.default = "100-200"
o:depends("fragment", true)
o = s:option(Flag, "noise", translate("Noise"), translate("UDP noise, Under some circumstances it can bypass some UDP based protocol restrictions.")) o = s:option(Flag, "noise", translate("Noise"), translate("UDP noise, Under some circumstances it can bypass some UDP based protocol restrictions."))
o.default = 0 o.default = 0
@ -416,6 +420,13 @@ o.rmempty = false
o = s:option(Value, "delay", translate("Delay (ms)")) o = s:option(Value, "delay", translate("Delay (ms)"))
o.datatype = "or(uinteger,portrange)" o.datatype = "or(uinteger,portrange)"
o.rmempty = false o.rmempty = false
o = s:option(Value, "applyto", translate("ApplyTo (IP type)"))
o.default = "IP"
o:value("IP", "IP")
o:value("IPV4", "IPv4")
o:value("IPV6", "IPv6")
o.rmempty = false
end end
return m return m

View File

@ -64,7 +64,7 @@ msgstr ""
msgid "8 Threads" msgid "8 Threads"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:375 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:379
msgid "<font style='color:red'>" msgid "<font style='color:red'>"
msgstr "" msgstr ""
@ -173,6 +173,10 @@ msgstr ""
msgid "Apply" msgid "Apply"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:424
msgid "ApplyTo (IP type)"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:133 #: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:133
msgid "Are you sure you want to restore the client to default settings?" msgid "Are you sure you want to restore the client to default settings?"
msgstr "" msgstr ""
@ -313,7 +317,7 @@ msgstr ""
msgid "Click here to view or manage the DNS list file" msgid "Click here to view or manage the DNS list file"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:378 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:382
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:833 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:833
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1138 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1138
msgid "Click to the page" msgid "Click to the page"
@ -477,7 +481,7 @@ msgid ""
"fastest_addr (default: load_balance)." "fastest_addr (default: load_balance)."
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:416 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:420
msgid "Delay (ms)" msgid "Delay (ms)"
msgstr "" msgstr ""
@ -542,7 +546,7 @@ msgstr ""
msgid "DoT upstream (Need use wolfssl version)" msgid "DoT upstream (Need use wolfssl version)"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:403 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:407
msgid "Domain Strategy" msgid "Domain Strategy"
msgstr "" msgstr ""
@ -568,7 +572,7 @@ msgid "Edit ShadowSocksR Server"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:263 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:263
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:392 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:396
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:82 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:82
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:101 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:101
msgid "Enable" msgid "Enable"
@ -741,7 +745,7 @@ msgid ""
"Chinese CDN IP addresses" "Chinese CDN IP addresses"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:376 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:380
msgid "For specific usage, see:" msgid "For specific usage, see:"
msgstr "" msgstr ""
@ -771,10 +775,18 @@ msgstr ""
msgid "Fragment Packets" msgid "Fragment Packets"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:370
msgid "Fragment maxSplit"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:366 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:366
msgid "Fragmentation interval (ms)" msgid "Fragmentation interval (ms)"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:370
msgid "Fragmented maxSplit (byte)"
msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:362 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:362
msgid "Fragmented packet length (byte)" msgid "Fragmented packet length (byte)"
msgstr "" msgstr ""
@ -1223,7 +1235,7 @@ msgstr ""
msgid "No specify upload file." msgid "No specify upload file."
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:370 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:374
msgid "Noise" msgid "Noise"
msgstr "" msgstr ""
@ -1323,7 +1335,7 @@ msgstr ""
msgid "Oversea Mode DNS-2 (114.114.115.115)" msgid "Oversea Mode DNS-2 (114.114.115.115)"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:412 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:416
msgid "Packet" msgid "Packet"
msgstr "" msgstr ""
@ -1857,7 +1869,7 @@ msgstr ""
msgid "Tips: Dnsproxy DNS Parse List Path:" msgid "Tips: Dnsproxy DNS Parse List Path:"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:375 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:379
msgid "To send noise packets, select \"Noise\" in Xray Settings." msgid "To send noise packets, select \"Noise\" in Xray Settings."
msgstr "" msgstr ""
@ -1878,7 +1890,7 @@ msgstr ""
msgid "Trojan" msgid "Trojan"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:396 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:400
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:185 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:185
msgid "Type" msgid "Type"
msgstr "" msgstr ""
@ -1887,7 +1899,7 @@ msgstr ""
msgid "UDP" msgid "UDP"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:370 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:374
msgid "" msgid ""
"UDP noise, Under some circumstances it can bypass some UDP based protocol " "UDP noise, Under some circumstances it can bypass some UDP based protocol "
"restrictions." "restrictions."
@ -2160,7 +2172,7 @@ msgstr ""
msgid "Xray Fragment Settings" msgid "Xray Fragment Settings"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:373 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:377
msgid "Xray Noise Packets" msgid "Xray Noise Packets"
msgstr "" msgstr ""

View File

@ -66,7 +66,7 @@ msgstr ""
msgid "8 Threads" msgid "8 Threads"
msgstr "8 线程" msgstr "8 线程"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:375 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:379
msgid "<font style='color:red'>" msgid "<font style='color:red'>"
msgstr "" msgstr ""
@ -175,6 +175,10 @@ msgstr "Apple 域名解析优化"
msgid "Apply" msgid "Apply"
msgstr "应用" msgstr "应用"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:424
msgid "ApplyTo (IP type)"
msgstr "ApplyToIP 类型)"
#: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:133 #: applications/luci-app-ssr-plus/luasrc/view/shadowsocksr/backup_restore.htm:133
msgid "Are you sure you want to restore the client to default settings?" msgid "Are you sure you want to restore the client to default settings?"
msgstr "是否真的要恢复客户端默认配置?" msgstr "是否真的要恢复客户端默认配置?"
@ -315,7 +319,7 @@ msgstr "清空日志"
msgid "Click here to view or manage the DNS list file" msgid "Click here to view or manage the DNS list file"
msgstr "点击此处查看或管理 DNS 列表文件" msgstr "点击此处查看或管理 DNS 列表文件"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:378 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:382
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:833 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:833
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1138 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua:1138
msgid "Click to the page" msgid "Click to the page"
@ -487,7 +491,7 @@ msgstr ""
"定义上游逻辑模式,可选择值:负载均衡、并行查询、最快响应(默认值:负载均" "定义上游逻辑模式,可选择值:负载均衡、并行查询、最快响应(默认值:负载均"
"衡)。" "衡)。"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:416 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:420
msgid "Delay (ms)" msgid "Delay (ms)"
msgstr "延迟ms" msgstr "延迟ms"
@ -552,7 +556,7 @@ msgstr "是否要恢复客户端默认配置?"
msgid "DoT upstream (Need use wolfssl version)" msgid "DoT upstream (Need use wolfssl version)"
msgstr "DoT 上游(需使用 wolfssl 版本)" msgstr "DoT 上游(需使用 wolfssl 版本)"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:403 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:407
msgid "Domain Strategy" msgid "Domain Strategy"
msgstr "域名解析策略" msgstr "域名解析策略"
@ -578,7 +582,7 @@ msgid "Edit ShadowSocksR Server"
msgstr "编辑服务器配置" msgstr "编辑服务器配置"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:263 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:263
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:392 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:396
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:82 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server-config.lua:82
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:101 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/server.lua:101
msgid "Enable" msgid "Enable"
@ -751,7 +755,7 @@ msgid ""
"Chinese CDN IP addresses" "Chinese CDN IP addresses"
msgstr "配备中国大陆 CDN 的 Apple 域名,始终应答中国大陆 CDN 地址" msgstr "配备中国大陆 CDN 的 Apple 域名,始终应答中国大陆 CDN 地址"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:376 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:380
msgid "For specific usage, see:" msgid "For specific usage, see:"
msgstr "具体使用方法,请参见:" msgstr "具体使用方法,请参见:"
@ -781,10 +785,18 @@ msgstr "分片包长"
msgid "Fragment Packets" msgid "Fragment Packets"
msgstr "分片方式" msgstr "分片方式"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:370
msgid "Fragment maxSplit"
msgstr "分片数据包拆分"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:366 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:366
msgid "Fragmentation interval (ms)" msgid "Fragmentation interval (ms)"
msgstr "分片间隔ms" msgstr "分片间隔ms"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:370
msgid "Fragmented maxSplit (byte)"
msgstr "分片数据包的拆分数量 (byte)"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:362 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:362
msgid "Fragmented packet length (byte)" msgid "Fragmented packet length (byte)"
msgstr "分片包长 (byte)" msgstr "分片包长 (byte)"
@ -1236,7 +1248,7 @@ msgstr "你已经是最新数据,无需更新!"
msgid "No specify upload file." msgid "No specify upload file."
msgstr "没有上传证书。" msgstr "没有上传证书。"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:370 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:374
msgid "Noise" msgid "Noise"
msgstr "噪声" msgstr "噪声"
@ -1336,7 +1348,7 @@ msgstr ""
msgid "Oversea Mode DNS-2 (114.114.115.115)" msgid "Oversea Mode DNS-2 (114.114.115.115)"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:412 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:416
msgid "Packet" msgid "Packet"
msgstr "数据包" msgstr "数据包"
@ -1873,7 +1885,7 @@ msgstr "连接超时时间(单位:秒)"
msgid "Tips: Dnsproxy DNS Parse List Path:" msgid "Tips: Dnsproxy DNS Parse List Path:"
msgstr "提示Dnsproxy 的 DNS 解析列表路径:" msgstr "提示Dnsproxy 的 DNS 解析列表路径:"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:375 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:379
msgid "To send noise packets, select \"Noise\" in Xray Settings." msgid "To send noise packets, select \"Noise\" in Xray Settings."
msgstr "在 Xray 设置中勾选 “噪声” 以发送噪声包。" msgstr "在 Xray 设置中勾选 “噪声” 以发送噪声包。"
@ -1894,7 +1906,7 @@ msgstr "传输协议"
msgid "Trojan" msgid "Trojan"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:396 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:400
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:185 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/servers.lua:185
msgid "Type" msgid "Type"
msgstr "类型" msgstr "类型"
@ -1903,7 +1915,7 @@ msgstr "类型"
msgid "UDP" msgid "UDP"
msgstr "" msgstr ""
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:370 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:374
msgid "" msgid ""
"UDP noise, Under some circumstances it can bypass some UDP based protocol " "UDP noise, Under some circumstances it can bypass some UDP based protocol "
"restrictions." "restrictions."
@ -2178,7 +2190,7 @@ msgstr "XHTTP 路径"
msgid "Xray Fragment Settings" msgid "Xray Fragment Settings"
msgstr "Xray 分片设置" msgstr "Xray 分片设置"
#: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:373 #: applications/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua:377
msgid "Xray Noise Packets" msgid "Xray Noise Packets"
msgstr "Xray 噪声数据包" msgstr "Xray 噪声数据包"

View File

@ -338,13 +338,15 @@ if xray_fragment.fragment ~= "0" or (xray_fragment.noise ~= "0" and xray_noise.e
fragment = (xray_fragment.fragment == "1") and { fragment = (xray_fragment.fragment == "1") and {
packets = (xray_fragment.fragment_packets ~= "") and xray_fragment.fragment_packets or nil, packets = (xray_fragment.fragment_packets ~= "") and xray_fragment.fragment_packets or nil,
length = (xray_fragment.fragment_length ~= "") and xray_fragment.fragment_length or nil, length = (xray_fragment.fragment_length ~= "") and xray_fragment.fragment_length or nil,
interval = (xray_fragment.fragment_interval ~= "") and xray_fragment.fragment_interval or nil interval = (xray_fragment.fragment_interval ~= "") and xray_fragment.fragment_interval or nil,
maxSplit = (xray_fragment.fragment_maxsplit ~= "") and xray_fragment.fragment_maxsplit or nil
} or nil, } or nil,
noises = (xray_fragment.noise == "1" and xray_noise.enabled == "1") and { noises = (xray_fragment.noise == "1" and xray_noise.enabled == "1") and {
{ {
type = xray_noise.type, type = xray_noise.type,
packet = xray_noise.packet, packet = xray_noise.packet,
delay = xray_noise.delay:find("-") and xray_noise.delay or tonumber(xray_noise.delay) delay = xray_noise.delay:find("-") and xray_noise.delay or tonumber(xray_noise.delay),
applyTo = xray_noise.applyto
} }
} or nil } or nil
}, },

View File

@ -28,7 +28,7 @@ config proxy 'proxy'
option 'proxy_tcp_dport' '0-65535' option 'proxy_tcp_dport' '0-65535'
option 'proxy_udp_dport' '0-65535' option 'proxy_udp_dport' '0-65535'
option 'tun_timeout' '30' option 'tun_timeout' '30'
option 'tun_inverval' '1' option 'tun_interval' '1'
config subscription 'subscription' config subscription 'subscription'
option 'name' 'default' option 'name' 'default'
@ -106,10 +106,12 @@ config router_access_control
config router_access_control config router_access_control
option 'enabled' '1' option 'enabled' '1'
option 'dns' '1'
option 'proxy' '1' option 'proxy' '1'
config lan_access_control config lan_access_control
option 'enabled' '1' option 'enabled' '1'
option 'dns' '1'
option 'proxy' '1' option 'proxy' '1'
config routing 'routing' config routing 'routing'