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

View File

@ -1 +1 @@
20250718035513
20250808035959

View File

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

View File

@ -779,6 +779,18 @@ o.rmempty = false
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
m.uci:foreach(appname, "socks", function(s)
if s[".name"] == section then
@ -793,7 +805,7 @@ o.datatype = "port"
o.rmempty = false
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.datatype = "port"
end

View File

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

View File

@ -31,7 +31,7 @@ test_url() {
if /usr/bin/curl --help all | grep -q "\-\-retry-all-errors"; then
extra_params="--retry-all-errors ${extra_params}"
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
204)
status=200
@ -41,12 +41,12 @@ test_url() {
}
test_proxy() {
result=0
status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x socks5h://127.0.0.1:${socks_port}")
local result=0
local status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x socks5h://127.0.0.1:${socks_port}")
if [ "$status" = "200" ]; then
result=0
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
result=1
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
local curlx="socks5h://127.0.0.1:${_tmp_port}"
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
@ -82,14 +82,14 @@ test_node() {
}
test_auto_switch() {
flag=$(expr $flag + 1)
flag=$((flag + 1))
local b_nodes=$1
local now_node=$2
[ -z "$now_node" ] && {
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}")
else
#echolog "自动切换检测:未知错误"
#echolog "Socks切换检测:未知错误"
return 1
fi
}
@ -98,58 +98,59 @@ test_auto_switch() {
main_node=$now_node
}
status=$(test_proxy)
if [ "$status" == 2 ]; then
echolog "自动切换检测:无法连接到网络,请检查网络是否正常!"
local status=$(test_proxy)
if [ "$status" = "2" ]; then
echolog "Socks切换检测:无法连接到网络,请检查网络是否正常!"
return 2
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}
[ $? -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}
[ $? -eq 0 ] && {
echolog "自动切换检测:${id}节点切换完毕!"
echolog "Socks切换检测:${id}节点切换完毕!"
}
return 0
}
fi
if [ "$status" == 0 ]; then
#echolog "自动切换检测:${id}【$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】正常。"
if [ "$status" = "0" ]; then
#echolog "Socks切换检测:${id}【$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】正常。"
return 0
elif [ "$status" == 1 ]; then
echolog "自动切换检测:${id}$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】异常,切换到下一个备用节点检测!"
local new_node
in_backup_nodes=$(echo $b_nodes | grep $now_node)
# 判断当前节点是否存在于备用节点列表里
if [ -z "$in_backup_nodes" ]; then
# 如果不存在,设置第一个节点为新的节点
new_node=$(echo $b_nodes | awk -F ' ' '{print $1}')
elif [ "$status" = "1" ]; then
local new_node msg
if [ "$backup_node_num" -gt 1 ]; then
# 有多个后备节点时
local first_node found node
for node in $b_nodes; do
[ -z "$first_node" ] && first_node="$node" # 记录第一个节点
[ "$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
# 如果存在,设置下一个备用节点为新的节点
#local count=$(expr $(echo $b_nodes | grep -o ' ' | wc -l) + 1)
local next_node=$(echo $b_nodes | awk -F "$now_node" '{print $2}' | awk -F " " '{print $1}')
if [ -z "$next_node" ]; then
new_node=$(echo $b_nodes | awk -F ' ' '{print $1}')
else
new_node=$next_node
fi
# 只有一个后备节点时,与主节点轮询
new_node=$([ "$now_node" = "$main_node" ] && echo "$b_nodes" || echo "$main_node")
msg="切换到$([ "$now_node" = "$main_node" ] && echo 备用节点 || echo 主节点)检测!"
fi
echolog "Socks切换检测${id}$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】异常,$msg"
test_node ${new_node}
if [ $? -eq 0 ]; then
[ "$restore_switch" == "0" ] && {
uci set $CONFIG.${id}.node=$new_node
[ -z "$(echo $b_nodes | grep $main_node)" ] && uci add_list $CONFIG.${id}.autoswitch_backup_node=$main_node
uci commit $CONFIG
}
echolog "自动切换检测:${id}$(config_n_get $new_node type)[$(config_n_get $new_node remarks)]】正常,切换到此节点!"
# [ "$restore_switch" = "0" ] && {
# uci set $CONFIG.${id}.node=$new_node
# [ -z "$(echo $b_nodes | grep $main_node)" ] && uci add_list $CONFIG.${id}.autoswitch_backup_node=$main_node
# uci commit $CONFIG
# }
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}
[ $? -eq 0 ] && {
echolog "自动切换检测:${id}节点切换完毕!"
echolog "Socks切换检测:${id}节点切换完毕!"
}
return 0
else
@ -166,12 +167,20 @@ start() {
main_node=$(config_n_get $id node)
socks_port=$(config_n_get $id port 0)
delay=$(config_n_get $id autoswitch_testing_time 30)
sleep 5s
connect_timeout=$(config_n_get $id autoswitch_connect_timeout 3)
retry_num=$(config_n_get $id autoswitch_retry_num 1)
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")
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
[ -f "$LOCK_FILE" ] && {
sleep 6s
@ -183,7 +192,6 @@ start() {
continue
}
touch $LOCK_FILE
backup_node=$(echo $backup_node | tr -s ' ' '\n' | uniq | tr -s '\n' ' ')
test_auto_switch "$backup_node"
rm -f $LOCK_FILE
sleep ${delay}
@ -191,4 +199,3 @@ start() {
}
start $@

View File

@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall2
PKG_VERSION:=25.7.15
PKG_VERSION:=25.8.9
PKG_RELEASE:=1
PKG_CONFIG_DEPENDS:= \
@ -123,7 +123,7 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server
config PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs
bool "Include Simple-Obfs (Shadowsocks Plugin)"
select PACKAGE_simple-obfs
select PACKAGE_simple-obfs-client
default y
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, "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_manual"}, call("subscribe_manual")).leaf = true
entry({"admin", "services", appname, "subscribe_manual_all"}, call("subscribe_manual_all")).leaf = true
--[[Components update]]
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"], "chain_proxy")
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)
if (uci:get(appname, w, "add_mode") or "0") == "2" then
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")
http.status(200, "OK")
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(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
m.uci:foreach(appname, "socks", function(s)
if s[".name"] == section then

View File

@ -53,6 +53,37 @@ function s.remove(e, t)
m:set(s[".name"], "node", "default")
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
local add_from = m:get(t, "add_from") or ""
if add_from ~= "" then

View File

@ -51,6 +51,11 @@ if api.is_js_luci() then
end
end
m.render = function(self, ...)
Map.render(self, ...)
api.optimize_cbi_ui()
end
-- [[ Subscribe Settings ]]--
s = m:section(TypedSection, "global_subscribe", "")
s.anonymous = true
@ -136,15 +141,15 @@ function o.cfgvalue(self, section)
translate("Delete All Subscribe Node"))
end
o = s:option(Button, "_update", translate("Manual subscription All"))
o.inputstyle = "apply"
function o.write(t, n)
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start > /dev/null 2>&1 &")
m.no_commit = true
luci.http.redirect(api.url("log"))
o = s:option(DummyValue, "_update", translate("Manual subscription All"))
o.rawhtml = true
o.cfgvalue = function(self, section)
return string.format([[
<button type="button" class="cbi-button cbi-button-apply" onclick="ManualSubscribeAll()">%s</button>]],
translate("Manual subscription All"))
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.anonymous = true
s.sortable = true
@ -205,12 +210,12 @@ function o.cfgvalue(self, section)
remark, translate("Delete the subscribed node"))
end
o = s:option(Button, "_update", translate("Manual subscription"))
o.inputstyle = "apply"
function o.write(t, n)
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start " .. n .. " > /dev/null 2>&1 &")
m.no_commit = true
luci.http.redirect(api.url("log"))
o = s:option(DummyValue, "_update", translate("Manual subscription"))
o.rawhtml = true
o.cfgvalue = function(self, section)
return string.format([[
<button type="button" class="cbi-button cbi-button-apply" onclick="ManualSubscribe('%s')">%s</button>]],
section, translate("Manual subscription"))
end
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)
end
m.render = function(self, ...)
Map.render(self, ...)
api.optimize_cbi_ui()
end
local has_ss = api.is_finded("ss-redir")
local has_ss_rust = api.is_finded("sslocal")
local has_singbox = api.finded_com("sing-box")

