mirror of
https://github.com/bol-van/zapret.git
synced 2025-05-24 22:32:58 +03:00
Compare commits
42 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
8b4b8c3fb0 | ||
|
228572afb5 | ||
|
ebb89c48e0 | ||
|
067be122b3 | ||
|
a4632ef6d7 | ||
|
c964677913 | ||
|
e0f8ff06b9 | ||
|
34e632a1f8 | ||
|
4adeb9499b | ||
|
149a7ed927 | ||
|
f22dcb2487 | ||
|
794336a509 | ||
|
d8082fbaec | ||
|
abb3cd3316 | ||
|
7f0eccb39c | ||
|
f8bf9bbb38 | ||
|
1548c86f87 | ||
|
bb74fa765a | ||
|
ee5d4c5017 | ||
|
d04eb28c7f | ||
|
ce2a51a137 | ||
|
4f37c19771 | ||
|
9d43dfdc71 | ||
|
b176af43a4 | ||
|
a6ef91124e | ||
|
1a722c1b78 | ||
|
2452a529eb | ||
|
daac1d2127 | ||
|
acfd844a49 | ||
|
2464d27550 | ||
|
1fdf5477b4 | ||
|
6686c4a190 | ||
|
e979f88963 | ||
|
840292e7d9 | ||
|
43cd263cff | ||
|
d8c07baab7 | ||
|
6e8dbb045a | ||
|
8446470de3 | ||
|
552ddee0da | ||
|
6be62d775b | ||
|
d59c77a899 | ||
|
37b5651976 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1,4 +1,5 @@
|
||||
* text=auto eol=lf
|
||||
binaries/win64/readme.txt eol=crlf
|
||||
binaries/win32/readme.txt eol=crlf
|
||||
*.cmd eol=crlf
|
||||
*.bat eol=crlf
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,7 +4,6 @@ mdig/mdig
|
||||
nfq/nfqws
|
||||
tpws/tpws
|
||||
binaries/my/
|
||||
binaries/win64/zapret-winws/autohostlist.txt
|
||||
init.d/**/custom
|
||||
ipset/zapret-ip*.txt
|
||||
ipset/zapret-ip*.gz
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
binaries/win32/WinDivert.dll
Normal file
BIN
binaries/win32/WinDivert.dll
Normal file
Binary file not shown.
BIN
binaries/win32/WinDivert32.sys
Normal file
BIN
binaries/win32/WinDivert32.sys
Normal file
Binary file not shown.
BIN
binaries/win32/cygwin1.dll
Normal file
BIN
binaries/win32/cygwin1.dll
Normal file
Binary file not shown.
BIN
binaries/win32/ip2net.exe
Normal file
BIN
binaries/win32/ip2net.exe
Normal file
Binary file not shown.
BIN
binaries/win32/killall.exe
Normal file
BIN
binaries/win32/killall.exe
Normal file
Binary file not shown.
BIN
binaries/win32/mdig.exe
Normal file
BIN
binaries/win32/mdig.exe
Normal file
Binary file not shown.
8
binaries/win32/readme.txt
Normal file
8
binaries/win32/readme.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
From this folder winws can be started only standalone.
|
||||
To run from cygwin shell delete, rename or move cygwin1.dll.
|
||||
Cygwin refuses to start winws if a copy of cygwin1.dll is present !
|
||||
|
||||
How to get win7 and winws compatible version of cygwin :
|
||||
|
||||
curl -O https://www.cygwin.com/setup-x86_64.exe
|
||||
setup-x86_64.exe --allow-unsupported-windows --no-verify --site http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2024/01/30/231215
|
BIN
binaries/win32/winws.exe
Normal file
BIN
binaries/win32/winws.exe
Normal file
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,5 @@
|
||||
Standalone version in zapret-winws folder !!
|
||||
From this folder winws can be started only from cygwin shell.
|
||||
|
||||
From this folder winws can be started only standalone.
|
||||
To run from cygwin shell delete, rename or move cygwin1.dll.
|
||||
Cygwin refuses to start winws if a copy of cygwin1.dll is present !
|
||||
|
||||
How to get win7 and winws compatible version of cygwin :
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,721 +0,0 @@
|
||||
5.200.14.249
|
||||
18.165.140.0/25
|
||||
23.227.38.74
|
||||
34.0.48.0/24
|
||||
34.0.49.64/26
|
||||
34.0.50.0/25
|
||||
34.0.51.0/24
|
||||
34.0.52.0/22
|
||||
34.0.56.0/23
|
||||
34.0.59.0/24
|
||||
34.0.60.0/24
|
||||
34.0.62.128/25
|
||||
34.0.63.228
|
||||
34.0.64.0/23
|
||||
34.0.66.130
|
||||
34.0.82.140
|
||||
34.0.129.128/25
|
||||
34.0.130.0/24
|
||||
34.0.131.130
|
||||
34.0.132.139
|
||||
34.0.133.75
|
||||
34.0.134.0/24
|
||||
34.0.135.251
|
||||
34.0.136.51
|
||||
34.0.137.0/24
|
||||
34.0.139.0/24
|
||||
34.0.140.0/23
|
||||
34.0.142.0/25
|
||||
34.0.144.0/23
|
||||
34.0.146.0/24
|
||||
34.0.148.25
|
||||
34.0.149.101
|
||||
34.0.151.0/25
|
||||
34.0.153.0/24
|
||||
34.0.155.0/24
|
||||
34.0.156.101
|
||||
34.0.157.0/25
|
||||
34.0.158.247
|
||||
34.0.159.188
|
||||
34.0.192.0/25
|
||||
34.0.193.0/24
|
||||
34.0.194.0/24
|
||||
34.0.195.172
|
||||
34.0.196.200/29
|
||||
34.0.197.81
|
||||
34.0.198.25
|
||||
34.0.199.0/24
|
||||
34.0.200.0/24
|
||||
34.0.201.81
|
||||
34.0.202.34
|
||||
34.0.203.0/24
|
||||
34.0.204.0/23
|
||||
34.0.206.0/25
|
||||
34.0.207.0/25
|
||||
34.0.208.195
|
||||
34.0.209.0/24
|
||||
34.0.210.20
|
||||
34.0.211.0/26
|
||||
34.0.212.0/24
|
||||
34.0.213.64/26
|
||||
34.0.215.128/25
|
||||
34.0.216.238
|
||||
34.0.217.0/24
|
||||
34.0.218.83
|
||||
34.0.220.103
|
||||
34.0.221.0/24
|
||||
34.0.222.193
|
||||
34.0.223.68
|
||||
34.0.227.0/24
|
||||
34.0.240.0/21
|
||||
34.0.248.0/23
|
||||
34.0.250.0/24
|
||||
34.0.251.0/25
|
||||
34.1.216.0/24
|
||||
34.1.221.166
|
||||
35.207.64.0/23
|
||||
35.207.67.116
|
||||
35.207.71.0/24
|
||||
35.207.72.32
|
||||
35.207.73.0/24
|
||||
35.207.74.0/24
|
||||
35.207.75.128/25
|
||||
35.207.76.128/26
|
||||
35.207.77.0/24
|
||||
35.207.78.129
|
||||
35.207.79.0/24
|
||||
35.207.80.76
|
||||
35.207.81.248/30
|
||||
35.207.82.0/23
|
||||
35.207.84.0/24
|
||||
35.207.85.160
|
||||
35.207.86.41
|
||||
35.207.87.184
|
||||
35.207.89.188
|
||||
35.207.91.146
|
||||
35.207.92.230
|
||||
35.207.95.0/24
|
||||
35.207.97.174
|
||||
35.207.99.134
|
||||
35.207.100.64/26
|
||||
35.207.101.130
|
||||
35.207.103.64/26
|
||||
35.207.104.0/24
|
||||
35.207.106.128/26
|
||||
35.207.107.19
|
||||
35.207.108.192/27
|
||||
35.207.109.185
|
||||
35.207.110.0/24
|
||||
35.207.111.174
|
||||
35.207.114.16
|
||||
35.207.115.163
|
||||
35.207.116.51
|
||||
35.207.117.0/24
|
||||
35.207.121.204
|
||||
35.207.122.0/25
|
||||
35.207.124.145
|
||||
35.207.125.116
|
||||
35.207.126.30
|
||||
35.207.129.0/24
|
||||
35.207.131.128/27
|
||||
35.207.132.247
|
||||
35.207.135.147
|
||||
35.207.136.69
|
||||
35.207.137.0/24
|
||||
35.207.139.0/24
|
||||
35.207.140.241
|
||||
35.207.141.119
|
||||
35.207.142.0/24
|
||||
35.207.143.96/27
|
||||
35.207.144.0/25
|
||||
35.207.145.0/24
|
||||
35.207.146.89
|
||||
35.207.147.0/24
|
||||
35.207.149.0/24
|
||||
35.207.150.0/24
|
||||
35.207.151.61
|
||||
35.207.153.117
|
||||
35.207.154.0/24
|
||||
35.207.155.128/25
|
||||
35.207.156.254
|
||||
35.207.157.7
|
||||
35.207.158.192
|
||||
35.207.160.160
|
||||
35.207.162.239
|
||||
35.207.163.0/24
|
||||
35.207.164.0/25
|
||||
35.207.165.147
|
||||
35.207.166.0/25
|
||||
35.207.167.0/24
|
||||
35.207.168.116
|
||||
35.207.170.0/23
|
||||
35.207.172.0/24
|
||||
35.207.174.55
|
||||
35.207.176.128/25
|
||||
35.207.178.0/24
|
||||
35.207.180.152
|
||||
35.207.181.76
|
||||
35.207.182.125
|
||||
35.207.184.101
|
||||
35.207.185.192
|
||||
35.207.186.128/25
|
||||
35.207.187.228
|
||||
35.207.188.0/24
|
||||
35.207.189.0/25
|
||||
35.207.190.194
|
||||
35.207.191.64/26
|
||||
35.207.193.165
|
||||
35.207.195.75
|
||||
35.207.196.0/24
|
||||
35.207.198.0/23
|
||||
35.207.201.186
|
||||
35.207.202.169
|
||||
35.207.205.211
|
||||
35.207.207.4
|
||||
35.207.209.0/25
|
||||
35.207.210.191
|
||||
35.207.211.253
|
||||
35.207.213.97
|
||||
35.207.214.0/24
|
||||
35.207.220.147
|
||||
35.207.221.58
|
||||
35.207.222.105
|
||||
35.207.224.151
|
||||
35.207.225.210
|
||||
35.207.227.0/24
|
||||
35.207.229.212
|
||||
35.207.232.26
|
||||
35.207.234.182
|
||||
35.207.238.0/24
|
||||
35.207.240.0/24
|
||||
35.207.245.0/24
|
||||
35.207.249.0/24
|
||||
35.207.250.212
|
||||
35.207.251.0/27
|
||||
35.212.4.134
|
||||
35.212.12.148
|
||||
35.212.88.11
|
||||
35.212.102.50
|
||||
35.212.111.0/26
|
||||
35.212.117.247
|
||||
35.212.120.122
|
||||
35.213.0.0/24
|
||||
35.213.2.8
|
||||
35.213.4.185
|
||||
35.213.6.118
|
||||
35.213.7.128/25
|
||||
35.213.8.168
|
||||
35.213.10.0/24
|
||||
35.213.11.21
|
||||
35.213.12.224/27
|
||||
35.213.13.19
|
||||
35.213.14.217
|
||||
35.213.16.67
|
||||
35.213.17.235
|
||||
35.213.23.166
|
||||
35.213.25.164
|
||||
35.213.26.62
|
||||
35.213.27.252
|
||||
35.213.32.0/24
|
||||
35.213.33.74
|
||||
35.213.34.204
|
||||
35.213.37.81
|
||||
35.213.38.186
|
||||
35.213.39.253
|
||||
35.213.42.0/24
|
||||
35.213.43.79
|
||||
35.213.45.0/24
|
||||
35.213.46.136
|
||||
35.213.49.17
|
||||
35.213.50.0/24
|
||||
35.213.51.213
|
||||
35.213.52.0/25
|
||||
35.213.53.0/24
|
||||
35.213.54.0/24
|
||||
35.213.56.0/25
|
||||
35.213.59.0/24
|
||||
35.213.61.58
|
||||
35.213.65.0/24
|
||||
35.213.67.0/24
|
||||
35.213.68.192/26
|
||||
35.213.70.151
|
||||
35.213.72.128/25
|
||||
35.213.73.245
|
||||
35.213.74.131
|
||||
35.213.78.0/24
|
||||
35.213.79.137
|
||||
35.213.80.0/25
|
||||
35.213.83.128/25
|
||||
35.213.84.245
|
||||
35.213.85.0/24
|
||||
35.213.88.145
|
||||
35.213.89.80/28
|
||||
35.213.90.0/24
|
||||
35.213.91.195
|
||||
35.213.92.0/24
|
||||
35.213.93.254
|
||||
35.213.94.78
|
||||
35.213.95.145
|
||||
35.213.96.87
|
||||
35.213.98.0/24
|
||||
35.213.99.126
|
||||
35.213.101.214
|
||||
35.213.102.0/24
|
||||
35.213.105.0/24
|
||||
35.213.106.128/25
|
||||
35.213.107.158
|
||||
35.213.109.0/24
|
||||
35.213.110.40
|
||||
35.213.111.0/25
|
||||
35.213.115.0/25
|
||||
35.213.120.0/24
|
||||
35.213.122.0/24
|
||||
35.213.124.89
|
||||
35.213.125.40
|
||||
35.213.126.185
|
||||
35.213.127.0/24
|
||||
35.213.128.0/22
|
||||
35.213.132.0/23
|
||||
35.213.134.140
|
||||
35.213.135.0/24
|
||||
35.213.136.0/23
|
||||
35.213.138.128/25
|
||||
35.213.139.0/24
|
||||
35.213.140.0/25
|
||||
35.213.141.164
|
||||
35.213.142.128/25
|
||||
35.213.143.0/24
|
||||
35.213.144.0/22
|
||||
35.213.148.0/23
|
||||
35.213.150.0/24
|
||||
35.213.152.0/23
|
||||
35.213.154.137
|
||||
35.213.155.134
|
||||
35.213.156.144
|
||||
35.213.157.0/24
|
||||
35.213.158.64/26
|
||||
35.213.160.90
|
||||
35.213.161.253
|
||||
35.213.162.0/25
|
||||
35.213.163.0/24
|
||||
35.213.164.0/23
|
||||
35.213.166.106
|
||||
35.213.167.160/27
|
||||
35.213.168.0/24
|
||||
35.213.169.179
|
||||
35.213.170.0/24
|
||||
35.213.171.201
|
||||
35.213.172.159
|
||||
35.213.173.0/24
|
||||
35.213.174.128/25
|
||||
35.213.175.128/26
|
||||
35.213.176.0/24
|
||||
35.213.177.0/25
|
||||
35.213.179.139
|
||||
35.213.180.0/24
|
||||
35.213.181.0/25
|
||||
35.213.182.0/23
|
||||
35.213.184.0/23
|
||||
35.213.186.70
|
||||
35.213.187.0/24
|
||||
35.213.188.128/25
|
||||
35.213.190.158
|
||||
35.213.191.0/24
|
||||
35.213.192.240/31
|
||||
35.213.193.74
|
||||
35.213.194.0/25
|
||||
35.213.195.178
|
||||
35.213.196.38
|
||||
35.213.197.68
|
||||
35.213.198.0/23
|
||||
35.213.200.0/23
|
||||
35.213.202.0/25
|
||||
35.213.203.195
|
||||
35.213.204.32/27
|
||||
35.213.205.170
|
||||
35.213.207.128/25
|
||||
35.213.208.85
|
||||
35.213.210.0/24
|
||||
35.213.211.176/29
|
||||
35.213.212.0/24
|
||||
35.213.213.225
|
||||
35.213.214.0/25
|
||||
35.213.215.255
|
||||
35.213.217.0/24
|
||||
35.213.218.248
|
||||
35.213.219.0/25
|
||||
35.213.220.211
|
||||
35.213.221.0/24
|
||||
35.213.222.215
|
||||
35.213.223.0/24
|
||||
35.213.225.0/24
|
||||
35.213.227.227
|
||||
35.213.229.17
|
||||
35.213.230.89
|
||||
35.213.231.0/24
|
||||
35.213.233.0/24
|
||||
35.213.234.134
|
||||
35.213.236.0/24
|
||||
35.213.237.212
|
||||
35.213.238.0/24
|
||||
35.213.240.212
|
||||
35.213.241.0/24
|
||||
35.213.242.10
|
||||
35.213.243.219
|
||||
35.213.244.146
|
||||
35.213.245.119
|
||||
35.213.246.0/23
|
||||
35.213.249.79
|
||||
35.213.250.0/24
|
||||
35.213.251.74
|
||||
35.213.252.0/24
|
||||
35.213.253.155
|
||||
35.213.254.89
|
||||
35.214.128.248
|
||||
35.214.129.220
|
||||
35.214.130.217
|
||||
35.214.131.144
|
||||
35.214.132.189
|
||||
35.214.133.0/24
|
||||
35.214.134.163
|
||||
35.214.137.0/24
|
||||
35.214.138.0/25
|
||||
35.214.140.0/24
|
||||
35.214.142.0/24
|
||||
35.214.143.41
|
||||
35.214.144.26
|
||||
35.214.145.200
|
||||
35.214.146.9
|
||||
35.214.147.135
|
||||
35.214.148.89
|
||||
35.214.149.110
|
||||
35.214.151.128/25
|
||||
35.214.152.0/24
|
||||
35.214.156.115
|
||||
35.214.158.181
|
||||
35.214.159.128/25
|
||||
35.214.160.128/25
|
||||
35.214.161.217
|
||||
35.214.162.0/24
|
||||
35.214.163.28
|
||||
35.214.165.102
|
||||
35.214.167.77
|
||||
35.214.169.0/24
|
||||
35.214.170.2
|
||||
35.214.171.0/25
|
||||
35.214.172.128/25
|
||||
35.214.173.0/24
|
||||
35.214.175.0/24
|
||||
35.214.177.183
|
||||
35.214.179.46
|
||||
35.214.180.0/23
|
||||
35.214.184.179
|
||||
35.214.185.28
|
||||
35.214.186.3
|
||||
35.214.187.0/24
|
||||
35.214.191.0/24
|
||||
35.214.192.128/25
|
||||
35.214.193.0/24
|
||||
35.214.194.128/25
|
||||
35.214.195.0/25
|
||||
35.214.196.64/26
|
||||
35.214.197.0/24
|
||||
35.214.198.7
|
||||
35.214.199.224
|
||||
35.214.201.0/25
|
||||
35.214.203.155
|
||||
35.214.204.0/23
|
||||
35.214.207.0/24
|
||||
35.214.208.128/25
|
||||
35.214.209.64
|
||||
35.214.210.0/24
|
||||
35.214.211.3
|
||||
35.214.212.64/26
|
||||
35.214.213.0/25
|
||||
35.214.214.0/24
|
||||
35.214.215.64/26
|
||||
35.214.216.0/23
|
||||
35.214.218.140
|
||||
35.214.219.0/24
|
||||
35.214.220.149
|
||||
35.214.221.0/24
|
||||
35.214.222.149
|
||||
35.214.223.0/24
|
||||
35.214.224.71
|
||||
35.214.225.0/24
|
||||
35.214.226.0/23
|
||||
35.214.228.0/23
|
||||
35.214.231.187
|
||||
35.214.233.8
|
||||
35.214.235.38
|
||||
35.214.237.0/24
|
||||
35.214.238.0/25
|
||||
35.214.239.0/24
|
||||
35.214.240.87
|
||||
35.214.241.0/24
|
||||
35.214.243.21
|
||||
35.214.244.0/24
|
||||
35.214.245.16/28
|
||||
35.214.246.106
|
||||
35.214.248.119
|
||||
35.214.249.154
|
||||
35.214.250.0/24
|
||||
35.214.251.128/25
|
||||
35.214.252.187
|
||||
35.214.253.0/24
|
||||
35.214.255.154
|
||||
35.215.72.85
|
||||
35.215.73.65
|
||||
35.215.83.0
|
||||
35.215.108.111
|
||||
35.215.115.120
|
||||
35.215.126.35
|
||||
35.215.127.34
|
||||
35.215.128.0/21
|
||||
35.215.136.0/26
|
||||
35.215.137.0/24
|
||||
35.215.138.0/23
|
||||
35.215.140.0/24
|
||||
35.215.141.64/27
|
||||
35.215.142.0/24
|
||||
35.215.143.83
|
||||
35.215.144.128/25
|
||||
35.215.145.0/24
|
||||
35.215.146.0/24
|
||||
35.215.147.86
|
||||
35.215.148.0/23
|
||||
35.215.150.0/26
|
||||
35.215.151.0/24
|
||||
35.215.152.0/24
|
||||
35.215.153.128/25
|
||||
35.215.154.240/28
|
||||
35.215.155.20
|
||||
35.215.156.0/24
|
||||
35.215.158.0/23
|
||||
35.215.160.192/26
|
||||
35.215.161.0/24
|
||||
35.215.163.0/24
|
||||
35.215.164.0/24
|
||||
35.215.165.236
|
||||
35.215.166.128/25
|
||||
35.215.167.128/25
|
||||
35.215.168.0/24
|
||||
35.215.169.12
|
||||
35.215.170.0/23
|
||||
35.215.172.0/22
|
||||
35.215.176.0/24
|
||||
35.215.177.72
|
||||
35.215.178.0/24
|
||||
35.215.179.161
|
||||
35.215.180.0/22
|
||||
35.215.184.253
|
||||
35.215.185.64/26
|
||||
35.215.186.0/25
|
||||
35.215.187.0/24
|
||||
35.215.188.0/23
|
||||
35.215.190.0/24
|
||||
35.215.191.61
|
||||
35.215.192.0/23
|
||||
35.215.194.192/28
|
||||
35.215.195.0/24
|
||||
35.215.196.0/25
|
||||
35.215.197.0/25
|
||||
35.215.198.230
|
||||
35.215.199.204
|
||||
35.215.200.0/23
|
||||
35.215.202.0/24
|
||||
35.215.203.0/25
|
||||
35.215.204.128/25
|
||||
35.215.205.0/25
|
||||
35.215.206.0/23
|
||||
35.215.208.0/24
|
||||
35.215.209.0/25
|
||||
35.215.210.0/23
|
||||
35.215.212.0/22
|
||||
35.215.216.0/22
|
||||
35.215.221.0/24
|
||||
35.215.222.128/25
|
||||
35.215.223.126
|
||||
35.215.224.0/23
|
||||
35.215.226.0/24
|
||||
35.215.227.0/25
|
||||
35.215.228.0/24
|
||||
35.215.229.64
|
||||
35.215.230.89
|
||||
35.215.231.0/24
|
||||
35.215.232.0/24
|
||||
35.215.233.0/25
|
||||
35.215.234.37
|
||||
35.215.235.0/24
|
||||
35.215.238.0/25
|
||||
35.215.239.119
|
||||
35.215.240.0/24
|
||||
35.215.241.128/25
|
||||
35.215.242.0/25
|
||||
35.215.243.0/24
|
||||
35.215.244.0/23
|
||||
35.215.246.222
|
||||
35.215.247.0/24
|
||||
35.215.248.0/22
|
||||
35.215.252.0/24
|
||||
35.215.253.118
|
||||
35.215.254.0/23
|
||||
35.217.0.0/24
|
||||
35.217.1.64/26
|
||||
35.217.2.5
|
||||
35.217.3.0/24
|
||||
35.217.4.72
|
||||
35.217.5.0/25
|
||||
35.217.6.0/24
|
||||
35.217.8.0/25
|
||||
35.217.9.0/24
|
||||
35.217.11.186
|
||||
35.217.12.0/24
|
||||
35.217.14.192/26
|
||||
35.217.15.65
|
||||
35.217.16.75
|
||||
35.217.17.128/25
|
||||
35.217.18.0/24
|
||||
35.217.19.183
|
||||
35.217.20.0/24
|
||||
35.217.21.128/25
|
||||
35.217.22.128/25
|
||||
35.217.23.128/25
|
||||
35.217.24.0/24
|
||||
35.217.25.81
|
||||
35.217.26.0/24
|
||||
35.217.27.128/25
|
||||
35.217.28.128/25
|
||||
35.217.29.0/24
|
||||
35.217.30.0/25
|
||||
35.217.31.0/25
|
||||
35.217.32.128/25
|
||||
35.217.33.0/24
|
||||
35.217.35.128/25
|
||||
35.217.36.0/23
|
||||
35.217.38.179
|
||||
35.217.39.186
|
||||
35.217.40.176
|
||||
35.217.41.204
|
||||
35.217.43.0/24
|
||||
35.217.45.248
|
||||
35.217.46.0/24
|
||||
35.217.47.128/25
|
||||
35.217.48.195
|
||||
35.217.49.160/27
|
||||
35.217.50.0/25
|
||||
35.217.51.0/24
|
||||
35.217.52.117
|
||||
35.217.53.128/25
|
||||
35.217.54.0/25
|
||||
35.217.55.96/27
|
||||
35.217.56.6
|
||||
35.217.57.184
|
||||
35.217.58.0/24
|
||||
35.217.59.64/26
|
||||
35.217.60.0/24
|
||||
35.217.61.128/25
|
||||
35.217.62.0/24
|
||||
35.217.63.128/25
|
||||
35.219.225.149
|
||||
35.219.226.57
|
||||
35.219.227.0/24
|
||||
35.219.228.37
|
||||
35.219.229.128/25
|
||||
35.219.230.0/23
|
||||
35.219.235.0/24
|
||||
35.219.236.198
|
||||
35.219.238.115
|
||||
35.219.239.0/24
|
||||
35.219.241.0/24
|
||||
35.219.242.221
|
||||
35.219.243.191
|
||||
35.219.244.1
|
||||
35.219.245.0/24
|
||||
35.219.246.159
|
||||
35.219.247.0/26
|
||||
35.219.248.0/24
|
||||
35.219.249.126
|
||||
35.219.251.186
|
||||
35.219.252.0/23
|
||||
35.219.254.0/24
|
||||
64.233.161.207
|
||||
64.233.162.207
|
||||
64.233.163.207
|
||||
64.233.164.207
|
||||
64.233.165.207
|
||||
66.22.196.0/26
|
||||
66.22.197.0/24
|
||||
66.22.198.0/26
|
||||
66.22.199.0/24
|
||||
66.22.200.0/26
|
||||
66.22.202.0/26
|
||||
66.22.204.0/24
|
||||
66.22.206.0/24
|
||||
66.22.208.0/25
|
||||
66.22.210.0/26
|
||||
66.22.212.0/24
|
||||
66.22.214.0/24
|
||||
66.22.216.0/23
|
||||
66.22.220.0/25
|
||||
66.22.221.0/24
|
||||
66.22.222.0/23
|
||||
66.22.224.0/25
|
||||
66.22.225.0/26
|
||||
66.22.226.0/25
|
||||
66.22.227.0/25
|
||||
66.22.228.0/22
|
||||
66.22.233.0/24
|
||||
66.22.234.0/24
|
||||
66.22.236.0/23
|
||||
66.22.238.0/24
|
||||
66.22.240.0/22
|
||||
66.22.244.0/23
|
||||
66.22.248.0/24
|
||||
74.125.131.207
|
||||
74.125.205.207
|
||||
104.17.51.93
|
||||
104.17.117.93
|
||||
104.18.4.161
|
||||
104.18.5.161
|
||||
104.18.8.105
|
||||
104.18.9.105
|
||||
104.18.30.128
|
||||
104.18.31.128
|
||||
104.21.2.204
|
||||
104.21.25.51
|
||||
104.21.40.151
|
||||
104.21.59.128
|
||||
104.21.72.221
|
||||
104.21.82.160
|
||||
108.177.14.207
|
||||
138.128.140.240/28
|
||||
142.250.150.207
|
||||
142.251.1.207
|
||||
162.159.128.232/30
|
||||
162.159.129.232/30
|
||||
162.159.130.232/30
|
||||
162.159.133.232/30
|
||||
162.159.134.232/30
|
||||
162.159.135.232/30
|
||||
162.159.136.232/30
|
||||
162.159.137.232/30
|
||||
162.159.138.232/30
|
||||
172.65.202.19
|
||||
172.66.41.34
|
||||
172.66.42.222
|
||||
172.67.152.224/28
|
||||
172.67.155.163
|
||||
172.67.159.89
|
||||
172.67.177.131
|
||||
172.67.222.182
|
||||
173.194.73.207
|
||||
173.194.220.207
|
||||
173.194.221.207
|
||||
173.194.222.207
|
||||
188.114.96.2
|
||||
188.114.97.2
|
||||
188.114.98.224
|
||||
188.114.99.224
|
||||
204.11.56.48
|
||||
209.85.233.207
|
Binary file not shown.
@@ -1,13 +0,0 @@
|
||||
googlevideo.com
|
||||
youtubei.googleapis.com
|
||||
ytimg.com
|
||||
yt3.ggpht.com
|
||||
yt4.ggpht.com
|
||||
youtube.com
|
||||
youtubeembeddedplayer.googleapis.com
|
||||
ytimg.l.google.com
|
||||
jnn-pa.googleapis.com
|
||||
youtube-nocookie.com
|
||||
youtube-ui.l.google.com
|
||||
yt-video-upload.l.google.com
|
||||
wide-youtube.l.google.com
|
@@ -1,9 +0,0 @@
|
||||
start "zapret: http,https,quic" /min "%~dp0winws.exe" ^
|
||||
--wf-tcp=80,443 --wf-udp=443,50000-50099 ^
|
||||
--filter-udp=50000-50099 --ipset="%~dp0ipset-discord.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-any-protocol --dpi-desync-cutoff=n2 --new ^
|
||||
--filter-udp=50000-50099 --new ^
|
||||
--filter-udp=443 --hostlist="%~dp0list-youtube.txt" --dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="%~dp0quic_initial_www_google_com.bin" --new ^
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=11 --new ^
|
||||
--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --new ^
|
||||
--filter-tcp=443 --hostlist="%~dp0list-youtube.txt" --dpi-desync=fake,split2 --dpi-desync-repeats=11 --dpi-desync-fooling=md5sig --dpi-desync-fake-tls="%~dp0tls_clienthello_www_google_com.bin" --new ^
|
||||
--dpi-desync=fake,disorder2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig
|
@@ -1,9 +0,0 @@
|
||||
start "zapret: http,https,quic" /min "%~dp0winws.exe" ^
|
||||
--wf-tcp=80,443 --wf-udp=443,50000-50099 ^
|
||||
--filter-udp=50000-50099 --ipset="%~dp0ipset-discord.txt" --dpi-desync=fake --dpi-desync-repeats=6 --dpi-desync-any-protocol --dpi-desync-cutoff=n2 --new ^
|
||||
--filter-udp=50000-50099 --new ^
|
||||
--filter-udp=443 --hostlist="%~dp0list-youtube.txt" --dpi-desync=fake --dpi-desync-repeats=11 --dpi-desync-fake-quic="%~dp0quic_initial_www_google_com.bin" --new ^
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=11 --new ^
|
||||
--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --hostlist-auto="%~dp0autohostlist.txt" --new ^
|
||||
--filter-tcp=443 --hostlist="%~dp0list-youtube.txt" --dpi-desync=fake,split2 --dpi-desync-repeats=11 --dpi-desync-fooling=md5sig --dpi-desync-fake-tls="%~dp0tls_clienthello_www_google_com.bin" --new ^
|
||||
--dpi-desync=fake,disorder2 --dpi-desync-autottl=2 --dpi-desync-fooling=md5sig --hostlist-auto="%~dp0autohostlist.txt"
|
Binary file not shown.
@@ -1 +0,0 @@
|
||||
%~dp0killall -HUP winws
|
@@ -1,12 +0,0 @@
|
||||
set ARGS=--wf-l3=ipv4,ipv6 --wf-tcp=80,443 --dpi-desync=fake,split --dpi-desync-ttl=7 --dpi-desync-fooling=md5sig
|
||||
call :srvinst winws1
|
||||
rem set ARGS=--wf-l3=ipv4,ipv6 --wf-udp=443 --dpi-desync=fake
|
||||
rem call :srvinst winws2
|
||||
goto :eof
|
||||
|
||||
:srvinst
|
||||
net stop %1
|
||||
sc delete %1
|
||||
sc create %1 binPath= "\"%~dp0winws.exe\" %ARGS%" DisplayName= "zapret DPI bypass : %1" start= auto
|
||||
sc description %1 "zapret DPI bypass software"
|
||||
sc start %1
|
@@ -1,7 +0,0 @@
|
||||
call :srvdel winws1
|
||||
rem call :srvdel winws2
|
||||
goto :eof
|
||||
|
||||
:srvdel
|
||||
net stop %1
|
||||
sc delete %1
|
@@ -1,2 +0,0 @@
|
||||
sc start winws1
|
||||
rem sc start winws2
|
@@ -1,2 +0,0 @@
|
||||
net stop winws1
|
||||
rem net stop winws2
|
@@ -1,4 +0,0 @@
|
||||
set WINWS1=--wf-l3=ipv4,ipv6 --wf-tcp=80,443 --dpi-desync=fake,split --dpi-desync-ttl=7 --dpi-desync-fooling=md5sig
|
||||
schtasks /Create /F /TN winws1 /NP /RU "" /SC onstart /TR "\"%~dp0winws.exe\" %WINWS1%"
|
||||
rem set WINWS2=--wf-l3=ipv4,ipv6 --wf-udp=443 --dpi-desync=fake
|
||||
rem schtasks /Create /F /TN winws2 /NP /RU "" /SC onstart /TR "\"%~dp0winws.exe\" %WINWS2%"
|
@@ -1,4 +0,0 @@
|
||||
schtasks /End /TN winws1
|
||||
schtasks /Delete /TN winws1 /F
|
||||
rem schtasks /End /TN winws2
|
||||
rem schtasks /Delete /TN winws2 /F
|
@@ -1,2 +0,0 @@
|
||||
schtasks /Run /TN winws1
|
||||
rem schtasks /Run /TN winws2
|
@@ -1,2 +0,0 @@
|
||||
schtasks /End /TN winws1
|
||||
rem schtasks /End /TN winws2
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
222
blockcheck.sh
222
blockcheck.sh
@@ -53,10 +53,13 @@ NFT_TABLE=blockcheck
|
||||
|
||||
DNSCHECK_DNS=${DNSCHECK_DNS:-8.8.8.8 1.1.1.1 77.88.8.1}
|
||||
DNSCHECK_DOM=${DNSCHECK_DOM:-pornhub.com ntc.party rutracker.org www.torproject.org bbc.com}
|
||||
DOH_SERVERS=${DOH_SERVERS:-"https://cloudflare-dns.com/dns-query https://dns.google/dns-query https://dns.quad9.net/dns-query https://dns.adguard.com/dns-query https://common.dot.dns.yandex.net/dns-query"}
|
||||
DNSCHECK_DIG1=/tmp/dig1.txt
|
||||
DNSCHECK_DIG2=/tmp/dig2.txt
|
||||
DNSCHECK_DIGS=/tmp/digs.txt
|
||||
|
||||
IPSET_FILE=/tmp/blockcheck_ipset.txt
|
||||
|
||||
unset PF_STATUS
|
||||
PF_RULES_SAVE=/tmp/pf-zapret-save.conf
|
||||
|
||||
@@ -129,19 +132,22 @@ opf_dvtws_anchor()
|
||||
{
|
||||
# $1 - tcp/udp
|
||||
# $2 - port
|
||||
local family=inet
|
||||
# $3 - ip list
|
||||
local iplist family=inet
|
||||
[ "$IPV" = 6 ] && family=inet6
|
||||
make_comma_list iplist "$3"
|
||||
echo "set reassemble no"
|
||||
[ "$1" = tcp ] && echo "pass in quick $family proto $1 from port $2 flags SA/SA divert-packet port $IPFW_DIVERT_PORT no state"
|
||||
echo "pass in quick $family proto $1 from port $2 no state"
|
||||
echo "pass out quick $family proto $1 to port $2 divert-packet port $IPFW_DIVERT_PORT no state"
|
||||
[ "$1" = tcp ] && echo "pass in quick $family proto $1 from {$iplist} port $2 flags SA/SA divert-packet port $IPFW_DIVERT_PORT no state"
|
||||
echo "pass in quick $family proto $1 from {$iplist} port $2 no state"
|
||||
echo "pass out quick $family proto $1 to {$iplist} port $2 divert-packet port $IPFW_DIVERT_PORT no state"
|
||||
echo "pass"
|
||||
}
|
||||
opf_prepare_dvtws()
|
||||
{
|
||||
# $1 - tcp/udp
|
||||
# $2 - port
|
||||
opf_dvtws_anchor $1 $2 | pfctl -qf -
|
||||
# $3 - ip list
|
||||
opf_dvtws_anchor $1 $2 "$3" | pfctl -qf -
|
||||
pfctl -qe
|
||||
}
|
||||
|
||||
@@ -201,6 +207,35 @@ nft_has_nfq()
|
||||
}
|
||||
return $res
|
||||
}
|
||||
|
||||
doh_resolve()
|
||||
{
|
||||
# $1 - ip version 4/6
|
||||
# $2 - hostname
|
||||
# $3 - doh server URL. use $DOH_SERVER if empty
|
||||
$MDIG --family=$1 --dns-make-query=$2 | curl -s --data-binary @- -H "Content-Type: application/dns-message" "${3:-$DOH_SERVER}" | $MDIG --dns-parse-query
|
||||
}
|
||||
doh_find_working()
|
||||
{
|
||||
local doh
|
||||
|
||||
[ -n "$DOH_SERVER" ] && return 0
|
||||
echo "* searching working DoH server"
|
||||
DOH_SERVER=
|
||||
for doh in $DOH_SERVERS; do
|
||||
echo -n "$doh : "
|
||||
if doh_resolve 4 iana.org $doh >/dev/null 2>/dev/null; then
|
||||
echo OK
|
||||
DOH_SERVER="$doh"
|
||||
return 0
|
||||
else
|
||||
echo FAIL
|
||||
fi
|
||||
done
|
||||
echo all DoH servers failed
|
||||
return 1
|
||||
}
|
||||
|
||||
mdig_vars()
|
||||
{
|
||||
# $1 - ip version 4/6
|
||||
@@ -219,7 +254,11 @@ mdig_cache()
|
||||
mdig_vars "$@"
|
||||
[ -n "$count" ] || {
|
||||
# windows version of mdig outputs 0D0A line ending. remove 0D.
|
||||
if [ "$SECURE_DNS" = 1 ]; then
|
||||
ips="$(echo $2 | doh_resolve $1 $2 | tr -d '\r' | xargs)"
|
||||
else
|
||||
ips="$(echo $2 | "$MDIG" --family=$1 | tr -d '\r' | xargs)"
|
||||
fi
|
||||
[ -n "$ips" ] || return 1
|
||||
count=0
|
||||
for ip in $ips; do
|
||||
@@ -360,7 +399,7 @@ zp_already_running()
|
||||
}
|
||||
check_already()
|
||||
{
|
||||
echo \* checking already running zapret processes
|
||||
echo \* checking already running DPI bypass processes
|
||||
if zp_already_running; then
|
||||
echo "!!! WARNING. some dpi bypass processes already running !!!"
|
||||
echo "!!! WARNING. blockcheck requires all DPI bypass methods disabled !!!"
|
||||
@@ -387,7 +426,7 @@ check_prerequisites()
|
||||
{
|
||||
echo \* checking prerequisites
|
||||
|
||||
[ "$UNAME" = Darwin -o -x "$PKTWS" ] && [ "$UNAME" = CYGWIN -o -x "$TPWS" ] && [ -x "$MDIG" ] || {
|
||||
[ "$SKIP_PKTWS" = 1 -o "$UNAME" = Darwin -o -x "$PKTWS" ] && [ "$SKIP_TPWS" = 1 -o "$UNAME" = CYGWIN -o -x "$TPWS" ] && [ -x "$MDIG" ] || {
|
||||
local target
|
||||
case $UNAME in
|
||||
Darwin)
|
||||
@@ -402,26 +441,27 @@ check_prerequisites()
|
||||
}
|
||||
|
||||
local prog progs='curl'
|
||||
[ "$SKIP_PKTWS" = 1 ] || {
|
||||
case "$UNAME" in
|
||||
Linux)
|
||||
case "$FWTYPE" in
|
||||
iptables)
|
||||
progs="$progs iptables ip6tables"
|
||||
ipt_has_nfq || {
|
||||
echo NFQUEUE iptables or ip6tables target is missing. pls install modules.
|
||||
exitp 6
|
||||
}
|
||||
progs="$progs iptables ip6tables"
|
||||
;;
|
||||
nftables)
|
||||
nft_has_nfq || {
|
||||
echo nftables queue support is not available. pls install modules.
|
||||
exitp 6
|
||||
}
|
||||
progs="$progs nft"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
FreeBSD)
|
||||
progs="$progs ipfw"
|
||||
freebsd_modules_loaded ipfw ipdivert || {
|
||||
echo ipfw or ipdivert kernel module not loaded
|
||||
exitp 6
|
||||
@@ -443,17 +483,20 @@ check_prerequisites()
|
||||
pf_restore
|
||||
}
|
||||
}
|
||||
progs="$progs ipfw"
|
||||
;;
|
||||
OpenBSD|Darwin)
|
||||
progs="$progs pfctl"
|
||||
pf_is_avail || {
|
||||
echo pf is not available
|
||||
exitp 6
|
||||
}
|
||||
# no divert sockets in MacOS
|
||||
[ "$UNAME" = "Darwin" ] && SKIP_PKTWS=1
|
||||
pf_save
|
||||
progs="$progs pfctl"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
case "$UNAME" in
|
||||
CYGWIN)
|
||||
SKIP_TPWS=1
|
||||
;;
|
||||
@@ -518,7 +561,7 @@ curl_supports_tls13()
|
||||
[ $? = 2 ] && return 1
|
||||
# curl can have tlsv1.3 key present but ssl library without TLS 1.3 support
|
||||
# this is online test because there's no other way to trigger library incompatibility case
|
||||
$CURL --tlsv1.3 --max-time $CURL_MAX_TIME -Is -o /dev/null https://w3.org 2>/dev/null
|
||||
$CURL --tlsv1.3 --max-time $CURL_MAX_TIME -Is -o /dev/null https://iana.org 2>/dev/null
|
||||
r=$?
|
||||
[ $r != 4 -a $r != 35 ]
|
||||
}
|
||||
@@ -666,13 +709,12 @@ curl_test_http3()
|
||||
curl_with_dig $1 $2 $QUIC_PORT -ISs -A "$USER_AGENT" --max-time $CURL_MAX_TIME_QUIC --http3-only $CURL_OPT "https://$2" -o /dev/null 2>&1
|
||||
}
|
||||
|
||||
ipt_scheme()
|
||||
ipt_aux_scheme()
|
||||
{
|
||||
# $1 - 1 - add , 0 - del
|
||||
# $2 - tcp/udp
|
||||
# $3 - port
|
||||
|
||||
IPT_ADD_DEL $1 OUTPUT -t mangle -p $2 --dport $3 -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK -j NFQUEUE --queue-num $QNUM
|
||||
# to avoid possible INVALID state drop
|
||||
[ "$2" = tcp ] && IPT_ADD_DEL $1 INPUT -p $2 --sport $3 ! --syn -j ACCEPT
|
||||
# for strategies with incoming packets involved (autottl)
|
||||
@@ -688,13 +730,42 @@ ipt_scheme()
|
||||
# raw table may not be present
|
||||
IPT_ADD_DEL $1 OUTPUT -t raw -m mark --mark $DESYNC_MARK/$DESYNC_MARK -j CT --notrack
|
||||
}
|
||||
ipt_scheme()
|
||||
{
|
||||
# $1 - tcp/udp
|
||||
# $2 - port
|
||||
# $3 - ip list
|
||||
|
||||
local ip
|
||||
|
||||
$IPTABLES -t mangle -N blockcheck_output 2>/dev/null
|
||||
$IPTABLES -t mangle -F blockcheck_output
|
||||
IPT OUTPUT -t mangle -j blockcheck_output
|
||||
|
||||
# prevent loop
|
||||
$IPTABLES -t mangle -A blockcheck_output -m mark --mark $DESYNC_MARK/$DESYNC_MARK -j RETURN
|
||||
$IPTABLES -t mangle -A blockcheck_output ! -p $1 -j RETURN
|
||||
$IPTABLES -t mangle -A blockcheck_output -p $1 ! --dport $2 -j RETURN
|
||||
|
||||
for ip in $3; do
|
||||
$IPTABLES -t mangle -A blockcheck_output -d $ip -j NFQUEUE --queue-num $QNUM
|
||||
done
|
||||
|
||||
ipt_aux_scheme 1 $1 $2
|
||||
}
|
||||
nft_scheme()
|
||||
{
|
||||
# $1 - tcp/udp
|
||||
# $2 - port
|
||||
# $3 - ip list
|
||||
|
||||
local iplist ipver=$IPV
|
||||
[ "$IPV" = 6 ] || ipver=
|
||||
make_comma_list iplist $3
|
||||
|
||||
nft add table inet $NFT_TABLE
|
||||
nft "add chain inet $NFT_TABLE postnat { type filter hook output priority 102; }"
|
||||
nft "add rule inet $NFT_TABLE postnat meta nfproto ipv${IPV} $1 dport $2 mark and $DESYNC_MARK != $DESYNC_MARK queue num $QNUM"
|
||||
nft "add rule inet $NFT_TABLE postnat meta nfproto ipv${IPV} $1 dport $2 mark and $DESYNC_MARK != $DESYNC_MARK ip${ipver} daddr {$iplist} queue num $QNUM"
|
||||
# for strategies with incoming packets involved (autottl)
|
||||
nft "add chain inet $NFT_TABLE prenat { type filter hook prerouting priority -102; }"
|
||||
# enable everything generated by nfqws (works only in OUTPUT, not in FORWARD)
|
||||
@@ -706,23 +777,33 @@ pktws_ipt_prepare()
|
||||
{
|
||||
# $1 - tcp/udp
|
||||
# $2 - port
|
||||
# $3 - ip list
|
||||
|
||||
local ip
|
||||
|
||||
case "$FWTYPE" in
|
||||
iptables)
|
||||
ipt_scheme 1 $1 $2
|
||||
ipt_scheme $1 $2 "$3"
|
||||
;;
|
||||
nftables)
|
||||
nft_scheme $1 $2
|
||||
nft_scheme $1 $2 "$3"
|
||||
;;
|
||||
ipfw)
|
||||
# disable PF to avoid interferences
|
||||
pf_is_avail && pfctl -qd
|
||||
IPFW_ADD divert $IPFW_DIVERT_PORT $1 from me to any $2 proto ip${IPV} out not diverted not sockarg
|
||||
for ip in $3; do
|
||||
IPFW_ADD divert $IPFW_DIVERT_PORT $1 from me to $ip $2 proto ip${IPV} out not diverted not sockarg
|
||||
done
|
||||
;;
|
||||
opf)
|
||||
opf_prepare_dvtws $1 $2
|
||||
opf_prepare_dvtws $1 $2 "$3"
|
||||
;;
|
||||
windivert)
|
||||
WF="--wf-l3=ipv${IPV} --wf-${1}=$2"
|
||||
rm -f "$IPSET_FILE"
|
||||
for ip in $3; do
|
||||
echo $ip >>"$IPSET_FILE"
|
||||
done
|
||||
;;
|
||||
|
||||
esac
|
||||
@@ -731,9 +812,13 @@ pktws_ipt_unprepare()
|
||||
{
|
||||
# $1 - tcp/udp
|
||||
# $2 - port
|
||||
|
||||
case "$FWTYPE" in
|
||||
iptables)
|
||||
ipt_scheme 0 $1 $2
|
||||
ipt_aux_scheme 0 $1 $2
|
||||
IPT_DEL OUTPUT -t mangle -j blockcheck_output
|
||||
$IPTABLES -t mangle -F blockcheck_output 2>/dev/null
|
||||
$IPTABLES -t mangle -X blockcheck_output 2>/dev/null
|
||||
;;
|
||||
nftables)
|
||||
nft delete table inet $NFT_TABLE 2>/dev/null
|
||||
@@ -747,6 +832,7 @@ pktws_ipt_unprepare()
|
||||
;;
|
||||
windivert)
|
||||
unset WF
|
||||
rm -f "$IPSET_FILE"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -754,21 +840,35 @@ pktws_ipt_unprepare()
|
||||
pktws_ipt_prepare_tcp()
|
||||
{
|
||||
# $1 - port
|
||||
# $2 - ip list
|
||||
|
||||
pktws_ipt_prepare tcp $1
|
||||
local ip iplist ipver
|
||||
|
||||
pktws_ipt_prepare tcp $1 "$2"
|
||||
|
||||
# for autottl mode
|
||||
case "$FWTYPE" in
|
||||
iptables)
|
||||
# for autottl
|
||||
IPT INPUT -t mangle -p tcp --sport $1 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:1 -j NFQUEUE --queue-num $QNUM
|
||||
$IPTABLES -N blockcheck_input -t mangle 2>/dev/null
|
||||
$IPTABLES -F blockcheck_input -t mangle 2>/dev/null
|
||||
IPT INPUT -t mangle -j blockcheck_input
|
||||
$IPTABLES -t mangle -A blockcheck_input ! -p tcp -j RETURN
|
||||
$IPTABLES -t mangle -A blockcheck_input -p tcp ! --sport $1 -j RETURN
|
||||
$IPTABLES -t mangle -A blockcheck_input -p tcp ! --tcp-flags SYN,ACK SYN,ACK -j RETURN
|
||||
for ip in $2; do
|
||||
$IPTABLES -A blockcheck_input -t mangle -s $ip -j NFQUEUE --queue-num $QNUM
|
||||
done
|
||||
;;
|
||||
nftables)
|
||||
# for autottl
|
||||
nft "add rule inet $NFT_TABLE prenat meta nfproto ipv${IPV} tcp sport $1 ct original packets 1 queue num $QNUM"
|
||||
ipver=$IPV
|
||||
[ "$IPV" = 6 ] || ipver=
|
||||
make_comma_list iplist $2
|
||||
nft "add rule inet $NFT_TABLE prenat meta nfproto ipv${IPV} tcp sport $1 tcp flags & (syn | ack) == (syn | ack) ip${ipver} saddr {$iplist} queue num $QNUM"
|
||||
;;
|
||||
ipfw)
|
||||
# for autottl mode
|
||||
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from any $1 to me proto ip${IPV} tcpflags syn,ack in not diverted not sockarg
|
||||
for ip in $2; do
|
||||
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from $ip $1 to me proto ip${IPV} tcpflags syn,ack in not diverted not sockarg
|
||||
done
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -780,15 +880,18 @@ pktws_ipt_unprepare_tcp()
|
||||
|
||||
case "$FWTYPE" in
|
||||
iptables)
|
||||
IPT_DEL INPUT -t mangle -p tcp --sport $1 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:1 -j NFQUEUE --queue-num $QNUM
|
||||
IPT_DEL INPUT -t mangle -j blockcheck_input
|
||||
$IPTABLES -t mangle -F blockcheck_input 2>/dev/null
|
||||
$IPTABLES -t mangle -X blockcheck_input 2>/dev/null
|
||||
;;
|
||||
esac
|
||||
}
|
||||
pktws_ipt_prepare_udp()
|
||||
{
|
||||
# $1 - port
|
||||
# $2 - ip list
|
||||
|
||||
pktws_ipt_prepare udp $1
|
||||
pktws_ipt_prepare udp $1 "$2"
|
||||
}
|
||||
pktws_ipt_unprepare_udp()
|
||||
{
|
||||
@@ -807,7 +910,7 @@ pktws_start()
|
||||
"$DVTWS" --port=$IPFW_DIVERT_PORT "$@" >/dev/null &
|
||||
;;
|
||||
CYGWIN)
|
||||
"$WINWS" $WF "$@" >/dev/null &
|
||||
"$WINWS" $WF --ipset="$IPSET_FILE" "$@" >/dev/null &
|
||||
;;
|
||||
esac
|
||||
PID=$!
|
||||
@@ -816,7 +919,9 @@ pktws_start()
|
||||
}
|
||||
tpws_start()
|
||||
{
|
||||
"$TPWS" --uid $TPWS_UID:$TPWS_GID --socks --bind-addr=127.0.0.1 --port=$SOCKS_PORT "$@" >/dev/null &
|
||||
local uid
|
||||
[ -n "$HAVE_ROOT" ] && uid="--uid $TPWS_UID:$TPWS_GID"
|
||||
"$TPWS" $uid --socks --bind-addr=127.0.0.1 --port=$SOCKS_PORT "$@" >/dev/null &
|
||||
PID=$!
|
||||
# give some time to initialize
|
||||
minsleep
|
||||
@@ -905,17 +1010,17 @@ tpws_curl_test()
|
||||
# $1 - test function
|
||||
# $2 - domain
|
||||
# $3,$4,$5, ... - tpws params
|
||||
echo - checking tpws $3 $4 $5 $6 $7 $8 $9 $TPWS_EXTRA "$TPWS_EXTRA_1" "$TPWS_EXTRA_2" "$TPWS_EXTRA_3" "$TPWS_EXTRA_4" "$TPWS_EXTRA_5" "$TPWS_EXTRA_6" "$TPWS_EXTRA_7" "$TPWS_EXTRA_8" "$TPWS_EXTRA_9"
|
||||
echo - checking tpws $3 $4 $5 $6 $7 $8 $9${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}
|
||||
local ALL_PROXY="socks5://127.0.0.1:$SOCKS_PORT"
|
||||
ws_curl_test tpws_start "$@" $TPWS_EXTRA "$TPWS_EXTRA_1" "$TPWS_EXTRA_2" "$TPWS_EXTRA_3" "$TPWS_EXTRA_4" "$TPWS_EXTRA_5" "$TPWS_EXTRA_6" "$TPWS_EXTRA_7" "$TPWS_EXTRA_8" "$TPWS_EXTRA_9"
|
||||
ws_curl_test tpws_start "$@"${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}
|
||||
}
|
||||
pktws_curl_test()
|
||||
{
|
||||
# $1 - test function
|
||||
# $2 - domain
|
||||
# $3,$4,$5, ... - nfqws/dvtws params
|
||||
echo - checking $PKTWSD ${WF:+$WF }$3 $4 $5 $6 $7 $8 $9 $PKTWS_EXTRA "$PKTWS_EXTRA_1" "$PKTWS_EXTRA_2" "$PKTWS_EXTRA_3" "$PKTWS_EXTRA_4" "$PKTWS_EXTRA_5" "$PKTWS_EXTRA_6" "$PKTWS_EXTRA_7" "$PKTWS_EXTRA_8" "$PKTWS_EXTRA_9"
|
||||
ws_curl_test pktws_start "$@" $PKTWS_EXTRA "$PKTWS_EXTRA_1" "$PKTWS_EXTRA_2" "$PKTWS_EXTRA_3" "$PKTWS_EXTRA_4" "$PKTWS_EXTRA_5" "$PKTWS_EXTRA_6" "$PKTWS_EXTRA_7" "$PKTWS_EXTRA_8" "$PKTWS_EXTRA_9"
|
||||
echo - checking $PKTWSD ${WF:+$WF }$3 $4 $5 $6 $7 $8 $9${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}
|
||||
ws_curl_test pktws_start "$@"${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}
|
||||
}
|
||||
xxxws_curl_test_update()
|
||||
{
|
||||
@@ -1173,7 +1278,7 @@ pktws_check_domain_http_bypass()
|
||||
|
||||
local strategy
|
||||
pktws_check_domain_http_bypass_ "$@"
|
||||
strategy="${strategy:+$strategy $PKTWS_EXTRA $PKTWS_EXTRA_1 $PKTWS_EXTRA_2 $PKTWS_EXTRA_3 $PKTWS_EXTRA_4 $PKTWS_EXTRA_5 $PKTWS_EXTRA_6 $PKTWS_EXTRA_7 $PKTWS_EXTRA_8 $PKTWS_EXTRA_9}"
|
||||
strategy="${strategy:+$strategy${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}}"
|
||||
report_strategy $1 $3 $PKTWSD
|
||||
}
|
||||
|
||||
@@ -1288,7 +1393,7 @@ tpws_check_domain_http_bypass()
|
||||
|
||||
local strategy
|
||||
tpws_check_domain_http_bypass_ "$@"
|
||||
strategy="${strategy:+$strategy $TPWS_EXTRA $TPWS_EXTRA_1 $TPWS_EXTRA_2 $TPWS_EXTRA_3 $TPWS_EXTRA_4 $TPWS_EXTRA_5 $TPWS_EXTRA_6 $TPWS_EXTRA_7 $TPWS_EXTRA_8 $TPWS_EXTRA_9}"
|
||||
strategy="${strategy:+$strategy${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}}"
|
||||
report_strategy $1 $3 tpws
|
||||
}
|
||||
|
||||
@@ -1379,7 +1484,7 @@ check_domain_http_tcp()
|
||||
[ "$SKIP_PKTWS" = 1 ] || {
|
||||
echo
|
||||
echo preparing $PKTWSD redirection
|
||||
pktws_ipt_prepare_tcp $2
|
||||
pktws_ipt_prepare_tcp $2 "$(mdig_resolve_all $IPV $4)"
|
||||
|
||||
pktws_check_domain_http_bypass $1 $3 $4
|
||||
|
||||
@@ -1402,7 +1507,7 @@ check_domain_http_udp()
|
||||
[ "$SKIP_PKTWS" = 1 ] || {
|
||||
echo
|
||||
echo preparing $PKTWSD redirection
|
||||
pktws_ipt_prepare_udp $2
|
||||
pktws_ipt_prepare_udp $2 "$(mdig_resolve_all $IPV $3)"
|
||||
|
||||
pktws_check_domain_http3_bypass $1 $3
|
||||
|
||||
@@ -1605,7 +1710,7 @@ ask_params()
|
||||
SCANLEVEL=${SCANLEVEL:-standard}
|
||||
ask_list SCANLEVEL "quick standard force" "$SCANLEVEL"
|
||||
# disable tpws checks by default in quick mode
|
||||
[ "$SCANLEVEL" = quick -a -z "$SKIP_TPWS" ] && SKIP_TPWS=1
|
||||
[ "$SCANLEVEL" = quick -a -z "$SKIP_TPWS" -a "$UNAME" != Darwin ] && SKIP_TPWS=1
|
||||
|
||||
echo
|
||||
|
||||
@@ -1677,7 +1782,7 @@ pingtest()
|
||||
dnstest()
|
||||
{
|
||||
# $1 - dns server. empty for system resolver
|
||||
"$LOOKUP" w3.org $1 >/dev/null 2>/dev/null
|
||||
"$LOOKUP" iana.org $1 >/dev/null 2>/dev/null
|
||||
}
|
||||
find_working_public_dns()
|
||||
{
|
||||
@@ -1722,10 +1827,14 @@ check_dns_cleanup()
|
||||
{
|
||||
rm -f "$DNSCHECK_DIG1" "$DNSCHECK_DIG2" "$DNSCHECK_DIGS" 2>/dev/null
|
||||
}
|
||||
check_dns()
|
||||
check_dns_()
|
||||
{
|
||||
local C1 C2 dom
|
||||
|
||||
DNS_IS_SPOOFED=0
|
||||
|
||||
[ "$SKIP_DNSCHECK" = 1 ] && return 0
|
||||
|
||||
echo \* checking DNS
|
||||
|
||||
[ -f "$DNSCHECK_DIGS" ] && rm -f "$DNSCHECK_DIGS"
|
||||
@@ -1748,6 +1857,7 @@ check_dns()
|
||||
check_dns_cleanup
|
||||
echo -- POSSIBLE DNS HIJACK DETECTED. ZAPRET WILL NOT HELP YOU IN CASE DNS IS SPOOFED !!!
|
||||
echo -- DNS CHANGE OR DNSCRYPT MAY BE REQUIRED
|
||||
DNS_IS_SPOOFED=1
|
||||
return 1
|
||||
else
|
||||
echo $dom : OK
|
||||
@@ -1759,8 +1869,8 @@ check_dns()
|
||||
for dom in $DNSCHECK_DOM; do echo $dom; done | "$MDIG" --threads=10 --family=4 >"$DNSCHECK_DIGS"
|
||||
fi
|
||||
|
||||
echo checking resolved IP uniqueness for : $DNSCHECK_DOM
|
||||
echo censor\'s DNS can return equal result for multiple blocked domains.
|
||||
echo "checking resolved IP uniqueness for : $DNSCHECK_DOM"
|
||||
echo "censor's DNS can return equal result for multiple blocked domains."
|
||||
C1=$(wc -l <"$DNSCHECK_DIGS")
|
||||
C2=$(sort -u "$DNSCHECK_DIGS" | wc -l)
|
||||
[ "$C1" -eq 0 ] &&
|
||||
@@ -1777,6 +1887,7 @@ check_dns()
|
||||
echo -- POSSIBLE DNS HIJACK DETECTED. ZAPRET WILL NOT HELP YOU IN CASE DNS IS SPOOFED !!!
|
||||
echo -- DNSCRYPT MAY BE REQUIRED
|
||||
check_dns_cleanup
|
||||
DNS_IS_SPOOFED=1
|
||||
return 1
|
||||
}
|
||||
echo all resolved IPs are unique
|
||||
@@ -1786,6 +1897,20 @@ check_dns()
|
||||
return 0
|
||||
}
|
||||
|
||||
check_dns()
|
||||
{
|
||||
local r
|
||||
check_dns_
|
||||
r=$?
|
||||
[ "$DNS_IS_SPOOFED" = 1 ] && SECURE_DNS=${SECURE_DNS:-1}
|
||||
[ "$SECURE_DNS" = 1 ] && {
|
||||
doh_find_working || {
|
||||
echo could not find working DoH server. exiting.
|
||||
exitp 7
|
||||
}
|
||||
}
|
||||
return $r
|
||||
}
|
||||
|
||||
unprepare_all()
|
||||
{
|
||||
@@ -1818,14 +1943,17 @@ sigsilent()
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
fsleep_setup
|
||||
fix_sbin_path
|
||||
check_system
|
||||
check_already
|
||||
[ "$UNAME" = CYGWIN ] || require_root
|
||||
# no divert sockets in MacOS
|
||||
[ "$UNAME" = "Darwin" ] && SKIP_PKTWS=1
|
||||
[ "$UNAME" != CYGWIN -a "$SKIP_PKTWS" != 1 ] && require_root
|
||||
check_prerequisites
|
||||
trap sigint_cleanup INT
|
||||
[ "$SKIP_DNSCHECK" = 1 ] || check_dns
|
||||
check_dns
|
||||
check_virt
|
||||
ask_params
|
||||
trap - INT
|
||||
|
@@ -1,13 +1,28 @@
|
||||
require_root()
|
||||
{
|
||||
local exe
|
||||
local exe preserve_env
|
||||
echo \* checking privileges
|
||||
[ $(id -u) -ne "0" ] && {
|
||||
echo root is required
|
||||
exe="$EXEDIR/$(basename "$0")"
|
||||
exists sudo && exec sudo sh "$exe"
|
||||
exists su && exec su root -c "sh \"$exe\""
|
||||
exists sudo && {
|
||||
echo elevating with sudo
|
||||
exec sudo -E sh "$exe"
|
||||
}
|
||||
exists su && {
|
||||
echo elevating with su
|
||||
case "$UNAME" in
|
||||
Linux)
|
||||
preserve_env="--preserve-environment"
|
||||
;;
|
||||
FreeBSD|OpenBSD|Darwin)
|
||||
preserve_env="-m"
|
||||
;;
|
||||
esac
|
||||
exec su $preserve_env root -c "sh \"$exe\""
|
||||
}
|
||||
echo su or sudo not found
|
||||
exitp 2
|
||||
}
|
||||
HAVE_ROOT=1
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
readonly HOSTLIST_MARKER="<HOSTLIST>"
|
||||
readonly HOSTLIST_NOAUTO_MARKER="<HOSTLIST_NOAUTO>"
|
||||
|
||||
find_hostlists()
|
||||
{
|
||||
@@ -24,10 +25,9 @@ filter_apply_hostlist_target()
|
||||
{
|
||||
# $1 - var name of tpws or nfqws params
|
||||
|
||||
local v parm parm1 parm2 parm3 parm4 parm5 parm6 parm7
|
||||
local v parm parm1 parm2 parm3 parm4 parm5 parm6 parm7 parm8 parmNA
|
||||
eval v="\$$1"
|
||||
contains "$v" "$HOSTLIST_MARKER" &&
|
||||
{
|
||||
if contains "$v" "$HOSTLIST_MARKER" || contains "$v" "$HOSTLIST_NOAUTO_MARKER"; then
|
||||
[ "$MODE_FILTER" = hostlist -o "$MODE_FILTER" = autohostlist ] &&
|
||||
{
|
||||
find_hostlists
|
||||
@@ -40,13 +40,16 @@ filter_apply_hostlist_target()
|
||||
parm5="${AUTOHOSTLIST_FAIL_THRESHOLD:+--hostlist-auto-fail-threshold=$AUTOHOSTLIST_FAIL_THRESHOLD}"
|
||||
parm6="${AUTOHOSTLIST_FAIL_TIME:+--hostlist-auto-fail-time=$AUTOHOSTLIST_FAIL_TIME}"
|
||||
parm7="${AUTOHOSTLIST_RETRANS_THRESHOLD:+--hostlist-auto-retrans-threshold=$AUTOHOSTLIST_RETRANS_THRESHOLD}"
|
||||
parm8="--hostlist=$HOSTLIST_AUTO"
|
||||
}
|
||||
parm="$parm1${parm2:+ $parm2}${parm3:+ $parm3}${parm4:+ $parm4}${parm5:+ $parm5}${parm6:+ $parm6}${parm7:+ $parm7}"
|
||||
parmNA="$parm1${parm2:+ $parm2}${parm3:+ $parm3}${parm8:+ $parm8}"
|
||||
}
|
||||
v="$(replace_str $HOSTLIST_NOAUTO_MARKER "$parmNA" "$v")"
|
||||
v="$(replace_str $HOSTLIST_MARKER "$parm" "$v")"
|
||||
[ "$MODE_FILTER" = autohostlist -a "$AUTOHOSTLIST_DEBUGLOG" = 1 ] && {
|
||||
v="$v --hostlist-auto-debug=$HOSTLIST_AUTO_DEBUGLOG"
|
||||
}
|
||||
eval $1=\""$v"\"
|
||||
}
|
||||
fi
|
||||
}
|
||||
|
@@ -50,8 +50,9 @@ DESYNC_MARK_POSTNAT=0x20000000
|
||||
TPWS_SOCKS_ENABLE=0
|
||||
# tpws socks listens on this port on localhost and LAN interfaces
|
||||
TPPORT_SOCKS=987
|
||||
# use <HOSTLIST> placeholders to engage standard hostlists and autohostlist in ipset dir
|
||||
# they are replaced to empty string if MODE_FILTER does not satisfy
|
||||
# use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir
|
||||
# hostlist markers are replaced to empty string if MODE_FILTER does not satisfy
|
||||
# <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list
|
||||
TPWS_SOCKS_OPT="
|
||||
--filter-tcp=80 --methodeol <HOSTLIST> --new
|
||||
--filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
|
||||
@@ -59,8 +60,9 @@ TPWS_SOCKS_OPT="
|
||||
|
||||
TPWS_ENABLE=0
|
||||
TPWS_PORTS=80,443
|
||||
# use <HOSTLIST> placeholders to engage standard hostlists and autohostlist in ipset dir
|
||||
# they are replaced to empty string if MODE_FILTER does not satisfy
|
||||
# use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir
|
||||
# hostlist markers are replaced to empty string if MODE_FILTER does not satisfy
|
||||
# <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list
|
||||
TPWS_OPT="
|
||||
--filter-tcp=80 --methodeol <HOSTLIST> --new
|
||||
--filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
|
||||
@@ -83,12 +85,13 @@ NFQWS_UDP_PKT_IN=0
|
||||
# this mode can be very CPU consuming. enable with care !
|
||||
#NFQWS_PORTS_TCP_KEEPALIVE=80
|
||||
#NFQWS_PORTS_UDP_KEEPALIVE=
|
||||
# use <HOSTLIST> placeholders to engage standard hostlists and autohostlist in ipset dir
|
||||
# they are replaced to empty string if MODE_FILTER does not satisfy
|
||||
# use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir
|
||||
# hostlist markers are replaced to empty string if MODE_FILTER does not satisfy
|
||||
# <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list
|
||||
NFQWS_OPT="
|
||||
--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
|
||||
--filter-tcp=443 --dpi-desync=fake,disorder2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST>
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST_NOAUTO>
|
||||
"
|
||||
|
||||
# none,ipset,hostlist,autohostlist
|
||||
|
@@ -341,3 +341,17 @@ v66:
|
||||
|
||||
init.d: rewrite traffic interception and daemon launch parameters in config file. this break compatibility with old versions.
|
||||
init.d: openwrt-minimal : tpws launch for low storage openwrt devices
|
||||
|
||||
v67:
|
||||
|
||||
mdig: --dns-make-query, --dns-parse-query for side-channel resolving (DoH)
|
||||
blockcheck: use DoH resolvers if DNS spoof is detected
|
||||
blockcheck: restring fooling to testing domain's IPs
|
||||
nfqws,tpws: internal hostlist deduplication to save RAM
|
||||
nfqws,tpws: hostlist/ipset auto reload on file change. no more HUP.
|
||||
nfqws,tpws: --filter-tcp, --filter-udp take comma separated port range list
|
||||
nfqws,tpws: @<config_file> - read config from a file
|
||||
config: <HOSTLIST_NOAUTO> marker
|
||||
binaries: remove zapret-winws. add win32.
|
||||
blockcheck, install_easy.sh: preserve user environment variables during elevation
|
||||
blockcheck: do not require root if SKIP_PKTWS=1
|
||||
|
@@ -42,8 +42,12 @@ install_prereq.sh
|
||||
Вас могут спросить о типе фаервола (iptables/nftables) и использовании ipv6. Это нужно для установки
|
||||
правильных пакетов в ОС, чтобы не устанавливать лишнее.
|
||||
|
||||
6) Запустите blockcheck.sh. blockcheck.sh в начале проверяет DNS. Если выводятся сообщения о подмене адресов, то
|
||||
первым делом нужно решить эту проблему, иначе ничего не будет работать.
|
||||
6) Запустите blockcheck.sh. blockcheck.sh в начале проверяет DNS.
|
||||
Если выводятся сообщения о подмене адресов, то нужно будет решить проблему с DNS.
|
||||
blockcheck перейдет в этом случае на DoH и будет пытаться получить и использовать реальные IP адреса.
|
||||
Но если вы не настроите решение этой проблемы, обход будет работать только для тех программ
|
||||
или ОС, которые сами реализуют механизмы SecureDNS. Для других программ обход работать не будет.
|
||||
|
||||
Решение проблемы DNS выходит за рамки проекта. Обычно она решается либо заменой DNS серверов
|
||||
от провайдера на публичные (1.1.1.1, 8.8.8.8), либо в случае перехвата провайдером обращений
|
||||
к сторонним серверам - через специальные средства шифрования DNS запросов, такие как dnscrypt, DoT, DoH.
|
||||
@@ -107,27 +111,31 @@ badseq может работать только на https и не работа
|
||||
с использованием мультистратегии. Как работают мультистратегии описано в readme.txt.
|
||||
|
||||
Если кратко, то обычно параметры конструируются так :
|
||||
"--filter-udp=443 'параметры для quic' <HOSTLIST> --new
|
||||
--filter-tcp=80-443 'обьединенные параметры для http и https' <HOSTLIST>"
|
||||
"--filter-udp=443 'параметры для quic' <HOSTLIST_NOAUTO> --new
|
||||
--filter-tcp=80,443 'обьединенные параметры для http и https' <HOSTLIST>"
|
||||
|
||||
Или так :
|
||||
"--filter-udp=443 "параметры для quic" <HOSTLIST> --new
|
||||
"--filter-udp=443 "параметры для quic" <HOSTLIST_NOAUTO> --new
|
||||
--filter-tcp=80 'параметры для http' <HOSTLIST> --new
|
||||
--filter-tcp=443 'параметры для https' <HOSTLIST>"
|
||||
|
||||
"<HOSTLIST>" так и пишется. Его не надо на что-то заменять. Это сделают скрипты запуска, если вы выбрали режим
|
||||
фильтрации по хостлистам, и уберут в противном случае.
|
||||
Если для какого-то протокола надо дурить все без стандартного хостлиста - просто уберите оттуда "<HOSTLIST>".
|
||||
"<HOSTLIST>" и "<HOSTLIST_NOAUTO>" так и пишутся. Их не надо на что-то заменять. Это сделают скрипты запуска,
|
||||
если вы выбрали режим фильтрации по хостлистам, и уберут в противном случае.
|
||||
Если для какого-то протокола надо дурить все без стандартного хостлиста - просто уберите оттуда "<HOSTLIST>"
|
||||
и "<HOSTLIST_NOAUTO>".
|
||||
Можно писать свои параметры --hostlist и --hostlist-exclude для дополнительных хостлистов
|
||||
или в профилях специализаций под конкретный ресурс. В последнем случае стандартный хостлист там не нужен.
|
||||
Следует избегать указания собственных параметров --hostlist на листы из директории ipset.
|
||||
Эта логика включена в "<HOSTLIST>".
|
||||
Эта логика включена в "<HOSTLIST>" и "<HOSTLIST_NOAUTO>".
|
||||
Отличие "<HOSTLIST_NOAUTO>" в том, что стандартный автолист по этому профилю используется как обычный,
|
||||
то есть без автоматического добавления доменов. Однако, добавления в других профилях автоматически
|
||||
отражаются во всех остальных.
|
||||
|
||||
Если стратегии отличаются по версии ip протокола, и вы не можете их обьединить, фильтр пишется так :
|
||||
"--filter-l3=ipv4 --filter-udp=443 "параметры для quic ipv4" <HOSTLIST> --new
|
||||
"--filter-l3=ipv4 --filter-udp=443 "параметры для quic ipv4" <HOSTLIST_NOAUTO> --new
|
||||
--filter-l3=ipv4 --filter-tcp=80 'параметры для http ipv4' <HOSTLIST> --new
|
||||
--filter-l3=ipv4 --filter-tcp=443 'параметры для https ipv4' <HOSTLIST> --new
|
||||
--filter-l3=ipv6 --filter-udp=443 "параметры для quic ipv6" <HOSTLIST> --new
|
||||
--filter-l3=ipv6 --filter-udp=443 "параметры для quic ipv6" <HOSTLIST_NOAUTO> --new
|
||||
--filter-l3=ipv6 --filter-tcp=80 'параметры для http ipv6' <HOSTLIST> --new
|
||||
--filter-l3=ipv6 --filter-tcp=443 'параметры для https ipv6' <HOSTLIST>"
|
||||
|
||||
|
@@ -54,13 +54,19 @@ cygwin так же имеет внушительный список несовм
|
||||
|
||||
4) Если вы работаете в виртуальной машине, необходимо использовать соединение с сетью в режиме bridge. nat не подходит
|
||||
|
||||
5) Запустите blockcheck\blockcheck.cmd. blockcheck в начале проверяет DNS. Если выводятся сообщения о подмене адресов, то
|
||||
первым делом нужно решить эту проблему, иначе ничего не будет работать.
|
||||
5) Запустите blockcheck\blockcheck.cmd. blockcheck в начале проверяет DNS.
|
||||
Если выводятся сообщения о подмене адресов, то нужно будет решить проблему с DNS.
|
||||
blockcheck перейдет в этом случае на DoH и будет пытаться получить и использовать реальные IP адреса.
|
||||
Но если вы не настроите решение этой проблемы, обход будет работать только для тех программ,
|
||||
которые сами реализуют механизмы SecureDNS. Для других программ обход работать не будет.
|
||||
|
||||
Решение проблемы DNS выходит за рамки проекта. Обычно она решается либо заменой DNS серверов
|
||||
от провайдера на публичные (1.1.1.1, 8.8.8.8), либо в случае перехвата провайдером обращений
|
||||
к сторонним серверам - через специальные средства шифрования DNS запросов, такие как dnscrypt, DoT, DoH.
|
||||
В современных броузерах чаще всего DoH включен по умолчанию, но curl будет использовать обычный системный DNS.
|
||||
Новые билды win10 и win11 поддерживают системные DoH из коробки. Они не настроены по умолчанию.
|
||||
win11 поддерживает системные DoH из коробки. Они не настроены по умолчанию.
|
||||
В последних билдах win10 существует неофициальный обходной путь для включения DoH.
|
||||
Для остальных систем нужно стороннее решение, работающие по принципу DNS proxy.
|
||||
|
||||
Тут все разжевано как и где это включается : https://hackware.ru/?p=13707
|
||||
|
||||
@@ -105,7 +111,7 @@ badseq может работать только на https и не работа
|
||||
|
||||
Если кратко по мультистратегии, то обычно параметры конструируются так :
|
||||
"--filter-udp=443 'параметры для quic' --new
|
||||
--filter-tcp=80-443 'обьединенные параметры для http и https'"
|
||||
--filter-tcp=80,443 'обьединенные параметры для http и https'"
|
||||
|
||||
Или так :
|
||||
"--filter-udp=443 "параметры для quic" --new
|
||||
|
@@ -153,6 +153,8 @@ For BSD systems there is dvtws. Its built from the same source and has almost th
|
||||
nfqws takes the following parameters:
|
||||
|
||||
```
|
||||
@<config_file> ; read file for options. must be the only argument. other options are ignored.
|
||||
|
||||
--debug=0|1
|
||||
--qnum=<nfqueue_number>
|
||||
--daemon ; daemonize
|
||||
@@ -209,8 +211,8 @@ nfqws takes the following parameters:
|
||||
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
||||
--new ; begin new strategy
|
||||
--filter-l3=ipv4|ipv6 ; L3 protocol filter. multiple comma separated values allowed.
|
||||
--filter-tcp=[~]port1[-port2] ; TCP port filter. ~ means negation. setting tcp and not setting udp filter denies udp.
|
||||
--filter-udp=[~]port1[-port2] ; UDP port filter. ~ means negation. setting udp and not setting tcp filter denies tcp.
|
||||
--filter-tcp=[~]port1[-port2]|* ; TCP port filter. ~ means negation. setting tcp and not setting udp filter denies udp. comma separated list supported.
|
||||
--filter-udp=[~]port1[-port2]|* ; UDP port filter. ~ means negation. setting udp and not setting tcp filter denies tcp. comma separated list supported.
|
||||
--filter-l7=[http|tls|quic|wireguard|dht|unknown] ; L6-L7 protocol filter. multiple comma separated values allowed.
|
||||
--ipset=<filename> ; ipset include filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||
--ipset-exclude=<filename> ; ipset exclude filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||
@@ -608,6 +610,8 @@ It's for the systems that lack ipset support : Windows and Linux without nftable
|
||||
tpws is transparent proxy.
|
||||
|
||||
```
|
||||
@<config_file> ; read file for options. must be the only argument. other options are ignored.
|
||||
|
||||
--debug=0|1|2|syslog|@<filename> ; 1 and 2 means log to console and set debug level. for other targets use --debug-level.
|
||||
--debug-level=0|1|2 ; specify debug level for syslog and @<filename>
|
||||
--bind-addr=<v4_addr>|<v6_addr>; for v6 link locals append %interface_name : fe80::1%br-lan
|
||||
@@ -642,7 +646,7 @@ tpws is transparent proxy.
|
||||
|
||||
--new ; begin new strategy
|
||||
--filter-l3=ipv4|ipv6 ; L3 protocol filter. multiple comma separated values allowed.
|
||||
--filter-tcp=[~]port1[-port2] ; TCP port filter. ~ means negation
|
||||
--filter-tcp=[~]port1[-port2]|* ; TCP port filter. ~ means negation. comma separated list supported.
|
||||
--filter-l7=[http|tls|unknown] ; L6-L7 protocol filter. multiple comma separated values allowed.
|
||||
--ipset=<filename> ; ipset include filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||
--ipset-exclude=<filename> ; ipset exclude filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||
@@ -854,7 +858,7 @@ If you need "all except" mode you dont have to delete zapret-hosts-users.txt. Ju
|
||||
|
||||
Subdomains auto apply. For example, "ru" in the list affects "*.ru" .
|
||||
|
||||
tpws and nfqws reread lists on HUP signal.
|
||||
tpws and nfqws automatically reload lists if their modification date is changed.
|
||||
|
||||
When filtering by domain name, daemons should run without filtering by ipset.
|
||||
When using large regulator lists estimate the amount of RAM on the router !
|
||||
@@ -864,7 +868,7 @@ When using large regulator lists estimate the amount of RAM on the router !
|
||||
This mode analyzes both client requests and server replies.
|
||||
If a host is not in any list and a situation similar to block occurs host is automatically added to the special list both in memory and file.
|
||||
Use exclude hostlist to prevent autohostlist triggering.
|
||||
If it did happen - delete the undesired record from the file and restart tpws/nfqws or send them SIGHUP to force lists reload.
|
||||
If it did happen - delete the undesired record from the file.
|
||||
|
||||
In case of nfqws it's required to redirect both incoming and outgoing traffic to the queue.
|
||||
It's strongly recommended to use connbytes filter or nfqws will process gigabytes of incoming traffic.
|
||||
@@ -892,7 +896,7 @@ Otherwise it's nothing to lose.
|
||||
However false positives still can occur in case target website is behaving abnormally
|
||||
(may be due to DDoS attack or server malfunction). If it happens bypass strategy
|
||||
may start to break the website. This situation can only be controlled manually.
|
||||
Remove undesired domain from the autohostlist file, restart nfqws/tpws or send them SIGHUP.
|
||||
Remove undesired domain from the autohostlist file.
|
||||
Use exclude hostlist to prevent further auto additions.
|
||||
|
||||
It's possible to use one auto hostlist with multiple processes. All processes check for file modification time.
|
||||
@@ -935,6 +939,8 @@ To use standard updatable hostlists from the `ipset` dir use `<HOSTLIST>` placeh
|
||||
with hostlist parameters if `MODE_FILTER` variable enables hostlists and is removed otherwise.
|
||||
Standard hostlists are expected in final (fallback) strategies closing groups of filter parameters.
|
||||
Don't use `<HOSTLIST>` in highly specialized profiles. Use your own filter or hostlist(s).
|
||||
`<HOSTLIST_NOAUTO>` marker uses standard autohostlist as usual hostlist thus disabling auto additions in this profile.
|
||||
If any other profile adds something this profile accepts the change automatically.
|
||||
|
||||
|
||||
`tpws` socks proxy mode switch
|
||||
@@ -1009,7 +1015,7 @@ It's advised also to remove these ports from `connbytes`-limited interception li
|
||||
NFQWS_OPT="
|
||||
--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
|
||||
--filter-tcp=443 --dpi-desync=fake,disorder2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST>
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST_NOAUTO>
|
||||
"
|
||||
```
|
||||
|
||||
@@ -1199,7 +1205,8 @@ Note that DNS check is mostly Russia targeted. It checks several pre-defined blo
|
||||
verifies system DNS answers with public DNS answers. Because ISP can block public DNS or redirect any DNS queries
|
||||
to their servers `blockcheck.sh` also checks that all returned answers are unique. Usually if DNS is blocked
|
||||
ISP returns single ip for all blocked domains to redirect you to their "access denied" page.
|
||||
`blockcheck.sh` works in Linux and FreeBSD.
|
||||
DoH servers are used automatically for checks if DNS spoof is detected.
|
||||
`blockcheck.sh` works on all systems supported by `zapret`.
|
||||
|
||||
### desktop linux system
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
zapret v.66
|
||||
zapret v.67
|
||||
|
||||
English
|
||||
-------
|
||||
@@ -225,6 +225,8 @@ nfqws
|
||||
Эта программа - модификатор пакетов и обработчик очереди NFQUEUE.
|
||||
Для BSD систем существует адаптированный вариант - dvtws, собираемый из тех же исходников (см. bsd.txt).
|
||||
|
||||
@<config_file> ; читать конфигурацию из файла. опция должна быть первой. остальные опции игнорируются.
|
||||
|
||||
--debug=0|1 ; 1=выводить отладочные сообщения
|
||||
--daemon ; демонизировать прогу
|
||||
--pidfile=<file> ; сохранить PID в файл
|
||||
@@ -269,8 +271,14 @@ nfqws
|
||||
--dpi-desync-udplen-pattern=<filename>|0xHEX ; чем добивать udp пакет в режиме udplen. по умолчанию - нули
|
||||
--dpi-desync-start=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N
|
||||
--dpi-desync-cutoff=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
|
||||
--hostlist=<filename> ; применять дурение только к хостам из листа. может быть множество листов, они объединяются. пустой обший лист = его отсутствие
|
||||
--hostlist-exclude=<filename> ; не применять дурение к хостам из листа. может быть множество листов, они объединяются
|
||||
--hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются.
|
||||
; в файле должен быть хост на каждой строке.
|
||||
; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
|
||||
; при изменении времени модификации файла он перечитывается автоматически по необходимости
|
||||
; список может быть запакован в gzip. формат автоматически распознается и разжимается
|
||||
; списков может быть множество. пустой общий лист = его отсутствие
|
||||
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
|
||||
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам.
|
||||
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
|
||||
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3)
|
||||
--hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60)
|
||||
@@ -278,11 +286,11 @@ nfqws
|
||||
--hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты.
|
||||
--new ; начало новой стратегии
|
||||
--filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии
|
||||
--filter-tcp=[~]port1[-port2] ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. установка фильтра tcp и неустановка фильтра udp запрещает udp.
|
||||
--filter-udp=[~]port1[-port2] ; фильтр портов udp для текущей стратегии. ~ означает инверсию. установка фильтра udp и неустановка фильтра tcp запрещает udp.
|
||||
--filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. установка фильтра tcp и неустановка фильтра udp запрещает udp. поддерживается список через запятую.
|
||||
--filter-udp=[~]port1[-port2]|* ; фильтр портов udp для текущей стратегии. ~ означает инверсию. установка фильтра udp и неустановка фильтра tcp запрещает udp. поддерживается список через запятую.
|
||||
--filter-l7=[http|tls|quic|wireguard|dht|unknown] ; фильтр протокола L6-L7. поддерживается несколько значений через запятую.
|
||||
--ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip.
|
||||
--ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip.
|
||||
--ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
|
||||
--ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
|
||||
|
||||
Параметры манипуляции могут сочетаться в любых комбинациях.
|
||||
|
||||
@@ -700,6 +708,9 @@ tpws
|
||||
-----
|
||||
|
||||
tpws - это transparent proxy.
|
||||
|
||||
@<config_file> ; читать конфигурацию из файла. опция должна быть первой. остальные опции игнорируются.
|
||||
|
||||
--debug=0|1|2|syslog|@<filename> ; 0,1,2 = логирование на косоль : 0=тихо, 1(default)=подробно, 2=отладка.
|
||||
--debug-level=0|1|2 ; указать уровень логирования для syslog и @<filename>
|
||||
--daemon ; демонизировать прогу
|
||||
@@ -773,22 +784,22 @@ tpws - это transparent proxy.
|
||||
--tamper-cutoff=[n]<pos> ; закончить дурение на указанной байтовой позиции или номере блока исходящего потока (считается позиция начала принятого блока)
|
||||
--hostlist=<filename> ; действовать только над доменами, входящими в список из filename. поддомены автоматически учитываются.
|
||||
; в файле должен быть хост на каждой строке.
|
||||
; список читается 1 раз при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
|
||||
; по сигналу HUP список будет перечитан при следующем принятом соединении
|
||||
; список читается при старте и хранится в памяти в виде иерархической структуры для быстрого поиска.
|
||||
; при изменении времени модификации файла он перечитывается автоматически по необходимости
|
||||
; список может быть запакован в gzip. формат автоматически распознается и разжимается
|
||||
; списков может быть множество, они объединяются. пустой общий лист = его отсутствие
|
||||
; списков может быть множество. пустой общий лист = его отсутствие
|
||||
; хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello.
|
||||
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов, они объединяются
|
||||
--hostlist-exclude=<filename> ; не применять дурение к доменам из листа. может быть множество листов. схема аналогична include листам.
|
||||
--hostlist-auto=<filename> ; обнаруживать автоматически блокировки и заполнять автоматический hostlist (требует перенаправления входящего трафика)
|
||||
--hostlist-auto-fail-threshold=<int> ; сколько раз нужно обнаружить ситуацию, похожую на блокировку, чтобы добавить хост в лист (по умолчанию: 3)
|
||||
--hostlist-auto-fail-time=<int> ; все эти ситуации должны быть в пределах указанного количества секунд (по умолчанию: 60)
|
||||
--hostlist-auto-debug=<logfile> ; лог положительных решений по autohostlist. позволяет разобраться почему там появляются хосты.
|
||||
--new ; начало новой стратегии
|
||||
--filter-l3=ipv4|ipv6 ; фильтр версии ip для текущей стратегии
|
||||
--filter-tcp=[~]port1[-port2] ; фильтр портов tcp для текущей стратегии. ~ означает инверсию.
|
||||
--filter-tcp=[~]port1[-port2]|* ; фильтр портов tcp для текущей стратегии. ~ означает инверсию. поддерживается список через запятую.
|
||||
--filter-l7=[http|tls|quic|wireguard|dht|unknown] ; фильтр протокола L6-L7. поддерживается несколько значений через запятую.
|
||||
--ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip.
|
||||
--ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip.
|
||||
--ipset=<filename> ; включающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
|
||||
--ipset-exclude=<filename> ; исключающий ip list. на каждой строчке ip или cidr ipv4 или ipv6. поддерживается множество листов и gzip. перечитка автоматическая.
|
||||
|
||||
|
||||
--debug позволяет выводить подробный лог действий на консоль, в syslog или в файл.
|
||||
@@ -1098,6 +1109,26 @@ ip2net фильтрует входные данные, выкидывая неп
|
||||
Не надо делать такое : 5000000/10000000. 1/2 - гораздо лучше.
|
||||
|
||||
|
||||
mdig
|
||||
----
|
||||
|
||||
Программа предназначена для многопоточного ресолвинга больших листов через системный DNS.
|
||||
Она берет из stdin список доменов и выводит в stdout результат ресолвинга. Ошибки выводятся в stderr.
|
||||
|
||||
--threads=<threads_number> ; количество потоков. по умолчанию 1.
|
||||
--family=<4|6|46> ; выбор семейства IP адресов : ipv4, ipv6, ipv4+ipv6
|
||||
--verbose ; дебаг-лог на консоль
|
||||
--stats=N ; выводить статистику каждые N доменов
|
||||
--log-resolved=<file> ; сохранять успешно отресолвленные домены в файл
|
||||
--log-failed=<file> ; сохранять неудачно отресолвленные домены в файл
|
||||
--dns-make-query=<domain> ; вывести в stdout бинарный DNS запрос по домену. если --family=6, запрос будет AAAA, иначе A.
|
||||
--dns-parse-query ; распарсить бинарный DNS ответ и выдать все ivp4 и ipv6 адреса из него в stdout
|
||||
|
||||
Параметры --dns-make-query и --dns-parse-query позволяют провести ресолвинг одного домена через произвольный канал.
|
||||
Например, следующим образом можно выполнить DoH запрос, используя лишь mdig и curl :
|
||||
mdig --family=6 --dns-make-query=rutracker.org | curl --data-binary @- -H "Content-Type: application/dns-message" https://cloudflare-dns.com/dns-query | mdig --dns-parse-query
|
||||
|
||||
|
||||
Фильтрация по именам доменов
|
||||
----------------------------
|
||||
|
||||
@@ -1134,9 +1165,7 @@ ipset/get_reestr_resolvable_domains.sh
|
||||
ipset/get_refilter_domains.sh
|
||||
- кладется в ipset/zapret-hosts.txt.gz.
|
||||
|
||||
Чтобы обновить списки, перезапускать nfqws или tpws не нужно. Обновляете файлы, затем даете сигнал HUP.
|
||||
По HUP листы будут перечитаны. Если вдруг какого-то листа не окажется, процесс завершится с ошибкой.
|
||||
Скрипты получения листов из ipset сами выдают HUP в конце.
|
||||
При изменении времени модификации файлов списки перечитываются автоматически.
|
||||
|
||||
При фильтрации по именам доменов демон должен запускаться без фильтрации по ipset.
|
||||
tpws и nfqws решают нужно ли применять дурение в зависимости от хоста, полученного из протокола прикладного уровня (http, tls, quic).
|
||||
@@ -1210,7 +1239,7 @@ nfqws и tpws могут сечь варианты 1-3, 4 они не распо
|
||||
По логу можно понять как избежать ложных срабатываний и подходит ли вообще вам этот режим.
|
||||
|
||||
Можно использовать один autohostlist с множеством процессов. Все процессы проверяют время модификации файла.
|
||||
Если файл был изменен в другом процессе, то происходит перечитывание всех include листов, включая autohostlist.
|
||||
Если файл был изменен в другом процессе, происходит его перечитывание.
|
||||
Все процессы должны работать под одним uid, чтобы были права доступа на файл.
|
||||
|
||||
Скрипты zapret ведут autohostlist в ipset/zapret-hosts-auto.txt.
|
||||
@@ -1232,6 +1261,7 @@ install_easy.sh при апгрейде zapret сохраняет этот фа
|
||||
Если DNS подменяется и провайдер перехватывает обращения к сторонним DNS, настройте dnscrypt.
|
||||
Еще один эффективный вариант - использовать ресолвер от yandex 77.88.8.88 на нестандартном порту 1253.
|
||||
Многие провайдеры не анализируют обращения к DNS на нестандартных портах.
|
||||
blockcheck если видит подмену DNS автоматически переключается на DoH сервера.
|
||||
|
||||
Следует прогнать blockcheck по нескольким заблокированным сайтам и выявить общий характер блокировок.
|
||||
Разные сайты могут быть заблокированы по-разному, нужно искать такую технику, которая работает на большинстве.
|
||||
@@ -1256,6 +1286,24 @@ Blockcheck имеет 3 уровня сканирования.
|
||||
standard дает возможность провести исследование как и на что реагирует DPI в плане методов обхода.
|
||||
force дает максимум проверок даже в случаях, когда ресурс работает без обхода или с более простыми стратегиями.
|
||||
|
||||
Есть ряд других параметров, которые не будут спрашиваться в диалоге, но которые можно переопределить через
|
||||
переменные.
|
||||
|
||||
DOMAINS - список тестируемых доменов через пробел
|
||||
CURL_MAX_TIME - время таймаута curl в секундах
|
||||
CURL_MAX_TIME_QUIC - время таймаута curl для quic. если не задано, используется значение CURL_MAX_TIME
|
||||
HTTP_PORT, HTTPS_PORT, QUIC_PORT - номера портов для соответствующих протоколов
|
||||
SKIP_DNSCHECK=1 - отказ от проверки DNS
|
||||
SKIP_TPWS=1 - отказ от тестов tpws
|
||||
SKIP_PKTWS=1 - отказ от тестов nfqws/dvtws/winws
|
||||
PKTWS_EXTRA, TPWS_EXTRA - дополнительные параметры nfqws/dvtws/winws и tpws
|
||||
PKTWS_EXTRA_1 .. PKTWS_EXTRA_9, TPWS_EXTRA_1 .. TPWS_EXTRA_9 - отдельно дополнительные параметры, содержащие пробелы
|
||||
SECURE_DNS=0|1 - принудительно выключить или включить DoH
|
||||
DOH_SERVERS - список URL DoH через пробел для автоматического выбора работающего сервера
|
||||
DOH_SERVER - конкретный DoH URL, отказ от поиска
|
||||
|
||||
Пример запуска с переменными : SECURE_DNS=1 SKIP_TPWS=1 CURL_MAX_TIME=1 ./blockcheck.sh
|
||||
|
||||
СКАН ПОРТОВ
|
||||
Если в системе присутствует совместимый netcat (ncat от nmap или openbsd ncat. в openwrt по умолчанию нет.),
|
||||
то выполняется сканирование портов http или https всех IP адресов домена.
|
||||
@@ -1397,6 +1445,9 @@ tpws-socks требует настройки параметров tpws, но н
|
||||
группе параметров фильтра. Таких мест может быть несколько.
|
||||
Не нужно использовать <HOSTLIST> в узких специализациях и в тех профилях, по которым точно не будет проходить
|
||||
трафик с известными протоколами, откуда поддерживается извлечение имени хоста (http, tls, quic).
|
||||
<HOSTLIST_NOAUTO> - это вариация, при которой стандартный автолист используется как обычный.
|
||||
То есть на этом профиле не происходит автоматическое добавление заблокированных доменов.
|
||||
Но если на другом профиле что-то будет добавлено, то этот профиль примет изменения автоматически.
|
||||
|
||||
# включение стандартной опции tpws в режиме socks
|
||||
TPWS_SOCKS_ENABLE=0
|
||||
@@ -1442,7 +1493,7 @@ NFQWS_UDP_PKT_IN=0
|
||||
NFQWS_OPT="
|
||||
--filter-tcp=80 --dpi-desync=fake,split2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
|
||||
--filter-tcp=443 --dpi-desync=fake,disorder2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST>
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST_NOAUTO>
|
||||
"
|
||||
|
||||
|
||||
|
@@ -71,7 +71,7 @@ NLM networks are adapter independent. Usually MAC address of the default router
|
||||
That's why NLM is more universal than `ssid-filter`.
|
||||
|
||||
`Cygwin` shell does not run binaries if their directory has it's own copy of `cygwin1.dll`.
|
||||
That's why exists separate standalone version in `binaries/win64/zapret-tpws`.
|
||||
If you want to run `winws` from `cygwin` delete, rename or move `cygwin1.dll`.
|
||||
`Cygwin` is required for `blockcheck.sh` support but `winws` itself can be run standalone without cygwin.
|
||||
|
||||
How to get `windows 7` and `winws` compatible `cygwin` :
|
||||
@@ -80,12 +80,10 @@ curl -O https://www.cygwin.com/setup-x86_64.exe
|
||||
setup-x86_64.exe --allow-unsupported-windows --no-verify --site http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2024/01/30/231215
|
||||
```
|
||||
You must choose to install `curl`. To compile from sources install `gcc-core`,`make`,`zlib-devel`.
|
||||
Make from directory `nfq` using `make cygwin`.
|
||||
Make from directory `nfq` using `make cygwin64` or `make cygwin32` for 64 and 32 bit versions.
|
||||
|
||||
`winws` requires `cygwin1.dll`, `windivert.dll`, `windivert64.sys`. You can take them from `binaries/win64/zapret-winws`.
|
||||
|
||||
32-bit x86 version can be build from 32-bit cygwin using `make cygwin32`.
|
||||
`windivert.dll` and `windivert32.sys` can be taken from [windivert 2.2.2 archive](https://reqrypt.org/download)
|
||||
`winws` requires `cygwin1.dll`, `windivert.dll`, `windivert64.sys` or `windivert32.sys`.
|
||||
You can take them from `binaries/win64` or `binaries/win32`.
|
||||
|
||||
There's no `arm64` signed `windivert` driver and no `cygwin`.
|
||||
But it's possible to use unsigned driver version in test mode and user mode components with x64 emulation.
|
||||
@@ -122,8 +120,12 @@ cd "C:\\Users\\vasya"
|
||||
cd "C:/Users/vasya"
|
||||
cd "/cygdrive/c/Users/vasya"
|
||||
```
|
||||
`Cygwin` shell does not run binaries if their directory has it's own copy of `cygwin1.dll`.
|
||||
If you want to run `winws` from `cygwin` delete, rename or move `cygwin1.dll`.
|
||||
|
||||
`Cygwin` is required only for `blockcheck.sh`. Standalone `winws` can be run without it.
|
||||
|
||||
To simplify things it's advised to use `zapret-win-bundle`.
|
||||
|
||||
### auto start
|
||||
|
||||
@@ -162,4 +164,4 @@ unix2dos winws.log
|
||||
|
||||
`winws.log` will be in `cygwin/home/<username>`. `unix2dos` helps with `windows 7` notepad. It's not necessary in `Windows 10` and later.
|
||||
|
||||
Pre-compiled 32-bit binaries can be downloaded [here](https://github.com/bol-van/zapret-win32)
|
||||
Because 32-bit systems are rare nowadays `zapret-win-bundle` exists only for `Windows x64/arm64`.
|
||||
|
@@ -105,11 +105,11 @@ network locations в win10/11. Кое-что есть в powershell.
|
||||
|
||||
Если в путях присутствуют национальные символы, то при вызове winws из cmd или bat кодировку нужно использовать OEM.
|
||||
Для русского языка это 866. Пути с пробелами нужно брать в кавычки.
|
||||
При использовании опции @<config_file> кодировка в файле должна быть UTF-8 без BOM mark.
|
||||
|
||||
Существует неочевидный момент, каcаемый запуска winws из cygwin шелла. Если в директории, где находится nfqws, находится
|
||||
копия cygwin1.dll, winws не запустится. Поэтому в binaries/win64 существует директория zapret-winws, содержащая полный
|
||||
комплект для запуска без cygwin. Его вы и берете для повседневного использования.
|
||||
Если нужен запуск под cygwin, то следует запускать из binaries/win64. Это нужно для работы blockcheck.
|
||||
Существует неочевидный момент, каcаемый запуска winws из cygwin шелла. Если в директории, где находится winws, находится
|
||||
копия cygwin1.dll, winws не запустится.
|
||||
Если нужен запуск под cygwin, то следует удалить или переместить cygwin1.dll из binaries/win64. Это нужно для работы blockcheck.
|
||||
Из cygwin шелла можно посылать winws сигналы через kill точно так же, как в *nix.
|
||||
|
||||
Как получить совместимый с windows 7 и winws cygwin :
|
||||
@@ -118,11 +118,9 @@ setup-x86_64.exe --allow-unsupported-windows --no-verify --site http://ctm.crouc
|
||||
Следует выбрать установку curl.
|
||||
|
||||
Для сборки из исходников требуется gcc-core,make,zlib-devel.
|
||||
Собирать из директории nfq командой "make cygwin".
|
||||
winws требует cygwin1.dll, windivert.dll, windivert64.sys. Их можно взять из binaries/win64/zapret-winws.
|
||||
|
||||
32-битную x86 версию можно собрать из 32-битного cygwin командой "make cygwin32".
|
||||
windivert.dll и windivert32.sys можно взять из комплекта windivert 2.2.2 : https://reqrypt.org/download
|
||||
Собирать из директории nfq командой "make cygwin64" или "make cygwin32" для 64 и 32 битных версий соответственно.
|
||||
winws требует cygwin1.dll, windivert.dll, windivert64.sys или windivert32.sys.
|
||||
Их можно взять из binaries/win64 и binaries/win32.
|
||||
|
||||
Для arm64 windows нет подписанного драйвера windivert и нет cygwin.
|
||||
Однако, эмуляция x64 windows 11 позволяет использовать все, кроме WinDivert64.sys без изменений.
|
||||
@@ -172,10 +170,15 @@ blockcheck.sh написан на posix shell и требует некоторы
|
||||
Корректный вариант 1 : cd "C:\\Users\\vasya"
|
||||
Корректный вариант 2 : cd "C:/Users/vasya"
|
||||
Корректный вариант 3 : cd "/cygdrive/c/Users/vasya"
|
||||
Существует неочевидный момент, каcаемый запуска winws из cygwin шелла. Если в директории, где находится winws, находится
|
||||
копия cygwin1.dll, winws не запустится. Нужно переименовать файл cygwin1.dll.
|
||||
Далее все как в *nix : 1 раз ./install_bin.sh , затем ./blockcheck.sh.
|
||||
WSL использовать нельзя, это не то же самое.
|
||||
|
||||
cygwin для обычной работы winws не нужен. Разве что вы хотите посылать winws SIGHUP для перечитки листов без перезапуска.
|
||||
cygwin для обычной работы winws не нужен.
|
||||
|
||||
Однако, хотя такой способ и работает, использование winws сильно облегчает zapret-win-bundle.
|
||||
Там нет проблемы с cygwin.dll.
|
||||
|
||||
автозапуск winws
|
||||
----------------
|
||||
@@ -222,5 +225,4 @@ winws.log будет в cygwin/home/<имя_пользователя>
|
||||
Если у вас windows 7, то блокнот не поймет переводы строк в стиле unix. Воспользуйтесь командой
|
||||
unix2dos winws.log
|
||||
|
||||
Готовую 32-битную версию можно скачать здесь : https://github.com/bol-van/zapret-win32
|
||||
Поскольку 32-битные windows мало востребованы, выложены только бинарники и ничего больше.
|
||||
Поскольку 32-битные windows мало востребованы, zapret-win-bundle существует только в варианте для windows x64/arm64.
|
||||
|
@@ -164,7 +164,7 @@ standard_mode_daemons()
|
||||
[ "$TPWS_SOCKS_ENABLE" = 1 ] && {
|
||||
opt="--socks --user=$WS_USER --port=$TPPORT_SOCKS"
|
||||
tpws_apply_socks_binds opt
|
||||
opt="$opt $TPWS_OPT"
|
||||
opt="$opt $TPWS_SOCKS_OPT"
|
||||
filter_apply_hostlist_target opt
|
||||
do_daemon $1 2 "$TPWS" "$opt"
|
||||
}
|
||||
|
@@ -123,12 +123,12 @@ standard_mode_daemons()
|
||||
run_tpws 1 "$opt"
|
||||
}
|
||||
[ "$TPWS_SOCKS_ENABLE" = 1 ] && {
|
||||
opt="--port=$TPPORT_SOCKS $TPWS_OPT"
|
||||
opt="--port=$TPPORT_SOCKS $TPWS_SOCKS_OPT"
|
||||
filter_apply_hostlist_target opt
|
||||
run_tpws_socks 2 "$opt"
|
||||
}
|
||||
[ "$NFQWS_ENABLE" = 1 ] && check_bad_ws_options 1 "$NFQWS_OPT" && {
|
||||
opt="--qnum=$QNUM $NFQWS_OPT"
|
||||
opt="--qnum=$QNUM $NFQWS_OPT_BASE $NFQWS_OPT"
|
||||
filter_apply_hostlist_target opt
|
||||
run_daemon 3 "$NFQWS" "$opt"
|
||||
}
|
||||
|
@@ -291,12 +291,12 @@ standard_mode_daemons()
|
||||
do_tpws $1 1 "$opt"
|
||||
}
|
||||
[ "$TPWS_SOCKS_ENABLE" = 1 ] && {
|
||||
opt="--port=$TPPORT_SOCKS $TPWS_OPT"
|
||||
opt="--port=$TPPORT_SOCKS $TPWS_SOCKS_OPT"
|
||||
filter_apply_hostlist_target opt
|
||||
do_tpws_socks $1 2 "$opt"
|
||||
}
|
||||
[ "$NFQWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$NFQWS_OPT" && {
|
||||
opt="--qnum=$QNUM $NFQWS_OPT_BASE $NFQWS_OPT"
|
||||
opt="--qnum=$QNUM $NFQWS_OPT"
|
||||
filter_apply_hostlist_target opt
|
||||
do_nfqws $1 3 "$opt"
|
||||
}
|
||||
|
13
ipset/def.sh
13
ipset/def.sh
@@ -255,16 +255,3 @@ getipban()
|
||||
_get_ipban
|
||||
return 0
|
||||
}
|
||||
|
||||
hup_zapret_daemons()
|
||||
{
|
||||
echo forcing zapret daemons to reload their hostlist
|
||||
if exists killall; then
|
||||
killall -HUP tpws nfqws dvtws 2>/dev/null
|
||||
elif exists pkill; then
|
||||
pkill -HUP ^tpws$ ^nfqws$ ^dvtws$
|
||||
else
|
||||
echo no mass killer available ! cant HUP zapret daemons
|
||||
fi
|
||||
}
|
||||
|
||||
|
@@ -31,6 +31,4 @@ sort -u "$ZDOM" | zz "$ZHOSTLIST"
|
||||
|
||||
rm -f "$ZDOM"
|
||||
|
||||
hup_zapret_daemons
|
||||
|
||||
exit 0
|
||||
|
@@ -9,5 +9,3 @@ IPSET_DIR="$(cd "$IPSET_DIR"; pwd)"
|
||||
getexclude
|
||||
|
||||
"$IPSET_DIR/create_ipset.sh"
|
||||
|
||||
[ "$MODE_FILTER" = hostlist ] && hup_zapret_daemons
|
||||
|
@@ -9,5 +9,3 @@ IPSET_DIR="$(cd "$IPSET_DIR"; pwd)"
|
||||
getipban
|
||||
|
||||
"$IPSET_DIR/create_ipset.sh"
|
||||
|
||||
[ "$MODE_FILTER" = hostlist ] && hup_zapret_daemons
|
||||
|
@@ -58,8 +58,6 @@ rm -f "$ZREESTR"
|
||||
[ "$DISABLE_IPV6" != "1" ] && $AWK '/^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}($|(\/[0-9]{2,3}$))/' "$IPB" | cut_local6 | ip2net6 | zz "$ZIPLIST_IPBAN6"
|
||||
rm -f "$IPB"
|
||||
|
||||
hup_zapret_daemons
|
||||
|
||||
ipban_fin
|
||||
|
||||
exit 0
|
||||
|
@@ -34,8 +34,6 @@ dl()
|
||||
|
||||
dl "$URL" "$ZHOSTLIST" 65536 67108864
|
||||
|
||||
hup_zapret_daemons
|
||||
|
||||
[ "$DISABLE_IPV4" != "1" ] && dl "$IPB4" "$ZIPLIST_IPBAN" 8192 1048576
|
||||
[ "$DISABLE_IPV6" != "1" ] && dl "$IPB6" "$ZIPLIST_IPBAN6" 128 1048576
|
||||
|
||||
|
@@ -37,6 +37,4 @@ getipban || FAIL=1
|
||||
|
||||
dl "$URL" "$ZHOSTLIST" 32768 4194304
|
||||
|
||||
hup_zapret_daemons
|
||||
|
||||
exit 0
|
||||
|
143
mdig/mdig.c
143
mdig/mdig.c
@@ -319,15 +319,135 @@ static int run_threads(void)
|
||||
return thread ? 0 : 12;
|
||||
}
|
||||
|
||||
// slightly patched musl code
|
||||
size_t dns_mk_query_blob(uint8_t op, const char *dname, uint8_t class, uint8_t type, uint8_t *buf, size_t buflen)
|
||||
{
|
||||
int i, j;
|
||||
uint16_t id;
|
||||
struct timespec ts;
|
||||
size_t l = strnlen(dname, 255);
|
||||
size_t n;
|
||||
|
||||
if (l && dname[l-1]=='.') l--;
|
||||
if (l && dname[l-1]=='.') return 0;
|
||||
n = 17+l+!!l;
|
||||
if (l>253 || buflen<n || op>15u) return 0;
|
||||
|
||||
/* Construct query template - ID will be filled later */
|
||||
memset(buf, 0, n);
|
||||
buf[2] = (op<<3) | 1;
|
||||
buf[5] = 1;
|
||||
memcpy((char *)buf+13, dname, l);
|
||||
for (i=13; buf[i]; i=j+1)
|
||||
{
|
||||
for (j=i; buf[j] && buf[j] != '.'; j++);
|
||||
if (j-i-1u > 62u) return 0;
|
||||
buf[i-1] = j-i;
|
||||
}
|
||||
buf[i+1] = type;
|
||||
buf[i+3] = class;
|
||||
|
||||
/* Make a reasonably unpredictable id */
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
id = (uint16_t)ts.tv_nsec + (uint16_t)(ts.tv_nsec>>16);
|
||||
buf[0] = id>>8;
|
||||
buf[1] = id;
|
||||
|
||||
return n;
|
||||
}
|
||||
int dns_make_query(const char *dom, char family)
|
||||
{
|
||||
uint8_t q[280];
|
||||
size_t l = dns_mk_query_blob(0, dom, 1, family == FAMILY6 ? 28 : 1, q, sizeof(q));
|
||||
if (!l)
|
||||
{
|
||||
fprintf(stderr, "could not make DNS query\n");
|
||||
return 1;
|
||||
}
|
||||
if (fwrite(q,l,1,stdout)!=1)
|
||||
{
|
||||
fprintf(stderr, "could not write DNS query blob to stdout\n");
|
||||
return 10;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool dns_parse_print(const uint8_t *a, size_t len)
|
||||
{
|
||||
// check of minimum header length and response flag
|
||||
uint16_t k, dlen, qcount = a[4]<<8 | a[5], acount = a[6]<<8 | a[7];
|
||||
char s_ip[40];
|
||||
|
||||
if (len<12 || !(a[2]&0x80)) return false;
|
||||
a+=12; len-=12;
|
||||
for(k=0;k<qcount;k++)
|
||||
{
|
||||
while (len && *a)
|
||||
{
|
||||
if ((*a+1)>len) return false;
|
||||
// skip to next label
|
||||
len -= *a+1; a += *a+1;
|
||||
}
|
||||
if (len<5) return false;
|
||||
// skip zero length label, type, class
|
||||
a+=5; len-=5;
|
||||
}
|
||||
for(k=0;k<acount;k++)
|
||||
{
|
||||
// 11 higher bits indicate pointer
|
||||
if (len<12 || (*a & 0xC0)!=0xC0) return false;
|
||||
dlen = a[10]<<8 | a[11];
|
||||
if (len<(dlen+12)) return false;
|
||||
if (a[4]==0 && a[5]==1 && a[2]==0) // IN class and higher byte of type = 0
|
||||
{
|
||||
switch(a[3])
|
||||
{
|
||||
case 1: // A
|
||||
if (dlen!=4) break;
|
||||
if (inet_ntop(AF_INET, a+12, s_ip, sizeof(s_ip)))
|
||||
printf("%s\n", s_ip);
|
||||
break;
|
||||
case 28: // AAAA
|
||||
if (dlen!=16) break;
|
||||
if (inet_ntop(AF_INET6, a+12, s_ip, sizeof(s_ip)))
|
||||
printf("%s\n", s_ip);
|
||||
break;
|
||||
}
|
||||
}
|
||||
len -= 12+dlen; a += 12+dlen;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
int dns_parse_query()
|
||||
{
|
||||
uint8_t a[1500];
|
||||
size_t l;
|
||||
l = fread(a,1,sizeof(a),stdin);
|
||||
if (!l || !feof(stdin))
|
||||
{
|
||||
fprintf(stderr, "could not read DNS reply blob from stdin\n");
|
||||
return 10;
|
||||
}
|
||||
if (!dns_parse_print(a,l))
|
||||
{
|
||||
fprintf(stderr, "could not parse DNS reply blob\n");
|
||||
return 11;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void exithelp(void)
|
||||
{
|
||||
printf(
|
||||
" --threads=<threads_number>\n"
|
||||
" --family=<4|6|46>\t; ipv4, ipv6, ipv4+ipv6\n"
|
||||
" --verbose\t\t; print query progress to stderr\n"
|
||||
" --stats=N\t\t; print resolve stats to stderr every N domains\n"
|
||||
" --log-resolved=<file>\t; log successfully resolved domains to a file\n"
|
||||
" --log-failed=<file>\t; log failed domains to a file\n"
|
||||
" --family=<4|6|46>\t\t; ipv4, ipv6, ipv4+ipv6\n"
|
||||
" --verbose\t\t\t; print query progress to stderr\n"
|
||||
" --stats=N\t\t\t; print resolve stats to stderr every N domains\n"
|
||||
" --log-resolved=<file>\t\t; log successfully resolved domains to a file\n"
|
||||
" --log-failed=<file>\t\t; log failed domains to a file\n"
|
||||
" --dns-make-query=<domain>\t; output to stdout binary blob with DNS query. use --family to specify ip version.\n"
|
||||
" --dns-parse-query\t\t; read from stdin binary DNS answer blob and parse it to ipv4/ipv6 addresses\n"
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
@@ -335,6 +455,7 @@ int main(int argc, char **argv)
|
||||
{
|
||||
int r, v, option_index = 0;
|
||||
char fn1[256],fn2[256];
|
||||
char dom[256];
|
||||
|
||||
static const struct option long_options[] = {
|
||||
{"help",no_argument,0,0}, // optidx=0
|
||||
@@ -344,11 +465,13 @@ int main(int argc, char **argv)
|
||||
{"stats",required_argument,0,0}, // optidx=4
|
||||
{"log-resolved",required_argument,0,0}, // optidx=5
|
||||
{"log-failed",required_argument,0,0}, // optidx=6
|
||||
{"dns-make-query",required_argument,0,0}, // optidx=7
|
||||
{"dns-parse-query",no_argument,0,0}, // optidx=8
|
||||
{NULL,0,NULL,0}
|
||||
};
|
||||
|
||||
memset(&glob, 0, sizeof(glob));
|
||||
*fn1 = *fn2 = 0;
|
||||
*fn1 = *fn2 = *dom = 0;
|
||||
glob.family = FAMILY4;
|
||||
glob.threads = 1;
|
||||
while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1)
|
||||
@@ -394,6 +517,12 @@ int main(int argc, char **argv)
|
||||
strncpy(fn2,optarg,sizeof(fn2));
|
||||
fn2[sizeof(fn2)-1] = 0;
|
||||
break;
|
||||
case 7: /* dns-make-query */
|
||||
strncpy(dom,optarg,sizeof(dom));
|
||||
dom[sizeof(dom)-1] = 0;
|
||||
break;
|
||||
case 8: /* dns-parse-query */
|
||||
return dns_parse_query();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,6 +535,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (*dom) return dns_make_query(dom, glob.family);
|
||||
|
||||
if (*fn1)
|
||||
{
|
||||
glob.F_log_resolved = fopen(fn1,"wt");
|
||||
|
73
nfq/desync.c
73
nfq/desync.c
@@ -146,51 +146,49 @@ enum dpi_desync_mode desync_mode_from_string(const char *s)
|
||||
return DESYNC_INVALID;
|
||||
}
|
||||
|
||||
static bool dp_match_l3l4(struct desync_profile *dp, uint8_t l3proto, const struct sockaddr *dest)
|
||||
{
|
||||
return ((dest->sa_family==AF_INET && dp->filter_ipv4) || (dest->sa_family==AF_INET6 && dp->filter_ipv6)) &&
|
||||
(l3proto==IPPROTO_TCP && pf_in_range(saport(dest), &dp->pf_tcp) || l3proto==IPPROTO_UDP && pf_in_range(saport(dest), &dp->pf_udp)) &&
|
||||
IpsetCheck(dp, dest->sa_family==AF_INET ? &((struct sockaddr_in*)dest)->sin_addr : NULL, dest->sa_family==AF_INET6 ? &((struct sockaddr_in6*)dest)->sin6_addr : NULL);
|
||||
}
|
||||
static bool dp_impossible(struct desync_profile *dp, const char *hostname, t_l7proto l7proto)
|
||||
{
|
||||
return !PROFILE_IPSETS_EMPTY(dp) &&
|
||||
((dp->filter_l7 && !l7_proto_match(l7proto, dp->filter_l7)) || (!*dp->hostlist_auto_filename && !hostname && (dp->hostlist || dp->hostlist_exclude)));
|
||||
}
|
||||
|
||||
static bool dp_match(
|
||||
struct desync_profile *dp,
|
||||
uint8_t l3proto, const struct sockaddr *dest, const char *hostname, t_l7proto l7proto,
|
||||
bool *bCheckDone, bool *bCheckResult, bool *bExcluded)
|
||||
{
|
||||
if (bCheckDone) *bCheckDone = false;
|
||||
// impossible case, hard filter
|
||||
// impossible check avoids relatively slow ipset search
|
||||
if (!dp_impossible(dp,hostname,l7proto) && dp_match_l3l4(dp,l3proto,dest))
|
||||
{
|
||||
// soft filter
|
||||
|
||||
if (!HostlistsReloadCheckForProfile(dp)) return false;
|
||||
|
||||
if ((dest->sa_family==AF_INET && !dp->filter_ipv4) || (dest->sa_family==AF_INET6 && !dp->filter_ipv6))
|
||||
// L3 filter does not match
|
||||
return false;
|
||||
if ((l3proto==IPPROTO_TCP && !port_filters_in_range(&dp->pf_tcp,saport(dest))) || (l3proto==IPPROTO_UDP && !port_filters_in_range(&dp->pf_udp,saport(dest))))
|
||||
// L4 filter does not match
|
||||
return false;
|
||||
if (dp->filter_l7 && !l7_proto_match(l7proto, dp->filter_l7))
|
||||
// L7 filter does not match
|
||||
return false;
|
||||
if (!dp->hostlist_auto && !hostname && !PROFILE_HOSTLISTS_EMPTY(dp))
|
||||
// avoid cpu consuming ipset check. profile cannot win if regular hostlists are present without auto hostlist and hostname is unknown.
|
||||
return false;
|
||||
if (!IpsetCheck(dp, dest->sa_family==AF_INET ? &((struct sockaddr_in*)dest)->sin_addr : NULL, dest->sa_family==AF_INET6 ? &((struct sockaddr_in6*)dest)->sin6_addr : NULL))
|
||||
// target ip does not match
|
||||
return false;
|
||||
|
||||
// autohostlist profile matching l3/l4 filter always win
|
||||
if (*dp->hostlist_auto_filename) return true;
|
||||
if (dp->hostlist_auto) return true;
|
||||
|
||||
if (dp->hostlist || dp->hostlist_exclude)
|
||||
if (PROFILE_HOSTLISTS_EMPTY(dp))
|
||||
// profile without hostlist filter wins
|
||||
return true;
|
||||
else
|
||||
{
|
||||
// without known hostname first profile matching l3/l4 filter and without hostlist filter wins
|
||||
if (hostname)
|
||||
{
|
||||
if (bCheckDone) *bCheckDone = true;
|
||||
bool b;
|
||||
b = HostlistCheck(dp, hostname, bExcluded);
|
||||
b = HostlistCheck(dp, hostname, bExcluded, true);
|
||||
if (bCheckResult) *bCheckResult = b;
|
||||
return b;
|
||||
}
|
||||
}
|
||||
else
|
||||
// profile without hostlist filter wins
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static struct desync_profile *dp_find(
|
||||
@@ -359,21 +357,21 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname
|
||||
|
||||
DLOG("auto hostlist (profile %d) : rechecking %s to avoid duplicates\n", dp->n, hostname);
|
||||
bool bExcluded=false;
|
||||
if (!HostlistCheck(dp, hostname, &bExcluded) && !bExcluded)
|
||||
if (!HostlistCheck(dp, hostname, &bExcluded, false) && !bExcluded)
|
||||
{
|
||||
DLOG("auto hostlist (profile %d) : adding %s to %s\n", dp->n, hostname, dp->hostlist_auto_filename);
|
||||
HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : adding to %s", hostname, dp->n, client_ip_port, l7proto_str(l7proto), dp->hostlist_auto_filename);
|
||||
if (!StrPoolAddStr(&dp->hostlist, hostname))
|
||||
DLOG("auto hostlist (profile %d) : adding %s to %s\n", dp->n, hostname, dp->hostlist_auto->filename);
|
||||
HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : adding to %s", hostname, dp->n, client_ip_port, l7proto_str(l7proto), dp->hostlist_auto->filename);
|
||||
if (!StrPoolAddStr(&dp->hostlist_auto->hostlist, hostname))
|
||||
{
|
||||
DLOG_ERR("StrPoolAddStr out of memory\n");
|
||||
return;
|
||||
}
|
||||
if (!append_to_list_file(dp->hostlist_auto_filename, hostname))
|
||||
if (!append_to_list_file(dp->hostlist_auto->filename, hostname))
|
||||
{
|
||||
DLOG_PERROR("write to auto hostlist:");
|
||||
return;
|
||||
}
|
||||
dp->hostlist_auto_mod_time = file_mod_time(dp->hostlist_auto_filename);
|
||||
dp->hostlist_auto->mod_time = file_mod_time(dp->hostlist_auto->filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -851,7 +849,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
size_t fake_size;
|
||||
char host[256];
|
||||
bool bHaveHost=false;
|
||||
uint8_t *p, *phost;
|
||||
uint8_t *p, *phost=NULL;
|
||||
const uint8_t *rdata_payload = data_payload;
|
||||
size_t rlen_payload = len_payload;
|
||||
size_t split_pos;
|
||||
@@ -1044,17 +1042,17 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
bCheckExcluded = ctrack_replay->bCheckExcluded;
|
||||
}
|
||||
|
||||
if (bHaveHost && (dp->hostlist || dp->hostlist_exclude))
|
||||
if (bHaveHost && !PROFILE_HOSTLISTS_EMPTY(dp))
|
||||
{
|
||||
if (!bCheckDone)
|
||||
bCheckResult = HostlistCheck(dp, host, &bCheckExcluded);
|
||||
bCheckResult = HostlistCheck(dp, host, &bCheckExcluded, false);
|
||||
if (bCheckResult)
|
||||
ctrack_stop_retrans_counter(ctrack_replay);
|
||||
else
|
||||
{
|
||||
if (ctrack_replay)
|
||||
{
|
||||
ctrack_replay->hostname_ah_check = *dp->hostlist_auto_filename && !bCheckExcluded;
|
||||
ctrack_replay->hostname_ah_check = dp->hostlist_auto && !bCheckExcluded;
|
||||
if (!ctrack_replay->hostname_ah_check)
|
||||
ctrack_stop_retrans_counter(ctrack_replay);
|
||||
}
|
||||
@@ -1099,7 +1097,6 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
}
|
||||
|
||||
ttl_fake = (ctrack_replay && ctrack_replay->autottl) ? ctrack_replay->autottl : (ip6hdr ? (dp->desync_ttl6 ? dp->desync_ttl6 : ttl_orig) : (dp->desync_ttl ? dp->desync_ttl : ttl_orig));
|
||||
|
||||
if ((l7proto == HTTP) && (dp->hostcase || dp->hostnospace || dp->domcase) && HttpFindHost(&phost,data_payload,len_payload))
|
||||
{
|
||||
if (dp->hostcase)
|
||||
@@ -1762,17 +1759,17 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
bCheckExcluded = ctrack_replay->bCheckExcluded;
|
||||
}
|
||||
|
||||
if (bHaveHost && (dp->hostlist || dp->hostlist_exclude))
|
||||
if (bHaveHost && !PROFILE_HOSTLISTS_EMPTY(dp))
|
||||
{
|
||||
if (!bCheckDone)
|
||||
bCheckResult = HostlistCheck(dp, host, &bCheckExcluded);
|
||||
bCheckResult = HostlistCheck(dp, host, &bCheckExcluded, false);
|
||||
if (bCheckResult)
|
||||
ctrack_stop_retrans_counter(ctrack_replay);
|
||||
else
|
||||
{
|
||||
if (ctrack_replay)
|
||||
{
|
||||
ctrack_replay->hostname_ah_check = *dp->hostlist_auto_filename && !bCheckExcluded;
|
||||
ctrack_replay->hostname_ah_check = dp->hostlist_auto && !bCheckExcluded;
|
||||
if (ctrack_replay->hostname_ah_check)
|
||||
{
|
||||
// first request is not retrans
|
||||
|
@@ -17,20 +17,9 @@ void rtrim(char *s)
|
||||
for (char *p = s + strlen(s) - 1; p >= s && (*p == '\n' || *p == '\r'); p--) *p = '\0';
|
||||
}
|
||||
|
||||
void hexdump_limited_dlog(const uint8_t *data, size_t size, size_t limit)
|
||||
void replace_char(char *s, char from, char to)
|
||||
{
|
||||
size_t k;
|
||||
bool bcut = false;
|
||||
if (size > limit)
|
||||
{
|
||||
size = limit;
|
||||
bcut = true;
|
||||
}
|
||||
if (!size) return;
|
||||
for (k = 0; k < size; k++) DLOG("%02X ", data[k]);
|
||||
DLOG(bcut ? "... : " : ": ");
|
||||
for (k = 0; k < size; k++) DLOG("%c", data[k] >= 0x20 && data[k] <= 0x7F ? (char)data[k] : '.');
|
||||
if (bcut) DLOG(" ...");
|
||||
for(;*s;s++) if (*s==from) *s=to;
|
||||
}
|
||||
|
||||
char *strncasestr(const char *s, const char *find, size_t slen)
|
||||
@@ -54,6 +43,23 @@ char *strncasestr(const char *s, const char *find, size_t slen)
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
void hexdump_limited_dlog(const uint8_t *data, size_t size, size_t limit)
|
||||
{
|
||||
size_t k;
|
||||
bool bcut = false;
|
||||
if (size > limit)
|
||||
{
|
||||
size = limit;
|
||||
bcut = true;
|
||||
}
|
||||
if (!size) return;
|
||||
for (k = 0; k < size; k++) DLOG("%02X ", data[k]);
|
||||
DLOG(bcut ? "... : " : ": ");
|
||||
for (k = 0; k < size; k++) DLOG("%c", data[k] >= 0x20 && data[k] <= 0x7F ? (char)data[k] : '.');
|
||||
if (bcut) DLOG(" ...");
|
||||
}
|
||||
|
||||
|
||||
bool load_file(const char *filename, void *buffer, size_t *buffer_size)
|
||||
{
|
||||
FILE *F;
|
||||
@@ -333,6 +339,11 @@ bool pf_parse(const char *s, port_filter *pf)
|
||||
char c;
|
||||
|
||||
if (!s) return false;
|
||||
if (*s=='*' && s[1]==0)
|
||||
{
|
||||
pf->from=1; pf->to=0xFFFF;
|
||||
return true;
|
||||
}
|
||||
if (*s=='~')
|
||||
{
|
||||
pf->neg=true;
|
||||
|
@@ -18,9 +18,10 @@ typedef union
|
||||
} sockaddr_in46;
|
||||
|
||||
void rtrim(char *s);
|
||||
void replace_char(char *s, char from, char to);
|
||||
char *strncasestr(const char *s,const char *find, size_t slen);
|
||||
|
||||
void hexdump_limited_dlog(const uint8_t *data, size_t size, size_t limit);
|
||||
char *strncasestr(const char *s,const char *find, size_t slen);
|
||||
bool load_file(const char *filename,void *buffer,size_t *buffer_size);
|
||||
bool load_file_nonempty(const char *filename,void *buffer,size_t *buffer_size);
|
||||
bool save_file(const char *filename, const void *buffer, size_t buffer_size);
|
||||
|
195
nfq/hostlist.c
195
nfq/hostlist.c
@@ -96,21 +96,37 @@ bool AppendHostList(strpool **hostlist, const char *filename)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadHostLists(strpool **hostlist, struct str_list_head *file_list)
|
||||
static bool LoadHostList(struct hostlist_file *hfile)
|
||||
{
|
||||
struct str_list *file;
|
||||
|
||||
if (*hostlist)
|
||||
time_t t = file_mod_time(hfile->filename);
|
||||
if (!t)
|
||||
{
|
||||
StrPoolDestroy(hostlist);
|
||||
*hostlist = NULL;
|
||||
}
|
||||
|
||||
LIST_FOREACH(file, file_list, next)
|
||||
{
|
||||
if (!AppendHostList(hostlist, file->str)) return false;
|
||||
}
|
||||
// stat() error
|
||||
DLOG_ERR("cannot access hostlist file '%s'. in-memory content remains unchanged.\n",hfile->filename);
|
||||
return true;
|
||||
}
|
||||
if (t==hfile->mod_time) return true; // up to date
|
||||
StrPoolDestroy(&hfile->hostlist);
|
||||
if (!AppendHostList(&hfile->hostlist, hfile->filename))
|
||||
{
|
||||
StrPoolDestroy(&hfile->hostlist);
|
||||
return false;
|
||||
}
|
||||
hfile->mod_time=t;
|
||||
return true;
|
||||
}
|
||||
static bool LoadHostLists(struct hostlist_files_head *list)
|
||||
{
|
||||
bool bres=true;
|
||||
struct hostlist_file *hfile;
|
||||
|
||||
LIST_FOREACH(hfile, list, next)
|
||||
{
|
||||
if (!LoadHostList(hfile))
|
||||
// at least one failed
|
||||
bres=false;
|
||||
}
|
||||
return bres;
|
||||
}
|
||||
|
||||
bool NonEmptyHostlist(strpool **hostlist)
|
||||
@@ -119,8 +135,27 @@ bool NonEmptyHostlist(strpool **hostlist)
|
||||
return *hostlist ? true : StrPoolAddStrLen(hostlist, "@&()", 4);
|
||||
}
|
||||
|
||||
static void MakeAutolistsNonEmpty()
|
||||
{
|
||||
struct desync_profile_list *dpl;
|
||||
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
||||
{
|
||||
if (dpl->dp.hostlist_auto)
|
||||
NonEmptyHostlist(&dpl->dp.hostlist_auto->hostlist);
|
||||
}
|
||||
}
|
||||
|
||||
bool SearchHostList(strpool *hostlist, const char *host)
|
||||
bool LoadAllHostLists()
|
||||
{
|
||||
if (!LoadHostLists(¶ms.hostlists))
|
||||
return false;
|
||||
MakeAutolistsNonEmpty();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool SearchHostList(strpool *hostlist, const char *host)
|
||||
{
|
||||
if (hostlist)
|
||||
{
|
||||
@@ -129,7 +164,7 @@ bool SearchHostList(strpool *hostlist, const char *host)
|
||||
while (p)
|
||||
{
|
||||
bInHostList = StrPoolCheckStr(hostlist, p);
|
||||
DLOG("Hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative");
|
||||
DLOG("hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative");
|
||||
if (bInHostList) return true;
|
||||
p = strchr(p, '.');
|
||||
if (p) p++;
|
||||
@@ -138,74 +173,108 @@ bool SearchHostList(strpool *hostlist, const char *host)
|
||||
return false;
|
||||
}
|
||||
|
||||
// return : true = apply fooling, false = do not apply
|
||||
static bool HostlistCheck_(strpool *hostlist, strpool *hostlist_exclude, const char *host, bool *excluded)
|
||||
|
||||
static bool HostlistsReloadCheck(const struct hostlist_collection_head *hostlists)
|
||||
{
|
||||
if (excluded) *excluded = false;
|
||||
if (hostlist_exclude)
|
||||
struct hostlist_item *item;
|
||||
LIST_FOREACH(item, hostlists, next)
|
||||
{
|
||||
DLOG("Checking exclude hostlist\n");
|
||||
if (SearchHostList(hostlist_exclude, host))
|
||||
if (!LoadHostList(item->hfile))
|
||||
return false;
|
||||
}
|
||||
MakeAutolistsNonEmpty();
|
||||
return true;
|
||||
}
|
||||
bool HostlistsReloadCheckForProfile(const struct desync_profile *dp)
|
||||
{
|
||||
return HostlistsReloadCheck(&dp->hl_collection) && HostlistsReloadCheck(&dp->hl_collection_exclude);
|
||||
}
|
||||
// return : true = apply fooling, false = do not apply
|
||||
static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, const struct hostlist_collection_head *hostlists_exclude, const char *host, bool *excluded, bool bSkipReloadCheck)
|
||||
{
|
||||
struct hostlist_item *item;
|
||||
|
||||
if (excluded) *excluded = false;
|
||||
|
||||
if (!bSkipReloadCheck)
|
||||
if (!HostlistsReloadCheck(hostlists) || !HostlistsReloadCheck(hostlists_exclude))
|
||||
return false;
|
||||
|
||||
LIST_FOREACH(item, hostlists_exclude, next)
|
||||
{
|
||||
DLOG("[%s] exclude ", item->hfile->filename);
|
||||
if (SearchHostList(item->hfile->hostlist, host))
|
||||
{
|
||||
if (excluded) *excluded = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (hostlist)
|
||||
// old behavior compat: all include lists are empty means check passes
|
||||
if (!hostlist_collection_is_empty(hostlists))
|
||||
{
|
||||
DLOG("Checking include hostlist\n");
|
||||
return SearchHostList(hostlist, host);
|
||||
LIST_FOREACH(item, hostlists, next)
|
||||
{
|
||||
DLOG("[%s] include ", item->hfile->filename);
|
||||
if (SearchHostList(item->hfile->hostlist, host))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool LoadIncludeHostListsForProfile(struct desync_profile *dp)
|
||||
{
|
||||
if (!LoadHostLists(&dp->hostlist, &dp->hostlist_files))
|
||||
return false;
|
||||
if (*dp->hostlist_auto_filename)
|
||||
{
|
||||
dp->hostlist_auto_mod_time = file_mod_time(dp->hostlist_auto_filename);
|
||||
NonEmptyHostlist(&dp->hostlist);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// return : true = apply fooling, false = do not apply
|
||||
bool HostlistCheck(struct desync_profile *dp, const char *host, bool *excluded)
|
||||
bool HostlistCheck(const struct desync_profile *dp, const char *host, bool *excluded, bool bSkipReloadCheck)
|
||||
{
|
||||
DLOG("* hostlist check for profile %d\n",dp->n);
|
||||
if (*dp->hostlist_auto_filename)
|
||||
{
|
||||
time_t t = file_mod_time(dp->hostlist_auto_filename);
|
||||
if (t!=dp->hostlist_auto_mod_time)
|
||||
{
|
||||
DLOG_CONDUP("Autohostlist '%s' from profile %d was modified. Reloading include hostlists for this profile.\n",dp->hostlist_auto_filename, dp->n);
|
||||
if (!LoadIncludeHostListsForProfile(dp))
|
||||
{
|
||||
// what will we do without hostlist ?? sure, gonna die
|
||||
exit(1);
|
||||
}
|
||||
dp->hostlist_auto_mod_time = t;
|
||||
NonEmptyHostlist(&dp->hostlist);
|
||||
}
|
||||
}
|
||||
return HostlistCheck_(dp->hostlist, dp->hostlist_exclude, host, excluded);
|
||||
return HostlistCheck_(&dp->hl_collection, &dp->hl_collection_exclude, host, excluded, bSkipReloadCheck);
|
||||
}
|
||||
|
||||
bool LoadIncludeHostLists()
|
||||
|
||||
static struct hostlist_file *RegisterHostlist_(struct hostlist_files_head *hostlists, struct hostlist_collection_head *hl_collection, const char *filename)
|
||||
{
|
||||
struct desync_profile_list *dpl;
|
||||
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
||||
if (!LoadIncludeHostListsForProfile(&dpl->dp))
|
||||
return false;
|
||||
return true;
|
||||
struct hostlist_file *hfile;
|
||||
if (!(hfile=hostlist_files_search(hostlists, filename)))
|
||||
if (!(hfile=hostlist_files_add(hostlists, filename)))
|
||||
return NULL;
|
||||
if (!hostlist_collection_search(hl_collection, filename))
|
||||
if (!hostlist_collection_add(hl_collection, hfile))
|
||||
return NULL;
|
||||
return hfile;
|
||||
}
|
||||
bool LoadExcludeHostLists()
|
||||
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename)
|
||||
{
|
||||
struct desync_profile_list *dpl;
|
||||
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
||||
if (!LoadHostLists(&dpl->dp.hostlist_exclude, &dpl->dp.hostlist_exclude_files))
|
||||
return false;
|
||||
return true;
|
||||
if (!file_mod_time(filename))
|
||||
{
|
||||
DLOG_ERR("cannot access hostlist file '%s'\n",filename);
|
||||
return NULL;
|
||||
}
|
||||
return RegisterHostlist_(
|
||||
¶ms.hostlists,
|
||||
bExclude ? &dp->hl_collection_exclude : &dp->hl_collection,
|
||||
filename);
|
||||
}
|
||||
|
||||
void HostlistsDebug()
|
||||
{
|
||||
if (!params.debug) return;
|
||||
|
||||
struct hostlist_file *hfile;
|
||||
struct desync_profile_list *dpl;
|
||||
struct hostlist_item *hl_item;
|
||||
|
||||
LIST_FOREACH(hfile, ¶ms.hostlists, next)
|
||||
DLOG("hostlist file %s%s\n",hfile->filename,hfile->hostlist ? "" : " (empty)");
|
||||
|
||||
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
||||
{
|
||||
LIST_FOREACH(hl_item, &dpl->dp.hl_collection, next)
|
||||
if (hl_item->hfile!=dpl->dp.hostlist_auto)
|
||||
DLOG("profile %d include hostlist %s%s\n",dpl->dp.n, hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
|
||||
LIST_FOREACH(hl_item, &dpl->dp.hl_collection_exclude, next)
|
||||
DLOG("profile %d exclude hostlist %s%s\n",dpl->dp.n,hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
|
||||
if (dpl->dp.hostlist_auto)
|
||||
DLOG("profile %d auto hostlist %s%s\n",dpl->dp.n,dpl->dp.hostlist_auto->filename,dpl->dp.hostlist_auto->hostlist ? "" : " (empty)");
|
||||
}
|
||||
}
|
||||
|
@@ -5,10 +5,10 @@
|
||||
#include "params.h"
|
||||
|
||||
bool AppendHostList(strpool **hostlist, const char *filename);
|
||||
bool LoadHostLists(strpool **hostlist, struct str_list_head *file_list);
|
||||
bool LoadIncludeHostLists();
|
||||
bool LoadExcludeHostLists();
|
||||
bool LoadAllHostLists();
|
||||
bool NonEmptyHostlist(strpool **hostlist);
|
||||
bool SearchHostList(strpool *hostlist, const char *host);
|
||||
// return : true = apply fooling, false = do not apply
|
||||
bool HostlistCheck(struct desync_profile *dp,const char *host, bool *excluded);
|
||||
bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck);
|
||||
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename);
|
||||
bool HostlistsReloadCheckForProfile(const struct desync_profile *dp);
|
||||
void HostlistsDebug();
|
||||
|
158
nfq/ipset.c
158
nfq/ipset.c
@@ -3,6 +3,7 @@
|
||||
#include "gzip.h"
|
||||
#include "helpers.h"
|
||||
|
||||
|
||||
// inplace tolower() and add to pool
|
||||
static bool addpool(ipset *ips, char **s, const char *end, int *ct)
|
||||
{
|
||||
@@ -116,37 +117,45 @@ static bool AppendIpset(ipset *ips, const char *filename)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool LoadIpsets(ipset *ips, struct str_list_head *file_list)
|
||||
static bool LoadIpset(struct ipset_file *hfile)
|
||||
{
|
||||
struct str_list *file;
|
||||
|
||||
ipsetDestroy(ips);
|
||||
|
||||
LIST_FOREACH(file, file_list, next)
|
||||
time_t t = file_mod_time(hfile->filename);
|
||||
if (!t)
|
||||
{
|
||||
if (!AppendIpset(ips, file->str)) return false;
|
||||
// stat() error
|
||||
DLOG_ERR("cannot access ipset file '%s'. in-memory content remains unchanged.\n",hfile->filename);
|
||||
return true;
|
||||
}
|
||||
if (t==hfile->mod_time) return true; // up to date
|
||||
ipsetDestroy(&hfile->ipset);
|
||||
if (!AppendIpset(&hfile->ipset, hfile->filename))
|
||||
{
|
||||
ipsetDestroy(&hfile->ipset);
|
||||
return false;
|
||||
}
|
||||
hfile->mod_time=t;
|
||||
return true;
|
||||
}
|
||||
static bool LoadIpsets(struct ipset_files_head *list)
|
||||
{
|
||||
bool bres=true;
|
||||
struct ipset_file *hfile;
|
||||
|
||||
LIST_FOREACH(hfile, list, next)
|
||||
{
|
||||
if (!LoadIpset(hfile))
|
||||
// at least one failed
|
||||
bres=false;
|
||||
}
|
||||
return bres;
|
||||
}
|
||||
|
||||
bool LoadIncludeIpsets()
|
||||
bool LoadAllIpsets()
|
||||
{
|
||||
struct desync_profile_list *dpl;
|
||||
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
||||
if (!LoadIpsets(&dpl->dp.ips, &dpl->dp.ipset_files))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool LoadExcludeIpsets()
|
||||
{
|
||||
struct desync_profile_list *dpl;
|
||||
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
||||
if (!LoadIpsets(&dpl->dp.ips_exclude, &dpl->dp.ipset_exclude_files))
|
||||
return false;
|
||||
return true;
|
||||
return LoadIpsets(¶ms.ipsets);
|
||||
}
|
||||
|
||||
bool SearchIpset(const ipset *ips, const struct in_addr *ipv4, const struct in6_addr *ipv6)
|
||||
static bool SearchIpset(const ipset *ips, const struct in_addr *ipv4, const struct in6_addr *ipv6)
|
||||
{
|
||||
char s_ip[40];
|
||||
bool bInSet=false;
|
||||
@@ -172,24 +181,109 @@ bool SearchIpset(const ipset *ips, const struct in_addr *ipv4, const struct in6_
|
||||
return bInSet;
|
||||
}
|
||||
|
||||
static bool IpsetCheck_(const ipset *ips, const ipset *ips_exclude, const struct in_addr *ipv4, const struct in6_addr *ipv6)
|
||||
static bool IpsetsReloadCheck(const struct ipset_collection_head *ipsets)
|
||||
{
|
||||
if (!IPSET_EMPTY(ips_exclude))
|
||||
struct ipset_item *item;
|
||||
LIST_FOREACH(item, ipsets, next)
|
||||
{
|
||||
DLOG("exclude ");
|
||||
if (SearchIpset(ips_exclude, ipv4, ipv6))
|
||||
if (!LoadIpset(item->hfile))
|
||||
return false;
|
||||
}
|
||||
if (!IPSET_EMPTY(ips))
|
||||
return true;
|
||||
}
|
||||
bool IpsetsReloadCheckForProfile(const struct desync_profile *dp)
|
||||
{
|
||||
return IpsetsReloadCheck(&dp->ips_collection) && IpsetsReloadCheck(&dp->ips_collection_exclude);
|
||||
}
|
||||
|
||||
static bool IpsetCheck_(const struct ipset_collection_head *ips, const struct ipset_collection_head *ips_exclude, const struct in_addr *ipv4, const struct in6_addr *ipv6)
|
||||
{
|
||||
struct ipset_item *item;
|
||||
|
||||
if (!IpsetsReloadCheck(ips) || !IpsetsReloadCheck(ips_exclude))
|
||||
return false;
|
||||
|
||||
LIST_FOREACH(item, ips_exclude, next)
|
||||
{
|
||||
DLOG("include ");
|
||||
return SearchIpset(ips, ipv4, ipv6);
|
||||
DLOG("[%s] exclude ",item->hfile->filename);
|
||||
if (SearchIpset(&item->hfile->ipset, ipv4, ipv6))
|
||||
return false;
|
||||
}
|
||||
// old behavior compat: all include lists are empty means check passes
|
||||
if (!ipset_collection_is_empty(ips))
|
||||
{
|
||||
LIST_FOREACH(item, ips, next)
|
||||
{
|
||||
DLOG("[%s] include ",item->hfile->filename);
|
||||
if (SearchIpset(&item->hfile->ipset, ipv4, ipv6))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IpsetCheck(struct desync_profile *dp, const struct in_addr *ipv4, const struct in6_addr *ipv6)
|
||||
bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *ipv4, const struct in6_addr *ipv6)
|
||||
{
|
||||
if (!PROFILE_IPSETS_EMPTY(dp)) DLOG("* ipset check for profile %d\n",dp->n);
|
||||
return IpsetCheck_(&dp->ips,&dp->ips_exclude,ipv4,ipv6);
|
||||
if (PROFILE_IPSETS_ABSENT(dp)) return true;
|
||||
DLOG("* ipset check for profile %d\n",dp->n);
|
||||
return IpsetCheck_(&dp->ips_collection,&dp->ips_collection_exclude,ipv4,ipv6);
|
||||
}
|
||||
|
||||
|
||||
static struct ipset_file *RegisterIpset_(struct ipset_files_head *ipsets, struct ipset_collection_head *ips_collection, const char *filename)
|
||||
{
|
||||
struct ipset_file *hfile;
|
||||
if (!(hfile=ipset_files_search(ipsets, filename)))
|
||||
if (!(hfile=ipset_files_add(ipsets, filename)))
|
||||
return NULL;
|
||||
if (!ipset_collection_search(ips_collection, filename))
|
||||
if (!ipset_collection_add(ips_collection, hfile))
|
||||
return NULL;
|
||||
return hfile;
|
||||
}
|
||||
struct ipset_file *RegisterIpset(struct desync_profile *dp, bool bExclude, const char *filename)
|
||||
{
|
||||
if (!file_mod_time(filename))
|
||||
{
|
||||
DLOG_ERR("cannot access ipset file '%s'\n",filename);
|
||||
return NULL;
|
||||
}
|
||||
return RegisterIpset_(
|
||||
¶ms.ipsets,
|
||||
bExclude ? &dp->ips_collection_exclude : &dp->ips_collection,
|
||||
filename);
|
||||
}
|
||||
|
||||
static const char *dbg_ipset_fill(const ipset *ips)
|
||||
{
|
||||
if (ips->ips4)
|
||||
if (ips->ips6)
|
||||
return "ipv4+ipv6";
|
||||
else
|
||||
return "ipv4";
|
||||
else
|
||||
if (ips->ips6)
|
||||
return "ipv6";
|
||||
else
|
||||
return "empty";
|
||||
}
|
||||
void IpsetsDebug()
|
||||
{
|
||||
if (!params.debug) return;
|
||||
|
||||
struct ipset_file *hfile;
|
||||
struct desync_profile_list *dpl;
|
||||
struct ipset_item *ips_item;
|
||||
|
||||
LIST_FOREACH(hfile, ¶ms.ipsets, next)
|
||||
DLOG("ipset file %s (%s)\n",hfile->filename,dbg_ipset_fill(&hfile->ipset));
|
||||
|
||||
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
||||
{
|
||||
LIST_FOREACH(ips_item, &dpl->dp.ips_collection, next)
|
||||
DLOG("profile %d include ipset %s (%s)\n",dpl->dp.n,ips_item->hfile->filename,dbg_ipset_fill(&ips_item->hfile->ipset));
|
||||
LIST_FOREACH(ips_item, &dpl->dp.ips_collection_exclude, next)
|
||||
DLOG("profile %d exclude ipset %s (%s)\n",dpl->dp.n,ips_item->hfile->filename,dbg_ipset_fill(&ips_item->hfile->ipset));
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include "params.h"
|
||||
#include "pools.h"
|
||||
|
||||
bool LoadIncludeIpsets();
|
||||
bool LoadExcludeIpsets();
|
||||
bool SearchIpset(const ipset *ips, const struct in_addr *ipv4, const struct in6_addr *ipv6);
|
||||
bool IpsetCheck(struct desync_profile *dp, const struct in_addr *ipv4, const struct in6_addr *ipv6);
|
||||
bool LoadAllIpsets();
|
||||
bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *ipv4, const struct in6_addr *ipv6);
|
||||
struct ipset_file *RegisterIpset(struct desync_profile *dp, bool bExclude, const char *filename);
|
||||
void IpsetsDebug();
|
||||
|
167
nfq/nfqws.c
167
nfq/nfqws.c
@@ -46,30 +46,17 @@
|
||||
#define CTRACK_T_EST 300
|
||||
#define CTRACK_T_UDP 60
|
||||
|
||||
#define MAX_CONFIG_FILE_SIZE 16384
|
||||
|
||||
struct params_s params;
|
||||
#ifdef __CYGWIN__
|
||||
bool bQuit=false;
|
||||
#endif
|
||||
|
||||
static bool bHup = false;
|
||||
static void onhup(int sig)
|
||||
{
|
||||
printf("HUP received !\n");
|
||||
printf("Will reload hostlists and ipsets on next request (if any)\n");
|
||||
bHup = true;
|
||||
}
|
||||
// should be called in normal execution
|
||||
static void dohup(void)
|
||||
{
|
||||
if (bHup)
|
||||
{
|
||||
if (!LoadIncludeHostLists() || !LoadExcludeHostLists() || !LoadIncludeIpsets() || !LoadExcludeIpsets())
|
||||
{
|
||||
// what will we do without hostlist ?? sure, gonna die
|
||||
exit(1);
|
||||
}
|
||||
bHup = false;
|
||||
}
|
||||
// do not do anything. lists auto reload themselves based on file time.
|
||||
}
|
||||
|
||||
static void onusr1(int sig)
|
||||
@@ -239,7 +226,6 @@ static int nfq_main(void)
|
||||
{
|
||||
while ((rv = recv(fd, buf, sizeof(buf), 0)) > 0)
|
||||
{
|
||||
dohup();
|
||||
int r = nfq_handle_packet(h, (char *)buf, rv);
|
||||
if (r) DLOG_ERR("nfq_handle_packet error %d\n", r);
|
||||
}
|
||||
@@ -351,7 +337,6 @@ static int dvt_main(void)
|
||||
if (errno==EINTR)
|
||||
{
|
||||
// a signal received
|
||||
dohup();
|
||||
continue;
|
||||
}
|
||||
DLOG_PERROR("select");
|
||||
@@ -507,8 +492,6 @@ static int win_main(const char *windivert_filter)
|
||||
}
|
||||
else
|
||||
{
|
||||
dohup();
|
||||
|
||||
mark=0;
|
||||
// pseudo interface id IfIdx.SubIfIdx
|
||||
verdict = processPacketData(&mark, ifout, packet, &len);
|
||||
@@ -569,12 +552,21 @@ static bool parse_ws_scale_factor(char *s, uint16_t *wsize, uint8_t *wscale)
|
||||
|
||||
|
||||
|
||||
static void cleanup_args()
|
||||
{
|
||||
wordfree(¶ms.wexp);
|
||||
}
|
||||
|
||||
static void cleanup_params(void)
|
||||
{
|
||||
cleanup_args();
|
||||
|
||||
ConntrackPoolDestroy(¶ms.conntrack);
|
||||
|
||||
dp_list_destroy(¶ms.desync_profiles);
|
||||
|
||||
hostlist_files_destroy(¶ms.hostlists);
|
||||
ipset_files_destroy(¶ms.ipsets);
|
||||
#ifdef __CYGWIN__
|
||||
strlist_destroy(¶ms.ssid_filter);
|
||||
strlist_destroy(¶ms.nlm_filter);
|
||||
@@ -686,6 +678,28 @@ static bool parse_l7_list(char *opt, uint32_t *l7)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_pf_list(char *opt, struct port_filters_head *pfl)
|
||||
{
|
||||
char *e,*p,c;
|
||||
port_filter pf;
|
||||
bool b;
|
||||
|
||||
for (p=opt ; p ; )
|
||||
{
|
||||
if ((e = strchr(p,',')))
|
||||
{
|
||||
c=*e;
|
||||
*e=0;
|
||||
}
|
||||
|
||||
b = pf_parse(p,&pf) && port_filter_add(pfl,&pf);
|
||||
if (e) *e++=c;
|
||||
if (!b) return false;
|
||||
|
||||
p = e;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool wf_make_l3(char *opt, bool *ipv4, bool *ipv6)
|
||||
{
|
||||
@@ -837,6 +851,7 @@ static unsigned int hash_jen(const void *data,unsigned int len)
|
||||
static void exithelp(void)
|
||||
{
|
||||
printf(
|
||||
" @<config_file>\t\t\t\t\t; read file for options. must be the only argument. other options are ignored.\n\n"
|
||||
" --debug=0|1|syslog|@<filename>\n"
|
||||
#ifdef __linux__
|
||||
" --qnum=<nfqueue_number>\n"
|
||||
@@ -870,8 +885,8 @@ static void exithelp(void)
|
||||
"\nMULTI-STRATEGY:\n"
|
||||
" --new\t\t\t\t\t\t; begin new strategy\n"
|
||||
" --filter-l3=ipv4|ipv6\t\t\t\t; L3 protocol filter. multiple comma separated values allowed.\n"
|
||||
" --filter-tcp=[~]port1[-port2]\t\t\t; TCP port filter. ~ means negation. setting tcp and not setting udp filter denies udp.\n"
|
||||
" --filter-udp=[~]port1[-port2]\t\t\t; UDP port filter. ~ means negation. setting udp and not setting tcp filter denies tcp.\n"
|
||||
" --filter-tcp=[~]port1[-port2]|*\t\t; TCP port filter. ~ means negation. setting tcp and not setting udp filter denies udp. comma separated list allowed.\n"
|
||||
" --filter-udp=[~]port1[-port2]|*\t\t; UDP port filter. ~ means negation. setting udp and not setting tcp filter denies tcp. comma separated list allowed.\n"
|
||||
" --filter-l7=[http|tls|quic|wireguard|dht|unknown] ; L6-L7 protocol filter. multiple comma separated values allowed.\n"
|
||||
" --ipset=<filename>\t\t\t\t; ipset include filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)\n"
|
||||
" --ipset-exclude=<filename>\t\t\t; ipset exclude filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)\n"
|
||||
@@ -997,6 +1012,7 @@ int main(int argc, char **argv)
|
||||
struct desync_profile_list *dpl;
|
||||
struct desync_profile *dp;
|
||||
int desync_profile_count=0;
|
||||
|
||||
if (!(dpl = dp_list_add(¶ms.desync_profiles)))
|
||||
{
|
||||
DLOG_ERR("desync_profile_add: out of memory\n");
|
||||
@@ -1016,6 +1032,9 @@ int main(int argc, char **argv)
|
||||
params.ctrack_t_fin = CTRACK_T_FIN;
|
||||
params.ctrack_t_udp = CTRACK_T_UDP;
|
||||
|
||||
LIST_INIT(¶ms.hostlists);
|
||||
LIST_INIT(¶ms.ipsets);
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
LIST_INIT(¶ms.ssid_filter);
|
||||
LIST_INIT(¶ms.nlm_filter);
|
||||
@@ -1027,6 +1046,33 @@ int main(int argc, char **argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc>=2 && argv[1][0]=='@')
|
||||
{
|
||||
// config from a file
|
||||
|
||||
char buf[MAX_CONFIG_FILE_SIZE];
|
||||
buf[0]='x'; // fake argv[0]
|
||||
buf[1]=' ';
|
||||
size_t bufsize=sizeof(buf)-3;
|
||||
if (!load_file(argv[1]+1,buf+2,&bufsize))
|
||||
{
|
||||
DLOG_ERR("could not load config file '%s'\n",argv[1]+1);
|
||||
exit_clean(1);
|
||||
}
|
||||
buf[bufsize+2]=0;
|
||||
// wordexp fails if it sees \t \n \r between args
|
||||
replace_char(buf,'\n',' ');
|
||||
replace_char(buf,'\r',' ');
|
||||
replace_char(buf,'\t',' ');
|
||||
if (wordexp(buf, ¶ms.wexp, WRDE_NOCMD))
|
||||
{
|
||||
DLOG_ERR("failed to split command line options from file '%s'\n",argv[1]+1);
|
||||
exit_clean(1);
|
||||
}
|
||||
argv=params.wexp.we_wordv;
|
||||
argc=params.wexp.we_wordc;
|
||||
}
|
||||
|
||||
const struct option long_options[] = {
|
||||
{"debug",optional_argument,0,0}, // optidx=0
|
||||
#ifdef __linux__
|
||||
@@ -1522,27 +1568,27 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case 45: /* hostlist */
|
||||
if (!strlist_add(&dp->hostlist_files, optarg))
|
||||
if (!RegisterHostlist(dp, false, optarg))
|
||||
{
|
||||
DLOG_ERR("strlist_add failed\n");
|
||||
DLOG_ERR("failed to register hostlist '%s'\n", optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 46: /* hostlist-exclude */
|
||||
if (!strlist_add(&dp->hostlist_exclude_files, optarg))
|
||||
if (!RegisterHostlist(dp, true, optarg))
|
||||
{
|
||||
DLOG_ERR("strlist_add failed\n");
|
||||
DLOG_ERR("failed to register hostlist '%s'\n", optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 47: /* hostlist-auto */
|
||||
if (*dp->hostlist_auto_filename)
|
||||
if (dp->hostlist_auto)
|
||||
{
|
||||
DLOG_ERR("only one auto hostlist per profile is supported\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
{
|
||||
FILE *F = fopen(optarg,"at");
|
||||
FILE *F = fopen(optarg,"a+b");
|
||||
if (!F)
|
||||
{
|
||||
DLOG_ERR("cannot create %s\n", optarg);
|
||||
@@ -1560,13 +1606,11 @@ int main(int argc, char **argv)
|
||||
DLOG_ERR("could not chown %s. auto hostlist file may not be writable after privilege drop\n", optarg);
|
||||
#endif
|
||||
}
|
||||
if (!strlist_add(&dp->hostlist_files, optarg))
|
||||
if (!(dp->hostlist_auto=RegisterHostlist(dp, false, optarg)))
|
||||
{
|
||||
DLOG_ERR("strlist_add failed\n");
|
||||
DLOG_ERR("failed to register hostlist '%s'\n", optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
strncpy(dp->hostlist_auto_filename, optarg, sizeof(dp->hostlist_auto_filename));
|
||||
dp->hostlist_auto_filename[sizeof(dp->hostlist_auto_filename) - 1] = '\0';
|
||||
break;
|
||||
case 48: /* hostlist-auto-fail-threshold */
|
||||
dp->hostlist_auto_fail_threshold = (uint8_t)atoi(optarg);
|
||||
@@ -1627,22 +1671,24 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case 54: /* filter-tcp */
|
||||
if (!pf_parse(optarg,&dp->pf_tcp))
|
||||
{
|
||||
DLOG_ERR("Invalid port filter : %s\n",optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
// deny udp if not set
|
||||
if (pf_is_empty(&dp->pf_udp)) dp->pf_udp.neg=true;
|
||||
break;
|
||||
case 55: /* filter-udp */
|
||||
if (!pf_parse(optarg,&dp->pf_udp))
|
||||
if (!parse_pf_list(optarg,&dp->pf_tcp))
|
||||
{
|
||||
DLOG_ERR("Invalid port filter : %s\n",optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
// deny tcp if not set
|
||||
if (pf_is_empty(&dp->pf_tcp)) dp->pf_tcp.neg=true;
|
||||
if (!port_filters_deny_if_empty(&dp->pf_udp))
|
||||
exit_clean(1);
|
||||
break;
|
||||
case 55: /* filter-udp */
|
||||
if (!parse_pf_list(optarg,&dp->pf_udp))
|
||||
{
|
||||
DLOG_ERR("Invalid port filter : %s\n",optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
// deny tcp if not set
|
||||
if (!port_filters_deny_if_empty(&dp->pf_tcp))
|
||||
exit_clean(1);
|
||||
break;
|
||||
case 56: /* filter-l7 */
|
||||
if (!parse_l7_list(optarg,&dp->filter_l7))
|
||||
@@ -1652,16 +1698,16 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case 57: /* ipset */
|
||||
if (!strlist_add(&dp->ipset_files, optarg))
|
||||
if (!RegisterIpset(dp, false, optarg))
|
||||
{
|
||||
DLOG_ERR("strlist_add failed\n");
|
||||
DLOG_ERR("failed to register ipset '%s'\n", optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 58: /* ipset-exclude */
|
||||
if (!strlist_add(&dp->ipset_exclude_files, optarg))
|
||||
if (!RegisterIpset(dp, true, optarg))
|
||||
{
|
||||
DLOG_ERR("strlist_add failed\n");
|
||||
DLOG_ERR("failed to register ipset '%s'\n", optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
@@ -1774,6 +1820,10 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
// do not need args from file anymore
|
||||
cleanup_args();
|
||||
argv=NULL; argc=0;
|
||||
|
||||
#ifdef __linux__
|
||||
if (params.qnum<0)
|
||||
{
|
||||
@@ -1854,27 +1904,22 @@ int main(int argc, char **argv)
|
||||
if (dp->desync_split_http_req==httpreqpos_none && dp->desync_split_pos) dp->desync_split_http_req=httpreqpos_pos;
|
||||
}
|
||||
|
||||
if (!LoadIncludeHostLists())
|
||||
if (!LoadAllHostLists())
|
||||
{
|
||||
DLOG_ERR("Include hostlists load failed\n");
|
||||
DLOG_ERR("hostlists load failed\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
if (!LoadExcludeHostLists())
|
||||
if (!LoadAllIpsets())
|
||||
{
|
||||
DLOG_ERR("Exclude hostlists load failed\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
if (!LoadIncludeIpsets())
|
||||
{
|
||||
DLOG_ERR("Include ipset load failed\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
if (!LoadExcludeIpsets())
|
||||
{
|
||||
DLOG_ERR("Exclude ipset load failed\n");
|
||||
DLOG_ERR("ipset load failed\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
|
||||
DLOG("\nlists summary:\n");
|
||||
HostlistsDebug();
|
||||
IpsetsDebug();
|
||||
DLOG("\n");
|
||||
|
||||
if (daemon) daemonize();
|
||||
|
||||
if (*pidfile && !writepid(pidfile))
|
||||
|
26
nfq/params.c
26
nfq/params.c
@@ -160,8 +160,13 @@ struct desync_profile_list *dp_list_add(struct desync_profile_list_head *head)
|
||||
struct desync_profile_list *entry = calloc(1,sizeof(struct desync_profile_list));
|
||||
if (!entry) return NULL;
|
||||
|
||||
LIST_INIT(&entry->dp.hostlist_files);
|
||||
LIST_INIT(&entry->dp.hostlist_exclude_files);
|
||||
LIST_INIT(&entry->dp.hl_collection);
|
||||
LIST_INIT(&entry->dp.hl_collection_exclude);
|
||||
LIST_INIT(&entry->dp.ips_collection);
|
||||
LIST_INIT(&entry->dp.ips_collection_exclude);
|
||||
LIST_INIT(&entry->dp.pf_tcp);
|
||||
LIST_INIT(&entry->dp.pf_udp);
|
||||
|
||||
memcpy(entry->dp.hostspell, "host", 4); // default hostspell
|
||||
entry->dp.desync_skip_nosni = true;
|
||||
entry->dp.desync_split_pos = 2;
|
||||
@@ -205,14 +210,12 @@ struct desync_profile_list *dp_list_add(struct desync_profile_list_head *head)
|
||||
}
|
||||
static void dp_entry_destroy(struct desync_profile_list *entry)
|
||||
{
|
||||
strlist_destroy(&entry->dp.hostlist_files);
|
||||
strlist_destroy(&entry->dp.hostlist_exclude_files);
|
||||
strlist_destroy(&entry->dp.ipset_files);
|
||||
strlist_destroy(&entry->dp.ipset_exclude_files);
|
||||
StrPoolDestroy(&entry->dp.hostlist_exclude);
|
||||
StrPoolDestroy(&entry->dp.hostlist);
|
||||
ipsetDestroy(&entry->dp.ips);
|
||||
ipsetDestroy(&entry->dp.ips_exclude);
|
||||
hostlist_collection_destroy(&entry->dp.hl_collection);
|
||||
hostlist_collection_destroy(&entry->dp.hl_collection_exclude);
|
||||
ipset_collection_destroy(&entry->dp.ips_collection);
|
||||
ipset_collection_destroy(&entry->dp.ips_collection_exclude);
|
||||
port_filters_destroy(&entry->dp.pf_tcp);
|
||||
port_filters_destroy(&entry->dp.pf_udp);
|
||||
HostFailPoolDestroy(&entry->dp.hostlist_auto_fail_counters);
|
||||
free(entry);
|
||||
}
|
||||
@@ -229,8 +232,7 @@ bool dp_list_have_autohostlist(struct desync_profile_list_head *head)
|
||||
{
|
||||
struct desync_profile_list *dpl;
|
||||
LIST_FOREACH(dpl, head, next)
|
||||
if (*dpl->dp.hostlist_auto_filename)
|
||||
if (dpl->dp.hostlist_auto)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
28
nfq/params.h
28
nfq/params.h
@@ -14,6 +14,7 @@
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <sys/queue.h>
|
||||
#include <wordexp.h>
|
||||
|
||||
#define TLS_PARTIALS_ENABLE true
|
||||
|
||||
@@ -65,20 +66,24 @@ struct desync_profile
|
||||
int udplen_increment;
|
||||
|
||||
bool filter_ipv4,filter_ipv6;
|
||||
port_filter pf_tcp,pf_udp;
|
||||
struct port_filters_head pf_tcp,pf_udp;
|
||||
uint32_t filter_l7; // L7_PROTO_* bits
|
||||
ipset ips,ips_exclude;
|
||||
struct str_list_head ipset_files, ipset_exclude_files;
|
||||
|
||||
strpool *hostlist, *hostlist_exclude;
|
||||
struct str_list_head hostlist_files, hostlist_exclude_files;
|
||||
char hostlist_auto_filename[PATH_MAX];
|
||||
// list of pointers to ipsets
|
||||
struct ipset_collection_head ips_collection, ips_collection_exclude;
|
||||
|
||||
// list of pointers to hostlist files
|
||||
struct hostlist_collection_head hl_collection, hl_collection_exclude;
|
||||
// pointer to autohostlist. NULL if no autohostlist for the profile.
|
||||
struct hostlist_file *hostlist_auto;
|
||||
int hostlist_auto_fail_threshold, hostlist_auto_fail_time, hostlist_auto_retrans_threshold;
|
||||
time_t hostlist_auto_mod_time;
|
||||
|
||||
hostfail_pool *hostlist_auto_fail_counters;
|
||||
};
|
||||
|
||||
#define PROFILE_IPSETS_EMPTY(dp) (IPSET_EMPTY(&dp->ips) && IPSET_EMPTY(&dp->ips_exclude))
|
||||
#define PROFILE_IPSETS_ABSENT(dp) (!LIST_FIRST(&dp->ips_collection) && !LIST_FIRST(&dp->ips_collection_exclude))
|
||||
#define PROFILE_IPSETS_EMPTY(dp) (ipset_collection_is_empty(&dp->ips_collection) && ipset_collection_is_empty(&dp->ips_collection_exclude))
|
||||
#define PROFILE_HOSTLISTS_EMPTY(dp) (hostlist_collection_is_empty(&dp->hl_collection) && hostlist_collection_is_empty(&dp->hl_collection_exclude))
|
||||
|
||||
struct desync_profile_list {
|
||||
struct desync_profile dp;
|
||||
@@ -91,6 +96,8 @@ bool dp_list_have_autohostlist(struct desync_profile_list_head *head);
|
||||
|
||||
struct params_s
|
||||
{
|
||||
wordexp_t wexp; // for file based config
|
||||
|
||||
enum log_target debug_target;
|
||||
char debug_logfile[PATH_MAX];
|
||||
bool debug;
|
||||
@@ -115,6 +122,11 @@ struct params_s
|
||||
|
||||
char hostlist_auto_debuglog[PATH_MAX];
|
||||
|
||||
// hostlist files with data for all profiles
|
||||
struct hostlist_files_head hostlists;
|
||||
// ipset files with data for all profiles
|
||||
struct ipset_files_head ipsets;
|
||||
|
||||
unsigned int ctrack_t_syn, ctrack_t_est, ctrack_t_fin, ctrack_t_udp;
|
||||
t_conntrack conntrack;
|
||||
};
|
||||
|
212
nfq/pools.c
212
nfq/pools.c
@@ -154,6 +154,93 @@ void strlist_destroy(struct str_list_head *head)
|
||||
|
||||
|
||||
|
||||
|
||||
struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const char *filename)
|
||||
{
|
||||
struct hostlist_file *entry = malloc(sizeof(struct hostlist_file));
|
||||
if (entry)
|
||||
{
|
||||
if (!(entry->filename = strdup(filename)))
|
||||
{
|
||||
free(entry);
|
||||
return false;
|
||||
}
|
||||
entry->mod_time=0;
|
||||
entry->hostlist = NULL;
|
||||
LIST_INSERT_HEAD(head, entry, next);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
static void hostlist_files_entry_destroy(struct hostlist_file *entry)
|
||||
{
|
||||
if (entry->filename) free(entry->filename);
|
||||
StrPoolDestroy(&entry->hostlist);
|
||||
free(entry);
|
||||
}
|
||||
void hostlist_files_destroy(struct hostlist_files_head *head)
|
||||
{
|
||||
struct hostlist_file *entry;
|
||||
while ((entry = LIST_FIRST(head)))
|
||||
{
|
||||
LIST_REMOVE(entry, next);
|
||||
hostlist_files_entry_destroy(entry);
|
||||
}
|
||||
}
|
||||
struct hostlist_file *hostlist_files_search(struct hostlist_files_head *head, const char *filename)
|
||||
{
|
||||
struct hostlist_file *hfile;
|
||||
|
||||
LIST_FOREACH(hfile, head, next)
|
||||
{
|
||||
if (!strcmp(hfile->filename,filename))
|
||||
return hfile;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct hostlist_item *hostlist_collection_add(struct hostlist_collection_head *head, struct hostlist_file *hfile)
|
||||
{
|
||||
struct hostlist_item *entry = malloc(sizeof(struct hostlist_item));
|
||||
if (entry)
|
||||
{
|
||||
entry->hfile = hfile;
|
||||
LIST_INSERT_HEAD(head, entry, next);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
void hostlist_collection_destroy(struct hostlist_collection_head *head)
|
||||
{
|
||||
struct hostlist_item *entry;
|
||||
while ((entry = LIST_FIRST(head)))
|
||||
{
|
||||
LIST_REMOVE(entry, next);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
struct hostlist_item *hostlist_collection_search(struct hostlist_collection_head *head, const char *filename)
|
||||
{
|
||||
struct hostlist_item *item;
|
||||
|
||||
LIST_FOREACH(item, head, next)
|
||||
{
|
||||
if (!strcmp(item->hfile->filename,filename))
|
||||
return item;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
bool hostlist_collection_is_empty(const struct hostlist_collection_head *head)
|
||||
{
|
||||
const struct hostlist_item *item;
|
||||
|
||||
LIST_FOREACH(item, head, next)
|
||||
{
|
||||
if (item->hfile->hostlist)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ipset4Destroy(ipset4 **ipset)
|
||||
{
|
||||
ipset4 *elem, *tmp;
|
||||
@@ -275,3 +362,128 @@ void ipsetPrint(ipset *ipset)
|
||||
ipset4Print(ipset->ips4);
|
||||
ipset6Print(ipset->ips6);
|
||||
}
|
||||
|
||||
|
||||
struct ipset_file *ipset_files_add(struct ipset_files_head *head, const char *filename)
|
||||
{
|
||||
struct ipset_file *entry = malloc(sizeof(struct ipset_file));
|
||||
if (entry)
|
||||
{
|
||||
if (!(entry->filename = strdup(filename)))
|
||||
{
|
||||
free(entry);
|
||||
return false;
|
||||
}
|
||||
entry->mod_time=0;
|
||||
memset(&entry->ipset,0,sizeof(entry->ipset));
|
||||
LIST_INSERT_HEAD(head, entry, next);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
static void ipset_files_entry_destroy(struct ipset_file *entry)
|
||||
{
|
||||
if (entry->filename) free(entry->filename);
|
||||
ipsetDestroy(&entry->ipset);
|
||||
free(entry);
|
||||
}
|
||||
void ipset_files_destroy(struct ipset_files_head *head)
|
||||
{
|
||||
struct ipset_file *entry;
|
||||
while ((entry = LIST_FIRST(head)))
|
||||
{
|
||||
LIST_REMOVE(entry, next);
|
||||
ipset_files_entry_destroy(entry);
|
||||
}
|
||||
}
|
||||
struct ipset_file *ipset_files_search(struct ipset_files_head *head, const char *filename)
|
||||
{
|
||||
struct ipset_file *hfile;
|
||||
|
||||
LIST_FOREACH(hfile, head, next)
|
||||
{
|
||||
if (!strcmp(hfile->filename,filename))
|
||||
return hfile;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ipset_item *ipset_collection_add(struct ipset_collection_head *head, struct ipset_file *hfile)
|
||||
{
|
||||
struct ipset_item *entry = malloc(sizeof(struct ipset_item));
|
||||
if (entry)
|
||||
{
|
||||
entry->hfile = hfile;
|
||||
LIST_INSERT_HEAD(head, entry, next);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
void ipset_collection_destroy(struct ipset_collection_head *head)
|
||||
{
|
||||
struct ipset_item *entry;
|
||||
while ((entry = LIST_FIRST(head)))
|
||||
{
|
||||
LIST_REMOVE(entry, next);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
struct ipset_item *ipset_collection_search(struct ipset_collection_head *head, const char *filename)
|
||||
{
|
||||
struct ipset_item *item;
|
||||
|
||||
LIST_FOREACH(item, head, next)
|
||||
{
|
||||
if (!strcmp(item->hfile->filename,filename))
|
||||
return item;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
bool ipset_collection_is_empty(const struct ipset_collection_head *head)
|
||||
{
|
||||
const struct ipset_item *item;
|
||||
|
||||
LIST_FOREACH(item, head, next)
|
||||
{
|
||||
if (!IPSET_EMPTY(&item->hfile->ipset))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool port_filter_add(struct port_filters_head *head, const port_filter *pf)
|
||||
{
|
||||
struct port_filter_item *entry = malloc(sizeof(struct port_filter_item));
|
||||
if (entry)
|
||||
{
|
||||
entry->pf = *pf;
|
||||
LIST_INSERT_HEAD(head, entry, next);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
void port_filters_destroy(struct port_filters_head *head)
|
||||
{
|
||||
struct port_filter_item *entry;
|
||||
while ((entry = LIST_FIRST(head)))
|
||||
{
|
||||
LIST_REMOVE(entry, next);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
bool port_filters_in_range(const struct port_filters_head *head, uint16_t port)
|
||||
{
|
||||
const struct port_filter_item *item;
|
||||
|
||||
if (!LIST_FIRST(head)) return true;
|
||||
LIST_FOREACH(item, head, next)
|
||||
{
|
||||
if (pf_in_range(port, &item->pf))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool port_filters_deny_if_empty(struct port_filters_head *head)
|
||||
{
|
||||
port_filter pf;
|
||||
if (LIST_FIRST(head)) return true;
|
||||
return pf_parse("0",&pf) && port_filter_add(head,&pf);
|
||||
}
|
||||
|
58
nfq/pools.h
58
nfq/pools.h
@@ -47,6 +47,30 @@ bool strlist_add(struct str_list_head *head, const char *filename);
|
||||
void strlist_destroy(struct str_list_head *head);
|
||||
|
||||
|
||||
|
||||
struct hostlist_file {
|
||||
char *filename;
|
||||
time_t mod_time;
|
||||
strpool *hostlist;
|
||||
LIST_ENTRY(hostlist_file) next;
|
||||
};
|
||||
LIST_HEAD(hostlist_files_head, hostlist_file);
|
||||
|
||||
struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const char *filename);
|
||||
void hostlist_files_destroy(struct hostlist_files_head *head);
|
||||
struct hostlist_file *hostlist_files_search(struct hostlist_files_head *head, const char *filename);
|
||||
|
||||
struct hostlist_item {
|
||||
struct hostlist_file *hfile;
|
||||
LIST_ENTRY(hostlist_item) next;
|
||||
};
|
||||
LIST_HEAD(hostlist_collection_head, hostlist_item);
|
||||
struct hostlist_item *hostlist_collection_add(struct hostlist_collection_head *head, struct hostlist_file *hfile);
|
||||
void hostlist_collection_destroy(struct hostlist_collection_head *head);
|
||||
struct hostlist_item *hostlist_collection_search(struct hostlist_collection_head *head, const char *filename);
|
||||
bool hostlist_collection_is_empty(const struct hostlist_collection_head *head);
|
||||
|
||||
|
||||
typedef struct ipset4 {
|
||||
struct cidr4 cidr; /* key */
|
||||
UT_hash_handle hh; /* makes this structure hashable */
|
||||
@@ -83,3 +107,37 @@ void ipset6Print(ipset6 *ipset);
|
||||
|
||||
void ipsetDestroy(ipset *ipset);
|
||||
void ipsetPrint(ipset *ipset);
|
||||
|
||||
|
||||
struct ipset_file {
|
||||
char *filename;
|
||||
time_t mod_time;
|
||||
ipset ipset;
|
||||
LIST_ENTRY(ipset_file) next;
|
||||
};
|
||||
LIST_HEAD(ipset_files_head, ipset_file);
|
||||
|
||||
struct ipset_file *ipset_files_add(struct ipset_files_head *head, const char *filename);
|
||||
void ipset_files_destroy(struct ipset_files_head *head);
|
||||
struct ipset_file *ipset_files_search(struct ipset_files_head *head, const char *filename);
|
||||
|
||||
struct ipset_item {
|
||||
struct ipset_file *hfile;
|
||||
LIST_ENTRY(ipset_item) next;
|
||||
};
|
||||
LIST_HEAD(ipset_collection_head, ipset_item);
|
||||
struct ipset_item * ipset_collection_add(struct ipset_collection_head *head, struct ipset_file *hfile);
|
||||
void ipset_collection_destroy(struct ipset_collection_head *head);
|
||||
struct ipset_item *ipset_collection_search(struct ipset_collection_head *head, const char *filename);
|
||||
bool ipset_collection_is_empty(const struct ipset_collection_head *head);
|
||||
|
||||
|
||||
struct port_filter_item {
|
||||
port_filter pf;
|
||||
LIST_ENTRY(port_filter_item) next;
|
||||
};
|
||||
LIST_HEAD(port_filters_head, port_filter_item);
|
||||
bool port_filter_add(struct port_filters_head *head, const port_filter *pf);
|
||||
void port_filters_destroy(struct port_filters_head *head);
|
||||
bool port_filters_in_range(const struct port_filters_head *head, uint16_t port);
|
||||
bool port_filters_deny_if_empty(struct port_filters_head *head);
|
||||
|
@@ -17,6 +17,11 @@ void rtrim(char *s)
|
||||
for (char *p = s + strlen(s) - 1; p >= s && (*p == '\n' || *p == '\r'); p--) *p = '\0';
|
||||
}
|
||||
|
||||
void replace_char(char *s, char from, char to)
|
||||
{
|
||||
for(;*s;s++) if (*s==from) *s=to;
|
||||
}
|
||||
|
||||
char *strncasestr(const char *s,const char *find, size_t slen)
|
||||
{
|
||||
char c, sc;
|
||||
@@ -38,6 +43,24 @@ char *strncasestr(const char *s,const char *find, size_t slen)
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
bool load_file(const char *filename, void *buffer, size_t *buffer_size)
|
||||
{
|
||||
FILE *F;
|
||||
|
||||
F = fopen(filename, "rb");
|
||||
if (!F) return false;
|
||||
|
||||
*buffer_size = fread(buffer, 1, *buffer_size, F);
|
||||
if (ferror(F))
|
||||
{
|
||||
fclose(F);
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(F);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool append_to_list_file(const char *filename, const char *s)
|
||||
{
|
||||
FILE *F = fopen(filename,"at");
|
||||
@@ -268,6 +291,11 @@ bool pf_parse(const char *s, port_filter *pf)
|
||||
char c;
|
||||
|
||||
if (!s) return false;
|
||||
if (*s=='*' && s[1]==0)
|
||||
{
|
||||
pf->from=1; pf->to=0xFFFF;
|
||||
return true;
|
||||
}
|
||||
if (*s=='~')
|
||||
{
|
||||
pf->neg=true;
|
||||
|
@@ -16,8 +16,10 @@ typedef union
|
||||
} sockaddr_in46;
|
||||
|
||||
void rtrim(char *s);
|
||||
void replace_char(char *s, char from, char to);
|
||||
char *strncasestr(const char *s,const char *find, size_t slen);
|
||||
|
||||
bool load_file(const char *filename,void *buffer,size_t *buffer_size);
|
||||
bool append_to_list_file(const char *filename, const char *s);
|
||||
|
||||
void ntop46(const struct sockaddr *sa, char *str, size_t len);
|
||||
|
195
tpws/hostlist.c
195
tpws/hostlist.c
@@ -1,7 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include "hostlist.h"
|
||||
#include "gzip.h"
|
||||
#include "params.h"
|
||||
#include "helpers.h"
|
||||
|
||||
// inplace tolower() and add to pool
|
||||
@@ -97,21 +96,37 @@ bool AppendHostList(strpool **hostlist, const char *filename)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LoadHostLists(strpool **hostlist, struct str_list_head *file_list)
|
||||
static bool LoadHostList(struct hostlist_file *hfile)
|
||||
{
|
||||
struct str_list *file;
|
||||
|
||||
if (*hostlist)
|
||||
time_t t = file_mod_time(hfile->filename);
|
||||
if (!t)
|
||||
{
|
||||
StrPoolDestroy(hostlist);
|
||||
*hostlist = NULL;
|
||||
}
|
||||
|
||||
LIST_FOREACH(file, file_list, next)
|
||||
{
|
||||
if (!AppendHostList(hostlist, file->str)) return false;
|
||||
}
|
||||
// stat() error
|
||||
DLOG_ERR("cannot access hostlist file '%s'. in-memory content remains unchanged.\n",hfile->filename);
|
||||
return true;
|
||||
}
|
||||
if (t==hfile->mod_time) return true; // up to date
|
||||
StrPoolDestroy(&hfile->hostlist);
|
||||
if (!AppendHostList(&hfile->hostlist, hfile->filename))
|
||||
{
|
||||
StrPoolDestroy(&hfile->hostlist);
|
||||
return false;
|
||||
}
|
||||
hfile->mod_time=t;
|
||||
return true;
|
||||
}
|
||||
static bool LoadHostLists(struct hostlist_files_head *list)
|
||||
{
|
||||
bool bres=true;
|
||||
struct hostlist_file *hfile;
|
||||
|
||||
LIST_FOREACH(hfile, list, next)
|
||||
{
|
||||
if (!LoadHostList(hfile))
|
||||
// at least one failed
|
||||
bres=false;
|
||||
}
|
||||
return bres;
|
||||
}
|
||||
|
||||
bool NonEmptyHostlist(strpool **hostlist)
|
||||
@@ -120,8 +135,27 @@ bool NonEmptyHostlist(strpool **hostlist)
|
||||
return *hostlist ? true : StrPoolAddStrLen(hostlist, "@&()", 4);
|
||||
}
|
||||
|
||||
static void MakeAutolistsNonEmpty()
|
||||
{
|
||||
struct desync_profile_list *dpl;
|
||||
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
||||
{
|
||||
if (dpl->dp.hostlist_auto)
|
||||
NonEmptyHostlist(&dpl->dp.hostlist_auto->hostlist);
|
||||
}
|
||||
}
|
||||
|
||||
bool SearchHostList(strpool *hostlist, const char *host)
|
||||
bool LoadAllHostLists()
|
||||
{
|
||||
if (!LoadHostLists(¶ms.hostlists))
|
||||
return false;
|
||||
MakeAutolistsNonEmpty();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool SearchHostList(strpool *hostlist, const char *host)
|
||||
{
|
||||
if (hostlist)
|
||||
{
|
||||
@@ -130,7 +164,7 @@ bool SearchHostList(strpool *hostlist, const char *host)
|
||||
while (p)
|
||||
{
|
||||
bInHostList = StrPoolCheckStr(hostlist, p);
|
||||
VPRINT("Hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative");
|
||||
VPRINT("hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative");
|
||||
if (bInHostList) return true;
|
||||
p = strchr(p, '.');
|
||||
if (p) p++;
|
||||
@@ -139,73 +173,108 @@ bool SearchHostList(strpool *hostlist, const char *host)
|
||||
return false;
|
||||
}
|
||||
|
||||
// return : true = apply fooling, false = do not apply
|
||||
static bool HostlistCheck_(strpool *hostlist, strpool *hostlist_exclude, const char *host, bool *excluded)
|
||||
|
||||
static bool HostlistsReloadCheck(const struct hostlist_collection_head *hostlists)
|
||||
{
|
||||
if (excluded) *excluded = false;
|
||||
if (hostlist_exclude)
|
||||
struct hostlist_item *item;
|
||||
LIST_FOREACH(item, hostlists, next)
|
||||
{
|
||||
VPRINT("Checking exclude hostlist\n");
|
||||
if (SearchHostList(hostlist_exclude, host))
|
||||
if (!LoadHostList(item->hfile))
|
||||
return false;
|
||||
}
|
||||
MakeAutolistsNonEmpty();
|
||||
return true;
|
||||
}
|
||||
bool HostlistsReloadCheckForProfile(const struct desync_profile *dp)
|
||||
{
|
||||
return HostlistsReloadCheck(&dp->hl_collection) && HostlistsReloadCheck(&dp->hl_collection_exclude);
|
||||
}
|
||||
// return : true = apply fooling, false = do not apply
|
||||
static bool HostlistCheck_(const struct hostlist_collection_head *hostlists, const struct hostlist_collection_head *hostlists_exclude, const char *host, bool *excluded, bool bSkipReloadCheck)
|
||||
{
|
||||
struct hostlist_item *item;
|
||||
|
||||
if (excluded) *excluded = false;
|
||||
|
||||
if (!bSkipReloadCheck)
|
||||
if (!HostlistsReloadCheck(hostlists) || !HostlistsReloadCheck(hostlists_exclude))
|
||||
return false;
|
||||
|
||||
LIST_FOREACH(item, hostlists_exclude, next)
|
||||
{
|
||||
VPRINT("[%s] exclude ", item->hfile->filename);
|
||||
if (SearchHostList(item->hfile->hostlist, host))
|
||||
{
|
||||
if (excluded) *excluded = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (hostlist)
|
||||
// old behavior compat: all include lists are empty means check passes
|
||||
if (!hostlist_collection_is_empty(hostlists))
|
||||
{
|
||||
VPRINT("Checking include hostlist\n");
|
||||
return SearchHostList(hostlist, host);
|
||||
}
|
||||
LIST_FOREACH(item, hostlists, next)
|
||||
{
|
||||
VPRINT("[%s] include ", item->hfile->filename);
|
||||
if (SearchHostList(item->hfile->hostlist, host))
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool LoadIncludeHostListsForProfile(struct desync_profile *dp)
|
||||
{
|
||||
if (!LoadHostLists(&dp->hostlist, &dp->hostlist_files))
|
||||
}
|
||||
return false;
|
||||
if (*dp->hostlist_auto_filename)
|
||||
{
|
||||
dp->hostlist_auto_mod_time = file_mod_time(dp->hostlist_auto_filename);
|
||||
NonEmptyHostlist(&dp->hostlist);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HostlistCheck(struct desync_profile *dp, const char *host, bool *excluded)
|
||||
|
||||
// return : true = apply fooling, false = do not apply
|
||||
bool HostlistCheck(const struct desync_profile *dp, const char *host, bool *excluded, bool bSkipReloadCheck)
|
||||
{
|
||||
VPRINT("* hostlist check for profile %d\n",dp->n);
|
||||
if (*dp->hostlist_auto_filename)
|
||||
{
|
||||
time_t t = file_mod_time(dp->hostlist_auto_filename);
|
||||
if (t!=dp->hostlist_auto_mod_time)
|
||||
{
|
||||
DLOG_CONDUP("Autohostlist '%s' from profile %d was modified. Reloading include hostlists for this profile.\n",dp->hostlist_auto_filename, dp->n);
|
||||
if (!LoadIncludeHostListsForProfile(dp))
|
||||
{
|
||||
// what will we do without hostlist ?? sure, gonna die
|
||||
exit(1);
|
||||
}
|
||||
dp->hostlist_auto_mod_time = t;
|
||||
NonEmptyHostlist(&dp->hostlist);
|
||||
}
|
||||
}
|
||||
return HostlistCheck_(dp->hostlist, dp->hostlist_exclude, host, excluded);
|
||||
return HostlistCheck_(&dp->hl_collection, &dp->hl_collection_exclude, host, excluded, bSkipReloadCheck);
|
||||
}
|
||||
|
||||
bool LoadIncludeHostLists()
|
||||
|
||||
static struct hostlist_file *RegisterHostlist_(struct hostlist_files_head *hostlists, struct hostlist_collection_head *hl_collection, const char *filename)
|
||||
{
|
||||
struct desync_profile_list *dpl;
|
||||
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
||||
if (!LoadIncludeHostListsForProfile(&dpl->dp))
|
||||
return false;
|
||||
return true;
|
||||
struct hostlist_file *hfile;
|
||||
if (!(hfile=hostlist_files_search(hostlists, filename)))
|
||||
if (!(hfile=hostlist_files_add(hostlists, filename)))
|
||||
return NULL;
|
||||
if (!hostlist_collection_search(hl_collection, filename))
|
||||
if (!hostlist_collection_add(hl_collection, hfile))
|
||||
return NULL;
|
||||
return hfile;
|
||||
}
|
||||
bool LoadExcludeHostLists()
|
||||
struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename)
|
||||
{
|
||||
struct desync_profile_list *dpl;
|
||||
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
||||
if (!LoadHostLists(&dpl->dp.hostlist_exclude, &dpl->dp.hostlist_exclude_files))
|
||||
return false;
|
||||
return true;
|
||||
if (!file_mod_time(filename))
|
||||
{
|
||||
DLOG_ERR("cannot access hostlist file '%s'\n",filename);
|
||||
return NULL;
|
||||
}
|
||||
return RegisterHostlist_(
|
||||
¶ms.hostlists,
|
||||
bExclude ? &dp->hl_collection_exclude : &dp->hl_collection,
|
||||
filename);
|
||||
}
|
||||
|
||||
void HostlistsDebug()
|
||||
{
|
||||
if (!params.debug) return;
|
||||
|
||||
struct hostlist_file *hfile;
|
||||
struct desync_profile_list *dpl;
|
||||
struct hostlist_item *hl_item;
|
||||
|
||||
LIST_FOREACH(hfile, ¶ms.hostlists, next)
|
||||
VPRINT("hostlist file %s%s\n",hfile->filename,hfile->hostlist ? "" : " (empty)");
|
||||
|
||||
LIST_FOREACH(dpl, ¶ms.desync_profiles, next)
|
||||
{
|
||||
LIST_FOREACH(hl_item, &dpl->dp.hl_collection, next)
|
||||
if (hl_item->hfile!=dpl->dp.hostlist_auto)
|
||||
VPRINT("profile %d include hostlist %s%s\n",dpl->dp.n, hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
|
||||
LIST_FOREACH(hl_item, &dpl->dp.hl_collection_exclude, next)
|
||||
VPRINT("profile %d exclude hostlist %s%s\n",dpl->dp.n,hl_item->hfile->filename,hl_item->hfile->hostlist ? "" : " (empty)");
|
||||
if (dpl->dp.hostlist_auto)
|
||||
VPRINT("profile %d auto hostlist %s%s\n",dpl->dp.n,dpl->dp.hostlist_auto->filename,dpl->dp.hostlist_auto->hostlist ? "" : " (empty)");
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user