View File

@ -234,6 +234,9 @@ if has_xray then
end
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.anonymous = true
s.addremove = false
@ -243,6 +246,7 @@ if has_singbox then
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.")
if not version_ge_1_12_0 then
o = s:option(Value, "geoip_path", translate("Custom geoip Path"))
o.default = "/usr/share/singbox/geoip.db"
o.rmempty = false
@ -279,6 +283,17 @@ if has_singbox then
os.remove(geosite_path)
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

View File

@ -136,6 +136,11 @@ domain_list.validate = function(self, value)
flag = 0
elseif host:find("ext:") and host:find("ext:") == 1 then
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
flag = 0
end
@ -147,13 +152,21 @@ domain_list.validate = function(self, value)
end
return value
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'.")
.. "</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><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>" .. 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>" .. translate("Pre-defined domain list: Begining with 'geosite:' and the rest is a name, such as geosite:google or geosite:cn.")
.. "</li><li>" .. translate("Annotation: Begining with #")
.. "</li></ul>"
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'.") .. "</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>"
.. "<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>" .. 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>" .. translate("Pre-defined domain list: Begining with 'geosite:' and the rest is a name, such as geosite:google or geosite:cn.") .. "</li>"
.. "<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.rows = 10
ip_list.wrap = "off"
@ -164,6 +177,11 @@ ip_list.validate = function(self, value)
for index, ipmask in ipairs(ipmasks) do
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("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
else
if not (datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask)) then
@ -173,10 +191,18 @@ ip_list.validate = function(self, value)
end
return value
end
ip_list.description = "<br /><ul><li>" .. translate("IP: such as '127.0.0.1'.")
.. "</li><li>" .. translate("CIDR: such as '127.0.0.0/8'.")
.. "</li><li>" .. translate("GeoIP: such as 'geoip:cn'. It begins with geoip: (lower case) and followed by two letter of country code.")
.. "</li><li>" .. translate("Annotation: Begining with #")
.. "</li></ul>"
ip_list.description = "<br /><ul>"
.. "<li>" .. translate("IP: such as '127.0.0.1'.") .. "</li>"
.. "<li>" .. translate("CIDR: such as '127.0.0.0/8'.") .. "</li>"
.. "<li>" .. translate("GeoIP: such as 'geoip:cn'. It begins with geoip: (lower case) and followed by two letter of country code.") .. "</li>"
.. "<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

View File

@ -135,7 +135,7 @@ if api.compare_versions(xray_version, ">=", "1.8.10") then
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")] = "leastLoad" })
@ -379,6 +379,19 @@ o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translat
o.default = "0"
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部分 ]] --
o = s:option(Value, _n("reality_publicKey"), translate("Public Key"))
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("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:value("raw", "RAW (TCP)")
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("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"))
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("obfs-local") then o:value("obfs-local") 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:depends({ [_n("plugin")] = "xray-plugin"})
o:depends({ [_n("plugin")] = "v2ray-plugin"})
o:depends({ [_n("plugin")] = "obfs-local"})
o:depends({ [_n("plugin")] = "shadow-tls"})
o:depends({ [_n("plugin_enabled")] = true })
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("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"))
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("obfs-local") then o:value("obfs-local") end
o:depends({ [_n("plugin_enabled")] = true })
o = s:option(Value, _n("plugin_opts"), translate("opts"))
o:depends({ [_n("plugin")] = "xray-plugin"})
o:depends({ [_n("plugin")] = "v2ray-plugin"})
o:depends({ [_n("plugin")] = "obfs-local"})
o:depends({ [_n("plugin_enabled")] = true })
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: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.default = "1.3"
-- o:value("1.3")
@ -223,6 +236,19 @@ o.validate = function(self, value, t)
return nil
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:value("raw", "RAW")
o:value("mkcp", "mKCP")

View File

@ -55,7 +55,8 @@ function uci_save(cursor, config, commit, apply)
end
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
function sh_uci_set(config, section, option, val, commit)
@ -1208,6 +1209,9 @@ function is_js_luci()
end
function set_apply_on_parse(map)
if not map then
return
end
if is_js_luci() == true then
map.apply_on_parse = false
map.on_after_apply = function(self)
@ -1217,6 +1221,10 @@ function set_apply_on_parse(map)
end
end
end
map.render = function(self, ...)
getmetatable(self).__index.render(self, ...) -- 保持原渲染流程
optimize_cbi_ui()
end
end
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
return result
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 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
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
_M.hysteria = {

View File

@ -28,6 +28,7 @@ function gen_config_server(node)
return config
end
local plugin_sh, plugin_bin
function gen_config(var)
local node_id = var["-node"]
@ -55,6 +56,13 @@ function gen_config(var)
end
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 = {
server = server,
server_port = tonumber(server_port),
@ -68,10 +76,8 @@ function gen_config(var)
}
if node.type == "SS" then
if node.plugin and node.plugin ~= "none" then
config.plugin = node.plugin
config.plugin_opts = node.plugin_opts or nil
end
config.plugin = plugin_file or nil
config.plugin_opts = (plugin_file) and node.plugin_opts or nil
config.mode = mode
elseif node.type == "SSR" then
config.protocol = node.protocol
@ -87,8 +93,8 @@ function gen_config(var)
method = node.method,
password = node.password,
timeout = tonumber(node.timeout),
plugin = (node.plugin and node.plugin ~= "none") and node.plugin or nil,
plugin_opts = (node.plugin and node.plugin ~= "none") and node.plugin_opts or nil
plugin = plugin_file or nil,
plugin_opts = (plugin_file) and node.plugin_opts or nil
}
},
locals = {},
@ -119,5 +125,15 @@ if arg[1] then
local func =_G[arg[1]]
if func then
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

View File

@ -8,8 +8,9 @@ local fs = api.fs
local CACHE_PATH = api.CACHE_PATH
local split = api.split
local local_version = api.get_app_version("sing-box")
local version_ge_1_11_0 = api.compare_versions(local_version:match("[^v]+"), ">=", "1.11.0")
local local_version = api.get_app_version("sing-box"):match("[^v]+")
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
@ -31,9 +32,13 @@ function gen_outbound(flag, node, tag, proxy_table)
end
local proxy_tag = nil
local fragment = nil
local record_fragment = nil
local run_socks_instance = true
if proxy_table ~= nil and type(proxy_table) == "table" then
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
end
@ -98,6 +103,8 @@ function gen_outbound(flag, node, tag, proxy_table)
alpn = alpn, --支持的应用层协议协商列表,按优先顺序排列。如果两个对等点都支持 ALPN则选择的协议将是此列表中的一个如果没有相互支持的协议则连接将失败。
--min_version = "1.2",
--max_version = "1.3",
fragment = fragment,
record_fragment = record_fragment,
ech = {
enabled = (node.ech == "1") and true or false,
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,
server_name = node.tls_serverName,
insecure = (node.tls_allowInsecure == "1") and true or false,
fragment = fragment,
record_fragment = record_fragment,
alpn = (node.hysteria_alpn and node.hysteria_alpn ~= "") and {
node.hysteria_alpn
} or nil,
@ -361,6 +370,8 @@ function gen_outbound(flag, node, tag, proxy_table)
enabled = true,
server_name = node.tls_serverName,
insecure = (node.tls_allowInsecure == "1") and true or false,
fragment = fragment,
record_fragment = record_fragment,
alpn = (node.tuic_alpn and node.tuic_alpn ~= "") and {
node.tuic_alpn
} or nil,
@ -398,6 +409,8 @@ function gen_outbound(flag, node, tag, proxy_table)
enabled = true,
server_name = node.tls_serverName,
insecure = (node.tls_allowInsecure == "1") and true or false,
fragment = fragment,
record_fragment = record_fragment,
ech = {
enabled = (node.ech == "1") and true or false,
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 inbounds = {}
local outbounds = {}
local rule_set_table = {}
local COMMON = {}
local CACHE_TEXT_FILE = CACHE_PATH .. "/cache_" .. flag .. ".txt"
@ -878,6 +892,45 @@ function gen_config(var)
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
if node_id then
node = uci:get_all(appname, node_id)
@ -978,7 +1031,7 @@ function gen_config(var)
end
if is_new_ut_node then
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
outbound.tag = outbound.tag .. ":" .. ut_node.remarks
table.insert(outbounds, outbound)
@ -1144,8 +1197,19 @@ function gen_config(var)
})
end
end
local _outbound = gen_outbound(flag, _node, rule_name, { tag = use_proxy and preproxy_tag or nil, run_socks_instance = not no_run})
local proxy_table = {
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
_outbound.tag = _outbound.tag .. ":" .. _node.remarks
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
end
local rule_set = {}
if e.domain_list then
local domain_table = {
outboundTag = outboundTag,
@ -1282,6 +1348,7 @@ function gen_config(var)
domain_keyword = {},
domain_regex = {},
geosite = {},
rule_set = {},
}
string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w)
if w:find("#") == 1 then return end
@ -1293,6 +1360,13 @@ function gen_config(var)
table.insert(domain_table.domain, w:sub(1 + #"full:"))
elseif w:find("domain:") == 1 then
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
table.insert(domain_table.domain_keyword, w)
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_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.rule_set = #domain_table.rule_set > 0 and domain_table.rule_set or nil
if outboundTag then
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("geoip:") == 1 then
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
table.insert(ip_cidr, w)
end
@ -1323,6 +1404,7 @@ function gen_config(var)
rule.ip_cidr = #ip_cidr > 0 and ip_cidr or nil
rule.geoip = #geoip > 0 and geoip or nil
end
rule.rule_set = #rule_set > 0 and rule_set or nil
table.insert(rules, rule)
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))
end
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
outbound.tag = outbound.tag .. ":" .. node.remarks
COMMON.default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds)
@ -1488,7 +1570,7 @@ function gen_config(var)
--按分流顺序DNS
if dns_domain_rules and #dns_domain_rules > 0 then
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 = {
server = value.outboundTag,
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_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,
rule_set = (value.rule_set and #value.rule_set > 0) and value.rule_set or nil,
disable_cache = false,
}
if value.outboundTag ~= "block" and value.outboundTag ~= "direct" then
@ -1590,6 +1673,13 @@ function gen_config(var)
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
local config = {
log = {
@ -1713,6 +1803,24 @@ function gen_config(var)
})
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)
end
end

View File

@ -154,14 +154,16 @@ function gen_outbound(flag, node, tag, proxy_table)
tlsSettings = (node.stream_security == "tls") and {
serverName = node.tls_serverName,
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,
realitySettings = (node.stream_security == "reality") and {
serverName = node.tls_serverName,
publicKey = node.reality_publicKey,
shortId = node.reality_shortId 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,
rawSettings = ((node.transport == "raw" or node.transport == "tcp") and node.protocol ~= "socks" and (node.tcp_guise and node.tcp_guise ~= "none")) and {
header = {
@ -460,7 +462,8 @@ function gen_config_server(node)
certificateFile = node.tls_certificateFile,
keyFile = node.tls_keyFile
}
}
},
echServerKeys = (node.ech == "1") and node.ech_key or nil
} or nil,
rawSettings = (node.transport == "raw" or node.transport == "tcp") and {
header = {
@ -545,7 +548,8 @@ function gen_config_server(node)
dest = node.reality_dest,
serverNames = node.reality_serverNames or {},
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
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))
end
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
outbound.tag = outbound.tag .. ":" .. node.remarks
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("sid", dom_prefix + "reality_shortId");
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) {
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 += opt.query("alpn", dom_prefix + "alpn");
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) {
@ -404,7 +407,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("path", dom_prefix + "ws_path");
if (v_type == "sing-box" && opt.get(dom_prefix + "ws_enableEarlyData").checked) {
var ws_maxEarlyData = opt.get(dom_prefix + "ws_maxEarlyData").value;
params += "?ed=" + ws_maxEarlyData;
params += encodeURIComponent("?ed=" + ws_maxEarlyData);
}
} else if (v_transport === "h2") {
v_transport = "http";
@ -440,7 +443,11 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
}
params += "&type=" + v_transport;
if (v_type === "sing-box") {
params += "&encryption=none";
} else {
params += opt.query("encryption", dom_prefix + "encryption");
}
if (opt.get(dom_prefix + "tls").checked) {
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("sid", dom_prefix + "reality_shortId");
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) {
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 += opt.query("alpn", dom_prefix + "alpn");
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);
@ -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("sid", dom_prefix + "reality_shortId");
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) {
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 += opt.query("alpn", dom_prefix + "alpn");
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);
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 + 'fingerprint', queryParam.fp);
}
opt.set(dom_prefix + 'ech', !!queryParam.ech);
opt.set(dom_prefix + 'ech_config', queryParam.ech || '');
}
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_shortId', queryParam.sid || '');
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_") {
opt.set(dom_prefix + 'plugin_enabled', true);
opt.set(dom_prefix + 'plugin', "shadow-tls");
let shadowtlsOpt = parseShadowTLSParams(queryParam["shadow-tls"]);
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 + 'fingerprint', queryParam.fp);
}
opt.set(dom_prefix + 'ech', !!queryParam.ech);
opt.set(dom_prefix + 'ech_config', queryParam.ech || '');
}
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_shortId', queryParam.sid || '');
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] || '');
}
}
if ((!queryParam.security || queryParam.security == "") && queryParam.sni && queryParam.sni != "") {
queryParam.security = "tls";
}
if (queryParam.security) {
if (queryParam.security == "tls") {
opt.set(dom_prefix + 'tls', true);

View File

@ -3,6 +3,8 @@ local api = require "luci.passwall2.api"
-%>
<script type="text/javascript">
//<![CDATA[
var appname = "<%= api.appname %>"
function confirmDeleteNode(remark) {
if (!confirm("<%:Delete the subscribed node%>: " + remark + " ?"))
return false;
@ -34,5 +36,76 @@ local api = require "luci.passwall2.api"
});
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>

View File

@ -98,10 +98,13 @@ msgid "When selected, devices in LAN can transparent proxy. Otherwise, it will n
msgstr "当勾选时,局域网内的设备可以透明代理。否则,将不代理。但您仍然可以使用访问控制允许指定的设备代理。"
msgid "Socks Config"
msgstr "Socks配置"
msgstr "Socks 配置"
msgid "Socks Node"
msgstr "Socks节点"
msgstr "Socks 节点"
msgid "Current Node"
msgstr "当前节点"
msgid "Listen Port"
msgstr "监听端口"
@ -343,7 +346,7 @@ msgstr "负载均衡策略"
msgid "Fallback Node"
msgstr "后备节点"
msgid "Use Custome Probe URL"
msgid "Use Custom Probe URL"
msgstr "使用自定义探测网址"
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"
msgstr "订阅网址访问方式"
msgid "Please input the subscription url first, save and submit before manual subscription."
msgstr "请输入订阅网址保存应用后再手动订阅。"
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 "新增订阅请先保存并应用后再手动订阅;如仅修改订阅地址,可直接手动订阅,系统将自动保存。"
msgid "Please save and apply before manually subscribing."
msgstr "请先保存并应用后再手动订阅。"
msgid "Subscribe URL cannot be empty."
msgstr "订阅网址不能为空。"
msgid "Subscribe via proxy"
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'."
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."
msgstr "预定义域名列表:由'geosite:'开头余下部分是一个名称如geosite:google或者geosite:cn。"
@ -1126,6 +1141,9 @@ msgstr "快速打开"
msgid "plugin"
msgstr "插件"
msgid "Supports custom SIP003 plugins, Make sure the plugin is installed."
msgstr "支持自定义 SIP003 插件,请确保插件已安装。"
msgid "opts"
msgstr "插件选项"
@ -1547,10 +1565,10 @@ msgid "Protocol parameter. Enable length block encryption."
msgstr "协议参数。启用长度块加密。"
msgid "ECH Config"
msgstr "ECH 密钥"
msgstr "ECH 配置"
msgid "ECH Key"
msgstr "ECH 配置"
msgstr "ECH 密钥"
msgid "PQ signature schemes"
msgstr "后量子对等证书签名方案"
@ -1585,6 +1603,12 @@ msgstr "分片间隔"
msgid "Fragmentation interval (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"
msgstr "噪声"

View File

@ -51,7 +51,7 @@ config global_rules
config global_app
option xray_file '/usr/bin/xray'
option hysteria_file '/usr/bin/hysteria'
option singbox_file '/usr/bin/sing-box'
option sing_box_file '/usr/bin/sing-box'
config global_subscribe
option filter_keyword_mode '1'
@ -112,6 +112,7 @@ alibaba.cdn.steampipe.steamcontent.com
# 国内游戏geosite域名
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
@ -181,13 +182,13 @@ steamcloud-sydney.storage.googleapis.com
steamcloud-taiwan.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'
option network 'tcp,udp'
option remarks 'Direct'
option ip_list 'geoip:private
114.114.114.114
option ip_list '114.114.114.114
114.114.115.115
223.5.5.5
223.6.6.6
@ -219,17 +220,20 @@ domain:xn--ngstr-lra8j.com'
config shunt_rules 'Netflix'
option remarks 'Netflix'
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'
option remarks 'OpenAI'
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'
option network 'tcp,udp'
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
91.108.4.0/22
91.108.56.0/24
@ -258,8 +262,10 @@ config shunt_rules 'Proxy'
config shunt_rules 'China'
option remarks 'China'
option network 'tcp,udp'
option ip_list 'geoip:cn'
option domain_list 'geosite:cn'
option ip_list 'geoip: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'
option remarks 'QUIC'

View File

@ -297,11 +297,11 @@ get_singbox_geoip() {
local geoip_code="$1"
local geoip_path=$(config_t_get global_singbox geoip_path)
[ -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
[ -f "${geoip_path}" ] && local geoip_md5=$(md5sum ${geoip_path} | awk '{print $1}')
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
ipv4)
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"
_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" ] && _extra_param="${_extra_param} -flag $flag"
@ -552,7 +552,7 @@ run_singbox() {
}
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() {
@ -604,7 +604,7 @@ run_socks() {
sing-box)
[ "$http_port" != "0" ] && {
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"
}
[ -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"
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)
[ "$http_port" != "0" ] && {
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"
}
[ -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
;;
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
;;
ss-rust)
local _extra_param
[ "$http_port" != "0" ] && {
http_flag=1
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g")
local _extra_param="-local_http_address $bind -local_http_port $http_port"
config_file="${config_file//SOCKS/HTTP_SOCKS}"
_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
[ -n "$no_run" ] || ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v
@ -652,7 +661,7 @@ run_socks() {
hysteria2)
[ "$http_port" != "0" ] && {
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"
}
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
[ -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
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
@ -688,9 +697,17 @@ socks_node_switch() {
local flag new_node
eval_set_val $@
[ -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
rm -rf $TMP_PATH/SOCKS_${flag}*
rm -rf $TMP_PATH/HTTP2SOCKS_${flag}*
for prefix in "" "HTTP_" "HTTP2"; do
rm -rf "$TMP_PATH/${prefix}SOCKS_${flag}"*
done
for filename in $(ls ${TMP_SCRIPT_FUNC_PATH}); do
cmd=$(cat ${TMP_SCRIPT_FUNC_PATH}/${filename})
@ -1312,7 +1329,15 @@ stop() {
eval_cache_var
[ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh stop
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 -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
@ -1402,7 +1427,7 @@ get_config() {
set_cache_var GLOBAL_DNSMASQ_CONF_PATH ${GLOBAL_ACL_PATH}/dnsmasq.d
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

View File

@ -1,13 +1,19 @@
#!/bin/sh
export PATH=/usr/sbin:/usr/bin:/sbin:/bin:/root/bin
CONFIG=passwall2
listen_address=$1
listen_port=$2
server_address=$3
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"
if [ -f "$probe_file" ]; then
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"
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
200|204)

View File

@ -27,7 +27,7 @@ test_url() {
if /usr/bin/curl --help all | grep -q "\-\-retry-all-errors"; then
extra_params="--retry-all-errors ${extra_params}"
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
204)
status=200
@ -37,12 +37,12 @@ test_url() {
}
test_proxy() {
result=0
status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x socks5h://127.0.0.1:${socks_port}")
local result=0
local status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x socks5h://127.0.0.1:${socks_port}")
if [ "$status" = "200" ]; then
result=0
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
result=1
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
local curlx="socks5h://127.0.0.1:${_tmp_port}"
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
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
return 0
fi
@ -75,14 +78,14 @@ test_node() {
}
test_auto_switch() {
flag=$(expr $flag + 1)
flag=$((flag + 1))
local b_nodes=$1
local now_node=$2
[ -z "$now_node" ] && {
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}")
else
#echolog "自动切换检测:未知错误"
#echolog "Socks切换检测:未知错误"
return 1
fi
}
@ -91,58 +94,59 @@ test_auto_switch() {
main_node=$now_node
}
status=$(test_proxy)
if [ "$status" == 2 ]; then
echolog "自动切换检测:无法连接到网络,请检查网络是否正常!"
local status=$(test_proxy)
if [ "$status" = "2" ]; then
echolog "Socks切换检测:无法连接到网络,请检查网络是否正常!"
return 2
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}
[ $? -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}
[ $? -eq 0 ] && {
echolog "自动切换检测:${id}节点切换完毕!"
echolog "Socks切换检测:${id}节点切换完毕!"
}
return 0
}
fi
if [ "$status" == 0 ]; then
#echolog "自动切换检测:${id}【$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】正常。"
if [ "$status" = "0" ]; then
#echolog "Socks切换检测:${id}【$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】正常。"
return 0
elif [ "$status" == 1 ]; then
echolog "自动切换检测:${id}$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】异常,切换到下一个备用节点检测!"
local new_node
in_backup_nodes=$(echo $b_nodes | grep $now_node)
# 判断当前节点是否存在于备用节点列表里
if [ -z "$in_backup_nodes" ]; then
# 如果不存在,设置第一个节点为新的节点
new_node=$(echo $b_nodes | awk -F ' ' '{print $1}')
elif [ "$status" = "1" ]; then
local new_node msg
if [ "$backup_node_num" -gt 1 ]; then
# 有多个后备节点时
local first_node found node
for node in $b_nodes; do
[ -z "$first_node" ] && first_node="$node" # 记录第一个节点
[ "$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
# 如果存在,设置下一个备用节点为新的节点
#local count=$(expr $(echo $b_nodes | grep -o ' ' | wc -l) + 1)
local next_node=$(echo $b_nodes | awk -F "$now_node" '{print $2}' | awk -F " " '{print $1}')
if [ -z "$next_node" ]; then
new_node=$(echo $b_nodes | awk -F ' ' '{print $1}')
else
new_node=$next_node
fi
# 只有一个后备节点时,与主节点轮询
new_node=$([ "$now_node" = "$main_node" ] && echo "$b_nodes" || echo "$main_node")
msg="切换到$([ "$now_node" = "$main_node" ] && echo 备用节点 || echo 主节点)检测!"
fi
echolog "Socks切换检测${id}$(config_n_get $now_node type)[$(config_n_get $now_node remarks)]】异常,$msg"
test_node ${new_node}
if [ $? -eq 0 ]; then
[ "$restore_switch" == "0" ] && {
uci set $CONFIG.${id}.node=$new_node
[ -z "$(echo $b_nodes | grep $main_node)" ] && uci add_list $CONFIG.${id}.autoswitch_backup_node=$main_node
uci commit $CONFIG
}
echolog "自动切换检测:${id}$(config_n_get $new_node type)[$(config_n_get $new_node remarks)]】正常,切换到此节点!"
# [ "$restore_switch" = "0" ] && {
# uci set $CONFIG.${id}.node=$new_node
# [ -z "$(echo $b_nodes | grep $main_node)" ] && uci add_list $CONFIG.${id}.autoswitch_backup_node=$main_node
# uci commit $CONFIG
# }
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}
[ $? -eq 0 ] && {
echolog "自动切换检测:${id}节点切换完毕!"
echolog "Socks切换检测:${id}节点切换完毕!"
}
return 0
else
@ -157,19 +161,31 @@ start() {
main_node=$(config_n_get $id node)
socks_port=$(config_n_get $id port 0)
delay=$(config_n_get $id autoswitch_testing_time 30)
sleep 5s
connect_timeout=$(config_n_get $id autoswitch_connect_timeout 3)
retry_num=$(config_n_get $id autoswitch_retry_num 1)
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")
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
[ -f "$LOCK_FILE" ] && {
sleep 6s
continue
}
pgrep -af "${CONFIG}/" | awk '/app\.sh.*(start|stop)/ || /nftables\.sh/ || /iptables\.sh/ { found = 1 } END { exit !found }' && {
# 特定任务执行中不检测
sleep 6s
continue
}
touch $LOCK_FILE
backup_node=$(echo $backup_node | tr -s ' ' '\n' | uniq | tr -s '\n' ' ')
test_auto_switch "$backup_node"
rm -f $LOCK_FILE
sleep ${delay}
@ -177,4 +193,3 @@ start() {
}
start $@

View File

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

View File

@ -344,78 +344,89 @@ o.rmempty = false
-- [[ fragmen Settings ]]--
if is_finded("xray") then
s = m:section(TypedSection, "global_xray_fragment", translate("Xray Fragment Settings"))
s.anonymous = true
s = m:section(TypedSection, "global_xray_fragment", translate("Xray Fragment Settings"))
s.anonymous = true
o = s:option(Flag, "fragment", translate("Fragment"), translate("TCP fragments, which can deceive the censorship system in some cases, such as bypassing SNI blacklists."))
o.default = 0
o = s:option(Flag, "fragment", translate("Fragment"), translate("TCP fragments, which can deceive the censorship system in some cases, such as bypassing SNI blacklists."))
o.default = 0
o = s:option(ListValue, "fragment_packets", translate("Fragment Packets"), translate("\"1-3\" is for segmentation at TCP layer, applying to the beginning 1 to 3 data writes by the client. \"tlshello\" is for TLS client hello packet fragmentation."))
o.default = "tlshello"
o:value("tlshello", "tlshello")
o:value("1-1", "1-1")
o:value("1-2", "1-2")
o:value("1-3", "1-3")
o:value("1-5", "1-5")
o:depends("fragment", true)
o = s:option(ListValue, "fragment_packets", translate("Fragment Packets"), translate("\"1-3\" is for segmentation at TCP layer, applying to the beginning 1 to 3 data writes by the client. \"tlshello\" is for TLS client hello packet fragmentation."))
o.default = "tlshello"
o:value("tlshello", "tlshello")
o:value("1-1", "1-1")
o:value("1-2", "1-2")
o:value("1-3", "1-3")
o:value("1-5", "1-5")
o:depends("fragment", true)
o = s:option(Value, "fragment_length", translate("Fragment Length"), translate("Fragmented packet length (byte)"))
o.default = "100-200"
o:depends("fragment", true)
o = s:option(Value, "fragment_length", translate("Fragment Length"), translate("Fragmented packet length (byte)"))
o.default = "100-200"
o:depends("fragment", true)
o = s:option(Value, "fragment_interval", translate("Fragment Interval"), translate("Fragmentation interval (ms)"))
o.default = "10-20"
o:depends("fragment", true)
o = s:option(Value, "fragment_interval", translate("Fragment Interval"), translate("Fragmentation interval (ms)"))
o.default = "10-20"
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.default = 0
o = s:option(Value, "fragment_maxsplit", translate("Fragment maxSplit"), translate("Fragmented maxSplit (byte)"))
o.default = "100-200"
o:depends("fragment", true)
s = m:section(TypedSection, "xray_noise_packets", translate("Xray Noise Packets"))
s.description = translate(
o = s:option(Flag, "noise", translate("Noise"), translate("UDP noise, Under some circumstances it can bypass some UDP based protocol restrictions."))
o.default = 0
s = m:section(TypedSection, "xray_noise_packets", translate("Xray Noise Packets"))
s.description = translate(
"<font style='color:red'>" .. translate("To send noise packets, select \"Noise\" in Xray Settings.") .. "</font>" ..
"<br/><font><b>" .. translate("For specific usage, see:") .. "</b></font>" ..
"<a href='https://xtls.github.io/config/outbounds/freedom.html' target='_blank'>" ..
"<font style='color:green'><b>" .. translate("Click to the page") .. "</b></font></a>")
s.template = "cbi/tblsection"
s.sortable = true
s.anonymous = true
s.addremove = true
s.template = "cbi/tblsection"
s.sortable = true
s.anonymous = true
s.addremove = true
s.remove = function(self, section)
s.remove = function(self, section)
for k, v in pairs(self.children) do
v.rmempty = true
v.validate = nil
end
TypedSection.remove(self, section)
end
end
o = s:option(Flag, "enabled", translate("Enable"))
o.default = 1
o.rmempty = false
o = s:option(Flag, "enabled", translate("Enable"))
o.default = 1
o.rmempty = false
o = s:option(ListValue, "type", translate("Type"))
o.default = "base64"
o:value("rand", "rand")
o:value("str", "str")
o:value("hex", "hex")
o:value("base64", "base64")
o = s:option(ListValue, "type", translate("Type"))
o.default = "base64"
o:value("rand", "rand")
o:value("str", "str")
o:value("hex", "hex")
o:value("base64", "base64")
o = s:option(Value, "domainStrategy", translate("Domain Strategy"))
o.default = "UseIP"
o:value("AsIs", "AsIs")
o:value("UseIP", "UseIP")
o:value("UseIPv4", "UseIPv4")
o:value("ForceIP", "ForceIP")
o:value("ForceIPv4", "ForceIPv4")
o.rmempty = false
o = s:option(Value, "domainStrategy", translate("Domain Strategy"))
o.default = "UseIP"
o:value("AsIs", "AsIs")
o:value("UseIP", "UseIP")
o:value("UseIPv4", "UseIPv4")
o:value("ForceIP", "ForceIP")
o:value("ForceIPv4", "ForceIPv4")
o.rmempty = false
o = s:option(Value, "packet", translate("Packet"))
o.datatype = "minlength(1)"
o.rmempty = false
o = s:option(Value, "packet", translate("Packet"))
o.datatype = "minlength(1)"
o.rmempty = false
o = s:option(Value, "delay", translate("Delay (ms)"))
o.datatype = "or(uinteger,portrange)"
o.rmempty = false
o = s:option(Value, "delay", translate("Delay (ms)"))
o.datatype = "or(uinteger,portrange)"
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
return m

View File

@ -64,7 +64,7 @@ msgstr ""
msgid "8 Threads"
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'>"
msgstr ""
@ -173,6 +173,10 @@ msgstr ""
msgid "Apply"
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
msgid "Are you sure you want to restore the client to default settings?"
msgstr ""
@ -313,7 +317,7 @@ msgstr ""
msgid "Click here to view or manage the DNS list file"
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:1138
msgid "Click to the page"
@ -477,7 +481,7 @@ msgid ""
"fastest_addr (default: load_balance)."
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)"
msgstr ""
@ -542,7 +546,7 @@ msgstr ""
msgid "DoT upstream (Need use wolfssl version)"
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"
msgstr ""
@ -568,7 +572,7 @@ msgid "Edit ShadowSocksR Server"
msgstr ""
#: 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.lua:101
msgid "Enable"
@ -741,7 +745,7 @@ msgid ""
"Chinese CDN IP addresses"
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:"
msgstr ""
@ -771,10 +775,18 @@ msgstr ""
msgid "Fragment Packets"
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
msgid "Fragmentation interval (ms)"
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
msgid "Fragmented packet length (byte)"
msgstr ""
@ -1223,7 +1235,7 @@ msgstr ""
msgid "No specify upload file."
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"
msgstr ""
@ -1323,7 +1335,7 @@ msgstr ""
msgid "Oversea Mode DNS-2 (114.114.115.115)"
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"
msgstr ""
@ -1857,7 +1869,7 @@ msgstr ""
msgid "Tips: Dnsproxy DNS Parse List Path:"
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."
msgstr ""
@ -1878,7 +1890,7 @@ msgstr ""
msgid "Trojan"
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
msgid "Type"
msgstr ""
@ -1887,7 +1899,7 @@ msgstr ""
msgid "UDP"
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 ""
"UDP noise, Under some circumstances it can bypass some UDP based protocol "
"restrictions."
@ -2160,7 +2172,7 @@ msgstr ""
msgid "Xray Fragment Settings"
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"
msgstr ""

View File

@ -66,7 +66,7 @@ msgstr ""
msgid "8 Threads"
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'>"
msgstr ""
@ -175,6 +175,10 @@ msgstr "Apple 域名解析优化"
msgid "Apply"
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
msgid "Are you sure you want to restore the client to default settings?"
msgstr "是否真的要恢复客户端默认配置?"
@ -315,7 +319,7 @@ msgstr "清空日志"
msgid "Click here to view or manage the DNS list file"
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:1138
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)"
msgstr "延迟ms"
@ -552,7 +556,7 @@ msgstr "是否要恢复客户端默认配置?"
msgid "DoT upstream (Need use wolfssl version)"
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"
msgstr "域名解析策略"
@ -578,7 +582,7 @@ msgid "Edit ShadowSocksR Server"
msgstr "编辑服务器配置"
#: 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.lua:101
msgid "Enable"
@ -751,7 +755,7 @@ msgid ""
"Chinese CDN IP addresses"
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:"
msgstr "具体使用方法,请参见:"
@ -781,10 +785,18 @@ msgstr "分片包长"
msgid "Fragment Packets"
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
msgid "Fragmentation interval (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
msgid "Fragmented packet length (byte)"
msgstr "分片包长 (byte)"
@ -1236,7 +1248,7 @@ msgstr "你已经是最新数据,无需更新!"
msgid "No specify upload file."
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"
msgstr "噪声"
@ -1336,7 +1348,7 @@ msgstr ""
msgid "Oversea Mode DNS-2 (114.114.115.115)"
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"
msgstr "数据包"
@ -1873,7 +1885,7 @@ msgstr "连接超时时间(单位:秒)"
msgid "Tips: Dnsproxy DNS Parse List Path:"
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."
msgstr "在 Xray 设置中勾选 “噪声” 以发送噪声包。"
@ -1894,7 +1906,7 @@ msgstr "传输协议"
msgid "Trojan"
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
msgid "Type"
msgstr "类型"
@ -1903,7 +1915,7 @@ msgstr "类型"
msgid "UDP"
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 ""
"UDP noise, Under some circumstances it can bypass some UDP based protocol "
"restrictions."
@ -2178,7 +2190,7 @@ msgstr "XHTTP 路径"
msgid "Xray Fragment Settings"
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"
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 {
packets = (xray_fragment.fragment_packets ~= "") and xray_fragment.fragment_packets 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,
noises = (xray_fragment.noise == "1" and xray_noise.enabled == "1") and {
{
type = xray_noise.type,
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
},

View File

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