mirror of
https://github.com/bol-van/zapret.git
synced 2025-05-24 22:32:58 +03:00
Compare commits
190 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
9c8662b25e | ||
|
fedb62df66 | ||
|
44c19c1743 | ||
|
56aa481226 | ||
|
9184317549 | ||
|
a3048ae120 | ||
|
fc44d74f2b | ||
|
1779cfad30 | ||
|
4856be4ef1 | ||
|
033043bdc0 | ||
|
46284938ce | ||
|
09378553b9 | ||
|
6b85884cdf | ||
|
1b14a8210c | ||
|
182fe850db | ||
|
62b081e9fb | ||
|
e3e7449d74 | ||
|
669f1978a3 | ||
|
57c4b1a2b2 | ||
|
ac7385391e | ||
|
50a52d79ec | ||
|
d77a1c8cd6 | ||
|
395b9480c5 | ||
|
4470c73e48 | ||
|
9812630ef2 | ||
|
818520452e | ||
|
f0cc49c7e3 | ||
|
cc30a90556 | ||
|
e12dd237c2 | ||
|
19e7fca627 | ||
|
a0e1742861 | ||
|
a93b142dcd | ||
|
fc2d511d78 | ||
|
5207104c06 | ||
|
06147836d0 | ||
|
46eb30a897 | ||
|
840617a0c3 | ||
|
f7ae5eaae5 | ||
|
827a838715 | ||
|
db5c60e19f | ||
|
256c2d7e50 | ||
|
07c8cd3d5d | ||
|
8979384847 | ||
|
2a134b864a | ||
|
765770d2c7 | ||
|
ba58892011 | ||
|
63f40dd8a4 | ||
|
30443ed31d | ||
|
a8432a3caa | ||
|
53546a8d92 | ||
|
97f20a1cb5 | ||
|
2816f93831 | ||
|
8624ae1c4a | ||
|
ebcec6e79d | ||
|
faa9a3e714 | ||
|
69007b5098 | ||
|
ee44aebcc4 | ||
|
667d32a3e7 | ||
|
9a087fc6c9 | ||
|
3ad029efe0 | ||
|
92c27ea7d8 | ||
|
7b850e2e0e | ||
|
c48398871c | ||
|
8629a29eaa | ||
|
df69ce1991 | ||
|
c56e672600 | ||
|
677feecada | ||
|
5d6c91f7e9 | ||
|
cde3ca15c2 | ||
|
fa6f6822a1 | ||
|
ce33a27c57 | ||
|
4d47749e7c | ||
|
42090daf24 | ||
|
36cd8ca3b2 | ||
|
9ec2d685e3 | ||
|
46d31003e2 | ||
|
ef9f9ae428 | ||
|
e5bcc5f682 | ||
|
4961e0d1a5 | ||
|
6a20fa27b3 | ||
|
01af779f2a | ||
|
feb332140a | ||
|
a85a0f19da | ||
|
611292281c | ||
|
14e9fc4d43 | ||
|
8bc74333b8 | ||
|
28797184e4 | ||
|
08238664cd | ||
|
187affb844 | ||
|
5a82874624 | ||
|
200cd9caf2 | ||
|
f8b3dca6f5 | ||
|
f973a6f3a6 | ||
|
9b3bbb7285 | ||
|
284f911785 | ||
|
a17e490851 | ||
|
c1e670be23 | ||
|
918d52c2e6 | ||
|
1c7080ca68 | ||
|
656c549113 | ||
|
41b4c6650b | ||
|
925fdd633a | ||
|
c16b125a55 | ||
|
591b246ed6 | ||
|
07b8567beb | ||
|
f0e68527ba | ||
|
6514b6f4c3 | ||
|
d551f2f4ae | ||
|
acb07c9792 | ||
|
da3eedb443 | ||
|
d7ce95ed50 | ||
|
c2413e4944 | ||
|
ad0aa27860 | ||
|
b5ade9baf0 | ||
|
68c7631713 | ||
|
4f31fb3b6b | ||
|
22534787a9 | ||
|
9e79c17a9f | ||
|
9345bdfe1e | ||
|
72cca01172 | ||
|
2466d5c758 | ||
|
43c24c501b | ||
|
b9962a0308 | ||
|
29520c9827 | ||
|
14dc328940 | ||
|
3bdedb2a9d | ||
|
f45fb421d8 | ||
|
6695245357 | ||
|
ca39017d10 | ||
|
7129923a70 | ||
|
9f1687ffec | ||
|
e1e55b1653 | ||
|
abe507c9c3 | ||
|
fa1430b604 | ||
|
a5e6b20e71 | ||
|
b79d8becd3 | ||
|
905a9519ce | ||
|
527c11e86f | ||
|
6250a26127 | ||
|
e1d417578d | ||
|
7ee5306d06 | ||
|
db0caf7d58 | ||
|
34c6c5e9ba | ||
|
868d115c5d | ||
|
969ddfb84c | ||
|
a5be4da22e | ||
|
a9dbb74973 | ||
|
6481f2204e | ||
|
a585d09c03 | ||
|
7f4356aa7e | ||
|
773da6383b | ||
|
07cd46bf90 | ||
|
c07fe4225a | ||
|
4374ca2290 | ||
|
cf320a7a2d | ||
|
086a0e4408 | ||
|
b28447e796 | ||
|
cff12dd431 | ||
|
cbba8a7876 | ||
|
bbeee9d640 | ||
|
466a142ebe | ||
|
8aa8bb5941 | ||
|
ffa701e497 | ||
|
e0063eecd5 | ||
|
2d530d5f63 | ||
|
95b3830afd | ||
|
0ea3215187 | ||
|
27745a3747 | ||
|
c68b75d4ac | ||
|
f4d31cdcb6 | ||
|
f2ea38cf93 | ||
|
9e84bf7a42 | ||
|
4559169e78 | ||
|
1987209613 | ||
|
913372a574 | ||
|
0ea4709726 | ||
|
9eef0ca113 | ||
|
88d7fd4088 | ||
|
1144f9afdc | ||
|
380d104407 | ||
|
31d4eaaa14 | ||
|
b2f94b083c | ||
|
4bdce508af | ||
|
74b6281770 | ||
|
a581e13498 | ||
|
174772e87f | ||
|
8f8e082ab4 | ||
|
7abf105777 | ||
|
db7078dcca | ||
|
cc38472e32 |
450
.github/workflows/build.yml
vendored
Normal file
450
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,450 @@
|
||||
name: build
|
||||
run-name: ${{ startsWith(github.ref, 'refs/tags/v') && format('Release {0}', github.ref_name) || null }}
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
tags:
|
||||
- v[0-9]+*
|
||||
# branches:
|
||||
# - master
|
||||
# paths:
|
||||
# - 'ip2net/**'
|
||||
# - 'mdig/**'
|
||||
# - 'nfq/**'
|
||||
# - 'tpws/**'
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
name: Linux ${{ matrix.arch }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: arm64
|
||||
tool: aarch64-unknown-linux-musl
|
||||
- arch: arm
|
||||
tool: arm-unknown-linux-musleabi
|
||||
# - arch: armhf
|
||||
# tool: arm-unknown-linux-musleabihf
|
||||
# - arch: armv7
|
||||
# tool: armv7-unknown-linux-musleabi
|
||||
# - arch: armv7hf
|
||||
# tool: armv7-unknown-linux-musleabihf
|
||||
# - arch: mips64el
|
||||
# tool: mips64el-unknown-linux-musl
|
||||
- arch: mips64
|
||||
tool: mips64-unknown-linux-musl
|
||||
# - arch: mipsel
|
||||
# tool: mipsel-unknown-linux-musl
|
||||
- arch: mipselsf
|
||||
tool: mipsel-unknown-linux-muslsf
|
||||
# - arch: mips
|
||||
# tool: mips-unknown-linux-musl
|
||||
- arch: mipssf
|
||||
tool: mips-unknown-linux-muslsf
|
||||
# - arch: ppc64
|
||||
# tool: powerpc64-unknown-linux-musl
|
||||
- arch: ppc
|
||||
tool: powerpc-unknown-linux-musl
|
||||
- arch: x86
|
||||
tool: i586-unknown-linux-musl
|
||||
- arch: x86_64
|
||||
tool: x86_64-unknown-linux-musl
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: zapret
|
||||
|
||||
- name: Set up build tools
|
||||
env:
|
||||
REPO: 'spvkgn/musl-cross'
|
||||
TOOL: ${{ matrix.tool }}
|
||||
run: |
|
||||
sudo apt update -qq && sudo apt install -y libcap-dev
|
||||
mkdir -p $HOME/tools
|
||||
wget -qO- https://github.com/$REPO/releases/download/latest/$TOOL.tar.xz | tar -C $HOME/tools -xJ || exit 1
|
||||
[ -d "$HOME/tools/$TOOL/bin" ] && echo "$HOME/tools/$TOOL/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Build
|
||||
env:
|
||||
ARCH: ${{ matrix.arch }}
|
||||
TARGET: ${{ matrix.tool }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
DEPS_DIR=$GITHUB_WORKSPACE/deps
|
||||
export CC="$TARGET-gcc"
|
||||
export LD=$TARGET-ld
|
||||
export AR=$TARGET-ar
|
||||
export NM=$TARGET-nm
|
||||
export STRIP=$TARGET-strip
|
||||
export PKG_CONFIG_PATH=$DEPS_DIR/lib/pkgconfig
|
||||
|
||||
# optimize for size
|
||||
export CFLAGS="-Os -flto=auto"
|
||||
export LDFLAGS="-Os"
|
||||
|
||||
# netfilter libs
|
||||
wget -qO- https://www.netfilter.org/pub/libnfnetlink/libnfnetlink-1.0.2.tar.bz2 | tar -xj
|
||||
wget -qO- https://www.netfilter.org/pub/libmnl/libmnl-1.0.5.tar.bz2 | tar -xj
|
||||
wget -qO- https://www.netfilter.org/pub/libnetfilter_queue/libnetfilter_queue-1.0.5.tar.bz2 | tar -xj
|
||||
|
||||
for i in libmnl libnfnetlink libnetfilter_queue ; do
|
||||
(
|
||||
cd $i-*
|
||||
./configure --prefix= --host=$TARGET --enable-static --disable-shared --disable-dependency-tracking
|
||||
make install -j$(nproc) DESTDIR=$DEPS_DIR
|
||||
)
|
||||
sed -i "s|^prefix=.*|prefix=$DEPS_DIR|g" $DEPS_DIR/lib/pkgconfig/$i.pc
|
||||
done
|
||||
|
||||
# zlib
|
||||
gh api repos/madler/zlib/releases/latest --jq '.tag_name' |\
|
||||
xargs -I{} wget -qO- https://github.com/madler/zlib/archive/refs/tags/{}.tar.gz | tar -xz
|
||||
(
|
||||
cd zlib-*
|
||||
./configure --prefix= --static
|
||||
make install -j$(nproc) DESTDIR=$DEPS_DIR
|
||||
)
|
||||
|
||||
# headers
|
||||
# wget https://git.alpinelinux.org/aports/plain/main/bsd-compat-headers/queue.h && \
|
||||
# wget https://git.kernel.org/pub/scm/libs/libcap/libcap.git/plain/libcap/include/sys/capability.h && \
|
||||
install -Dm644 -t $DEPS_DIR/include/sys /usr/include/x86_64-linux-gnu/sys/queue.h /usr/include/sys/capability.h
|
||||
|
||||
# zapret
|
||||
CFLAGS="$CFLAGS -static-libgcc -static -I$DEPS_DIR/include" \
|
||||
LDFLAGS="$LDFLAGS -L$DEPS_DIR/lib" \
|
||||
make -C zapret -j$(nproc)
|
||||
tar -C zapret/binaries/my -cJf zapret-linux-$ARCH.tar.xz .
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: zapret-linux-${{ matrix.arch }}
|
||||
path: zapret-*.tar.xz
|
||||
if-no-files-found: error
|
||||
|
||||
build-macos:
|
||||
name: macOS
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build zapret
|
||||
run: |
|
||||
make mac -j$(sysctl -n hw.logicalcpu)
|
||||
tar -C binaries/my -cJf zapret-mac-x64.tar.xz .
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: zapret-mac-x64
|
||||
path: zapret-*.tar.xz
|
||||
if-no-files-found: error
|
||||
|
||||
build-freebsd:
|
||||
name: FreeBSD ${{ matrix.arch }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- target: x86_64
|
||||
arch: x86_64
|
||||
# - target: i386
|
||||
# arch: x86
|
||||
container:
|
||||
image: empterdose/freebsd-cross-build:11.4
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install packages
|
||||
run: apk add tar xz
|
||||
|
||||
- name: Build zapret
|
||||
env:
|
||||
TARGET: ${{ matrix.target }}
|
||||
ARCH: ${{ matrix.arch }}
|
||||
run: |
|
||||
settarget $TARGET-freebsd11 make bsd -j$(nproc) || exit 1
|
||||
tar -C binaries/my -cJf zapret-freebsd-$ARCH.tar.xz .
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: zapret-freebsd-${{ matrix.arch }}
|
||||
path: zapret-*.tar.xz
|
||||
if-no-files-found: error
|
||||
|
||||
build-windows:
|
||||
name: Windows ${{ matrix.arch }}
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch: [ x86_64, x86 ]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: zapret
|
||||
|
||||
- name: Set up MinGW
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.arch == 'x86_64' && 'MINGW64' || 'MINGW32' }}
|
||||
install: >-
|
||||
${{ matrix.arch == 'x86_64' && 'mingw-w64-x86_64-toolchain' || 'mingw-w64-i686-toolchain' }}
|
||||
|
||||
- name: Build ip2net, mdig
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
mkdir -p output
|
||||
cd zapret
|
||||
mingw32-make -C ip2net win
|
||||
mingw32-make -C mdig win
|
||||
cp -a {ip2net/ip2net,mdig/mdig}.exe ../output
|
||||
|
||||
- name: Restore psmisc from cache
|
||||
id: cache-restore-psmisc
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/psmisc
|
||||
key: psmisc-${{ matrix.arch }}
|
||||
|
||||
- name: Set up Cygwin
|
||||
env:
|
||||
PACKAGES: ${{ steps.cache-restore-psmisc.outputs.cache-hit != 'true' && 'cygport gettext-devel libiconv-devel libncurses-devel' || null }}
|
||||
uses: cygwin/cygwin-install-action@v4
|
||||
with:
|
||||
platform: ${{ matrix.arch }}
|
||||
site: ${{ matrix.arch == 'x86_64' && 'http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2024/01/30/231215' || null }}
|
||||
check-sig: ${{ matrix.arch == 'x86_64' && 'false' || null }}
|
||||
packages: >-
|
||||
gcc-core
|
||||
make
|
||||
zlib-devel
|
||||
zip
|
||||
unzip
|
||||
wget
|
||||
${{ env.PACKAGES }}
|
||||
|
||||
- name: Build psmisc
|
||||
if: steps.cache-restore-psmisc.outputs.cache-hit != 'true'
|
||||
env:
|
||||
URL: https://mirrors.kernel.org/sourceware/cygwin/x86_64/release/psmisc
|
||||
shell: C:\cygwin\bin\bash.exe -eo pipefail '{0}'
|
||||
run: >-
|
||||
export MAKEFLAGS=-j$(nproc) &&
|
||||
mkdir -p psmisc && cd psmisc &&
|
||||
wget -qO- ${URL} | grep -Po 'href=\"\Kpsmisc-(\d+\.)+\d+.+src\.tar\.xz(?=\")' | xargs -I{} wget -O- ${URL}/{} | tar -xJ &&
|
||||
cd psmisc-*.src &&
|
||||
echo CYGCONF_ARGS+=\" --disable-dependency-tracking --disable-nls\" >> psmisc.cygport &&
|
||||
cygport psmisc.cygport prep compile install
|
||||
|
||||
- name: Save psmisc to cache
|
||||
if: steps.cache-restore-psmisc.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/psmisc
|
||||
key: psmisc-${{ matrix.arch }}
|
||||
|
||||
- name: Build winws
|
||||
env:
|
||||
TARGET: ${{ matrix.arch == 'x86_64' && 'cygwin' || 'cygwin32' }}
|
||||
shell: C:\cygwin\bin\bash.exe -eo pipefail '{0}'
|
||||
run: >-
|
||||
export MAKEFLAGS=-j$(nproc) &&
|
||||
cd zapret &&
|
||||
make -C nfq ${TARGET} &&
|
||||
cp -a nfq/winws.exe ../output
|
||||
|
||||
- name: Create zip
|
||||
env:
|
||||
BITS: ${{ matrix.arch == 'x86_64' && '64' || '32' }}
|
||||
DIR: ${{ matrix.arch == 'x86_64' && 'x64' || 'x86' }}
|
||||
shell: C:\cygwin\bin\bash.exe -e '{0}'
|
||||
run: >-
|
||||
cp -a -t output psmisc/psmisc-*.src/psmisc-*/inst/usr/bin/killall.exe /usr/bin/cygwin1.dll &&
|
||||
wget -O WinDivert.zip https://github.com/basil00/WinDivert/releases/download/v2.2.2/WinDivert-2.2.2-A.zip &&
|
||||
unzip -j WinDivert.zip "*/${DIR}/WinDivert.dll" "*/${DIR}/WinDivert${BITS}.sys" -d output &&
|
||||
zip zapret-win-${{ matrix.arch }}.zip -j output/*
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: zapret-win-${{ matrix.arch }}
|
||||
path: zapret-*.zip
|
||||
if-no-files-found: error
|
||||
|
||||
build-android:
|
||||
name: Android ${{ matrix.abi }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- abi: armeabi-v7a
|
||||
target: armv7a-linux-androideabi
|
||||
- abi: arm64-v8a
|
||||
target: aarch64-linux-android
|
||||
- abi: x86
|
||||
target: i686-linux-android
|
||||
- abi: x86_64
|
||||
target: x86_64-linux-android
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: zapret
|
||||
|
||||
- name: Build
|
||||
env:
|
||||
ABI: ${{ matrix.abi }}
|
||||
TARGET: ${{ matrix.target }}
|
||||
run: |
|
||||
DEPS_DIR=$GITHUB_WORKSPACE/deps
|
||||
export TOOLCHAIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64
|
||||
export API=21
|
||||
export CC="$TOOLCHAIN/bin/clang --target=$TARGET$API"
|
||||
export AR=$TOOLCHAIN/bin/llvm-ar
|
||||
export AS=$CC
|
||||
export LD=$TOOLCHAIN/bin/ld
|
||||
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
|
||||
export STRIP=$TOOLCHAIN/bin/llvm-strip
|
||||
export PKG_CONFIG_PATH=$DEPS_DIR/lib/pkgconfig
|
||||
|
||||
# optimize for size
|
||||
export CFLAGS="-Os -flto=auto"
|
||||
export LDFLAGS="-Os"
|
||||
|
||||
# netfilter libs
|
||||
wget -qO- https://www.netfilter.org/pub/libnfnetlink/libnfnetlink-1.0.2.tar.bz2 | tar -xj
|
||||
wget -qO- https://www.netfilter.org/pub/libmnl/libmnl-1.0.5.tar.bz2 | tar -xj
|
||||
wget -qO- https://www.netfilter.org/pub/libnetfilter_queue/libnetfilter_queue-1.0.5.tar.bz2 | tar -xj
|
||||
patch -p1 -d libnetfilter_queue-* -i ../zapret/.github/workflows/libnetfilter_queue-android.patch
|
||||
|
||||
for i in libmnl libnfnetlink libnetfilter_queue ; do
|
||||
(
|
||||
cd $i-*
|
||||
CFLAGS="$CFLAGS -Wno-implicit-function-declaration" \
|
||||
./configure --prefix= --host=$TARGET --enable-static --disable-shared --disable-dependency-tracking
|
||||
make install -j$(nproc) DESTDIR=$DEPS_DIR
|
||||
)
|
||||
sed -i "s|^prefix=.*|prefix=$DEPS_DIR|g" $DEPS_DIR/lib/pkgconfig/$i.pc
|
||||
done
|
||||
|
||||
# zapret
|
||||
CFLAGS="$CFLAGS -I$DEPS_DIR/include" LDFLAGS="$LDFLAGS -L$DEPS_DIR/lib" \
|
||||
make -C zapret android -j$(nproc)
|
||||
zip zapret-android-$ABI.zip -j zapret/binaries/my/*
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: zapret-android-${{ matrix.abi }}
|
||||
path: zapret-*.zip
|
||||
if-no-files-found: error
|
||||
|
||||
release:
|
||||
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
||||
needs: [ build-linux, build-windows, build-macos, build-freebsd, build-android ]
|
||||
permissions:
|
||||
contents: write
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
repo_dir: zapret-${{ github.ref_name }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: ${{ env.repo_dir }}
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
id: bins
|
||||
with:
|
||||
path: ${{ env.repo_dir }}/binaries
|
||||
pattern: zapret-*
|
||||
|
||||
- name: Install upx
|
||||
uses: crazy-max/ghaction-upx@v3
|
||||
with:
|
||||
install-only: true
|
||||
|
||||
- name: Prepare binaries
|
||||
shell: bash
|
||||
run: |
|
||||
cd ${{ steps.bins.outputs.download-path }}
|
||||
run_upx() {
|
||||
upx --best --lzma $@ || true
|
||||
}
|
||||
run_dir() {
|
||||
for f in $dir/* ; do
|
||||
# extract binaries
|
||||
case $f in
|
||||
*.tar.xz )
|
||||
tar -C $dir -xvf $f && rm $f
|
||||
if [[ $dir == *-linux-x86_64 ]]; then
|
||||
tar -C $dir -czvf $dir/tpws_wsl.tgz tpws
|
||||
run_upx $dir/*
|
||||
elif [[ $dir =~ linux ]] && [[ $dir != *-linux-mips64 ]]; then
|
||||
run_upx $dir/*
|
||||
fi
|
||||
;;
|
||||
*.zip )
|
||||
unzip $f -d $dir && rm $f
|
||||
if [[ $dir =~ win ]]; then
|
||||
chmod -x $dir/*
|
||||
run_upx --force $dir/cygwin1.dll
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
mv $dir $1
|
||||
}
|
||||
for dir in * ; do
|
||||
if [ -d $dir ]; then
|
||||
echo "Processing $dir"
|
||||
case $dir in
|
||||
*-android-arm64-v8a ) run_dir android-aarch64 ;;
|
||||
*-android-armeabi-v7a ) run_dir android-arm ;;
|
||||
*-android-x86 ) run_dir android-x86 ;;
|
||||
*-android-x86_64 ) run_dir android-x86_64 ;;
|
||||
*-freebsd-x86_64 ) run_dir freebsd-x64 ;;
|
||||
*-linux-arm ) run_dir arm ;;
|
||||
*-linux-arm64 ) run_dir aarch64 ;;
|
||||
*-linux-mips64 ) run_dir mips64r2-msb ;;
|
||||
*-linux-mipselsf ) run_dir mips32r1-lsb ;;
|
||||
*-linux-mipssf ) run_dir mips32r1-msb ;;
|
||||
*-linux-ppc ) run_dir ppc ;;
|
||||
*-linux-x86 ) run_dir x86 ;;
|
||||
*-linux-x86_64 ) run_dir x86_64 ;;
|
||||
*-mac-x64 ) run_dir mac64 ;;
|
||||
*-win-x86 ) run_dir win32 ;;
|
||||
*-win-x86_64 ) run_dir win64 ;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
ls -lhR
|
||||
|
||||
- name: Create release bundles
|
||||
run: |
|
||||
rm -rf ${{ env.repo_dir }}/.git*
|
||||
tar -czf ${{ env.repo_dir }}.tar.gz ${{ env.repo_dir }}
|
||||
zip -qr ${{ env.repo_dir }}.zip ${{ env.repo_dir }}
|
||||
|
||||
- name: Upload release assets
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
fail_on_unmatched_files: true
|
||||
prerelease: false
|
||||
draft: false
|
||||
body: |
|
||||
### zapret ${{ github.ref_name }}
|
||||
files: |
|
||||
zapret*.tar.gz
|
||||
zapret*.zip
|
41
.github/workflows/libnetfilter_queue-android.patch
vendored
Normal file
41
.github/workflows/libnetfilter_queue-android.patch
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
--- a/src/extra/pktbuff.c
|
||||
+++ b/src/extra/pktbuff.c
|
||||
@@ -14,7 +14,7 @@
|
||||
#include <string.h> /* for memcpy */
|
||||
#include <stdbool.h>
|
||||
|
||||
-#include <netinet/if_ether.h>
|
||||
+#include <linux/if_ether.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
--- a/src/nlmsg.c
|
||||
+++ b/src/nlmsg.c
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include <linux/netfilter/nfnetlink_queue.h>
|
||||
|
||||
-#include <libnetfilter_queue/libnetfilter_queue.h>
|
||||
+// #include <libnetfilter_queue/libnetfilter_queue.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
--- a/src/extra/tcp.c
|
||||
+++ b/src/extra/tcp.c
|
||||
@@ -139,12 +139,16 @@ void nfq_tcp_compute_checksum_ipv6(struc
|
||||
* (union is compatible to any of its members)
|
||||
* This means this part of the code is -fstrict-aliasing safe now.
|
||||
*/
|
||||
+#ifndef __ANDROID__
|
||||
union tcp_word_hdr {
|
||||
struct tcphdr hdr;
|
||||
uint32_t words[5];
|
||||
};
|
||||
+#endif
|
||||
|
||||
+#ifndef tcp_flag_word
|
||||
#define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words[3])
|
||||
+#endif
|
||||
|
||||
/**
|
||||
* nfq_pkt_snprintf_tcp_hdr - print tcp header into one buffer in a humnan
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,7 +1,9 @@
|
||||
/config
|
||||
ip2net/ip2net
|
||||
mdig/mdig
|
||||
nfq/dvtws
|
||||
nfq/nfqws
|
||||
nfq/winws.exe
|
||||
tpws/tpws
|
||||
binaries/my/
|
||||
init.d/**/custom
|
||||
|
13
Makefile
13
Makefile
@@ -15,6 +15,19 @@ all: clean
|
||||
done \
|
||||
done
|
||||
|
||||
android: clean
|
||||
@mkdir -p "$(TGT)"; \
|
||||
for dir in $(DIRS); do \
|
||||
find "$$dir" -type f \( -name "*.c" -o -name "*.h" -o -name "*akefile" \) -exec chmod -x {} \; ; \
|
||||
$(MAKE) -C "$$dir" android || exit; \
|
||||
for exe in "$$dir/"*; do \
|
||||
if [ -f "$$exe" ] && [ -x "$$exe" ]; then \
|
||||
mv -f "$$exe" "${TGT}" ; \
|
||||
ln -fs "../${TGT}/$$(basename "$$exe")" "$$exe" ; \
|
||||
fi \
|
||||
done \
|
||||
done
|
||||
|
||||
bsd: clean
|
||||
@mkdir -p "$(TGT)"; \
|
||||
for dir in $(DIRS); do \
|
||||
|
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.
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.
@@ -1,8 +0,0 @@
|
||||
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
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,8 +0,0 @@
|
||||
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
|
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.
323
blockcheck.sh
323
blockcheck.sh
@@ -45,7 +45,6 @@ HTTP_PORT=${HTTP_PORT:-80}
|
||||
HTTPS_PORT=${HTTPS_PORT:-443}
|
||||
QUIC_PORT=${QUIC_PORT:-443}
|
||||
UNBLOCKED_DOM=${UNBLOCKED_DOM:-iana.org}
|
||||
[ "$CURL_VERBOSE" = 1 ] && CURL_CMD=1
|
||||
|
||||
HDRTEMP=/tmp/zapret-hdr.txt
|
||||
|
||||
@@ -792,7 +791,7 @@ pktws_ipt_prepare()
|
||||
# disable PF to avoid interferences
|
||||
pf_is_avail && pfctl -qd
|
||||
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
|
||||
IPFW_ADD divert $IPFW_DIVERT_PORT $1 from me to $ip $2 proto ip${IPV} out not diverted
|
||||
done
|
||||
;;
|
||||
opf)
|
||||
@@ -867,7 +866,7 @@ pktws_ipt_prepare_tcp()
|
||||
;;
|
||||
ipfw)
|
||||
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
|
||||
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from $ip $1 to me proto ip${IPV} tcpflags syn,ack in not diverted
|
||||
done
|
||||
;;
|
||||
esac
|
||||
@@ -994,7 +993,6 @@ ws_curl_test()
|
||||
# $2 - test function
|
||||
# $3 - domain
|
||||
# $4,$5,$6, ... - ws params
|
||||
|
||||
local code ws_start=$1 testf=$2 dom=$3
|
||||
shift
|
||||
shift
|
||||
@@ -1013,6 +1011,15 @@ tpws_curl_test()
|
||||
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}${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 code=$?
|
||||
[ "$code" = 0 ] && {
|
||||
local testf=$1 dom=$2
|
||||
shift; shift;
|
||||
local strategy="$@"
|
||||
strategy_append_extra_tpws
|
||||
report_append "ipv${IPV} $dom $testf : tpws ${WF:+$WF }$strategy"
|
||||
}
|
||||
return $code
|
||||
}
|
||||
pktws_curl_test()
|
||||
{
|
||||
@@ -1021,7 +1028,26 @@ pktws_curl_test()
|
||||
# $3,$4,$5, ... - nfqws/dvtws params
|
||||
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"}
|
||||
local code=$?
|
||||
[ "$code" = 0 ] && {
|
||||
local testf=$1 dom=$2
|
||||
shift; shift;
|
||||
local strategy="$@"
|
||||
strategy_append_extra_pktws
|
||||
report_append "ipv${IPV} $dom $testf : $PKTWSD ${WF:+$WF }$strategy"
|
||||
}
|
||||
return $code
|
||||
}
|
||||
|
||||
strategy_append_extra_pktws()
|
||||
{
|
||||
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"}}"
|
||||
}
|
||||
strategy_append_extra_tpws()
|
||||
{
|
||||
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"}}"
|
||||
}
|
||||
|
||||
xxxws_curl_test_update()
|
||||
{
|
||||
# $1 - xxx_curl_test function
|
||||
@@ -1073,7 +1099,7 @@ report_strategy()
|
||||
strategy="$(echo "$strategy" | xargs)"
|
||||
echo "!!!!! $1: working strategy found for ipv${IPV} $2 : $3 $strategy !!!!!"
|
||||
echo
|
||||
report_append "ipv${IPV} $2 $1 : $3 ${WF:+$WF }$strategy"
|
||||
# report_append "ipv${IPV} $2 $1 : $3 ${WF:+$WF }$strategy"
|
||||
return 0
|
||||
else
|
||||
echo "$1: $3 strategy for ipv${IPV} $2 not found"
|
||||
@@ -1088,7 +1114,7 @@ test_has_split()
|
||||
}
|
||||
test_has_fake()
|
||||
{
|
||||
contains "$1" fake
|
||||
[ "$1" = fake ] || starts_with "$1" fake,
|
||||
}
|
||||
warn_fool()
|
||||
{
|
||||
@@ -1105,25 +1131,34 @@ pktws_curl_test_update_vary()
|
||||
# $4 - desync mode
|
||||
# $5,$6,... - strategy
|
||||
|
||||
local testf=$1 sec=$2 domain=$3 desync=$4 zerofake split fake
|
||||
local testf=$1 sec=$2 domain=$3 desync=$4 proto zerofake= splits= pos fake ret=1
|
||||
|
||||
shift; shift; shift; shift
|
||||
|
||||
zerofake=http
|
||||
[ "$sec" = 0 ] || zerofake=tls
|
||||
zerofake="--dpi-desync-fake-$zerofake=0x00000000"
|
||||
|
||||
proto=http
|
||||
[ "$sec" = 0 ] || proto=tls
|
||||
test_has_fake $desync && zerofake="--dpi-desync-fake-$proto=0x00000000"
|
||||
test_has_split $desync && {
|
||||
splits="method+2 midsld"
|
||||
[ "$sec" = 0 ] || splits="1 midsld 1,midsld"
|
||||
}
|
||||
for fake in '' $zerofake ; do
|
||||
for split in '' '--dpi-desync-split-pos=1' ; do
|
||||
pktws_curl_test_update $testf $domain --dpi-desync=$desync "$@" $fake $split && return 0
|
||||
# split-pos=1 is meaningful for DPIs searching for 16 03 in TLS. no reason to apply to http
|
||||
[ "$sec" = 1 ] || break
|
||||
test_has_split $desync || break
|
||||
if [ -n "$splits" ]; then
|
||||
for pos in $splits ; do
|
||||
pktws_curl_test_update $testf $domain --dpi-desync=$desync "$@" --dpi-desync-split-pos=$pos $fake && {
|
||||
[ "$SCANLEVEL" = force ] || return 0
|
||||
ret=0
|
||||
}
|
||||
done
|
||||
test_has_fake $desync || break
|
||||
else
|
||||
pktws_curl_test_update $testf $domain --dpi-desync=$desync "$@" $fake && {
|
||||
[ "$SCANLEVEL" = force ] || return 0
|
||||
ret=0
|
||||
}
|
||||
fi
|
||||
done
|
||||
|
||||
return 1
|
||||
return $ret
|
||||
}
|
||||
|
||||
pktws_check_domain_http_bypass_()
|
||||
@@ -1132,82 +1167,73 @@ pktws_check_domain_http_bypass_()
|
||||
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $3 - domain
|
||||
|
||||
local tests='fake' ret ok ttls s f e desync pos fooling frag sec="$2" delta hostcase
|
||||
local ok ttls s f f2 e desync pos fooling frag sec="$2" delta splits
|
||||
local need_split need_disorder need_fakedsplit need_fakeddisorder need_fake need_wssize
|
||||
local splits_http='method+2 midsld method+2,midsld'
|
||||
local splits_tls='2 1 sniext+1 sniext+4 host+1 midsld 1,midsld 1,sniext+1,host+1,midsld-2,midsld,midsld+2,endhost-1'
|
||||
|
||||
[ "$sec" = 0 ] && {
|
||||
for s in '--hostcase' '--hostspell=hoSt' '--hostnospace' '--domcase'; do
|
||||
for s in '--hostcase' '--hostspell=hoSt' '--hostnospace' '--domcase' '--methodeol'; do
|
||||
pktws_curl_test_update $1 $3 $s
|
||||
done
|
||||
}
|
||||
|
||||
s="--dpi-desync=split2"
|
||||
ok=0
|
||||
pktws_curl_test_update $1 $3 $s
|
||||
ret=$?
|
||||
[ "$ret" = 0 ] && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
}
|
||||
[ "$ret" != 0 -o "$SCANLEVEL" = force ] && {
|
||||
if [ "$sec" = 0 ]; then
|
||||
pktws_curl_test_update $1 $3 $s --hostcase && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
}
|
||||
for pos in method host; do
|
||||
for hostcase in '' '--hostcase'; do
|
||||
pktws_curl_test_update $1 $3 $s --dpi-desync-split-http-req=$pos $hostcase && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
}
|
||||
done
|
||||
done
|
||||
else
|
||||
for pos in sni sniext; do
|
||||
pktws_curl_test_update $1 $3 $s --dpi-desync-split-tls=$pos && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
}
|
||||
done
|
||||
fi
|
||||
for pos in 1 3 4 5 10 50; do
|
||||
s="--dpi-desync=split2 --dpi-desync-split-pos=$pos"
|
||||
if pktws_curl_test_update $1 $3 $s; then
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
[ "$SCANLEVEL" = force ] || break
|
||||
elif [ "$sec" = 0 ]; then
|
||||
pktws_curl_test_update $1 $3 $s --hostcase && [ "$SCANLEVEL" = quick ] && return
|
||||
fi
|
||||
done
|
||||
}
|
||||
[ "$ok" = 1 -a "$SCANLEVEL" != force ] || tests="$tests split fake,split2 fake,split"
|
||||
|
||||
pktws_curl_test_update $1 $3 --dpi-desync=disorder2
|
||||
ret=$?
|
||||
[ "$ret" = 0 -a "$SCANLEVEL" = quick ] && return
|
||||
[ "$ret" != 0 -o "$SCANLEVEL" = force ] && {
|
||||
pktws_curl_test_update $1 $3 --dpi-desync=disorder2 --dpi-desync-split-pos=1
|
||||
ret=$?
|
||||
[ "$ret" = 0 -a "$SCANLEVEL" = quick ] && return
|
||||
}
|
||||
[ "$ret" != 0 -o "$SCANLEVEL" = force ] && tests="$tests disorder fake,disorder2 fake,disorder"
|
||||
|
||||
ttls=$(seq -s ' ' $MIN_TTL $MAX_TTL)
|
||||
need_wssize=1
|
||||
for e in '' '--wssize 1:6'; do
|
||||
need_split=
|
||||
need_disorder=
|
||||
|
||||
[ -n "$e" ] && {
|
||||
pktws_curl_test_update $1 $3 $e && [ "$SCANLEVEL" = quick ] && return
|
||||
for desync in split2 disorder2; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync $e && [ "$SCANLEVEL" = quick ] && return
|
||||
done
|
||||
}
|
||||
for desync in $tests; do
|
||||
|
||||
for desync in multisplit multidisorder; do
|
||||
ok=0
|
||||
splits="$splits_http"
|
||||
[ "$sec" = 0 ] || splits="$splits_tls"
|
||||
for pos in $splits; do
|
||||
pktws_curl_test_update $1 $3 --dpi-desync=$desync --dpi-desync-split-pos=$pos $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
need_wssize=0
|
||||
[ "$SCANLEVEL" = force ] || break
|
||||
}
|
||||
done
|
||||
[ "$ok" = 1 -a "$SCANLEVEL" != force ] || {
|
||||
case $desync in
|
||||
multisplit)
|
||||
need_split=1
|
||||
;;
|
||||
multidisorder)
|
||||
need_disorder=1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
done
|
||||
|
||||
need_fakedsplit=1
|
||||
need_fakeddisorder=1
|
||||
need_fake=1
|
||||
for desync in fake ${need_split:+fakedsplit fake,multisplit fake,fakedsplit} ${need_disorder:+fakeddisorder fake,multidisorder fake,fakeddisorder}; do
|
||||
[ "$need_fake" = 0 ] && test_has_fake "$desync" && continue
|
||||
[ "$need_fakedsplit" = 0 ] && contains "$desync" fakedsplit && continue
|
||||
[ "$need_fakeddisorder" = 0 ] && contains "$desync" fakeddisorder && continue
|
||||
ok=0
|
||||
for ttl in $ttls; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-ttl=$ttl $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
need_wssize=0
|
||||
break
|
||||
}
|
||||
done
|
||||
# only skip tests if TTL succeeded. do not skip if TTL failed but fooling succeeded
|
||||
[ $ok = 1 -a "$SCANLEVEL" != force ] && {
|
||||
[ "$desync" = fake ] && need_fake=0
|
||||
[ "$desync" = fakedsplit ] && need_fakedsplit=0
|
||||
[ "$desync" = fakeddisorder ] && need_fakeddisorder=0
|
||||
}
|
||||
f=
|
||||
[ "$UNAME" = "OpenBSD" ] || f="badsum"
|
||||
f="$f badseq datanoack md5sig"
|
||||
@@ -1216,37 +1242,68 @@ pktws_check_domain_http_bypass_()
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fooling=$fooling $e && {
|
||||
warn_fool $fooling
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
}
|
||||
done
|
||||
done
|
||||
|
||||
[ "$IPV" = 6 ] && {
|
||||
f="hopbyhop hopbyhop,split2 hopbyhop,disorder2 destopt destopt,split2 destopt,disorder2"
|
||||
[ -n "$IP6_DEFRAG_DISABLE" ] && f="$f ipfrag1 ipfrag1,split2 ipfrag1,disorder2"
|
||||
f="hopbyhop ${need_split:+hopbyhop,multisplit} ${need_disorder:+hopbyhop,multidisorder} destopt ${need_split:+destopt,multisplit} ${need_disorder:+destopt,multidisorder}"
|
||||
[ -n "$IP6_DEFRAG_DISABLE" ] && f="$f ipfrag1 ${need_split:+ ipfrag1,multisplit} ${need_disorder:+ ipfrag1,multidisorder}"
|
||||
for desync in $f; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync $e && [ "$SCANLEVEL" = quick ] && return
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
}
|
||||
done
|
||||
}
|
||||
|
||||
for desync in split2 disorder2; do
|
||||
s="--dpi-desync=$desync"
|
||||
[ "$need_split" = 1 ] && {
|
||||
# relative markers can be anywhere, even in subsequent packets. first packet can be MTU-full.
|
||||
# make additional split pos "10" to guarantee enough space for seqovl and likely to be before midsld,sniext,...
|
||||
# method is always expected in the beginning of the first packet
|
||||
f="method+2 method+2,midsld"
|
||||
[ "$sec" = 0 ] || f="10 10,sniext+1 10,sniext+4 10,midsld"
|
||||
for pos in $f; do
|
||||
pktws_curl_test_update $1 $3 --dpi-desync=multisplit --dpi-desync-split-pos=$pos --dpi-desync-split-seqovl=1 $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
}
|
||||
done
|
||||
[ "$sec" != 0 ] && pktws_curl_test_update $1 $3 --dpi-desync=multisplit --dpi-desync-split-pos=2 --dpi-desync-split-seqovl=336 --dpi-desync-split-seqovl-pattern="$ZAPRET_BASE/files/fake/tls_clienthello_iana_org.bin" $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
}
|
||||
}
|
||||
[ "$need_disorder" = 1 ] && {
|
||||
if [ "$sec" = 0 ]; then
|
||||
for pos in method host; do
|
||||
pktws_curl_test_update $1 $3 $s --dpi-desync-split-seqovl=1 --dpi-desync-split-http-req=$pos $e && [ "$SCANLEVEL" = quick ] && return
|
||||
for pos in 'method+1 method+2' 'midsld-1 midsld' 'method+1 method+2,midsld'; do
|
||||
f="$(extract_arg 1 $pos)"
|
||||
f2="$(extract_arg 2 $pos)"
|
||||
pktws_curl_test_update $1 $3 --dpi-desync=multidisorder --dpi-desync-split-pos=$f2 --dpi-desync-split-seqovl=$f $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
}
|
||||
done
|
||||
else
|
||||
for pos in sni sniext; do
|
||||
pktws_curl_test_update $1 $3 $s --dpi-desync-split-seqovl=1 --dpi-desync-split-tls=$pos $e && [ "$SCANLEVEL" = quick ] && return
|
||||
done
|
||||
fi
|
||||
for pos in 2 3 4 5 10 50; do
|
||||
pktws_curl_test_update $1 $3 $s --dpi-desync-split-seqovl=$(($pos - 1)) --dpi-desync-split-pos=$pos $e && [ "$SCANLEVEL" = quick ] && return
|
||||
done
|
||||
[ "$sec" != 0 -a $desync = split2 ] && {
|
||||
pktws_curl_test_update $1 $3 $s --dpi-desync-split-seqovl=336 --dpi-desync-split-seqovl-pattern="$ZAPRET_BASE/files/fake/tls_clienthello_iana_org.bin" $e && [ "$SCANLEVEL" = quick ] && return
|
||||
for pos in '1 2' 'sniext sniext+1' 'sniext+3 sniext+4' 'midsld-1 midsld' '1 2,midsld'; do
|
||||
f=$(extract_arg 1 $pos)
|
||||
f2=$(extract_arg 2 $pos)
|
||||
pktws_curl_test_update $1 $3 --dpi-desync=multidisorder --dpi-desync-split-pos=$f2 --dpi-desync-split-seqovl=$f $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
}
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
for desync in $tests; do
|
||||
need_fakedsplit=1
|
||||
need_fakeddisorder=1
|
||||
need_fake=1
|
||||
for desync in fake ${need_split:+fakedsplit fake,multisplit fake,fakedsplit} ${need_disorder:+fakeddisorder fake,multidisorder fake,fakeddisorder}; do
|
||||
[ "$need_fake" = 0 ] && test_has_fake "$desync" && continue
|
||||
[ "$need_fakedsplit" = 0 ] && contains "$desync" fakedsplit && continue
|
||||
[ "$need_fakeddisorder" = 0 ] && contains "$desync" fakeddisorder && continue
|
||||
ok=0
|
||||
for delta in 1 2 3 4 5; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-ttl=1 --dpi-desync-autottl=$delta $e && ok=1
|
||||
@@ -1256,18 +1313,25 @@ pktws_check_domain_http_bypass_()
|
||||
echo "WARNING ! although autottl worked it requires testing on multiple domains to find out reliable delta"
|
||||
echo "WARNING ! if a reliable delta cannot be found it's a good idea not to use autottl"
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
[ "$SCANLEVEL" = force ] || {
|
||||
[ "$desync" = fake ] && need_fake=0
|
||||
[ "$desync" = fakedsplit ] && need_fakedsplit=0
|
||||
[ "$desync" = fakeddisorder ] && need_fakeddisorder=0
|
||||
}
|
||||
}
|
||||
done
|
||||
|
||||
s="http_iana_org.bin"
|
||||
[ "$sec" = 0 ] || s="tls_clienthello_iana_org.bin"
|
||||
for desync in syndata syndata,split2 syndata,disorder2 ; do
|
||||
for desync in syndata ${need_split:+syndata,multisplit} ${need_disorder:+syndata,multidisorder} ; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync $e && [ "$SCANLEVEL" = quick ] && return
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fake-syndata="$ZAPRET_BASE/files/fake/$s" $e && [ "$SCANLEVEL" = quick ] && return
|
||||
done
|
||||
|
||||
# do not do wssize test for http and TLS 1.3. it's useless
|
||||
[ "$sec" = 1 ] || break
|
||||
[ "$SCANLEVEL" = force -o "$need_wssize" = 1 ] || break
|
||||
done
|
||||
}
|
||||
pktws_check_domain_http_bypass()
|
||||
@@ -1278,7 +1342,7 @@ pktws_check_domain_http_bypass()
|
||||
|
||||
local strategy
|
||||
pktws_check_domain_http_bypass_ "$@"
|
||||
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"}}"
|
||||
strategy_append_extra_pktws
|
||||
report_strategy $1 $3 $PKTWSD
|
||||
}
|
||||
|
||||
@@ -1323,7 +1387,7 @@ pktws_check_domain_http3_bypass()
|
||||
|
||||
local strategy
|
||||
pktws_check_domain_http3_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_append_extra_pktws
|
||||
report_strategy $1 $2 $PKTWSD
|
||||
}
|
||||
warn_mss()
|
||||
@@ -1338,50 +1402,58 @@ tpws_check_domain_http_bypass_()
|
||||
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $3 - domain
|
||||
|
||||
local s mss s2 s3 pos sec="$2"
|
||||
local s mss s2 s3 oobdis pos sec="$2"
|
||||
local splits_tls='2 1 sniext+1 sniext+4 host+1 midsld 1,midsld 1,sniext+1,host+1,midsld,endhost-1'
|
||||
local splits_http='method+2 midsld method+2,midsld'
|
||||
|
||||
# simulteneous oob and disorder works properly only in linux. other systems retransmit oob byte without URG tcp flag and poison tcp stream.
|
||||
[ "$UNAME" = Linux ] && oobdis='--oob --disorder'
|
||||
if [ "$sec" = 0 ]; then
|
||||
for s in '--hostcase' '--hostspell=hoSt' '--hostdot' '--hosttab' '--hostnospace' '--domcase' \
|
||||
'--hostpad=1024' '--hostpad=2048' '--hostpad=4096' '--hostpad=8192' '--hostpad=16384' ; do
|
||||
for s in '--hostcase' '--hostspell=hoSt' '--hostdot' '--hosttab' '--hostnospace' '--domcase' ; do
|
||||
tpws_curl_test_update $1 $3 $s && [ "$SCANLEVEL" = quick ] && return
|
||||
done
|
||||
for s2 in '' '--oob' '--disorder' '--oob --disorder'; do
|
||||
for s in '--split-http-req=method' '--split-http-req=method --hostcase' '--split-http-req=host' '--split-http-req=host --hostcase' ; do
|
||||
tpws_curl_test_update $1 $3 $s $s2 && [ "$SCANLEVEL" = quick ] && return
|
||||
for s in 1024 2048 4096 8192 16384 ; do
|
||||
tpws_curl_test_update $1 $3 --hostpad=$s && [ "$SCANLEVEL" != force ] && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
break
|
||||
}
|
||||
done
|
||||
for s2 in '' '--hostcase' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
|
||||
for s in $splits_http ; do
|
||||
tpws_curl_test_update $1 $3 --split-pos=$s $s2 && [ "$SCANLEVEL" != force ] && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
break
|
||||
}
|
||||
done
|
||||
done
|
||||
for s in '--methodspace' '--unixeol' '--methodeol'; do
|
||||
tpws_curl_test_update $1 $3 $s && [ "$SCANLEVEL" = quick ] && return
|
||||
done
|
||||
else
|
||||
local need_mss=1
|
||||
for mss in '' 88; do
|
||||
s3=${mss:+--mss=$mss}
|
||||
for s2 in '' '--oob' '--disorder' '--oob --disorder'; do
|
||||
for pos in sni sniext; do
|
||||
s="--split-tls=$pos"
|
||||
tpws_curl_test_update $1 $3 $s $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
break
|
||||
}
|
||||
done
|
||||
for pos in 1 2 3 4 5 10 50; do
|
||||
s="--split-pos=$pos"
|
||||
tpws_curl_test_update $1 $3 $s $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
|
||||
for s2 in '' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
|
||||
for pos in $splits_tls; do
|
||||
tpws_curl_test_update $1 $3 --split-pos=$pos $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_mss=0
|
||||
break
|
||||
}
|
||||
done
|
||||
done
|
||||
for s2 in '--tlsrec=sni' '--tlsrec=sni --split-tls=sni' '--tlsrec=sni --split-tls=sni --oob' \
|
||||
'--tlsrec=sni --split-tls=sni --disorder' '--tlsrec=sni --split-tls=sni --oob --disorder' \
|
||||
'--tlsrec=sni --split-pos=1' '--tlsrec=sni --split-pos=1 --oob' '--tlsrec=sni --split-pos=1 --disorder' \
|
||||
'--tlsrec=sni --split-pos=1 --oob --disorder'; do
|
||||
tpws_curl_test_update $1 $3 $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
|
||||
for s in '' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
|
||||
for s2 in '--tlsrec=midsld' '--tlsrec=sniext+1 --split-pos=midsld' '--tlsrec=sniext+4 --split-pos=midsld' '--tlsrec=sniext+1 --split-pos=1,midsld' '--tlsrec=sniext+4 --split-pos=1,midsld' ; do
|
||||
tpws_curl_test_update $1 $3 $s2 $s $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_mss=0
|
||||
break
|
||||
}
|
||||
done
|
||||
done
|
||||
# only linux supports mss
|
||||
[ "$UNAME" = Linux -a "$sec" = 1 ] || break
|
||||
[ "$SCANLEVEL" = force -o "$need_mss" = 1 ] || break
|
||||
done
|
||||
fi
|
||||
}
|
||||
@@ -1393,7 +1465,7 @@ tpws_check_domain_http_bypass()
|
||||
|
||||
local strategy
|
||||
tpws_check_domain_http_bypass_ "$@"
|
||||
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"}}"
|
||||
strategy_append_extra_tpws
|
||||
report_strategy $1 $3 tpws
|
||||
}
|
||||
|
||||
@@ -1682,17 +1754,6 @@ ask_params()
|
||||
echo "installed curl version does not support http3 QUIC. tests disabled."
|
||||
fi
|
||||
|
||||
IGNORE_CA=0
|
||||
CURL_OPT=
|
||||
[ $ENABLE_HTTPS_TLS13 = 1 -o $ENABLE_HTTPS_TLS12 = 1 ] && {
|
||||
echo
|
||||
echo "on limited systems like openwrt CA certificates might not be installed to preserve space"
|
||||
echo "in such a case curl cannot verify server certificate and you should either install ca-bundle or disable verification"
|
||||
echo "however disabling verification will break https check if ISP does MitM attack and substitutes server certificate"
|
||||
ask_yes_no_var IGNORE_CA "do not verify server certificate"
|
||||
[ "$IGNORE_CA" = 1 ] && CURL_OPT=-k
|
||||
}
|
||||
|
||||
echo
|
||||
echo "sometimes ISPs use multiple DPIs or load balancing. bypass strategies may work unstable."
|
||||
printf "how many times to repeat each test (default: 1) : "
|
||||
|
@@ -60,11 +60,22 @@ starts_with()
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
extract_arg()
|
||||
{
|
||||
# $1 - arg number
|
||||
# $2,$3,... - args
|
||||
local n=$1
|
||||
while [ -n "$1" ]; do
|
||||
shift
|
||||
[ $n -eq 1 ] && { echo "$1"; return 0; }
|
||||
n=$(($n-1))
|
||||
done
|
||||
return 1
|
||||
}
|
||||
find_str_in_list()
|
||||
{
|
||||
# $1 - string
|
||||
# $2 - space separated values
|
||||
|
||||
local v
|
||||
[ -n "$1" ] && {
|
||||
for v in $2; do
|
||||
@@ -400,6 +411,7 @@ check_bad_ws_options()
|
||||
# $2 - nfqws/tpws options
|
||||
if [ "$1" = 1 ] && has_bad_ws_options "$2"; then
|
||||
echo "!!! REFUSING TO USE BAD OPTIONS : $2"
|
||||
help_bad_ws_options
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
@@ -408,8 +420,7 @@ check_bad_ws_options()
|
||||
help_bad_ws_options()
|
||||
{
|
||||
echo "WARNING ! you have specified --ipset option"
|
||||
echo "WARNING ! it would work but on $UNAME it's not the best option"
|
||||
echo "WARNING ! it would work but on ${UNAME:-$(uname)} it's not the best option"
|
||||
echo "WARNING ! you should use kernel mode sets. they are much more efficient."
|
||||
echo "WARNING ! to use ipsets you have to write your own custom script"
|
||||
echo "WARNING ! installer will stop here to prevent distribution of easy to use but bad copy-paste solutions"
|
||||
}
|
||||
|
@@ -190,6 +190,7 @@ check_system()
|
||||
|
||||
get_fwtype
|
||||
OPENWRT_FW3=
|
||||
OPENWRT_FW4=
|
||||
|
||||
local info
|
||||
UNAME=$(uname)
|
||||
@@ -201,27 +202,35 @@ check_system()
|
||||
# some distros include systemctl without systemd
|
||||
if [ -d "$SYSTEMD_DIR" ] && [ -x "$SYSTEMCTL" ] && [ "$INIT" = "systemd" ]; then
|
||||
SYSTEM=systemd
|
||||
elif [ -f "/etc/openwrt_release" ] && exists opkg && exists uci && [ "$INIT" = "procd" ] ; then
|
||||
{
|
||||
elif [ -f "/etc/openwrt_release" ] && exists opkg || exists apk && exists uci && [ "$INIT" = "procd" ] ; then
|
||||
SYSTEM=openwrt
|
||||
OPENWRT_PACKAGER=opkg
|
||||
OPENWRT_PACKAGER_INSTALL="opkg install"
|
||||
OPENWRT_PACKAGER_UPDATE="opkg update"
|
||||
exists apk && {
|
||||
OPENWRT_PACKAGER=apk
|
||||
OPENWRT_PACKAGER_INSTALL="apk add"
|
||||
OPENWRT_PACKAGER_UPDATE=
|
||||
}
|
||||
info="package manager $OPENWRT_PACKAGER\n"
|
||||
if openwrt_fw3 ; then
|
||||
OPENWRT_FW3=1
|
||||
info="openwrt firewall uses fw3"
|
||||
info="${info}firewall fw3"
|
||||
if is_ipt_flow_offload_avail; then
|
||||
info="$info. hardware flow offloading requires iptables."
|
||||
else
|
||||
info="$info. flow offloading unavailable."
|
||||
fi
|
||||
elif openwrt_fw4; then
|
||||
info="openwrt firewall uses fw4. flow offloading requires nftables."
|
||||
OPENWRT_FW4=1
|
||||
info="${info}firewall fw4. flow offloading requires nftables."
|
||||
fi
|
||||
}
|
||||
elif openrc_test; then
|
||||
SYSTEM=openrc
|
||||
else
|
||||
echo system is not either systemd, openrc or openwrt based
|
||||
echo easy installer can set up config settings but can\'t configure auto start
|
||||
echo you have to do it manually. check readme.txt for manual setup info.
|
||||
echo you have to do it manually. check readme.md for manual setup info.
|
||||
if [ -n "$1" ] || ask_yes_no N "do you want to continue"; then
|
||||
SYSTEM=linux
|
||||
else
|
||||
@@ -232,11 +241,11 @@ check_system()
|
||||
elif [ "$UNAME" = "Darwin" ]; then
|
||||
SYSTEM=macos
|
||||
else
|
||||
echo easy installer only supports Linux and MacOS. check readme.txt for supported systems and manual setup info.
|
||||
echo easy installer only supports Linux and MacOS. check readme.md for supported systems and manual setup info.
|
||||
exitp 5
|
||||
fi
|
||||
echo system is based on $SYSTEM
|
||||
[ -n "$info" ] && echo $info
|
||||
[ -n "$info" ] && printf "${info}\n"
|
||||
}
|
||||
|
||||
get_free_space_mb()
|
||||
@@ -420,14 +429,21 @@ check_kmod()
|
||||
}
|
||||
check_package_exists_openwrt()
|
||||
{
|
||||
[ -n "$(opkg list $1)" ]
|
||||
[ -n "$($OPENWRT_PACKAGER list $1)" ]
|
||||
}
|
||||
check_package_openwrt()
|
||||
{
|
||||
case $OPENWRT_PACKAGER in
|
||||
opkg)
|
||||
[ -n "$(opkg list-installed $1)" ] && return 0
|
||||
local what="$(opkg whatprovides $1 | tail -n +2 | head -n 1)"
|
||||
[ -n "$what" ] || return 1
|
||||
[ -n "$(opkg list-installed $what)" ]
|
||||
;;
|
||||
apk)
|
||||
apk info -e $1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
check_packages_openwrt()
|
||||
{
|
||||
@@ -516,9 +532,8 @@ restart_openwrt_firewall()
|
||||
|
||||
local FW=fw4
|
||||
[ -n "$OPENWRT_FW3" ] && FW=fw3
|
||||
$FW -q restart || {
|
||||
exists $FW && $FW -q restart || {
|
||||
echo could not restart firewall $FW
|
||||
exitp 30
|
||||
}
|
||||
}
|
||||
remove_openwrt_firewall()
|
||||
@@ -682,16 +697,59 @@ check_prerequisites_linux()
|
||||
fi
|
||||
}
|
||||
|
||||
removable_pkgs_openwrt()
|
||||
{
|
||||
local pkg PKGS2
|
||||
[ -n "$OPENWRT_FW4" ] && PKGS2="$PKGS2 iptables-zz-legacy iptables ip6tables-zz-legacy ip6tables"
|
||||
[ -n "$OPENWRT_FW3" ] && PKGS2="$PKGS2 nftables-json nftables-nojson nftables"
|
||||
PKGS=
|
||||
for pkg in $PKGS2; do
|
||||
check_package_exists_openwrt $pkg && PKGS="${PKGS:+$PKGS }$pkg"
|
||||
done
|
||||
PKGS="ipset iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt iptables-mod-conntrack-extra ip6tables-mod-nat ip6tables-extra kmod-nft-queue gzip coreutils-sort coreutils-sleep curl $PKGS"
|
||||
}
|
||||
|
||||
openwrt_fix_broken_apk_uninstall_scripts()
|
||||
{
|
||||
# at least in early snapshots with apk removing gnu gzip, sort, ... does not restore links to busybox
|
||||
# system may become unusable
|
||||
exists sort || { echo fixing missing sort; ln -fs /bin/busybox /usr/bin/sort; }
|
||||
exists gzip || { echo fixing missing gzip; ln -fs /bin/busybox /bin/gzip; }
|
||||
exists sleep || { echo fixing missing sleep; ln -fs /bin/busybox /bin/sleep; }
|
||||
}
|
||||
|
||||
remove_extra_pkgs_openwrt()
|
||||
{
|
||||
local PKGS
|
||||
echo \* remove dependencies
|
||||
removable_pkgs_openwrt
|
||||
echo these packages may have been installed by install_easy.sh : $PKGS
|
||||
ask_yes_no N "do you want to remove them" && {
|
||||
case $OPENWRT_PACKAGER in
|
||||
opkg)
|
||||
opkg remove --autoremove $PKGS
|
||||
;;
|
||||
apk)
|
||||
apk del $PKGS
|
||||
openwrt_fix_broken_apk_uninstall_scripts
|
||||
;;
|
||||
esac
|
||||
}
|
||||
}
|
||||
|
||||
check_prerequisites_openwrt()
|
||||
{
|
||||
echo \* checking prerequisites
|
||||
|
||||
local PKGS="curl" UPD=0
|
||||
local PKGS="curl" UPD=0 local pkg_iptables
|
||||
|
||||
case "$FWTYPE" in
|
||||
iptables)
|
||||
PKGS="$PKGS ipset iptables iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt iptables-mod-conntrack-extra"
|
||||
[ "$DISABLE_IPV6" != "1" ] && PKGS="$PKGS ip6tables ip6tables-mod-nat ip6tables-extra"
|
||||
pkg_iptables=iptables
|
||||
check_package_exists_openwrt iptables-zz-legacy && pkg_iptables=iptables-zz-legacy
|
||||
PKGS="$PKGS ipset $pkg_iptables iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt iptables-mod-conntrack-extra"
|
||||
check_package_exists_openwrt ip6tables-zz-legacy && pkg_iptables=ip6tables-zz-legacy
|
||||
[ "$DISABLE_IPV6" = 1 ] || PKGS="$PKGS $pkg_iptables ip6tables-mod-nat ip6tables-extra"
|
||||
;;
|
||||
nftables)
|
||||
PKGS="$PKGS nftables kmod-nft-nat kmod-nft-offload kmod-nft-queue"
|
||||
@@ -703,9 +761,9 @@ check_prerequisites_openwrt()
|
||||
else
|
||||
echo \* installing prerequisites
|
||||
|
||||
opkg update
|
||||
$OPENWRT_PACKAGER_UPDATE
|
||||
UPD=1
|
||||
opkg install $PKGS || {
|
||||
$OPENWRT_PACKAGER_INSTALL $PKGS || {
|
||||
echo could not install prerequisites
|
||||
exitp 6
|
||||
}
|
||||
@@ -718,10 +776,10 @@ check_prerequisites_openwrt()
|
||||
echo installer can install GNU gzip but it requires about 100 Kb space
|
||||
if ask_yes_no N "do you want to install GNU gzip"; then
|
||||
[ "$UPD" = "0" ] && {
|
||||
opkg update
|
||||
$OPENWRT_PACKAGER_UPDATE
|
||||
UPD=1
|
||||
}
|
||||
opkg install --force-overwrite gzip
|
||||
$OPENWRT_PACKAGER_INSTALL --force-overwrite gzip
|
||||
fi
|
||||
}
|
||||
is_linked_to_busybox sort && {
|
||||
@@ -731,10 +789,10 @@ check_prerequisites_openwrt()
|
||||
echo installer can install GNU sort but it requires about 100 Kb space
|
||||
if ask_yes_no N "do you want to install GNU sort"; then
|
||||
[ "$UPD" = "0" ] && {
|
||||
opkg update
|
||||
$OPENWRT_PACKAGER_UPDATE
|
||||
UPD=1
|
||||
}
|
||||
opkg install --force-overwrite coreutils-sort
|
||||
$OPENWRT_PACKAGER_INSTALL --force-overwrite coreutils-sort
|
||||
fi
|
||||
}
|
||||
[ "$FSLEEP" = 0 ] && is_linked_to_busybox sleep && {
|
||||
@@ -743,10 +801,10 @@ check_prerequisites_openwrt()
|
||||
echo if you want to speed up blockcheck install coreutils-sleep. it requires about 40 Kb space
|
||||
if ask_yes_no N "do you want to install COREUTILS sleep"; then
|
||||
[ "$UPD" = "0" ] && {
|
||||
opkg update
|
||||
$OPENWRT_PACKAGER_UPDATE
|
||||
UPD=1
|
||||
}
|
||||
opkg install --force-overwrite coreutils-sleep
|
||||
$OPENWRT_PACKAGER_INSTALL --force-overwrite coreutils-sleep
|
||||
fsleep_setup
|
||||
fi
|
||||
}
|
||||
|
@@ -125,3 +125,13 @@ resolve_lower_devices()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default_route_interfaces6()
|
||||
{
|
||||
sed -nre 's/^00000000000000000000000000000000 00 [0-9a-f]{32} [0-9a-f]{2} [0-9a-f]{32} [0-9a-f]{8} [0-9a-f]{8} [0-9a-f]{8} [0-9a-f]{8} +(.*)$/\1/p' /proc/net/ipv6_route | grep -v '^lo$' | sort -u | xargs
|
||||
}
|
||||
|
||||
default_route_interfaces4()
|
||||
{
|
||||
sed -nre 's/^([^\t]+)\t00000000\t[0-9A-F]{8}\t[0-9A-F]{4}\t[0-9]+\t[0-9]+\t[0-9]+\t00000000.*$/\1/p' /proc/net/route | sort -u | xargs
|
||||
}
|
||||
|
@@ -55,7 +55,7 @@ TPPORT_SOCKS=987
|
||||
# <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>
|
||||
--filter-tcp=443 --split-pos=1,midsld --disorder <HOSTLIST>
|
||||
"
|
||||
|
||||
TPWS_ENABLE=0
|
||||
@@ -65,7 +65,7 @@ TPWS_PORTS=80,443
|
||||
# <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>
|
||||
--filter-tcp=443 --split-pos=1,midsld --disorder <HOSTLIST>
|
||||
"
|
||||
|
||||
NFQWS_ENABLE=0
|
||||
@@ -89,8 +89,8 @@ NFQWS_UDP_PKT_IN=0
|
||||
# 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-tcp=80 --dpi-desync=fake,multisplit --dpi-desync-split-pos=method+2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
|
||||
--filter-tcp=443 --dpi-desync=fake,multidisorder --dpi-desync-split-pos=1,midsld --dpi-desync-fooling=badseq,md5sig <HOSTLIST> --new
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST_NOAUTO>
|
||||
"
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016-2021 bol-van
|
||||
Copyright (c) 2016-2024 bol-van
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@@ -100,7 +100,7 @@ Later you will add ipfw commands to `/etc/rc.firewall.my` to be reapplied after
|
||||
You can also run zapret daemons from there. Start them with `--daemon` options, for example
|
||||
```
|
||||
pkill ^dvtws$
|
||||
/opt/zapret/nfq/dvtws --port=989 --daemon --dpi-desync=split2
|
||||
/opt/zapret/nfq/dvtws --port=989 --daemon --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
```
|
||||
|
||||
To restart firewall and daemons run : `/etc/rc.d/ipfw restart`
|
||||
@@ -157,7 +157,7 @@ ipfw delete 100
|
||||
ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted not sockarg xmit em0
|
||||
# required for autottl mode only
|
||||
ipfw add 100 divert 989 tcp from any 80,443 to any tcpflags syn,ack in not diverted not sockarg recv em0
|
||||
/opt/zapret/nfq/dvtws --port=989 --dpi-desync=split2
|
||||
/opt/zapret/nfq/dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
```
|
||||
|
||||
Process only table zapret with the exception of table nozapret:
|
||||
@@ -167,7 +167,7 @@ ipfw add 100 allow tcp from me to table\(nozapret\) 80,443
|
||||
ipfw add 100 divert 989 tcp from any to table\(zapret\) 80,443 out not diverted not sockarg xmit em0
|
||||
# required for autottl mode only
|
||||
ipfw add 100 divert 989 tcp from table\(zapret\) 80,443 to any tcpflags syn,ack in not diverted not sockarg recv em0
|
||||
/opt/zapret/nfq/dvtws --port=989 --dpi-desync=split2
|
||||
/opt/zapret/nfq/dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
```
|
||||
|
||||
Reinjection loop avoidance. FreeBSD artificially ignores sockarg for ipv6 in
|
||||
@@ -217,8 +217,9 @@ ipfrag2 desync mode.
|
||||
|
||||
There's autostart script example in `init.d/pfsense`. It should be placed to
|
||||
`/usr/local/etc/rc.d` and edited. Write your ipfw rules and daemon start
|
||||
commands. Because git is absent the most convinient way to copy files is ssh.
|
||||
curl is present by default.
|
||||
commands.
|
||||
curl is present by default. You can use it to download `tar.gz` release directly from github.
|
||||
Or you can copy files using sftp.
|
||||
|
||||
Copy zip with zapret files to `/opt` and unpack there as it's done in other
|
||||
systems. In this case run `dvtws` as `/opt/zapret/nfq/dvtws`. Or just copy
|
||||
@@ -227,9 +228,6 @@ present. It's possible to renew lists.
|
||||
|
||||
If you dont like poverty of default repos its possible to enable FreeBSD repo.
|
||||
Change `no` to `yes` in `/usr/local/etc/pkg/repos/FreeBSD.conf` and `/usr/local/etc/pkg/repos/pfSense.conf`.
|
||||
Then it becomes possible to install all the required software including git to download
|
||||
zapret from github directly.
|
||||
|
||||
|
||||
`/usr/local/etc/rc.d/zapret.sh` (chmod 755)
|
||||
```
|
||||
@@ -247,7 +245,7 @@ sysctl net.inet6.ip6.pfil.inbound=ipfw,pf
|
||||
ipfw delete 100
|
||||
ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted not sockarg xmit em0
|
||||
pkill ^dvtws$
|
||||
dvtws --daemon --port 989 --dpi-desync=split2
|
||||
dvtws --daemon --port 989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
|
||||
# required for newer pfsense versions (2.6.0 tested) to return ipfw to functional state
|
||||
pfctl -d ; pfctl -e
|
||||
@@ -282,7 +280,7 @@ Autostart `/usr/local/etc/rc.d/zapret.sh`:
|
||||
```
|
||||
pfctl -a zapret -f /etc/zapret.anchor
|
||||
pkill ^tpws$
|
||||
tpws --daemon --port=988 --enable-pf --bind-addr=127.0.0.1 --bind-iface6=em1 --bind-linklocal=force --split-http-req=method --split-pos=2
|
||||
tpws --daemon --port=988 --enable-pf --bind-addr=127.0.0.1 --bind-iface6=em1 --bind-linklocal=force --split-pos=2
|
||||
```
|
||||
|
||||
After reboot check that anchor is created and referred from the main ruleset:
|
||||
@@ -344,7 +342,7 @@ pass out quick on em0 proto tcp to port {80,443} divert-packet port 989
|
||||
Then:
|
||||
```
|
||||
pfctl -f /etc/pf.conf
|
||||
./dvtws --port=989 --dpi-desync=split2
|
||||
./dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
```
|
||||
|
||||
`dwtws` only for table zapret with the exception of table nozapret :
|
||||
@@ -377,7 +375,7 @@ pass out quick on em0 inet6 proto tcp to <zapret6-user> port {80,443} divert-p
|
||||
Then:
|
||||
```
|
||||
pfctl -f /etc/pf.conf
|
||||
./dvtws --port=989 --dpi-desync=split2
|
||||
./dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
```
|
||||
|
||||
divert-packet automatically adds the reverse rule. By default also incoming
|
725
docs/bsd.md
Normal file
725
docs/bsd.md
Normal file
@@ -0,0 +1,725 @@
|
||||
# Настройка BSD-подобных систем
|
||||
|
||||
* [Поддерживаемые версии](#поддерживаемые-версии)
|
||||
* [Особенности BSD систем](#особенности-bsd-систем)
|
||||
* [Отсутствие nfqueue](#отсутствие-nfqueue)
|
||||
* [Типы Firewall](#типы-firewall)
|
||||
* [Сборка](#сборка)
|
||||
* [Divert сокеты](#divert-сокеты)
|
||||
* [Lookup Tables](#lookup-tables)
|
||||
* [Загрузка ip таблиц из файла](#загрузка-ip-таблиц-из-файла)
|
||||
* [Отсутствие splice](#отсутствие-splice)
|
||||
* [mdig и ip2net](#mdig-и-ip2net)
|
||||
* [FreeBSD](#freebsd)
|
||||
* [Подгрузка ipdivert](#подгрузка-ipdivert)
|
||||
* [Авто-восстановление правил ipfw и работа в фоне](#авто-восстановление-правил-ipfw-и-работа-в-фоне)
|
||||
* [tpws в прозрачном режиме](#tpws-в-прозрачном-режиме)
|
||||
* [Запуск dvtws](#запуск-dvtws)
|
||||
* [PF в FreeBSD](#pf-в-freebsd)
|
||||
* [pfsense](#pfsense)
|
||||
* [OpenBSD](#openbsd)
|
||||
* [tpws bind на ipv4](#tpws-bind-на-ipv4)
|
||||
* [tpws для проходящего трафика](#tpws-для-проходящего-трафика)
|
||||
* [Запуск dvtws](#запуск-dvtws)
|
||||
* [Проблемы с badsum](#проблемы-с-badsum)
|
||||
* [Особенность отправки fake пакетов](#особенность-отправки-fake-пакетов)
|
||||
* [Перезагрузка PF таблиц](#перезагрузка-pf-таблиц)
|
||||
* [MacOS](#macos)
|
||||
* [Введение](#введение)
|
||||
* [dvtws бесполезен](#dvtws-бесполезен)
|
||||
* [tpws](#tpws)
|
||||
* [Проблема link-local адреса](#проблема-link-local-адреса)
|
||||
* [Сборка](#сборка)
|
||||
* [Простая установка](#простая-установка)
|
||||
* [Вариант Custom](#вариант-custom)
|
||||
|
||||
|
||||
## Поддерживаемые версии
|
||||
**FreeBSD** 11.x+ , **OpenBSD** 6.x+, частично **MacOS Sierra** +
|
||||
|
||||
> [!CAUTION]
|
||||
> На более старых может собираться, может не собираться, может работать или не
|
||||
> работать. На **FreeBSD** 10 собирается и работает `dvtws`. С `tpws` есть
|
||||
> проблемы из-за слишком старой версии компилятора clang. Вероятно, будет
|
||||
> работать, если обновить компилятор. Возможна прикрутка к последним версиям
|
||||
> pfsense без веб интерфейса в ручном режиме через консоль.
|
||||
|
||||
|
||||
## Особенности BSD систем
|
||||
|
||||
### Отсутствие nfqueue
|
||||
В **BSD** нет `nfqueue`. Похожий механизм - divert sockets. Из каталога
|
||||
[`nfq/`](../nfq/) под **BSD** собирается `dvtws` вместо `nfqws`. Он разделяет с
|
||||
`nfqws` большую часть кода и почти совпадает по параметрам командной строки.
|
||||
|
||||
### Типы Firewall
|
||||
**FreeBSD** содержит 3 фаервола : **IPFilter**, **ipfw** и **Packet Filter (PF
|
||||
в дальнейшем)**. **OpenBSD** содержит только **PF**.
|
||||
|
||||
### Сборка
|
||||
Под **FreeBSD** `tpws` и `dvtws` собираются через `make`.
|
||||
|
||||
Под **OpenBSD**:
|
||||
```sh
|
||||
make bsd
|
||||
```
|
||||
|
||||
Под **MacOS**:
|
||||
```sh
|
||||
make mac
|
||||
```
|
||||
|
||||
**FreeBSD** make распознает BSDmakefile, **OpenBSD** и **MacOS** - нет. Поэтому
|
||||
там используется отдельный target в Makefile. Сборка всех исходников:
|
||||
```sh
|
||||
make -C /opt/zapret
|
||||
```
|
||||
|
||||
### Divert сокеты
|
||||
Divert сокет это внутренний тип сокета ядра **BSD**. Он не привязывается ни к
|
||||
какому сетевому адресу, не участвует в обмене данными через сеть и
|
||||
идентифицируется по номеру порта `1..65535`. Аналогия с номером очереди
|
||||
`NFQUEUE`. На divert сокеты заворачивается трафик посредством правил ipfw или
|
||||
PF. Если в фаерволе есть правило divert, но на divert порту никто не слушает,
|
||||
то пакеты дропаются. Это поведение аналогично правилам `NFQUEUE` без параметра
|
||||
`--queue-bypass`. На **FreeBSD** divert сокеты могут быть только ipv4, хотя на
|
||||
них принимаются и ipv4, и ipv6 фреймы. На **OpenBSD** divert сокеты создаются
|
||||
отдельно для ipv4 и ipv6 и работают только с одной версией `ip` каждый. На
|
||||
**MacOS** похоже, что divert сокеты из ядра вырезаны. См подробнее раздел про
|
||||
**MacOS**. Отсылка в divert сокет работает аналогично отсылке через raw socket
|
||||
на linux. Передается полностью IP фрейм, начиная с ip загловка. Эти особенности
|
||||
учитываются в `dvtws`.
|
||||
|
||||
### Lookup Tables
|
||||
Скрипты [`ipset/*.sh`](../ipset/) при наличии ipfw работают с ipfw lookup
|
||||
tables. Это прямой аналог ipset. lookup tables не разделены на v4 и v6. Они
|
||||
могут содержать v4 и v6 адреса и подсети одновременно. Если ipfw отсутствует,
|
||||
то действие зависит от переменной `LISTS_RELOAD` в config. Если она задана, то
|
||||
выполняется команда из `LISTS_RELOAD`. В противном случае не делается ничего.
|
||||
Если `LISTS_RELOAD=-`, то заполнение таблиц отключается даже при наличии ipfw.
|
||||
|
||||
### Загрузка ip таблиц из файла
|
||||
PF может загружать ip таблицы из файла. Чтобы использовать эту возможность
|
||||
следует отключить сжатие gzip для листов через параметр файла config:
|
||||
`GZIP_LISTS=0`.
|
||||
|
||||
### Отсутствие splice
|
||||
**BSD** не содержит системного вызова splice. `tpws` работает через переброску
|
||||
данных в user mode в оба конца. Это медленнее, но не критически. Управление
|
||||
асинхронными сокетами в `tpws` основано на linux-specific механизме epoll. В
|
||||
**BSD** для его эмуляции используется epoll-shim - прослойка для эмуляции epoll
|
||||
на базе kqueue.
|
||||
|
||||
### mdig и ip2net
|
||||
mdig и ip2net полностью работоспособны в **BSD**. В них нет ничего
|
||||
системо-зависимого.
|
||||
|
||||
|
||||
## FreeBSD
|
||||
|
||||
### Подгрузка ipdivert
|
||||
Divert сокеты требуют специального модуля ядра - `ipdivert`.
|
||||
|
||||
- Поместите следующие строки в `/boot/loader.conf` (создать, если отсутствует):
|
||||
```
|
||||
ipdivert_load="YES"
|
||||
net.inet.ip.fw.default_to_accept=1
|
||||
```
|
||||
|
||||
`/etc/rc.conf`:
|
||||
```
|
||||
firewall_enable="YES"
|
||||
firewall_script="/etc/rc.firewall.my"
|
||||
```
|
||||
|
||||
`/etc/rc.firewall.my`:
|
||||
```sh
|
||||
$ ipfw -q -f flush
|
||||
```
|
||||
|
||||
### Авто-восстановление правил ipfw и работа в фоне
|
||||
В `/etc/rc.firewall.my` можно дописывать правила ipfw, чтобы они
|
||||
восстанавливались после перезагрузки. Оттуда же можно запускать и демоны
|
||||
zapret, добавив в параметры `--daemon`. Например так:
|
||||
```sh
|
||||
$ pkill ^dvtws$
|
||||
$ /opt/zapret/nfq/dvtws --port=989 --daemon --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
```
|
||||
|
||||
Для перезапуска фаервола и демонов достаточно будет сделать:
|
||||
```sh
|
||||
$ /etc/rc.d/ipfw restart
|
||||
```
|
||||
|
||||
### tpws в прозрачном режиме
|
||||
Краткая инструкция по запуску `tpws` в прозрачном режиме.
|
||||
|
||||
> [!NOTE]
|
||||
> Предполагается, что интерфейс LAN называется `em1`, WAN - `em0`.
|
||||
|
||||
#### Весь трафик
|
||||
```sh
|
||||
$ ipfw delete 100
|
||||
$ ipfw add 100 fwd 127.0.0.1,988 tcp from me to any 80,443 proto ip4 xmit em0 not uid daemon
|
||||
$ ipfw add 100 fwd ::1,988 tcp from me to any 80,443 proto ip6 xmit em0 not uid daemon
|
||||
$ ipfw add 100 fwd 127.0.0.1,988 tcp from any to any 80,443 proto ip4 recv em1
|
||||
$ ipfw add 100 fwd ::1,988 tcp from any to any 80,443 proto ip6 recv em1
|
||||
$ /opt/zapret/tpws/tpws --port=988 --user=daemon --bind-addr=::1 --bind-addr=127.0.0.1
|
||||
```
|
||||
|
||||
#### Трафик только на таблицу zapret, за исключением таблицы nozapret
|
||||
|
||||
```sh
|
||||
$ ipfw delete 100
|
||||
$ ipfw add 100 allow tcp from me to table\(nozapret\) 80,443
|
||||
$ ipfw add 100 fwd 127.0.0.1,988 tcp from me to table\(zapret\) 80,443 proto ip4 xmit em0 not uid daemon
|
||||
$ ipfw add 100 fwd ::1,988 tcp from me to table\(zapret\) 80,443 proto ip6 xmit em0 not uid daemon
|
||||
$ ipfw add 100 allow tcp from any to table\(nozapret\) 80,443 recv em1
|
||||
$ ipfw add 100 fwd 127.0.0.1,988 tcp from any to any 80,443 proto ip4 recv em1
|
||||
$ ipfw add 100 fwd ::1,988 tcp from any to any 80,443 proto ip6 recv em1
|
||||
$ /opt/zapret/tpws/tpws --port=988 --user=daemon --bind-addr=::1 --bind-addr=127.0.0.1
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Таблицы zapret, nozapret, ipban создаются скриптами из ipset по аналогии с
|
||||
> Linux. Обновление скриптов можно забить в cron под root:
|
||||
> ```sh
|
||||
> $ crontab -e
|
||||
> ```
|
||||
>
|
||||
> ```
|
||||
> <...>
|
||||
> 0 12 */2 * * /opt/zapret/ipset/get_config.sh
|
||||
> ```
|
||||
|
||||
> [!CAUTION]
|
||||
> При использовании ipfw `tpws` не требует повышенных привилегий для реализации
|
||||
> прозрачного режима. Однако, без рута невозможен bind на порты `< 1024` и
|
||||
> смена UID/GID. Без смены UID будет рекурсия, поэтому правила ipfw нужно
|
||||
> создавать с учетом UID, под которым работает `tpws`. Переадресация на порты
|
||||
> `>= 1024` может создать угрозу перехвата трафика непривилегированным
|
||||
> процессом, если вдруг `tpws` не запущен.
|
||||
|
||||
|
||||
### Запуск dvtws
|
||||
|
||||
#### Весь трафик
|
||||
```sh
|
||||
$ ipfw delete 100
|
||||
$ ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted xmit em0
|
||||
# required for autottl mode only
|
||||
$ ipfw add 100 divert 989 tcp from any 80,443 to any tcpflags syn,ack in not diverted recv em0
|
||||
$ /opt/zapret/nfq/dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
```
|
||||
|
||||
#### Трафик только на таблицу zapret, за исключением таблицы nozapret
|
||||
|
||||
```sh
|
||||
$ ipfw delete 100
|
||||
$ ipfw add 100 allow tcp from me to table\(nozapret\) 80,443
|
||||
$ ipfw add 100 divert 989 tcp from any to table\(zapret\) 80,443 out not diverted not sockarg xmit em0
|
||||
# required for autottl mode only
|
||||
$ ipfw add 100 divert 989 tcp from table\(zapret\) 80,443 to any tcpflags syn,ack in not diverted not sockarg recv em0
|
||||
$ /opt/zapret/nfq/dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
```
|
||||
|
||||
|
||||
### PF в FreeBSD
|
||||
Настройка аналогична **OpenBSD**, но есть важные нюансы.
|
||||
|
||||
- В **FreeBSD** поддержка PF в `tpws` отключена по умолчанию. Чтобы ее
|
||||
включить, нужно использовать параметр `--enable-pf`.
|
||||
- Нельзя сделать ipv6 rdr на `::1`. Нужно делать на link-local адрес входящего
|
||||
интерфейса. Смотрите через `ifconfig` адрес `fe80:...` и добавляете в правило.
|
||||
- Синтаксис `pf.conf` немного отличается. Более новая версия PF.
|
||||
- Лимит на количество элементов таблиц задается так:
|
||||
```sh
|
||||
$ sysctl net.pf.request_maxcount=2000000
|
||||
```
|
||||
- Сломан divert-to. Он работает, но не работает механизм предотвращения
|
||||
зацикливаний. Кто-то уже написал патч, но в `14-RELEASE` проблема все еще
|
||||
есть. Следовательно, на данный момент работа `dvtws` через PF невозможна.
|
||||
|
||||
`/etc/pf.conf`:
|
||||
```
|
||||
rdr pass on em1 inet6 proto tcp to port {80,443} -> fe80::31c:29ff:dee2:1c4d port 988
|
||||
rdr pass on em1 inet proto tcp to port {80,443} -> 127.0.0.1 port 988
|
||||
```
|
||||
|
||||
```sh
|
||||
$ /opt/zapret/tpws/tpws --port=988 --enable-pf --bind-addr=127.0.0.1 --bind-iface6=em1 --bind-linklocal=force
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> В PF не выходит делать rdr-to с той же системы, где работает proxy.
|
||||
> Вариант с route-to не сохраняет мета информацию. Адрес назначения теряется.
|
||||
> Поэтому этот вариант годится для squid, берущего адрес из протокола прикладного уровня, но не годится для tpws, полагающегося на метаданные ОС.
|
||||
> Поддержка rdr-to реализована через `/dev/pf`, поэтому прозрачный режим **требует root**.
|
||||
|
||||
|
||||
### pfsense
|
||||
|
||||
#### Описание
|
||||
pfsense основан на **FreeBSD** и использует фаервол PF, имеющий проблемы с
|
||||
divert. К счастью, модули ipfw и ipdivert присутствуют в поставке последних
|
||||
версий pfsense. Их можно подгрузить через `kldload`.
|
||||
|
||||
В некоторых более старых версиях pfsense требуется изменить порядок фаерволов
|
||||
через `sysctl`, сделав ipfw первым. В более новых эти параметры `sysctl`
|
||||
отсутствуют, но система работает как надо и без них. В некоторых случаях
|
||||
фаервол PF может ограничивать возможности `dvtws`, в частности в области
|
||||
фрагментации ip.
|
||||
|
||||
Присутствуют по умолчанию правила scrub для реассемблинга фрагментов.
|
||||
|
||||
Бинарики из [`binaries/freebsd-x64`](../binaries/freebsd-x64) собраны под
|
||||
**FreeBSD 11**. Они должны работать и на последующих версиях **FreeBSD**,
|
||||
включая pfsense. Можно пользоваться `install_bin.sh`.
|
||||
|
||||
#### Автозапуск
|
||||
Пример скрипта автозапуска лежит в [`init.d/pfsense`](../init.d/pfsense). Его
|
||||
следует поместить в `/usr/local/etc/rc.d` и отредактировать на предмет правил
|
||||
ipfw и запуска демонов. Есть встроенный редактор `edit` как более приемлемая
|
||||
альтернатива `vi`.
|
||||
|
||||
> [!NOTE]
|
||||
> Поскольку `git` отсутствует, копировать файлы удобнее всего через `ssh`.
|
||||
> `curl` присутствует по умолчанию. Можно скопировать zip с файлами zapret и
|
||||
> распаковать в `/opt`, как это делается на других системах. Тогда `dvtws`
|
||||
> нужно запускать как `/opt/zapret/nfq/dvtws`. Либо скопировать только `dvtws`
|
||||
> в `/usr/local/sbin`. Как вам больше нравится.
|
||||
|
||||
> [!NOTE]
|
||||
> Скрипты ipset работают, крон есть. Можно сделать автообновление листов.
|
||||
|
||||
> [!NOTE]
|
||||
> Если вас напрягает бедность имеющегося репозитория, можно включить
|
||||
> репозиторий от **FreeBSD**, который по умолчанию выключен.
|
||||
>
|
||||
> Поменяйте `no` на `yes` в `/usr/local/etc/pkg/repos/FreeBSD.conf`
|
||||
>
|
||||
> Можно установить весь привычный софт, включая `git`, чтобы напрямую скачивать
|
||||
> zapret с github.
|
||||
|
||||
`/usr/local/etc/rc.d/zapret.sh` (chmod `755`):
|
||||
```sh
|
||||
#!/bin/sh
|
||||
|
||||
kldload ipfw
|
||||
kldload ipdivert
|
||||
|
||||
# for older pfsense versions. newer do not have these sysctls
|
||||
sysctl net.inet.ip.pfil.outbound=ipfw,pf
|
||||
sysctl net.inet.ip.pfil.inbound=ipfw,pf
|
||||
sysctl net.inet6.ip6.pfil.outbound=ipfw,pf
|
||||
sysctl net.inet6.ip6.pfil.inbound=ipfw,pf
|
||||
|
||||
ipfw delete 100
|
||||
ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted xmit em0
|
||||
pkill ^dvtws$
|
||||
dvtws --daemon --port 989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
|
||||
# required for newer pfsense versions (2.6.0 tested) to return ipfw to functional state
|
||||
pfctl -d ; pfctl -e
|
||||
```
|
||||
|
||||
#### Проблемы tpws
|
||||
Что касается `tpws`, то видимо имеется некоторый конфликт двух фаерволов, и
|
||||
правила fwd в ipfw не работают. Работает перенаправление средствами PF как
|
||||
описано в разделе по **FreeBSD**. В PF можно изменять правила только целыми
|
||||
блоками - якорями (anchors). Нельзя просто так добавить или удалить что-то. Но
|
||||
чтобы какой-то anchor был обработан, на него должна быть ссылка из основного
|
||||
набора правил. Его трогать нельзя, иначе порушится весь фаервол. Поэтому
|
||||
придется править код скриптов pfsense.
|
||||
|
||||
1. Поправьте `/etc/inc/filter.inc` следующим образом:
|
||||
```
|
||||
<...>
|
||||
/* MOD */
|
||||
$natrules .= "# ZAPRET redirection\n";
|
||||
$natrules .= "rdr-anchor \"zapret\"\n";
|
||||
|
||||
$natrules .= "# TFTP proxy\n";
|
||||
$natrules .= "rdr-anchor \"tftp-proxy/*\"\n";
|
||||
<...>
|
||||
```
|
||||
|
||||
2. Напишите файл с содержимым anchor-а (например, `/etc/zapret.anchor`):
|
||||
```
|
||||
rdr pass on em1 inet proto tcp to port {80,443} -> 127.0.0.1 port 988
|
||||
rdr pass on em1 inet6 proto tcp to port {80,443} -> fe80::20c:29ff:5ae3:4821 port 988
|
||||
```
|
||||
|
||||
`fe80::20c:29ff:5ae3:4821` замените на ваш link local адрес LAN интерфейса,
|
||||
либо уберите строчку, если ipv6 не нужен.
|
||||
|
||||
3. Добавьте в автозапуск `/usr/local/etc/rc.d/zapret.sh`:
|
||||
```sh
|
||||
$ pfctl -a zapret -f /etc/zapret.anchor
|
||||
$ pkill ^tpws$
|
||||
$ tpws --daemon --port=988 --enable-pf --bind-addr=127.0.0.1 --bind-iface6=em1 --bind-linklocal=force --split-pos=2
|
||||
```
|
||||
|
||||
4. После перезагрузки проверьте, что правила создались:
|
||||
```sh
|
||||
$ pfctl -s nat
|
||||
no nat proto carp all
|
||||
nat-anchor "natearly/*" all
|
||||
nat-anchor "natrules/*" all
|
||||
<...>
|
||||
no rdr proto carp all
|
||||
rdr-anchor "zapret" all
|
||||
rdr-anchor "tftp-proxy/*" all
|
||||
rdr-anchor "miniupnpd" all
|
||||
|
||||
$ pfctl -s nat -a zapret
|
||||
rdr pass on em1 inet proto tcp from any to any port = http -> 127.0.0.1 port 988
|
||||
rdr pass on em1 inet proto tcp from any to any port = https -> 127.0.0.1 port 988
|
||||
rdr pass on em1 inet6 proto tcp from any to any port = http -> fe80::20c:29ff:5ae3:4821 port 988
|
||||
rdr pass on em1 inet6 proto tcp from any to any port = https -> fe80::20c:29ff:5ae3:4821 port 988
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Так же есть более элегантный способ запуска `tpws` через @reboot в cron и
|
||||
> правило перенаправления в UI. Это позволит не редактировать код pfsense.
|
||||
|
||||
|
||||
## OpenBSD
|
||||
|
||||
### tpws bind на ipv4
|
||||
В `tpws` bind по умолчанию только на ipv6. Для bind на ipv4 нужно указать `--bind-addr=0.0.0.0`.
|
||||
Используйте `--bind-addr=0.0.0.0 --bind-addr=::` для достижения того же результата, как в других ОС по умолчанию.
|
||||
Но лучше все же так не делать, а сажать на определенные внутренние адреса или интерфейсы.
|
||||
|
||||
|
||||
### tpws для проходящего трафика
|
||||
|
||||
`/etc/pf.conf`:
|
||||
```
|
||||
pass in quick on em1 inet proto tcp to port {80,443} rdr-to 127.0.0.1 port 988
|
||||
pass in quick on em1 inet6 proto tcp to port {80,443} rdr-to ::1 port 988
|
||||
```
|
||||
|
||||
```sh
|
||||
$ pfctl -f /etc/pf.conf
|
||||
$ tpws --port=988 --user=daemon --bind-addr=::1 --bind-addr=127.0.0.1
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> В PF не выходит делать rdr-to с той же системы, где работает proxy.
|
||||
> Вариант с route-to не сохраняет мета информацию. Адрес назначения теряется.
|
||||
> Поэтому этот вариант годится для squid, берущего адрес из протокола прикладного уровня, но не годится для tpws, полагающегося на метаданные ОС.
|
||||
> Поддержка rdr-to реализована через `/dev/pf`, поэтому прозрачный режим **требует root**.
|
||||
|
||||
|
||||
### Запуск dvtws
|
||||
|
||||
#### Весь трафик
|
||||
`/etc/pf.conf`:
|
||||
```
|
||||
pass in quick on em0 proto tcp from port {80,443} flags SA/SA divert-packet port 989 no state
|
||||
pass in quick on em0 proto tcp from port {80,443} no state
|
||||
pass out quick on em0 proto tcp to port {80,443} divert-packet port 989 no state
|
||||
```
|
||||
|
||||
```sh
|
||||
$ pfctl -f /etc/pf.conf
|
||||
$ ./dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
```
|
||||
|
||||
#### Трафик только на таблицу zapret, за исключением таблицы nozapret
|
||||
|
||||
`/etc/pf.conf`:
|
||||
```
|
||||
set limit table-entries 2000000
|
||||
table <zapret> file "/opt/zapret/ipset/zapret-ip.txt"
|
||||
table <zapret-user> file "/opt/zapret/ipset/zapret-ip-user.txt"
|
||||
table <nozapret> file "/opt/zapret/ipset/zapret-ip-exclude.txt"
|
||||
pass out quick on em0 inet proto tcp to <nozapret> port {80,443}
|
||||
pass in quick on em0 inet proto tcp from <zapret> port {80,443} flags SA/SA divert-packet port 989 no state
|
||||
pass in quick on em0 inet proto tcp from <zapret> port {80,443} no state
|
||||
pass out quick on em0 inet proto tcp to <zapret> port {80,443} divert-packet port 989 no state
|
||||
pass in quick on em0 inet proto tcp from <zapret-user> port {80,443} flags SA/SA divert-packet port 989 no state
|
||||
pass in quick on em0 inet proto tcp from <zapret-user> port {80,443} no state
|
||||
pass out quick on em0 inet proto tcp to <zapret-user> port {80,443} divert-packet port 989 no state
|
||||
table <zapret6> file "/opt/zapret/ipset/zapret-ip6.txt"
|
||||
table <zapret6-user> file "/opt/zapret/ipset/zapret-ip-user6.txt"
|
||||
table <nozapret6> file "/opt/zapret/ipset/zapret-ip-exclude6.txt"
|
||||
pass out quick on em0 inet6 proto tcp to <nozapret6> port {80,443}
|
||||
pass in quick on em0 inet6 proto tcp from <zapret6> port {80,443} flags SA/SA divert-packet port 989 no state
|
||||
pass in quick on em0 inet6 proto tcp from <zapret6> port {80,443} no state
|
||||
pass out quick on em0 inet6 proto tcp to <zapret6> port {80,443} divert-packet port 989 no state
|
||||
pass in quick on em0 inet6 proto tcp from <zapret6-user> port {80,443} flags SA/SA divert-packet port 989 no state
|
||||
pass in quick on em0 inet6 proto tcp from <zapret6-user> port {80,443} no state
|
||||
pass out quick on em0 inet6 proto tcp to <zapret6-user> port {80,443} divert-packet port 989 no state
|
||||
```
|
||||
|
||||
```sh
|
||||
$ pfctl -f /etc/pf.conf
|
||||
$ ./dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
```
|
||||
|
||||
|
||||
### Проблемы с badsum
|
||||
**OpenBSD** принудительно пересчитывает tcp checksum после divert, поэтому
|
||||
скорее всего `dpi-desync-fooling=badsum` у вас не заработает. При использовании
|
||||
этого параметра `dvtws` предупредит о возможной проблеме.
|
||||
|
||||
|
||||
### Особенность отправки fake пакетов
|
||||
В **OpenBSD** `dvtws` все фейки отсылает через divert socket, поскольку эта
|
||||
возможность через raw sockets заблокирована. Видимо PF автоматически
|
||||
предотвращает повторный заворот diverted фреймов, поэтому проблемы зацикливания
|
||||
нет.
|
||||
|
||||
divert-packet автоматически вносит обратное правило для перенаправления. Трюк с
|
||||
no state и in правилом позволяет обойти эту проблему, чтобы напрасно не гнать
|
||||
массивный трафик через `dvtws`.
|
||||
|
||||
|
||||
### Перезагрузка PF таблиц
|
||||
Скрипты из ipset не перезагружают таблицы в PF по умолчанию.
|
||||
|
||||
Чтобы они это делали, добавьте параметр в `/opt/zapret/config`:
|
||||
```
|
||||
LISTS_RELOAD="pfctl -f /etc/pf.conf"
|
||||
```
|
||||
|
||||
Более новые версии `pfctl` понимают команду перезагрузить только таблицы. Но это не относится к **OpenBSD**. В новых **FreeBSD** есть.
|
||||
```sh
|
||||
$ pfctl -Tl -f /etc/pf.conf
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Не забудьте выключить сжатие gzip: `GZIP_LISTS=0`
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Если в вашей конфигурации какого-то файла листа нет, то его необходимо
|
||||
> исключить из правил PF. Если вдруг листа нет, и он задан в pf.conf, будет
|
||||
> ошибка перезагрузки фаервола.
|
||||
|
||||
> [!NOTE]
|
||||
> После настройки обновление листов можно поместить в cron:
|
||||
> ```sh
|
||||
> $ crontab -e
|
||||
> ```
|
||||
>
|
||||
> ```
|
||||
> <...>
|
||||
> 0 12 */2 * * /opt/zapret/ipset/get_config.sh
|
||||
> ```
|
||||
|
||||
|
||||
## MacOS
|
||||
|
||||
### Введение
|
||||
Иначально ядро этой ОС "darwin" основывалось на **BSD**, потому в ней много
|
||||
похожего на другие версии **BSD**. Однако, как и в других массовых коммерческих
|
||||
проектах, приоритеты смещаются в сторону от оригинала. Яблочники что хотят, то
|
||||
и творят.
|
||||
|
||||
|
||||
### dvtws бесполезен
|
||||
Раньше был ipfw, потом его убрали, заменили на PF. Есть сомнения, что divert
|
||||
сокеты в ядре остались. Попытка создать divert socket не выдает ошибок, но
|
||||
полученный сокет ведет себя точно так же, как raw, со всеми его унаследованными
|
||||
косяками + еще яблочно специфическими. В PF divert-packet не работает. Простой
|
||||
grep бинарика `pfctl` показывает, что там нет слова "divert", а в других
|
||||
версиях **BSD** оно есть. `dvtws` собирается, но совершенно бесполезен.
|
||||
|
||||
|
||||
### tpws
|
||||
`tpws` удалось адаптировать, он работоспособен. Получение адреса назначения для
|
||||
прозрачного прокси в PF (`DIOCNATLOOK`) убрали из заголовков в новых SDK,
|
||||
сделав фактически недокументированным.
|
||||
|
||||
В `tpws` перенесены некоторые определения из более старых версий яблочных SDK.
|
||||
С ними удалось завести прозрачный режим. Однако, что будет в следующих версиях
|
||||
угадать сложно. Гарантий нет. Еще одной особенностью PF в **MacOS** является
|
||||
проверка на рута в момент обращения к `/dev/pf`, чего нет в остальных **BSD**.
|
||||
`tpws` по умолчанию сбрасывает рутовые привилегии. Необходимо явно указать
|
||||
параметр `--user=root`. В остальном PF себя ведет похоже на **FreeBSD**.
|
||||
Синтаксис `pf.conf` тот же.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> На **MacOS** работает редирект как с проходящего трафика, так и с локальной
|
||||
> системы через route-to. Поскольку `tpws` вынужден работать под root, для
|
||||
> исключения рекурсии приходится пускать исходящий от root трафик напрямую.
|
||||
> Отсюда имеем недостаток - **обход DPI для рута работать НЕ будет**.
|
||||
|
||||
#### Работа в прозрачном режиме только для исходящих запросов
|
||||
`/etc/pf.conf`:
|
||||
```
|
||||
rdr pass on lo0 inet proto tcp from !127.0.0.0/8 to any port {80,443} -> 127.0.0.1 port 988
|
||||
rdr pass on lo0 inet6 proto tcp from !::1 to any port {80,443} -> fe80::1 port 988
|
||||
pass out route-to (lo0 127.0.0.1) inet proto tcp from any to any port {80,443} user { >root }
|
||||
pass out route-to (lo0 fe80::1) inet6 proto tcp from any to any port {80,443} user { >root }
|
||||
```
|
||||
|
||||
```sh
|
||||
$ pfctl -ef /etc/pf.conf
|
||||
$ /opt/zapret/tpws/tpws --user=root --port=988 --bind-addr=127.0.0.1 --bind-iface6=lo0 --bind-linklocal=force
|
||||
```
|
||||
|
||||
#### Работа в прозрачном режиме
|
||||
> [!NOTE]
|
||||
> Предполагается, что имя LAN интерфейса - `en1`
|
||||
|
||||
```sh
|
||||
$ ifconfig en1 | grep fe80
|
||||
inet6 fe80::bbbb:bbbb:bbbb:bbbb%en1 prefixlen 64 scopeid 0x8
|
||||
```
|
||||
|
||||
`/etc/pf.conf`:
|
||||
```
|
||||
rdr pass on en1 inet proto tcp from any to any port {80,443} -> 127.0.0.1 port 988
|
||||
rdr pass on en1 inet6 proto tcp from any to any port {80,443} -> fe80::bbbb:bbbb:bbbb:bbbb port 988
|
||||
rdr pass on lo0 inet proto tcp from !127.0.0.0/8 to any port {80,443} -> 127.0.0.1 port 988
|
||||
rdr pass on lo0 inet6 proto tcp from !::1 to any port {80,443} -> fe80::1 port 988
|
||||
pass out route-to (lo0 127.0.0.1) inet proto tcp from any to any port {80,443} user { >root }
|
||||
pass out route-to (lo0 fe80::1) inet6 proto tcp from any to any port {80,443} user { >root }
|
||||
```
|
||||
|
||||
```sh
|
||||
$ pfctl -ef /etc/pf.conf
|
||||
$ /opt/zapret/tpws/tpws --user=root --port=988 --bind-addr=127.0.0.1 --bind-iface6=lo0 --bind-linklocal=force --bind-iface6=en1 --bind-linklocal=force
|
||||
```
|
||||
|
||||
|
||||
### Проблема link-local адреса
|
||||
Если вы пользуетесь **MaсOS** в качестве ipv6 роутера, то нужно будет
|
||||
решить вопрос с регулярно изменяемым link-local адресом. С некоторых версий
|
||||
**MacOS** использует по умолчанию постоянные "secured" ipv6 адреса вместо
|
||||
генерируемых на базе MAC адреса.
|
||||
|
||||
Все замечательно, но есть одна проблема. Постоянными остаются только global
|
||||
scope адреса. Link locals периодически меняются. Смена завязана на системное
|
||||
время. Перезагрузки адрес не меняют, Но если перевести время на день вперед и
|
||||
перезагрузиться - link local станет другим (по крайней мере в vmware это так).
|
||||
Информации по вопросу крайне мало, но тянет на баг. Не должен меняться link
|
||||
local. Скрывать link local не имеет смысла, а динамический link local нельзя
|
||||
использовать в качестве адреса шлюза. Проще всего отказаться от "secured"
|
||||
адресов. Для этого поместите строчку `net.inet6.send.opmode=0` в
|
||||
`/etc/sysctl.conf` и перезагрузите систему.
|
||||
|
||||
Все равно для исходящих соединений будут использоваться temporary адреса, как и
|
||||
в других системах. Или вам идея не по вкусу, можно прописать дополнительный
|
||||
статический ipv6 из диапазона маски `fc00::/7` - выберите любой с длиной
|
||||
префикса `128`. Это можно сделать в системных настройках, создав дополнительный
|
||||
адаптер на базе того же сетевого интерфейса, отключить в нем ipv4 и вписать
|
||||
статический ipv6. Он добавится к автоматически настраеваемым.
|
||||
|
||||
|
||||
### Сборка
|
||||
```sh
|
||||
$ make -C /opt/zapret mac
|
||||
```
|
||||
|
||||
|
||||
### Простая установка
|
||||
В **MacOS** поддерживается `install_easy.sh`
|
||||
|
||||
В комплекте идут бинарики, собраные под 64-bit с опцией
|
||||
`-mmacosx-version-min=10.8`. Они должны работать на всех поддерживаемых версиях
|
||||
**MacOS**. Если вдруг не работают - можно собрать свои. Developer tools
|
||||
ставятся автоматом при запуске `make`.
|
||||
|
||||
> [!WARNING]
|
||||
> Internet sharing средствами системы **не поддерживается**!
|
||||
>
|
||||
> Поддерживается только роутер, настроенный своими силами через PF. Если вы
|
||||
> вдруг включили шаринг, а потом выключили, то доступ к сайтам может пропасть
|
||||
> совсем.
|
||||
>
|
||||
> Лечение:
|
||||
> ```sh
|
||||
> $ pfctl -f /etc/pf.conf
|
||||
> ```
|
||||
>
|
||||
> Если вам нужен шаринг интернета, лучше отказаться от прозрачного режима и
|
||||
> использовать socks прокси.
|
||||
|
||||
Для автостарта используется launchd (`/Library/LaunchDaemons/zapret.plist`)
|
||||
Управляющий скрипт : `/opt/zapret/init.d/macos/zapret`
|
||||
|
||||
Следующие команды работают с `tpws` и фаерволом одновременно (если
|
||||
`INIT_APPLY_FW=1` в config)
|
||||
|
||||
```sh
|
||||
$ /opt/zapret/init.d/macos/zapret start
|
||||
$ /opt/zapret/init.d/macos/zapret stop
|
||||
$ /opt/zapret/init.d/macos/zapret restart
|
||||
```
|
||||
|
||||
Работа только с tpws:
|
||||
```sh
|
||||
$ /opt/zapret/init.d/macos/zapret start-daemons
|
||||
$ /opt/zapret/init.d/macos/zapret stop-daemons
|
||||
$ /opt/zapret/init.d/macos/zapret restart-daemons
|
||||
```
|
||||
|
||||
Работа только с PF:
|
||||
```sh
|
||||
$ /opt/zapret/init.d/macos/zapret start-fw
|
||||
$ /opt/zapret/init.d/macos/zapret stop-fw
|
||||
$ /opt/zapret/init.d/macos/zapret restart-fw
|
||||
```
|
||||
|
||||
Перезагрузка всех IP таблиц из файлов:
|
||||
```sh
|
||||
$ /opt/zapret/init.d/macos/zapret reload-fw-tables
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Инсталятор настраивает `LISTS_RELOAD` в config, так что скрипты
|
||||
> [`ipset/*.sh`](../ipset/) автоматически перезагружают IP таблицы в PF.
|
||||
|
||||
> [!NOTE]
|
||||
> Автоматически создается cron job на
|
||||
> [`ipset/get_config.sh`](../ipset/get_config.sh), по аналогии с openwrt.
|
||||
|
||||
При start-fw скрипт автоматически модицифирует `/etc/pf.conf`, вставляя туда
|
||||
anchors "zapret". Модификация расчитана на `pf.conf`, в котором сохранены
|
||||
дефолтные anchors от apple. Если у вас измененный `pf.conf` и модификация не
|
||||
удалась, об этом будет предупреждение. Не игнорируйте его. В этом случае вам
|
||||
нужно вставить в свой `pf.conf` (в соответствии с порядком типов правил):
|
||||
```
|
||||
rdr-anchor "zapret"
|
||||
anchor "zapret"
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> При деинсталяции через `uninstall_easy.sh` модификации `pf.conf` убираются.
|
||||
|
||||
> [!NOTE]
|
||||
> start-fw создает 3 файла anchors в `/etc/pf.anchors`: `zapret`, `zapret-v4`,
|
||||
> `zapret-v6`. Последние 2 подключаются из anchor "zapret".
|
||||
|
||||
> [!NOTE]
|
||||
> Таблицы `nozapret` и `nozapret6` принадлежат anchor "zapret".
|
||||
>
|
||||
> Таблицы `zapret` и `zapret-user` в anchor "zapret-v4".
|
||||
>
|
||||
> Таблицы `zapret6` и `zapret6-user` в anchor "zapret-v6".
|
||||
>
|
||||
> Если какая-то версия протокола отключена - соответствующий anchor пустой и не
|
||||
> упоминается в anchor "zapret". Таблицы и правила создаются только на те
|
||||
> листы, которые фактически есть в директории ipset.
|
||||
|
||||
|
||||
### Вариант Custom
|
||||
Так же как и в других системах, поддерживаемых в простом инсталяторе, можно
|
||||
создавать свои custom скрипты.
|
||||
|
||||
Расположение: `/opt/zapret/init.d/macos/custom`
|
||||
|
||||
`zapret_custom_daemons()` получает в `$1`: `0` или `1`. `0` = stop, `1` = start
|
||||
|
||||
custom firewall отличается от linux варианта. Вместо заполнения `iptables` вам
|
||||
нужно сгенерировать правила для `zapret-v4` и `zapret-v6` anchors и выдать их в
|
||||
stdout. Это делается в функциях `zapret_custom_firewall_v4()` и
|
||||
`zapret_custom_firewall_v6()`. Определения таблиц заполняются основным скриптом
|
||||
\- вам это делать не нужно. Можно ссылаться на таблицы `zapret` и `zapret-user`
|
||||
в v4, `zapret6` и `zapret6-user`.
|
||||
|
||||
Cм. пример [в файле](../init.d/macos/custom.d.examples/50-extra-tpws).
|
476
docs/bsd.txt
476
docs/bsd.txt
@@ -1,476 +0,0 @@
|
||||
Поддерживаемые версии
|
||||
---------------------
|
||||
|
||||
FreeBSD 11.x+ , OpenBSD 6.x+, частично MacOS Sierra+
|
||||
|
||||
На более старых может собираться, может не собираться, может работать или не работать.
|
||||
На FreeBSD 10 собирается и работает dvtws. С tpws есть проблемы из-за слишком старой версии компилятора clang.
|
||||
Вероятно, будет работать, если обновить компилятор.
|
||||
Возможна прикрутка к последним версиям pfsense без веб интерфейса в ручном режиме через консоль.
|
||||
|
||||
|
||||
Особенности BSD систем
|
||||
----------------------
|
||||
|
||||
В BSD нет nfqueue. Похожий механизм - divert sockets.
|
||||
Из каталога "nfq" под BSD собирается dvtws вместо nfqws.
|
||||
Он разделяет с nfqws большую часть кода и почти совпадает по параметрам командной строки.
|
||||
|
||||
FreeBSD содержит 3 фаервола : IPFilter, ipfw и Packet Filter (PF). OpenBSD содержит только PF.
|
||||
|
||||
Под FreeBSD tpws и dvtws собираются через "make", под OpenBSD - "make bsd", под MacOS - "make mac".
|
||||
FreeBSD make распознает BSDmakefile , OpenBSD и MacOS - нет. Поэтому там используется отдельный target в Makefile.
|
||||
Сборка всех исходников : make -C /opt/zapret
|
||||
|
||||
divert сокет - внутренний тип сокета ядра BSD. Он не привязывается ни к какому сетевому адресу, не участвует
|
||||
в обмене данными через сеть и идентифицируется по номеру порта 1..65535. Аналогия с номером очереди NFQUEUE.
|
||||
На divert сокеты заворачивается трафик посредством правил ipfw или PF.
|
||||
Если в фаерволе есть правило divert, но на divert порту никто не слушает, то пакеты дропаются.
|
||||
Это поведение аналогично правилам NFQUEUE без параметра --queue-bypass.
|
||||
На FreeBSD divert сокеты могут быть только ipv4, хотя на них принимаются и ipv4, и ipv6 фреймы.
|
||||
На OpenBSD divert сокеты создаются отдельно для ipv4 и ipv6 и работают только с одной версией ip каждый.
|
||||
На MacOS похоже, что divert сокеты из ядра вырезаны. См подробнее раздел про MacOS.
|
||||
Отсылка в divert сокет работает аналогично отсылке через raw socket на linux. Передается полностью IP фрейм, начиная
|
||||
с ip загловка . Эти особенности учитываются в dvtws.
|
||||
|
||||
Скрипты ipset/*.sh при наличии ipfw работают с ipfw lookup tables.
|
||||
Это прямой аналог ipset. lookup tables не разделены на v4 и v6. Они могут содержать v4 и v6 адреса и подсети одновременно.
|
||||
Если ipfw отсутствует, то действие зависит от переменной LISTS_RELOAD в config.
|
||||
Если она задана, то выполняется команда из LISTS_RELOAD. В противном случае не делается ничего.
|
||||
Если LISTS_RELOAD=-, то заполнение таблиц отключается даже при наличии ipfw.
|
||||
|
||||
PF может загружать ip таблицы из файла. Чтобы использовать эту возможность следует отключить сжатие gzip для листов
|
||||
через параметр файла config "GZIP_LISTS=0".
|
||||
|
||||
BSD не содержит системного вызова splice. tpws работает через переброску данных в user mode в оба конца.
|
||||
Это медленнее, но не критически.
|
||||
Управление асинхронными сокетами в tpws основано на linux-specific механизме epoll.
|
||||
В BSD для его эмуляции используется epoll-shim - прослойка для эмуляции epoll на базе kqueue.
|
||||
|
||||
mdig и ip2net полностью работоспособны в BSD. В них нет ничего системо-зависимого.
|
||||
|
||||
FreeBSD
|
||||
-------
|
||||
|
||||
divert сокеты требуют специального модуля ядра ipdivert.
|
||||
Поместите следующие строки в /boot/loader.conf (создать, если отсутствует) :
|
||||
-----------
|
||||
ipdivert_load="YES"
|
||||
net.inet.ip.fw.default_to_accept=1
|
||||
-----------
|
||||
В /etc/rc.conf :
|
||||
-----------
|
||||
firewall_enable="YES"
|
||||
firewall_script="/etc/rc.firewall.my"
|
||||
-----------
|
||||
/etc/rc.firewall.my :
|
||||
-----------
|
||||
ipfw -q -f flush
|
||||
-----------
|
||||
В /etc/rc.firewall.my можно дописывать правила ipfw, чтобы они восстанавливались после перезагрузки.
|
||||
Оттуда же можно запускать и демоны zapret, добавив в параметры "--daemon". Например так :
|
||||
-----------
|
||||
pkill ^dvtws$
|
||||
/opt/zapret/nfq/dvtws --port=989 --daemon --dpi-desync=split2
|
||||
-----------
|
||||
Для перезапуска фаервола и демонов достаточно будет сделать : /etc/rc.d/ipfw restart
|
||||
|
||||
|
||||
Краткая инструкция по запуску tpws в прозрачном режиме.
|
||||
Предполагается, что интерфейс LAN называется em1, WAN - em0.
|
||||
|
||||
Для всего трафика :
|
||||
ipfw delete 100
|
||||
ipfw add 100 fwd 127.0.0.1,988 tcp from me to any 80,443 proto ip4 xmit em0 not uid daemon
|
||||
ipfw add 100 fwd ::1,988 tcp from me to any 80,443 proto ip6 xmit em0 not uid daemon
|
||||
ipfw add 100 fwd 127.0.0.1,988 tcp from any to any 80,443 proto ip4 recv em1
|
||||
ipfw add 100 fwd ::1,988 tcp from any to any 80,443 proto ip6 recv em1
|
||||
/opt/zapret/tpws/tpws --port=988 --user=daemon --bind-addr=::1 --bind-addr=127.0.0.1
|
||||
|
||||
Для трафика только на таблицу zapret, за исключением таблицы nozapret :
|
||||
ipfw delete 100
|
||||
ipfw add 100 allow tcp from me to table\(nozapret\) 80,443
|
||||
ipfw add 100 fwd 127.0.0.1,988 tcp from me to table\(zapret\) 80,443 proto ip4 xmit em0 not uid daemon
|
||||
ipfw add 100 fwd ::1,988 tcp from me to table\(zapret\) 80,443 proto ip6 xmit em0 not uid daemon
|
||||
ipfw add 100 allow tcp from any to table\(nozapret\) 80,443 recv em1
|
||||
ipfw add 100 fwd 127.0.0.1,988 tcp from any to any 80,443 proto ip4 recv em1
|
||||
ipfw add 100 fwd ::1,988 tcp from any to any 80,443 proto ip6 recv em1
|
||||
/opt/zapret/tpws/tpws --port=988 --user=daemon --bind-addr=::1 --bind-addr=127.0.0.1
|
||||
|
||||
Таблицы zapret, nozapret, ipban создаются скриптами из ipset по аналогии с Linux.
|
||||
Обновление скриптов можно забить в cron под root :
|
||||
crontab -e
|
||||
Создать строчку "0 12 */2 * * /opt/zapret/ipset/get_config.sh"
|
||||
|
||||
При использовании ipfw tpws не требует повышенных привилегий для реализации прозрачного режима.
|
||||
Однако, без рута невозможен бинд на порты <1024 и смена UID/GID. Без смены UID будет рекурсия,
|
||||
поэтому правила ipfw нужно создавать с учетом UID, под которым работает tpws.
|
||||
Переадресация на порты >=1024 может создать угрозу перехвата трафика непривилегированным
|
||||
процессом, если вдруг tpws не запущен.
|
||||
|
||||
|
||||
Краткая инструкция по запуску dvtws.
|
||||
|
||||
Для всего трафика :
|
||||
ipfw delete 100
|
||||
ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted xmit em0
|
||||
# required for autottl mode only
|
||||
ipfw add 100 divert 989 tcp from any 80,443 to any tcpflags syn,ack in not diverted recv em0
|
||||
/opt/zapret/nfq/dvtws --port=989 --dpi-desync=split2
|
||||
|
||||
Для трафика только на таблицу zapret, за исключением таблицы nozapret :
|
||||
ipfw delete 100
|
||||
ipfw add 100 allow tcp from me to table\(nozapret\) 80,443
|
||||
ipfw add 100 divert 989 tcp from any to table\(zapret\) 80,443 out not diverted not sockarg xmit em0
|
||||
# required for autottl mode only
|
||||
ipfw add 100 divert 989 tcp from table\(zapret\) 80,443 to any tcpflags syn,ack in not diverted not sockarg recv em0
|
||||
/opt/zapret/nfq/dvtws --port=989 --dpi-desync=split2
|
||||
|
||||
|
||||
PF в FreeBSD:
|
||||
Настройка аналогична OpenBSD, но есть важные нюансы.
|
||||
1) В FreeBSD поддержка PF в tpws отключена по умолчанию. Чтобы ее включить, нужно использовать параметр --enable-pf.
|
||||
2) Нельзя сделать ipv6 rdr на ::1. Нужно делать на link-local адрес входящего интерфейса.
|
||||
Смотрите через ifconfig адрес fe80:... и добавляете в правило
|
||||
3) Синтаксис pf.conf немного отличается. Более новая версия PF.
|
||||
4) Лимит на количество элементов таблиц задается так : sysctl net.pf.request_maxcount=2000000
|
||||
5) divert-to сломан. Он работает, но не работает механизм предотвращения зацикливаний.
|
||||
Кто-то уже написал патч, но в 14-RELEASE проблема все еще есть.
|
||||
Следовательно, на данный момент работа dvtws через pf невозможна.
|
||||
|
||||
/etc/pf.conf
|
||||
-----------
|
||||
rdr pass on em1 inet6 proto tcp to port {80,443} -> fe80::31c:29ff:dee2:1c4d port 988
|
||||
rdr pass on em1 inet proto tcp to port {80,443} -> 127.0.0.1 port 988
|
||||
-----------
|
||||
/opt/zapret/tpws/tpws --port=988 --enable-pf --bind-addr=127.0.0.1 --bind-iface6=em1 --bind-linklocal=force
|
||||
|
||||
В PF непонятно как делать rdr-to с той же системы, где работает proxy. Вариант с route-to у меня не заработал.
|
||||
|
||||
|
||||
pfsense
|
||||
-------
|
||||
|
||||
pfsense основано на FreeBSD.
|
||||
pfsense использует фаервол pf, а он имеет проблемы с divert.
|
||||
К счастью, модули ipfw и ipdivert присутствуют в поставке последних версий pfsense.
|
||||
Их можно подгрузить через kldload.
|
||||
В некоторых более старых версиях pfsense требуется изменить порядок фаерволов через sysctl, сделав ipfw первым.
|
||||
В более новых эти параметры sysctl отсутствуют, но система работает как надо и без них.
|
||||
В некоторых случаях фаервол pf может ограничивать возможности dvtws, в частности в области фрагментации ip.
|
||||
Присутствуют по умолчанию правила scrub для реассемблинга фрагментов.
|
||||
Бинарики из binaries/freebsd-x64 собраны под FreeBSD 11. Они должны работать и на последующих версиях FreeBSD,
|
||||
включая pfsense. Можно пользоваться install_bin.sh.
|
||||
|
||||
Пример скрипта автозапуска лежит в init.d/pfsense. Его следует поместить в /usr/local/etc/rc.d и отредактировать
|
||||
на предмет правил ipfw и запуска демонов. Есть встроенный редактор edit как более приемлемая альтернатива vi.
|
||||
Поскольку git отсутствует, копировать файлы удобнее всего через ssh. curl присутствует по умолчанию.
|
||||
Можно скопировать zip с файлами zapret и распаковать в /opt, как это делается на других системах.
|
||||
Тогда dvtws нужно запускать как /opt/zapret/nfq/dvtws. Либо скопировать только dvtws в /usr/local/sbin.
|
||||
Как вам больше нравится.
|
||||
ipset скрипты работают, крон есть. Можно сделать автообновление листов.
|
||||
|
||||
Если вас напрягает бедность имеющегося репозитория, можно включить репозиторий от FreeBSD, который по умолчанию выключен.
|
||||
Поменяйте no на yes в /usr/local/etc/pkg/repos/FreeBSD.conf
|
||||
Можно установить весь привычный soft, включая git, чтобы напрямую скачивать zapret с github.
|
||||
|
||||
/usr/local/etc/rc.d/zapret.sh (chmod 755)
|
||||
-----------
|
||||
#!/bin/sh
|
||||
|
||||
kldload ipfw
|
||||
kldload ipdivert
|
||||
|
||||
# for older pfsense versions. newer do not have these sysctls
|
||||
sysctl net.inet.ip.pfil.outbound=ipfw,pf
|
||||
sysctl net.inet.ip.pfil.inbound=ipfw,pf
|
||||
sysctl net.inet6.ip6.pfil.outbound=ipfw,pf
|
||||
sysctl net.inet6.ip6.pfil.inbound=ipfw,pf
|
||||
|
||||
ipfw delete 100
|
||||
ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted xmit em0
|
||||
pkill ^dvtws$
|
||||
dvtws --daemon --port 989 --dpi-desync=split2
|
||||
|
||||
# required for newer pfsense versions (2.6.0 tested) to return ipfw to functional state
|
||||
pfctl -d ; pfctl -e
|
||||
-----------
|
||||
|
||||
Что касается tpws, то видимо имеется некоторый конфликт двух фаерволов, и правила fwd в ipfw не работают.
|
||||
Работает перенаправление средствами pf как описано в разделе по FreeBSD.
|
||||
В pf можно изменять правила только целыми блоками - якорями (anchors). Нельзя просто так добавить или удалить что-то.
|
||||
Но чтобы какой-то anchor был обработан, на него должна быть ссылка из основного набора правил.
|
||||
Его трогать нельзя, иначе порушится весь фаервол.
|
||||
Поэтому придется править код скриптов pfsense. Поправьте /etc/inc/filter.inc следующим образом :
|
||||
-----------
|
||||
.................
|
||||
/* MOD */
|
||||
$natrules .= "# ZAPRET redirection\n";
|
||||
$natrules .= "rdr-anchor \"zapret\"\n";
|
||||
|
||||
$natrules .= "# TFTP proxy\n";
|
||||
$natrules .= "rdr-anchor \"tftp-proxy/*\"\n";
|
||||
.................
|
||||
-----------
|
||||
|
||||
Напишите файл с содержимым anchor-а (например, /etc/zapret.anchor):
|
||||
-----------
|
||||
rdr pass on em1 inet proto tcp to port {80,443} -> 127.0.0.1 port 988
|
||||
rdr pass on em1 inet6 proto tcp to port {80,443} -> fe80::20c:29ff:5ae3:4821 port 988
|
||||
-----------
|
||||
fe80::20c:29ff:5ae3:4821 замените на ваш link local адрес LAN интерфейса, либо уберите строчку, если ipv6 не нужен.
|
||||
|
||||
Добавьте в автозапуск /usr/local/etc/rc.d/zapret.sh :
|
||||
-----------
|
||||
pfctl -a zapret -f /etc/zapret.anchor
|
||||
pkill ^tpws$
|
||||
tpws --daemon --port=988 --enable-pf --bind-addr=127.0.0.1 --bind-iface6=em1 --bind-linklocal=force --split-http-req=method --split-pos=2
|
||||
-----------
|
||||
|
||||
После перезагрузки проверьте, что правила создались :
|
||||
-----------
|
||||
[root@pfSense /]# pfctl -s nat
|
||||
no nat proto carp all
|
||||
nat-anchor "natearly/*" all
|
||||
nat-anchor "natrules/*" all
|
||||
...................
|
||||
no rdr proto carp all
|
||||
rdr-anchor "zapret" all
|
||||
rdr-anchor "tftp-proxy/*" all
|
||||
rdr-anchor "miniupnpd" all
|
||||
[root@pfSense /]# pfctl -s nat -a zapret
|
||||
rdr pass on em1 inet proto tcp from any to any port = http -> 127.0.0.1 port 988
|
||||
rdr pass on em1 inet proto tcp from any to any port = https -> 127.0.0.1 port 988
|
||||
rdr pass on em1 inet6 proto tcp from any to any port = http -> fe80::20c:29ff:5ae3:4821 port 988
|
||||
rdr pass on em1 inet6 proto tcp from any to any port = https -> fe80::20c:29ff:5ae3:4821 port 988
|
||||
-----------
|
||||
|
||||
Так же есть более элегантный способ запуска tpws через @reboot в cron и правило перенаправления в UI.
|
||||
Это позволит не редактировать код pfsense.
|
||||
|
||||
|
||||
OpenBSD
|
||||
-------
|
||||
|
||||
В tpws бинд по умолчанию только на ipv6. для бинда на ipv4 указать "--bind-addr=0.0.0.0"
|
||||
Используйте --bind-addr=0.0.0.0 --bind-addr=:: для достижения того же результата, как в других ОС по умолчанию.
|
||||
(лучше все же так не делать, а сажать на определенные внутренние адреса или интерфейсы)
|
||||
|
||||
tpws для проходящего трафика :
|
||||
|
||||
/etc/pf.conf
|
||||
------------
|
||||
pass in quick on em1 inet proto tcp to port {80,443} rdr-to 127.0.0.1 port 988
|
||||
pass in quick on em1 inet6 proto tcp to port {80,443} rdr-to ::1 port 988
|
||||
------------
|
||||
pfctl -f /etc/pf.conf
|
||||
tpws --port=988 --user=daemon --bind-addr=::1 --bind-addr=127.0.0.1
|
||||
|
||||
В PF непонятно как делать rdr-to с той же системы, где работает proxy. Вариант с route-to у меня не заработал.
|
||||
Поддержка rdr-to реализована через /dev/pf, поэтому прозрачный режим требует root.
|
||||
|
||||
dvtws для всего трафика :
|
||||
|
||||
/etc/pf.conf
|
||||
------------
|
||||
pass in quick on em0 proto tcp from port {80,443} flags SA/SA divert-packet port 989 no state
|
||||
pass in quick on em0 proto tcp from port {80,443} no state
|
||||
pass out quick on em0 proto tcp to port {80,443} divert-packet port 989 no state
|
||||
------------
|
||||
pfctl -f /etc/pf.conf
|
||||
./dvtws --port=989 --dpi-desync=split2
|
||||
|
||||
dvtws для трафика только на таблицу zapret, за исключением таблицы nozapret :
|
||||
|
||||
/etc/pf.conf
|
||||
------------
|
||||
set limit table-entries 2000000
|
||||
table <zapret> file "/opt/zapret/ipset/zapret-ip.txt"
|
||||
table <zapret-user> file "/opt/zapret/ipset/zapret-ip-user.txt"
|
||||
table <nozapret> file "/opt/zapret/ipset/zapret-ip-exclude.txt"
|
||||
pass out quick on em0 inet proto tcp to <nozapret> port {80,443}
|
||||
pass in quick on em0 inet proto tcp from <zapret> port {80,443} flags SA/SA divert-packet port 989 no state
|
||||
pass in quick on em0 inet proto tcp from <zapret> port {80,443} no state
|
||||
pass out quick on em0 inet proto tcp to <zapret> port {80,443} divert-packet port 989 no state
|
||||
pass in quick on em0 inet proto tcp from <zapret-user> port {80,443} flags SA/SA divert-packet port 989 no state
|
||||
pass in quick on em0 inet proto tcp from <zapret-user> port {80,443} no state
|
||||
pass out quick on em0 inet proto tcp to <zapret-user> port {80,443} divert-packet port 989 no state
|
||||
table <zapret6> file "/opt/zapret/ipset/zapret-ip6.txt"
|
||||
table <zapret6-user> file "/opt/zapret/ipset/zapret-ip-user6.txt"
|
||||
table <nozapret6> file "/opt/zapret/ipset/zapret-ip-exclude6.txt"
|
||||
pass out quick on em0 inet6 proto tcp to <nozapret6> port {80,443}
|
||||
pass in quick on em0 inet6 proto tcp from <zapret6> port {80,443} flags SA/SA divert-packet port 989 no state
|
||||
pass in quick on em0 inet6 proto tcp from <zapret6> port {80,443} no state
|
||||
pass out quick on em0 inet6 proto tcp to <zapret6> port {80,443} divert-packet port 989 no state
|
||||
pass in quick on em0 inet6 proto tcp from <zapret6-user> port {80,443} flags SA/SA divert-packet port 989 no state
|
||||
pass in quick on em0 inet6 proto tcp from <zapret6-user> port {80,443} no state
|
||||
pass out quick on em0 inet6 proto tcp to <zapret6-user> port {80,443} divert-packet port 989 no state
|
||||
------------
|
||||
pfctl -f /etc/pf.conf
|
||||
./dvtws --port=989 --dpi-desync=split2
|
||||
|
||||
divert-packet автоматически вносит обратное правило для перенаправления.
|
||||
Трюк с no state и in правилом позволяет обойти эту проблему, чтобы напрасно не гнать массивный трафик через dvtws.
|
||||
|
||||
В OpenBSD dvtws все фейки отсылает через divert socket, поскольку эта возможность через raw sockets заблокирована.
|
||||
Видимо pf автоматически предотвращает повторный заворот diverted фреймов, поэтому проблемы зацикливания нет.
|
||||
|
||||
OpenBSD принудительно пересчитывает tcp checksum после divert, поэтому скорее всего
|
||||
dpi-desync-fooling=badsum у вас не заработает. При использовании этого параметра
|
||||
dvtws предупредит о возможной проблеме.
|
||||
|
||||
Скрипты из ipset не перезагружают таблицы в PF по умолчанию.
|
||||
Чтобы они это делали, добавьте параметр в /opt/zapret/config :
|
||||
LISTS_RELOAD="pfctl -f /etc/pf.conf"
|
||||
Более новые версии pfctl понимают команду перезагрузить только таблицы : pfctl -Tl -f /etc/pf.conf
|
||||
Но это не относится к OpenBSD 6.8. В новых FreeBSD есть.
|
||||
Не забудьте выключить сжатие gzip :
|
||||
GZIP_LISTS=0
|
||||
Если в вашей конфигурации какого-то файла листа нет, то его необходимо исключить из правил PF.
|
||||
Если вдруг листа нет, и он задан в pf.conf, будет ошибка перезагрузки фаервола.
|
||||
После настройки обновление листов можно поместить в cron :
|
||||
crontab -e
|
||||
дописать строчку : 0 12 */2 * * /opt/zapret/ipset/get_config.sh
|
||||
|
||||
|
||||
MacOS
|
||||
-----
|
||||
|
||||
Иначально ядро этой ОС "darwin" основывалось на BSD, потому в ней много похожего на другие версии BSD.
|
||||
Однако, как и в других массовых коммерческих проектах, приоритеты смещаются в сторону от оригинала.
|
||||
Яблочники что хотят, то и творят.
|
||||
Раньше был ipfw, потом его убрали, заменили на PF.
|
||||
Есть сомнения, что divert сокеты в ядре остались. Попытка создать divert socket не выдает ошибок,
|
||||
но полученный сокет ведет себя точно так же, как raw, со всеми его унаследованными косяками + еще яблочно специфическими.
|
||||
В PF divert-packet не работает. Простой grep бинарика pfctl показывает, что там нет слова "divert",
|
||||
а в других версиях BSD оно есть. dvtws собирается, но совершенно бесполезен.
|
||||
|
||||
tpws удалось адаптировать, он работоспособен. Получение адреса назначения для прозрачного прокси в PF (DIOCNATLOOK)
|
||||
убрали из заголовков в новых SDK, сделав фактически недокументированным.
|
||||
В tpws перенесены некоторые определения из более старых версий яблочных SDK. С ними удалось завести прозрачный режим.
|
||||
Однако, что будет в следующих версиях угадать сложно. Гарантий нет.
|
||||
Еще одной особенностью PF в MacOS является проверка на рута в момент обращения к /dev/pf, чего нет в остальных BSD.
|
||||
tpws по умолчанию сбрасывает рутовые привилегии. Необходимо явно указать параметр --user=root.
|
||||
В остальном PF себя ведет похоже на FreeBSD. Синтаксис pf.conf тот же.
|
||||
|
||||
На MacOS работает редирект как с проходящего трафика, так и с локальной системы через route-to.
|
||||
Поскольку tpws вынужден работать под root, для исключения рекурсии приходится пускать исходящий от root трафик напрямую.
|
||||
Отсюда имеем недостаток : обход DPI для рута работать не будет.
|
||||
|
||||
Если вы пользуетесь MaсOS в качестве ipv6 роутера, то нужно будет решить вопрос с регулярно изменяемым link-local адресом.
|
||||
С некоторых версий MacOS использует по умолчанию постоянные "secured" ipv6 адреса вместо генерируемых на базе MAC адреса.
|
||||
Все замечательно, но есть одна проблема. Постоянными остаются только global scope адреса.
|
||||
Link locals периодически меняются. Смена завязана на системное время. Перезагрузки адрес не меняют,
|
||||
Но если перевести время на день вперед и перезагрузиться - link local станет другим. (по крайней мере в vmware это так)
|
||||
Информации по вопросу крайне мало, но тянет на баг. Не должен меняться link local. Скрывать link local не имеет смысла,
|
||||
а динамический link local нельзя использовать в качестве адреса шлюза.
|
||||
Проще всего отказаться от "secured" адресов.
|
||||
Поместите строчку "net.inet6.send.opmode=0" в /etc/sysctl.conf. Затем перезагрузите систему.
|
||||
Все равно для исходящих соединений будут использоваться temporary адреса, как и в других системах.
|
||||
Или вам идея не по вкусу, можно прописать дополнительный статический ipv6 из диапазона fc00::/7 -
|
||||
выберите любой с длиной префикса 128. Это можно сделать в системных настройках, создав дополнительный адаптер на базе
|
||||
того же сетевого интерфейса, отключить в нем ipv4 и вписать статический ipv6. Он добавится к автоматически настраеваемым.
|
||||
|
||||
Настройка tpws на macos в прозрачном режиме только для исходящих запросов :
|
||||
|
||||
/etc/pf.conf
|
||||
------------
|
||||
rdr pass on lo0 inet proto tcp from !127.0.0.0/8 to any port {80,443} -> 127.0.0.1 port 988
|
||||
rdr pass on lo0 inet6 proto tcp from !::1 to any port {80,443} -> fe80::1 port 988
|
||||
pass out route-to (lo0 127.0.0.1) inet proto tcp from any to any port {80,443} user { >root }
|
||||
pass out route-to (lo0 fe80::1) inet6 proto tcp from any to any port {80,443} user { >root }
|
||||
------------
|
||||
pfctl -ef /etc/pf.conf
|
||||
/opt/zapret/tpws/tpws --user=root --port=988 --bind-addr=127.0.0.1 --bind-iface6=lo0 --bind-linklocal=force
|
||||
|
||||
|
||||
Настройка tpws на macos роутере в прозрачном режиме, где en1 - LAN.
|
||||
|
||||
ifconfig en1 | grep fe80
|
||||
inet6 fe80::bbbb:bbbb:bbbb:bbbb%en1 prefixlen 64 scopeid 0x8
|
||||
/etc/pf.conf
|
||||
------------
|
||||
rdr pass on en1 inet proto tcp from any to any port {80,443} -> 127.0.0.1 port 988
|
||||
rdr pass on en1 inet6 proto tcp from any to any port {80,443} -> fe80::bbbb:bbbb:bbbb:bbbb port 988
|
||||
rdr pass on lo0 inet proto tcp from !127.0.0.0/8 to any port {80,443} -> 127.0.0.1 port 988
|
||||
rdr pass on lo0 inet6 proto tcp from !::1 to any port {80,443} -> fe80::1 port 988
|
||||
pass out route-to (lo0 127.0.0.1) inet proto tcp from any to any port {80,443} user { >root }
|
||||
pass out route-to (lo0 fe80::1) inet6 proto tcp from any to any port {80,443} user { >root }
|
||||
------------
|
||||
pfctl -ef /etc/pf.conf
|
||||
/opt/zapret/tpws/tpws --user=root --port=988 --bind-addr=127.0.0.1 --bind-iface6=lo0 --bind-linklocal=force --bind-iface6=en1 --bind-linklocal=force
|
||||
|
||||
|
||||
Сборка : make -C /opt/zapret mac
|
||||
|
||||
Скрипты получения листов ipset/*.sh работают.
|
||||
Если будете пользоваться ipset/get_combined.sh, нужно установить gnu grep через brew.
|
||||
Имеющийся очень старый и безумно медленный с оцией -f.
|
||||
|
||||
|
||||
MacOS простая установка
|
||||
-----------------------
|
||||
|
||||
В MacOS поддерживается install_easy.sh
|
||||
|
||||
В комплекте идут бинарики, собраные под 64-bit с опцией -mmacosx-version-min=10.8.
|
||||
Они должны работать на всех поддерживаемых версиях macos.
|
||||
Если вдруг не работают - можно собрать свои. Developer tools ставятся автоматом при запуске make.
|
||||
|
||||
!! Internet sharing средствами системы НЕ ПОДДЕРЖИВАЕТСЯ !!
|
||||
Поддерживается только роутер, настроенный своими силами через PF.
|
||||
Если вы вдруг включили шаринг, а потом выключили, то доступ к сайтам может пропасть совсем.
|
||||
Лечение : pfctl -f /etc/pf.conf
|
||||
Если вам нужен шаринг интернета, лучше отказаться от прозрачного режима и использовать socks.
|
||||
|
||||
Для автостарта используется launchd (/Library/LaunchDaemons/zapret.plist)
|
||||
Управляющий скрипт : /opt/zapret/init.d/macos/zapret
|
||||
Следующие команды работают с tpws и фаерволом одновременно (если INIT_APPLY_FW=1 в config)
|
||||
/opt/zapret/init.d/macos/zapret start
|
||||
/opt/zapret/init.d/macos/zapret stop
|
||||
/opt/zapret/init.d/macos/zapret restart
|
||||
Работа только с tpws :
|
||||
/opt/zapret/init.d/macos/zapret start-daemons
|
||||
/opt/zapret/init.d/macos/zapret stop-daemons
|
||||
/opt/zapret/init.d/macos/zapret restart-daemons
|
||||
Работа только с PF :
|
||||
/opt/zapret/init.d/macos/zapret start-fw
|
||||
/opt/zapret/init.d/macos/zapret stop-fw
|
||||
/opt/zapret/init.d/macos/zapret restart-fw
|
||||
Перезагрузка всех IP таблиц из файлов :
|
||||
/opt/zapret/init.d/macos/zapret reload-fw-tables
|
||||
|
||||
Инсталятор настраивает LISTS_RELOAD в config, так что скрипты ipset/*.sh автоматически перезагружают IP таблицы в PF.
|
||||
Автоматически создается cron job на ipset/get_config.sh, по аналогии с openwrt.
|
||||
|
||||
При start-fw скрипт автоматически модицифирует /etc/pf.conf, вставляя туда anchors "zapret".
|
||||
Модификация расчитана на pf.conf, в котором сохранены дефолтные anchors от apple.
|
||||
Если у вас измененный pf.conf и модификация не удалась, об этом будет предупреждение. Не игнорируйте его.
|
||||
В этом случае вам нужно вставить в свой pf.conf (в соответствии с порядком типов правил) :
|
||||
rdr-anchor "zapret"
|
||||
anchor "zapret"
|
||||
При деинсталяции через uninstall_easy.sh модификации pf.conf убираются.
|
||||
|
||||
start-fw создает 3 файла anchors в /etc/pf.anchors : zapret,zapret-v4,zapret-v6.
|
||||
Последние 2 подключаются из anchor "zapret".
|
||||
Таблицы nozapret,nozapret6 принадлежат anchor "zapret".
|
||||
Таблицы zapret,zapret-user - в anchor "zapret-v4".
|
||||
Таблицы zapret6,zapret6-user - в anchor "zapret-v6".
|
||||
Если какая-то версия протокола отключена - соответствующий anchor пустой и не упоминается в anchor "zapret".
|
||||
Таблицы и правила создаются только на те листы, которые фактически есть в директории ipset.
|
||||
|
||||
|
||||
MacOS вариант custom
|
||||
--------------------
|
||||
|
||||
Так же как и в других системах, поддерживаемых в простом инсталяторе, можно создавать свои custom скрипты.
|
||||
Расположение : /opt/zapret/init.d/macos/custom
|
||||
|
||||
zapret_custom_daemons() получает в $1 "0" или "1". "0" - stop, "1" - start
|
||||
custom firewall отличается от linux варианта.
|
||||
Вместо заполнения iptables вам нужно сгенерировать правила для zapret-v4 и zapret-v6 anchors и выдать их в stdout.
|
||||
Это делается в функциях zapret_custom_firewall_v4() и zapret_custom_firewall_v6().
|
||||
Определения таблиц заполняются основным скриптом - вам это делать не нужно.
|
||||
Можно ссылаться на таблицы zapret и zapret-user в v4, zapret6 и zapret6-user.
|
||||
|
||||
Cм. пример в файле custom-tpws
|
@@ -70,7 +70,7 @@ pass in quick on em0 proto tcp from port {80,443} flags SA/SA divert-packet por
|
||||
pass in quick on em0 proto tcp from port {80,443} no state
|
||||
pass out quick on em0 proto tcp to port {80,443} divert-packet port 989 no state
|
||||
pfctl -f /etc/pf.conf
|
||||
./dvtws --port=989 --dpi-desync=split2
|
||||
./dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
|
||||
|
||||
; dvtws with table limitations : to zapret,zapret6 but not to nozapret,nozapret6
|
||||
; reload tables : pfctl -f /etc/pf.conf
|
||||
|
@@ -355,3 +355,48 @@ 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
|
||||
|
||||
v68:
|
||||
|
||||
docs : move russian version to markdown
|
||||
nfqws,tpws: use alternate $ sign for $<config_file>
|
||||
repo: binaries removed from repo. git actions binaries build in releases.
|
||||
uninstall_easy.sh: offer to remove dependencies in openwrt
|
||||
install_easy.sh: allow to download lists in autohostlist filter mode
|
||||
|
||||
v69:
|
||||
|
||||
nfqws, tpws: multisplit/multidisorder support.
|
||||
nfqws: name change split->fakedsplit, disorder->fakeddisorder. compat : old names are synonyms
|
||||
nfqws: --dpi-desync-split-http-req, --dpi-desync-split-tls deprecated. compat : these parameters add split point to multisplit.
|
||||
nfqws: --dpi-desync=split2|disorder2 deprecated. compat: they are now synonyms for multisplit/multidisorder
|
||||
nfqws: cancel seqovl if MTU is exceeded (linux only). cancel seqovl for disorder if seqovl>=first_part_size.
|
||||
nfqws: fixed splits in multiple TLS segments.
|
||||
tpws: --split-http-req,--split-tls deprecated. compat : these parameters add split point to multisplit.
|
||||
tpws: --tlsrec now takes pos markers. compat : old names are converted to pos markers
|
||||
tpws: --tlsrec-pos deprecated. compat : sets absolute pos marker
|
||||
nfqws,tpws: chown autohostlist, autohostlist debug log and debug log files after options parse
|
||||
nfqws,tpws: set EXEDIR env var to use in @config (won't work for stadalone winws without /bin/sh)
|
||||
dvtws: set random/increasing ip_id value in generated packets
|
||||
mdig: fixed parsing of DNS reply in windows (stdin is opened as text, not binary)
|
||||
tpws: support compile for android NDK api level >= 21 (Android 5.0)
|
||||
tpws: --fix-seg segmentation fixer
|
||||
repo: build for android NDK api level 21 (Android 5.0)
|
||||
install_easy: support for APK package manager in openwrt
|
||||
blockcheck: removed ignore CA question
|
||||
blockcheck: removed IGNORE_CA, CURL_VERBOSE
|
||||
blockcheck: added CURL_OPT
|
||||
blockcheck: new strategies support
|
||||
blockcheck: test sequence rework
|
||||
blockcheck: view all working strategies in summary
|
||||
|
||||
v69.1:
|
||||
|
||||
init.d: keenetic udp fix custom
|
||||
tpws: fixed incorrect hostlist checks
|
||||
|
||||
v69.2:
|
||||
|
||||
nfqws,tpws: --skip
|
||||
nfqws: --methodeol
|
||||
init.d: do not use pgrep in sysv for busybox compat
|
||||
|
@@ -1,42 +1,57 @@
|
||||
How to compile native programs for use in openwrt
|
||||
-------------------------------------------------
|
||||
|
||||
1) <fetch correct version of openwrt>
|
||||
1) Install required packages to the host system :
|
||||
|
||||
cd ~
|
||||
debian,ubuntu : apt install build-essential patch libncurses-dev python3-distutils unzip gawk wget git
|
||||
fedora: dnf install make patch gcc g++ ncurses-devel git perl
|
||||
|
||||
<chaos calmer>
|
||||
git clone git://git.openwrt.org/15.05/openwrt.git
|
||||
<barrier breaker>
|
||||
git clone git://git.openwrt.org/14.07/openwrt.git
|
||||
<trunk>
|
||||
git clone git://git.openwrt.org/openwrt.git
|
||||
Other packages may be required on your distribution. Look for the errors.
|
||||
|
||||
cd openwrt
|
||||
2) Download latest SDK for your target platform from https://downloads.openwrt.org
|
||||
|
||||
2) ./scripts/feeds update -a
|
||||
./scripts/feeds install -a
|
||||
examples :
|
||||
|
||||
3) #add zapret packages to build root
|
||||
#copy package descriptions
|
||||
copy compile/openwrt/* to ~/openwrt
|
||||
#copy source code of tpws
|
||||
copy tpws to ~/openwrt/package/zapret/tpws
|
||||
#copy source code of nfq
|
||||
copy nfq to ~/openwrt/package/zapret/nfq
|
||||
#copy source code of ip2net
|
||||
copy ip2net to ~/openwrt/package/zapret/ip2net
|
||||
curl -o - https://downloads.openwrt.org/releases/23.05.5/targets/x86/64/openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64.tar.xz | tar -Jxvf -
|
||||
cd openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64
|
||||
|
||||
4) make menuconfig
|
||||
#select your target architecture
|
||||
#select packages Network/Zapret/* as "M"
|
||||
curl -o - https://downloads.openwrt.org/snapshots/targets/x86/64/openwrt-sdk-x86-64_gcc-13.3.0_musl.Linux-x86_64.tar.zst | tar --zstd -xvf -
|
||||
cd openwrt-sdk-x86-64_gcc-13.3.0_musl.Linux-x86_64
|
||||
|
||||
5) make toolchain/compile
|
||||
3) Install required libs
|
||||
|
||||
6) make package/tpws/compile
|
||||
make package/nfqws/compile
|
||||
make package/ip2net/compile
|
||||
make package/mdig/compile
|
||||
./scripts/feeds update base packages
|
||||
./scripts/feeds install libnetfilter-queue zlib libcap
|
||||
|
||||
7) find bin -name tpws*.ipk
|
||||
#take your tpws*.ipk , nfqws*.ipk , ip2net*.ipk, mdig*.ipk from there
|
||||
4) Prepare openwrt package definitions
|
||||
|
||||
cp -R /opt/zapret/docs/compile/openwrt/. .
|
||||
cp -R /opt/zapret/tpws package/zapret/tpws
|
||||
cp -R /opt/zapret/nfq package/zapret/nfqws
|
||||
cp -R /opt/zapret/mdig package/zapret/mdig
|
||||
cp -R /opt/zapret/ip2net package/zapret/ip2net
|
||||
rm -f package/zapret/tpws/tpws/tpws package/zapret/nfqws/nfq/nfqws package/zapret/mdig/mdig/mdig package/zapret/ip2net/ip2net/ip2net
|
||||
|
||||
5) Prepare .config
|
||||
|
||||
make defconfig
|
||||
|
||||
If you only need bins without packages comment 'CONFIG_AUTOREMOVE=y' line in .config
|
||||
|
||||
6) Compile
|
||||
|
||||
dynamic build : make package/{tpws,nfqws,mdig,ip2net}/compile
|
||||
static build : make CFLAGS=-static package/{tpws,nfqws,mdig,ip2net}/compile
|
||||
|
||||
7) Get result
|
||||
|
||||
executables only : build_dir/target/<progname>
|
||||
ipk or apk packages : bin/packages/*/base
|
||||
|
||||
8) Installating to openwrt to use with zapret
|
||||
|
||||
zapret with or without binaries should be already installed in /opt/zapret.
|
||||
Install ipk's or apk's with all compiled progs using opkg or apk.
|
||||
Bins are placed to /opt/zapret/binaries/my.
|
||||
Or copy binaries there manually and set chmod 755 to them.
|
||||
Run install_bin.sh or install_easy.sh. They will use bins in 'my' folder.
|
||||
|
16
docs/compile/build_howto_unix.txt
Normal file
16
docs/compile/build_howto_unix.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
debian,ubuntu :
|
||||
|
||||
apt install make gcc zlib1g-dev libcap-dev libnetfilter-queue-dev
|
||||
make -C /opt/zapret
|
||||
|
||||
FreeBSD :
|
||||
|
||||
make -C /opt/zapret
|
||||
|
||||
OpenBSD :
|
||||
|
||||
make -C /opt/zapret bsd
|
||||
|
||||
MacOS :
|
||||
|
||||
make -C /opt/zapret mac
|
29
docs/compile/build_howto_windows.txt
Normal file
29
docs/compile/build_howto_windows.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
Windows x64
|
||||
|
||||
1) Download latest cygwin for windows 7
|
||||
|
||||
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
|
||||
|
||||
2) During setup install packages : make gcc-core zlib-devel
|
||||
|
||||
3) Run Cygwin.bat
|
||||
|
||||
4) cd to %ZAPRET_BASE%/nfq
|
||||
|
||||
cd C:/Users/user/Downloads/zapret/nfq
|
||||
|
||||
5) Compile
|
||||
|
||||
make cygwin64
|
||||
|
||||
use winws.exe
|
||||
|
||||
6) Take windivert.dll and windivert64.sys here : https://reqrypt.org/download
|
||||
Choose version 2.2.2 for Windows 10 and 2.2.0 for Windows 7.
|
||||
|
||||
7) Copy cygwin1.dll, winws.exe, windivert.dll and windivert64.sys to one folder.
|
||||
|
||||
8) Run winws.exe from cmd.exe running as administrator.
|
||||
winws will not run from cygwin shell with cygwin1.dll copy in it's folder.
|
||||
winws will not run without cygwin1.dll outside of cygwin shell.
|
@@ -24,8 +24,8 @@ define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/ip2net/install
|
||||
$(INSTALL_DIR) $(1)/opt/zapret/ip2net
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/ip2net $(1)/opt/zapret/ip2net
|
||||
$(INSTALL_DIR) $(1)/opt/zapret/binaries/my
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/ip2net $(1)/opt/zapret/binaries/my
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,ip2net))
|
||||
|
@@ -24,8 +24,8 @@ define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/mdig/install
|
||||
$(INSTALL_DIR) $(1)/opt/zapret/mdig
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mdig $(1)/opt/zapret/mdig
|
||||
$(INSTALL_DIR) $(1)/opt/zapret/binaries/my
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mdig $(1)/opt/zapret/binaries/my
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,mdig))
|
||||
|
@@ -25,8 +25,8 @@ define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/nfqws/install
|
||||
$(INSTALL_DIR) $(1)/opt/zapret/nfq
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/nfqws $(1)/opt/zapret/nfq
|
||||
$(INSTALL_DIR) $(1)/opt/zapret/binaries/my
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/nfqws $(1)/opt/zapret/binaries/my
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,nfqws))
|
||||
|
@@ -25,8 +25,8 @@ define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/tpws/install
|
||||
$(INSTALL_DIR) $(1)/opt/zapret/tpws
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/tpws $(1)/opt/zapret/tpws
|
||||
$(INSTALL_DIR) $(1)/opt/zapret/binaries/my
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/tpws $(1)/opt/zapret/binaries/my
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,tpws))
|
||||
|
@@ -12,7 +12,7 @@ iptables -t mangle -I POSTROUTING -p udp --dport 443 -m mark ! --mark 0x40000000
|
||||
# auto hostlist with avoiding wrong ACK numbers in RST,ACK packets sent by russian DPI
|
||||
sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1
|
||||
iptables -t mangle -I POSTROUTING -p tcp -m multiport --dports 80,443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:12 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
iptables -t mangle -I PREROUTING -p tcp -m multiport --sports 80,443 -m connbytes --connbytes-dir=reply --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
iptables -t mangle -I PREROUTING -p tcp -m multiport --sports 80,443 -m connbytes --connbytes-dir=reply --connbytes-mode=packets --connbytes 1:3 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
|
||||
|
||||
For TPROXY :
|
||||
|
@@ -1,282 +0,0 @@
|
||||
Пример ручной установки на debian-подобную систему
|
||||
--------------------------------------------------
|
||||
|
||||
На debian основано большое количество дистрибутивов linux, включая ubuntu.
|
||||
Здесь рассматриваются прежде всего Debian 8+ и Ubuntu 16+.
|
||||
Но с большой вероятностью может сработать и на производных от них.
|
||||
Главное условие - наличие systemd, apt и нескольких стандартных пакетов в репозитории.
|
||||
|
||||
Установить пакеты :
|
||||
apt-get update
|
||||
apt-get install ipset curl dnsutils git
|
||||
|
||||
Если хотите использовать nftables, то нужен пакет nftables, а ipset не обязателен.
|
||||
|
||||
Скопировать директорию zapret в /opt или скачать через git :
|
||||
cd /opt
|
||||
git clone --depth 1 https://github.com/bol-van/zapret
|
||||
|
||||
Запустить автоинсталятор бинариков. Он сам определит рабочую архитектуру и настроит все бинарики.
|
||||
/opt/zapret/install_bin.sh
|
||||
АЛЬТЕРНАТИВА : make -C /opt/zapret. Получите динамические бинарики под вашу ось.
|
||||
Для сборки требуются dev пакеты : zlib1g-dev libcap-dev libnetfilter-queue-dev
|
||||
|
||||
Создать конфиг по умолчанию :
|
||||
cp /opt/zapret/config.default /opt/zapret/config
|
||||
|
||||
Настроить параметры согласно разделу "Выбор параметров".
|
||||
|
||||
Создать user листы по умолчанию :
|
||||
cp /opt/zapret/ipset/zapret-hosts-user-exclude.txt.default /opt/zapret/ipset/zapret-hosts-user-exclude.txt
|
||||
echo nonexistent.domain >/opt/zapret/ipset/zapret-hosts-user.txt
|
||||
touch /opt/zapret/ipset/zapret-hosts-user-ipban.txt
|
||||
|
||||
Создать ссылку на service unit в systemd :
|
||||
ln -fs /opt/zapret/init.d/systemd/zapret.service /lib/systemd/system
|
||||
|
||||
Удалить старые листы, если они были созданы ранее :
|
||||
/opt/zapret/ipset/clear_lists.sh
|
||||
По желанию прописать в /opt/zapret/ipset/zapret-hosts-user.txt свои домены.
|
||||
Выполнить скрипт обновления листа :
|
||||
/opt/zapret/ipset/get_config.sh
|
||||
Настроить таймер systemd для обновления листа :
|
||||
ln -fs /opt/zapret/init.d/systemd/zapret-list-update.service /lib/systemd/system
|
||||
ln -fs /opt/zapret/init.d/systemd/zapret-list-update.timer /lib/systemd/system
|
||||
|
||||
Принять изменения в systemd :
|
||||
systemctl daemon-reload
|
||||
|
||||
Включить автозапуск службы :
|
||||
systemctl enable zapret
|
||||
|
||||
Включить таймер обновления листа :
|
||||
systemctl enable zapret-list-update.timer
|
||||
|
||||
Запустить службу :
|
||||
systemctl start zapret
|
||||
|
||||
Шпаргалка по управлению службой и таймером :
|
||||
|
||||
enable auto start : systemctl enable zapret
|
||||
disable auto start : systemctl disable zapret
|
||||
start : systemctl start zapret
|
||||
stop : systemctl stop zapret
|
||||
status, output messages : systemctl status zapret
|
||||
timer info : systemctl list-timer
|
||||
delete service : systemctl disable zapret ; rm /lib/systemd/system/zapret.service
|
||||
delete timer : systemctl disable zapret-list-update.timer ; rm /lib/systemd/system/zapret-list-update.*
|
||||
|
||||
Centos 7+, Fedora
|
||||
-----------------
|
||||
|
||||
Centos с 7 версии и более-менее новые федоры построены на systemd.
|
||||
В качестве пакетного менеджера используется yum.
|
||||
|
||||
Установить пакеты :
|
||||
yum install -y curl ipset dnsutils git
|
||||
|
||||
Далее все аналогично debian.
|
||||
|
||||
OpenSUSE
|
||||
--------
|
||||
|
||||
Новые OpenSUSE основаны на systemd и менеджере пакетов zypper.
|
||||
|
||||
Установить пакеты :
|
||||
zypper --non-interactive install curl ipset
|
||||
|
||||
Далее все аналогично debian, кроме расположения systemd.
|
||||
В opensuse он находится не в /lib/systemd, а в /usr/lib/systemd.
|
||||
Правильные команды будут :
|
||||
|
||||
ln -fs /opt/zapret/init.d/systemd/zapret.service /usr/lib/systemd/system
|
||||
ln -fs /opt/zapret/init.d/systemd/zapret-list-update.service /usr/lib/systemd/system
|
||||
ln -fs /opt/zapret/init.d/systemd/zapret-list-update.timer /usr/lib/systemd/system
|
||||
|
||||
Arch linux
|
||||
----------
|
||||
|
||||
Построен на базе systemd.
|
||||
|
||||
Установить пакеты :
|
||||
pacman -Syy
|
||||
pacman --noconfirm -S ipset curl
|
||||
|
||||
Далее все аналогично debian.
|
||||
|
||||
Gentoo
|
||||
------
|
||||
|
||||
Эта система использует OpenRC - улучшенную версию sysvinit.
|
||||
Установка пакетов производится командой : emerge <package_name>
|
||||
Пакеты собираются из исходников.
|
||||
|
||||
Требуются все те же ipset, curl, git для скачивания с github.
|
||||
git и curl по умолчанию могут присутствовать, ipset отсутствует.
|
||||
|
||||
emerge ipset
|
||||
|
||||
Настроить параметры согласно разделу "Выбор параметров".
|
||||
|
||||
Запустить автоинсталятор бинариков. Он сам определит рабочую архитектуру и настроит все бинарики.
|
||||
/opt/zapret/install_bin.sh
|
||||
АЛЬТЕРНАТИВА : make -C /opt/zapret. Получите динамические бинарики под вашу ось.
|
||||
|
||||
Удалить старые листы, если они были созданы ранее :
|
||||
/opt/zapret/ipset/clear_lists.sh
|
||||
По желанию прописать в /opt/zapret/ipset/zapret-hosts-user.txt свои домены.
|
||||
Выполнить скрипт обновления листа :
|
||||
/opt/zapret/ipset/get_config.sh
|
||||
Зашедулить обновление листа :
|
||||
crontab -e
|
||||
Создать строчку "0 12 */2 * * /opt/zapret/ipset/get_config.sh"
|
||||
|
||||
Подключить init скрипт :
|
||||
|
||||
ln -fs /opt/zapret/init.d/openrc/zapret /etc/init.d
|
||||
rc-update add zapret
|
||||
|
||||
Запустить службу :
|
||||
|
||||
rc-service zapret start
|
||||
|
||||
Шпаргалка по управлению службой :
|
||||
|
||||
enable auto start : rc-update add zapret
|
||||
disable auto start : rc-update del zapret
|
||||
start : rc-service zapret start
|
||||
stop : rc-service zapret stop
|
||||
|
||||
|
||||
|
||||
Ручная установка на openwrt/LEDE 15.xx-21.xx
|
||||
--------------------------------------------
|
||||
|
||||
!!! Данная инструкция написана для систем, основанных на iptables+firewall3
|
||||
!!! В новых версиях openwrt переходит на nftables+firewall4, инструкция неприменима. Пользуйтесь install_easy.sh
|
||||
|
||||
Установить дополнительные пакеты :
|
||||
opkg update
|
||||
opkg install iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt iptables-mod-conntrack-extra ipset curl
|
||||
(ipv6) opkg install ip6tables-mod-nat
|
||||
(опционально) opkg install gzip
|
||||
(опционально) opkg install coreutils-sort
|
||||
|
||||
ЭКОНОМИЯ МЕСТА :
|
||||
|
||||
gzip от busybox в разы медленней полноценного варианта. gzip используется скриптами получения листов.
|
||||
sort от busybox медленней полноценного варианта и жрет намного больше памяти. sort используется скриптами получения листов.
|
||||
iptables-mod-nfqueue можно выкинуть, если не будем пользоваться nfqws
|
||||
curl можно выкинуть, если для получения ip листа будет использоваться только get_user.sh
|
||||
|
||||
Самая главная трудность - скомпилировать программы на C. Это можно сделать на linux x64 при помощи SDK, который
|
||||
можно скачать с официального сайта openwrt или LEDE. Но процесс кросс компиляции - это всегда сложности.
|
||||
Недостаточно запустить make как на традиционной linux системе.
|
||||
Поэтому в binaries имеются готовые статические бинарики для всех самых распространенных архитектур.
|
||||
Статическая сборка означает, что бинарик не зависит от типа libc (glibc, uclibc или musl) и наличия установленных so.
|
||||
Его можно использовать сразу. Лишь бы подходил тип CPU. У ARM и MIPS есть несколько версий.
|
||||
Скорее всего найдется рабочий вариант. Если нет - вам придется собирать самостоятельно.
|
||||
Для всех поддерживаемых архитектур бинарики запакованы upx. На текущий момент все, кроме mips64.
|
||||
|
||||
Скопировать директорию "zapret" в /opt на роутер.
|
||||
|
||||
Если места достаточно, самый простой способ :
|
||||
opkg update
|
||||
opkg install git-http
|
||||
mkdir /opt
|
||||
cd /opt
|
||||
git clone --depth 1 https://github.com/bol-van/zapret
|
||||
|
||||
Если места немного :
|
||||
opkg update
|
||||
opkg install openssh-sftp-server unzip
|
||||
ifconfig br-lan
|
||||
Скачать на комп с github zip архив кнопкой "Clone or download"->Download ZIP
|
||||
Скопировать средствами sftp zip архив на роутер в /tmp.
|
||||
mkdir /opt
|
||||
cd /opt
|
||||
unzip /tmp/zapret-master.zip
|
||||
mv zapret-master zapret
|
||||
rm /tmp/zapret-master.zip
|
||||
|
||||
Если места совсем мало :
|
||||
На linux системе скачать и распаковать zapret. Оставить необходимый минимум файлов.
|
||||
Запаковать в архив zapret.tar.gz.
|
||||
nc -l -p 1111 <zapret.tar.gz
|
||||
На роутере
|
||||
cd /tmp
|
||||
nc <linux_system_ip> 1111 >zapret.tar.gz
|
||||
|
||||
Не стоит работать с распакованной версией zapret на windows. Потеряются ссылки и chmod.
|
||||
|
||||
Запустить автоинсталятор бинариков. Он сам определит рабочую архитектуру и настроит все бинарики.
|
||||
/opt/zapret/install_bin.sh
|
||||
|
||||
Создать ссылку на скрипт запуска :
|
||||
ln -fs /opt/zapret/init.d/openwrt/zapret /etc/init.d
|
||||
Создать ссылку на скрипт события поднятия интерфейса :
|
||||
ln -fs /opt/zapret/init.d/openwrt/90-zapret /etc/hotplug.d/iface
|
||||
|
||||
Создать конфиг по умолчанию :
|
||||
cp /opt/zapret/config.default /opt/zapret/config
|
||||
|
||||
Настроить параметры согласно разделу "Выбор параметров".
|
||||
|
||||
Создать user листы по умолчанию :
|
||||
cp /opt/zapret/ipset/zapret-hosts-user-exclude.txt.default /opt/zapret/ipset/zapret-hosts-user-exclude.txt
|
||||
echo nonexistent.domain >/opt/zapret/ipset/zapret-hosts-user.txt
|
||||
touch /opt/zapret/ipset/zapret-hosts-user-ipban.txt
|
||||
|
||||
Удалить старые листы, если они были созданы ранее :
|
||||
/opt/zapret/ipset/clear_lists.sh
|
||||
По желанию прописать в /opt/zapret/ipset/zapret-hosts-user.txt свои домены.
|
||||
Выполнить скрипт обновления листа :
|
||||
/opt/zapret/ipset/get_config.sh
|
||||
Зашедулить обновление листа :
|
||||
crontab -e
|
||||
Создать строчку "0 12 */2 * * /opt/zapret/ipset/get_config.sh"
|
||||
|
||||
Включить автозапуск службы и запустить ее :
|
||||
/etc/init.d/zapret enable
|
||||
/etc/init.d/zapret start
|
||||
ПРИМЕЧАНИЕ : на этапе старта системы интерфейсы еще не подняты. в некоторых случаях невозможно правильно
|
||||
сформировать параметры запуска демонов, не зная имя физического интерфейса LAN.
|
||||
Cкрипт из /etc/hotplug.d/iface перезапустит демоны по событию поднятия LAN.
|
||||
|
||||
Создать ссылку на firewall include :
|
||||
ln -fs /opt/zapret/init.d/openwrt/firewall.zapret /etc/firewall.zapret
|
||||
Проверить была ли создана ранее запись о firewall include :
|
||||
uci show firewall | grep firewall.zapret
|
||||
Если firewall.zapret нет, значит добавить :
|
||||
uci add firewall include
|
||||
uci set firewall.@include[-1].path="/etc/firewall.zapret"
|
||||
uci set firewall.@include[-1].reload="1"
|
||||
uci commit firewall
|
||||
Проверить не включен ли flow offload :
|
||||
uci show firewall.@defaults[0]
|
||||
Если flow_offloading=1 или flow_offloading_hw=1 ,
|
||||
uci set firewall.@defaults[0].flow_offloading=0
|
||||
uci set firewall.@defaults[0].flow_offloading_hw=0
|
||||
uci commit firewall
|
||||
Перезапустить фаервол :
|
||||
fw3 restart
|
||||
|
||||
Посмотреть через iptables -nL, ip6tables -nL или через luci вкладку "firewall" появились ли нужные правила.
|
||||
|
||||
ЭКОНОМИЯ МЕСТА : если его мало, то можно оставить в директории zapret лишь подкаталоги
|
||||
ipset, common, файл config, init.d/openwrt.
|
||||
Далее нужно создать подкаталоги с реально используемыми бинариками (ip2net, mdig, tpws, nfq)
|
||||
и скопировать туда из binaries рабочие executables.
|
||||
|
||||
ЕСЛИ ВСЕ ПЛОХО С МЕСТОМ : откажитесь от работы со списком РКН. используйте только get_user.sh
|
||||
|
||||
ЕСЛИ СОВСЕМ ВСЕ УЖАСНО С МЕСТОМ : берете tpws и делаете все своими руками. поднятие iptables, автостарт бинарика.
|
||||
С некоторых версий скрипты запуска zapret без ipset не работают (он требуется для ip exclude)
|
||||
|
||||
СОВЕТ : Покупайте только роутеры с USB. В USB можно воткнуть флэшку и вынести на нее корневую файловую систему
|
||||
или использовать ее в качестве оверлея. Не надо мучать себя, запихивая незапихиваемое в 8 мб встроенной флэшки.
|
||||
Для комфортной работы с zapret нужен роутер с 16 Mb встроенной памяти или USB разъемом и 128+ Mb RAM.
|
||||
На 64 Mb без swap будут проблемы с листами РКН. Если у вас только 64 Mb, и вы хотите листы РКН, подключите swap.
|
||||
32 Mb для современных версий openwrt - конфигурация на грани живучести. Возможны хаотические падения процессов в oom.
|
||||
Работа с листами РКН невозможна в принципе.
|
||||
|
@@ -19,8 +19,8 @@ For dpi desync attack :
|
||||
nft delete table inet ztest
|
||||
nft create table inet ztest
|
||||
nft add chain inet ztest post "{type filter hook postrouting priority mangle;}"
|
||||
nft add rule inet ztest post meta mark and 0x40000000 == 0 tcp dport "{80,443}" ct original packets 1-12 queue num 200 bypass
|
||||
nft add rule inet ztest post meta mark and 0x40000000 == 0 udp dport 443 ct original packets 1-12 queue num 200 bypass
|
||||
nft add rule inet ztest post meta mark and 0x40000000 == 0 tcp dport "{80,443}" ct original packets 1-6 queue num 200 bypass
|
||||
nft add rule inet ztest post meta mark and 0x40000000 == 0 udp dport 443 ct original packets 1-6 queue num 200 bypass
|
||||
|
||||
# auto hostlist with avoiding wrong ACK numbers in RST,ACK packets sent by russian DPI
|
||||
sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1
|
||||
|
258
docs/quick_start.md
Normal file
258
docs/quick_start.md
Normal file
@@ -0,0 +1,258 @@
|
||||
# Быстрая настройка Linux/OpenWrt
|
||||
|
||||
> [!CAUTION]
|
||||
> Не пишите в issue вопросы типа "как скопировать файл", "как скачать", "как
|
||||
> запустить", ... То есть все , что касается базовых навыков обращения с ОС
|
||||
> linux. Эти вопросы будут закрывать сразу. Если у вас подобные вопросы
|
||||
> возникают, рекомендую не использовать данный софт или искать помощь где-то в
|
||||
> другом месте. То же самое могу сказать тем, кто хочет нажать 1 кнопку, чтобы
|
||||
> все заработало, и совсем не хочет читать и изучать. Увы, такое не подвезли и
|
||||
> не подвезут. Ищите другие более простые методы обхода. Этот метод **не для
|
||||
> рядового пользователя**.
|
||||
|
||||
|
||||
## Вступление
|
||||
Специально для тех, кто хочет побыстрее начать, но не хочет слишком углубляться
|
||||
в простыню [readme.md](readme.md).
|
||||
|
||||
Обход DPI является хакерской методикой. Под этим словом понимается метод,
|
||||
которому сопротивляется окружающая среда, которому автоматически не
|
||||
гарантирована работоспособность в любых условиях и на любых ресурсах, требуется
|
||||
настройка под специфические условия у вашего провайдера. Условия могут меняться
|
||||
со временем, и методика может начинать или переставать работать, может
|
||||
потребоваться повторный анализ ситуации. Могут обнаруживаться отдельные
|
||||
ресурсы, которые заблокированы иначе, и которые не работают или перестали
|
||||
работать. Могут и сломаться отдельные не заблокированные ресурсы. Поэтому очень
|
||||
желательно иметь знания в области сетей, чтобы иметь возможность
|
||||
проанализировать техническую ситуацию. Не будет лишним иметь обходные каналы
|
||||
проксирования трафика на случай, если обход DPI не помогает.
|
||||
|
||||
Вариант, когда вы нашли стратегию где-то в интернете и пытаетесь ее приспособить к своему случаю - заведомо проблемный.
|
||||
Нет универсальной таблетки. Везде ситуация разная. В сети гуляют написанные кем-то откровенные глупости, которые тиражируются массово ничего не понимающей публикой.
|
||||
Такие варианты чаще всего работают нестабильно, только на части ресурсов, только на части провайдеров, не работают вообще или ломают другие ресурсы. В худших случаях еще и устраивают флуд в сети.
|
||||
Если даже вариант когда-то и работал неплохо, завтра он может перестать, а в сети останется устаревшая информация.
|
||||
|
||||
Будем считать, что у вас есть система на базе традиционного **linux** или
|
||||
**openwrt**. Если у вас традиционный linux - задача обойти блокировки только на
|
||||
этой системе, если openwrt - обойти блокировки для подключенных устройств. Это
|
||||
наиболее распространенный случай.
|
||||
|
||||
|
||||
## Настройка
|
||||
> [!TIP]
|
||||
> Чтобы процедура установки сработала в штатном режиме на openwrt, нужно
|
||||
> рассчитывать на свободное место около 1-2 Mb для установки самого zapret и
|
||||
> необходимых дополнительных пакетов. Если места мало и нет возможности его
|
||||
> увеличить за счет `extroot`, возможно придется отказаться от варианта простой
|
||||
> установки и прикручивать в ручном режиме без имеющихся скриптов запуска.
|
||||
> Можно использовать [облегченный `tpws` вариант](../init.d/openwrt-minimal),
|
||||
> либо попробовать засунуть требуемые zapret дополнительные пакеты в сжатый
|
||||
> образ `squashfs` с помощью `image builder` и перешить этим вариантом роутер.
|
||||
|
||||
1. Скачайте последний [tar.gz релиз](https://github.com/bol-van/zapret/releases) в /tmp, распакуйте его, затем удалите архив.
|
||||
|
||||
2. Убедитесь, что у вас отключены все средства обхода блокировок, в том числе и
|
||||
сам zapret. Гарантированно уберет zapret скрипт `uninstall_easy.sh`.
|
||||
|
||||
3. Если вы работаете в виртуальной машине, необходимо использовать соединение с
|
||||
сетью в режиме bridge. NAT **не** подходит.
|
||||
|
||||
4. Выполните однократные действия по установке требуемых пакетов в ОС и
|
||||
настройке исполняемых файлов правильной архитектуры:
|
||||
```sh
|
||||
$ install_bin.sh
|
||||
$ install_prereq.sh
|
||||
```
|
||||
|
||||
> Вас могут спросить о типе фаервола (iptables/nftables) и использовании
|
||||
> ipv6. Это нужно для установки правильных пакетов в ОС, чтобы не
|
||||
> устанавливать лишнее.
|
||||
|
||||
5. Запустите `blockcheck.sh`. Скрипт вначале проверяет DNS. Если выводятся
|
||||
сообщения о подмене адресов, то нужно будет решить проблему с DNS.
|
||||
`blockcheck.sh` перейдет в этом случае на DoH и будет пытаться получить и
|
||||
использовать реальные IP адреса. Но если вы не настроите решение этой
|
||||
проблемы, обход будет работать только для тех программ или ОС, которые сами
|
||||
реализуют механизмы SecureDNS. Для других программ обход работать не будет.
|
||||
|
||||
> Решение проблемы DNS выходит за рамки проекта. Обычно она решается либо
|
||||
> заменой DNS серверов от провайдера на публичные (`1.1.1.1`, `8.8.8.8`),
|
||||
> либо в случае перехвата провайдером обращений к сторонним серверам - через
|
||||
> специальные средства шифрования DNS запросов, такие как `dnscrypt`, `DoT`,
|
||||
> `DoH`.
|
||||
>
|
||||
> Еще один эффективный вариант - использовать ресолвер от yandex
|
||||
> (`77.88.8.88`) на нестандартном порту `1253`. Многие провайдеры не
|
||||
> анализируют обращения к DNS на нестандартных портах.
|
||||
>
|
||||
> Проверить работает ли этот вариант можно так:
|
||||
> ```sh
|
||||
> $ dig -p 53 @77.88.8.88 rutracker.org dig -p 1253 @77.88.8.88 rutracker.org
|
||||
> ```
|
||||
>
|
||||
> Если DNS действительно подменяется, и ответ на эти 2 команды разный,
|
||||
> значит метод вероятно работает.
|
||||
>
|
||||
> В openwrt DNS на нестандартном порту можно прописать в `/etc/config/dhcp`
|
||||
> таким способом :
|
||||
>
|
||||
> ```
|
||||
> config dnsmasq
|
||||
> <...>
|
||||
> list server '77.88.8.88#1253'
|
||||
> ```
|
||||
>
|
||||
> Если настройки IP и DNS получаются автоматически от провайдера, в
|
||||
> `/etc/config/network` найдите секцию интерфейса `wan` и сделайте так:
|
||||
>
|
||||
> ```
|
||||
> config interface 'wan'
|
||||
> <...>
|
||||
> option peerdns '0'
|
||||
> ```
|
||||
>
|
||||
> ```sh
|
||||
> $ /etc/init.d/network restart
|
||||
> $ /etc/init.d/dnsmasq restart
|
||||
> ```
|
||||
>
|
||||
> Если это не подходит, можно перенаправлять обращения на UDP и TCP порты
|
||||
> `53` вашего DNS сервера на `77.88.8.88:1253` средствами
|
||||
> `iptables`/`nftables`. В `/etc/resolv.conf` нельзя прописать DNS на
|
||||
> нестандартном порту.
|
||||
|
||||
6. `blockcheck.sh` позволяет выявить рабочую стратегию обхода блокировок. По
|
||||
результатам скрипта нужно понять какой вариант будете использовать : `nfqws`
|
||||
или `tpws` и запомнить найденные стратегии для дальнейшего применения.
|
||||
|
||||
Следует понимать, что скрипт проверяет доступность только конкретного
|
||||
домена, который вы вводите в начале. Вероятно, все остальные домены
|
||||
блокированы подобным образом, **но не факт**. В большинстве случаев можно
|
||||
объединить несколько стратегий в одну универсальную, и это **крайне
|
||||
желательно**. Необходимо понимать как работают стратегии. zapret **не может
|
||||
пробить блокировку по IP адресу**. Для проверки нескольких доменов вводите
|
||||
их через пробел.
|
||||
|
||||
> Сейчас блокираторы ставят на магистральных каналах. В сложных случаях у
|
||||
> вас может быть несколько маршрутов с различной длиной по ХОПам, с DPI на
|
||||
> разных хопах. Приходится преодолевать целый зоопарк DPI, которые еще и
|
||||
> включаются в работу хаотичным образом или образом, зависящим от
|
||||
> направления (IP сервера). скрипт не всегда может выдать вам в итогах
|
||||
> оптимальную стратегию, которую надо просто переписать в настройки. В
|
||||
> некоторых случаях надо реально думать что происходит, анализируя результат
|
||||
> на разных стратегиях. Если вы применяете большой TTL, чтобы достать до
|
||||
> магистрала, то не лишним будет добавить дополнительный ограничитель
|
||||
> `--dpi-desync-fooling`, чтобы не сломать сайты на более коротких
|
||||
> дистанциях. `md5sig` наиболее совместим, но работает **только** на linux
|
||||
> серверах. `badseq` может работать только на https и не работать на http.
|
||||
> Чтобы выяснить какие дополнительные ограничители работают, смотрите
|
||||
> результат теста аналогичных стратегий без TTL с каждым из этих
|
||||
> ограничителей.
|
||||
>
|
||||
> При использовании `autottl` следует протестировать как можно больше разных
|
||||
> доменов. Эта техника может на одних провайдерах работать стабильно, на
|
||||
> других потребуется выяснить при каких параметрах она стабильна, на третьих
|
||||
> полный хаос, и проще отказаться.
|
||||
>
|
||||
> Далее, имея понимание что работает на http, https, quic нужно
|
||||
> сконструировать параметры запуска `tpws` и/или `nfqws` с использованием
|
||||
> мультистратегии. Как работают мультистратегии описано в readme.txt.
|
||||
>
|
||||
> Если кратко, то обычно параметры конструируются так:
|
||||
> ```sh
|
||||
> "--filter-udp=443 'параметры для quic' <HOSTLIST_NOAUTO> --new
|
||||
> --filter-tcp=80,443 'обьединенные параметры для http и https' <HOSTLIST>"
|
||||
> ```
|
||||
>
|
||||
> Или так:
|
||||
> ```sh
|
||||
> "--filter-udp=443 'параметры для quic' <HOSTLIST_NOAUTO> --new
|
||||
> --filter-tcp=80 'параметры для http' <HOSTLIST> --new
|
||||
> --filter-tcp=443 'параметры для https' <HOSTLIST>"
|
||||
> ```
|
||||
>
|
||||
> `<HOSTLIST>` и `<HOSTLIST_NOAUTO>` так и пишутся. Их не надо на что-то
|
||||
> заменять. Это сделают скрипты запуска, если вы выбрали режим фильтрации по
|
||||
> хостлистам, и уберут в противном случае. Если для какого-то протокола надо
|
||||
> дурить все без стандартного хостлиста - просто уберите оттуда `<HOSTLIST>`
|
||||
> и `<HOSTLIST_NOAUTO>`. Можно писать свои параметры `--hostlist` и
|
||||
> `--hostlist-exclude` для дополнительных хостлистов или в профилях
|
||||
> специализаций под конкретный ресурс. В последнем случае стандартный
|
||||
> хостлист там не нужен. Следует избегать указания собственных параметров
|
||||
> `--hostlist` на листы из директории ipset. Эта логика включена в
|
||||
> `<HOSTLIST>` и `<HOSTLIST_NOAUTO>`. Отличие `<HOSTLIST_NOAUTO>` в том, что
|
||||
> стандартный автолист по этому профилю используется как обычный, то есть
|
||||
> без автоматического добавления доменов. Однако, добавления в других
|
||||
> профилях автоматически отражаются во всех остальных.
|
||||
>
|
||||
> Если стратегии отличаются по версии ip протокола, и вы не можете их
|
||||
> обьединить, фильтр пишется так:
|
||||
> ```sh
|
||||
> "--filter-l3=ipv4 --filter-udp=443 lпараметры для 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_NOAUTO> --new
|
||||
> --filter-l3=ipv6 --filter-tcp=80 'параметры для http ipv6' <HOSTLIST> --new
|
||||
> --filter-l3=ipv6 --filter-tcp=443 'параметры для https ipv6' <HOSTLIST>"
|
||||
> ```
|
||||
>
|
||||
> Но здесь совсем "копи-пастный" вариант. Чем больше вы объедините стратегий и
|
||||
> сократите их общее количество, тем будет лучше.
|
||||
>
|
||||
> Если вам не нужно дурение отдельных протоколов, лучше всего будет их
|
||||
> убрать из системы перехвата трафика через параметры `TPWS_PORTS`,
|
||||
> `NFQWS_PORTS_TCP`, `NFQWS_PORTS_UDP` и убрать соответствующие им профили
|
||||
> мультистратегии.
|
||||
>
|
||||
> | Протокол | Порт | Примечание |
|
||||
> |---|---|---|
|
||||
> | `tcp` | `80` | `http` соединение |
|
||||
> | `tcp` | `443` | `https` соединение |
|
||||
> | `udp` | `443` | `quic` соединение |
|
||||
>
|
||||
> Если используются методы нулевой фазы десинхронизации (`--mss`,
|
||||
> `--wssize`, `--dpi-desync=syndata`) и режим фильтрации `hostlist`, то все
|
||||
> параметры, относящиеся к этим методам, следует помещать в отдельные
|
||||
> профили мультистратегии, которые получат управление до определения имени
|
||||
> хоста. Необходимо понимать алгоритм работы мультистратегий. Самым надежным
|
||||
> вариантом будет дублирование этих параметров на 2 профиля. Какой-нибудь
|
||||
> сработает в зависимости от параметра `MODE_FILTER`.
|
||||
>
|
||||
> ```sh
|
||||
> "--filter-tcp=80 'параметры для http' <HOSTLIST> --new
|
||||
> --filter-tcp=443 'параметры для https' --wssize 1:6 <HOSTLIST> --new
|
||||
> --filter-tcp=443 --wssize 1:6"
|
||||
> ```
|
||||
>
|
||||
> В этом примере `wssize` будет применяться всегда к порту tcp `443` вне
|
||||
> зависимости от параметра `MODE_FILTER`. Хостлист будет игнорироваться,
|
||||
> если таковой имеется. К http применять `wssize` вредно и бессмысленно.
|
||||
|
||||
7. Запустите скрипт облегченной установки - `install_easy.sh` Выберите `nfqws`
|
||||
и/или `tpws`, затем согласитесь на редактирование параметров. Откроется
|
||||
редактор, куда впишите созданную на предыдущем этапе стратегию.
|
||||
|
||||
8. На все остальные вопросы `install_easy.sh` отвечайте согласно выводимой
|
||||
аннотации.
|
||||
|
||||
9. Удалите директорию из /tmp, откуда производилась установка.
|
||||
|
||||
## Полное удаление
|
||||
|
||||
1. Прогоните `/opt/zapret/uninstall_easy.sh`.
|
||||
2. Cогласитесь на удаление зависимостей в openwrt.
|
||||
3. Удалите каталог `/opt/zapret`.
|
||||
|
||||
## Итог
|
||||
Это минимальная инструкция, чтобы быстро сориентироваться с чего начать.
|
||||
Однако, это не гарантированное решение и в некоторых случаях вы не обойдетесь
|
||||
без знаний и основного "талмуда". Подробности и полное техническое описание
|
||||
расписаны в [README](readme.md).
|
||||
|
||||
Если ломаются отдельные **не заблокированные** ресурсы, следует вносить их в
|
||||
исключения, либо пользоваться ограничивающим `ipset` или хост листом. Лучше
|
||||
подбирать такие стратегии, которые вызывают минимальные поломки. Есть стратегии
|
||||
довольно безобидные, а есть сильно ломающие, которые подходят только для
|
||||
точечного пробития отдельных ресурсов, когда ничего лучше нет. Хорошая
|
||||
стратегия может сильно ломать из-за плохо подобранных ограничителей для фейков
|
||||
\- ttl, fooling.
|
@@ -1,179 +0,0 @@
|
||||
Специально для тех, кто хочет побыстрее начать, но не хочет слишком углубляться в простыню readme.txt.
|
||||
|
||||
Предупреждение : не пишите в issue вопросы типа "как скопировать файл", "как скачать", "как запустить", ...
|
||||
То есть все , что касается базовых навыков обращения с ОС linux. Эти вопросы буду закрывать сразу.
|
||||
Если у вас подобные вопросы возникают, рекомендую не использовать данный софт или искать помощь где-то в другом месте.
|
||||
То же самое могу сказать тем, кто хочет нажать 1 кнопку, чтобы все заработало, и совсем не хочет читать и изучать.
|
||||
Увы, такое не подвезли и не подвезут. Ищите другие более простые методы обхода. Этот метод не для рядового пользователя.
|
||||
|
||||
Обход DPI является хакерской методикой. Под этим словом понимается метод, которому сопротивляется окружающая среда,
|
||||
которому автоматически не гарантирована работоспособность в любых условиях и на любых ресурсах,
|
||||
требуется настройка под специфические условия у вашего провайдера. Условия могут меняться со временем,
|
||||
и методика может начинать или переставать работать, может потребоваться повторный анализ ситуации.
|
||||
Могут обнаруживаться отдельные ресурсы, которые заблокированы иначе, и которые не работают или перестали работать.
|
||||
Могут и сломаться отдельные незаблокированные ресурсы.
|
||||
Поэтому очень желательно иметь знания в области сетей, чтобы иметь возможность проанализировать техническую ситуацию.
|
||||
Не будет лишним иметь обходные каналы проксирования трафика на случай, если обход DPI не помогает.
|
||||
|
||||
Будем считать, что у вас есть система на базе традиционного linux или openwrt.
|
||||
Если у вас традиционный linux - задача обойти блокировки только на этой системе, если openwrt - обойти блокировки
|
||||
для подключенных устройств. Это наиболее распространенный случай.
|
||||
|
||||
1) Чтобы процедура установки сработала в штатном режиме на openwrt, нужно раcсчитывать на свободное место около 1-2 Mb
|
||||
для установки самого zapret и необходимых дополнительных пакетов.
|
||||
Если места мало и нет возможности его увеличить за счет extroot, возможно придется отказаться от варианта
|
||||
простой установки и прикручивать в ручном режиме без имеющихся скриптов запуска.
|
||||
Можно использовать облегченный tpws вариант из init.d/openwrt-minimal, либо попробовать засунуть требуемые zapret
|
||||
дополнительные пакеты в сжатый образ squashfs с помощью image builder и перешить этим вариантом роутер.
|
||||
|
||||
2) Скачайте zip архив проекта с github в /tmp, распакуйте его там,
|
||||
либо клонируйте проект через : git clone --depth 1 https://github.com/bol-van/zapret
|
||||
|
||||
3) Убедитесь, что у вас отключены все средства обхода блокировок, в том числе и сам zapret.
|
||||
Гарантированно уберет zapret скрипт uninstall_easy.sh.
|
||||
|
||||
4) Если вы работаете в виртуальной машине, необходимо использовать соединение с сетью в режиме bridge. nat не подходит
|
||||
|
||||
5) Выполните однократные действия по установке требуемых пакетов в ОС и настройке бинариков правильной архитектуры
|
||||
|
||||
install_bin.sh
|
||||
install_prereq.sh
|
||||
|
||||
Вас могут спросить о типе фаервола (iptables/nftables) и использовании ipv6. Это нужно для установки
|
||||
правильных пакетов в ОС, чтобы не устанавливать лишнее.
|
||||
|
||||
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.
|
||||
|
||||
Еще один эффективный вариант - использовать ресолвер от yandex 77.88.8.88 на нестандартном порту 1253.
|
||||
Многие провайдеры не анализируют обращения к DNS на нестандартных портах.
|
||||
|
||||
Проверить работает ли этот вариант можно так :
|
||||
|
||||
dig -p 53 @77.88.8.88 rutracker.org
|
||||
dig -p 1253 @77.88.8.88 rutracker.org
|
||||
|
||||
Если DNS действительно подменяется, и ответ на эти 2 команды разный, значит метод вероятно работает.
|
||||
|
||||
В openwrt DNS на нестандартном порту можно прописать в /etc/config/dhcp таким способом :
|
||||
|
||||
config dnsmasq
|
||||
.............
|
||||
list server '77.88.8.88#1253'
|
||||
|
||||
Если настройки IP и DNS получаются автоматически от провайдера, в /etc/config/network
|
||||
найдите секцию интерфейса 'wan' и сделайте так :
|
||||
|
||||
config interface 'wan'
|
||||
.............
|
||||
option peerdns '0'
|
||||
|
||||
/etc/init.d/network restart
|
||||
/etc/init.d/dnsmasq restart
|
||||
|
||||
Если это не подходит, можно перенаправлять обращения на udp и tcp порты 53 вашего DNS сервера на 77.88.8.88:1253 средствами
|
||||
iptables/nftables. В /etc/resolv.conf нельзя прописать DNS на нестандартном порту.
|
||||
|
||||
7) blockcheck позволяет выявить рабочую стратегию обхода блокировок
|
||||
По результатам blockcheck нужно понять какой вариант будете использовать : nfqws или tpws
|
||||
И запомнить найденные стратегии.
|
||||
|
||||
Следует понимать, что blockcheck проверяет доступность только конкретного домена, который вы вводите в начале.
|
||||
Вероятно, все остальные домены блокированы подобным образом, но не факт.
|
||||
В большинстве случаев можно обьединить несколько стратегий в одну универсальную, и это крайне желательно.
|
||||
Необходимо понимать как работают стратегии.
|
||||
zapret не может пробить блокировку по IP адресу. Для проверки нескольких доменов вводите их через пробел.
|
||||
|
||||
Сейчас блокираторы ставят на магистральных каналах. В сложных случаях у вас может быть несколько маршрутов
|
||||
с различной длиной по ХОПам, с DPI на разных хопах. Приходится преодолевать целый зоопарк DPI,
|
||||
которые еще и включаются в работу хаотичным образом или образом, зависящим от направления (IP сервера).
|
||||
blockcheck не всегда может выдать вам в итогах оптимальную стратегию, которую надо просто переписать в настройки.
|
||||
В некоторых случаях надо реально думать что происходит, анализируя результат на разных стратегиях.
|
||||
Если вы применяете большой TTL, чтобы достать до магистрала, то не лишним будет добавить дополнительный ограничитель
|
||||
--dpi-desync-fooling, чтобы не сломать сайты на более коротких дистанциях.
|
||||
md5sig наиболее совместим, но работает только на linux серверах.
|
||||
badseq может работать только на https и не работать на http.
|
||||
Чтобы выяснить какие дополнительные ограничители работают, смотрите результат теста аналогичных стратегий без TTL
|
||||
с каждым из этих ограничителей.
|
||||
|
||||
При использовании autottl следует протестировать как можно больше разных доменов. Эта техника
|
||||
может на одних провайдерах работать стабильно, на других потребуется выяснить при каких параметрах
|
||||
она стабильна, на третьих полный хаос, и проще отказаться.
|
||||
|
||||
Далее, имея понимание что работает на http, https, quic, нужно сконструировать параметры запуска tpws и/или nfqws
|
||||
с использованием мультистратегии. Как работают мультистратегии описано в readme.txt.
|
||||
|
||||
Если кратко, то обычно параметры конструируются так :
|
||||
"--filter-udp=443 'параметры для quic' <HOSTLIST_NOAUTO> --new
|
||||
--filter-tcp=80,443 'обьединенные параметры для http и https' <HOSTLIST>"
|
||||
|
||||
Или так :
|
||||
"--filter-udp=443 "параметры для quic" <HOSTLIST_NOAUTO> --new
|
||||
--filter-tcp=80 'параметры для http' <HOSTLIST> --new
|
||||
--filter-tcp=443 'параметры для https' <HOSTLIST>"
|
||||
|
||||
"<HOSTLIST>" и "<HOSTLIST_NOAUTO>" так и пишутся. Их не надо на что-то заменять. Это сделают скрипты запуска,
|
||||
если вы выбрали режим фильтрации по хостлистам, и уберут в противном случае.
|
||||
Если для какого-то протокола надо дурить все без стандартного хостлиста - просто уберите оттуда "<HOSTLIST>"
|
||||
и "<HOSTLIST_NOAUTO>".
|
||||
Можно писать свои параметры --hostlist и --hostlist-exclude для дополнительных хостлистов
|
||||
или в профилях специализаций под конкретный ресурс. В последнем случае стандартный хостлист там не нужен.
|
||||
Следует избегать указания собственных параметров --hostlist на листы из директории ipset.
|
||||
Эта логика включена в "<HOSTLIST>" и "<HOSTLIST_NOAUTO>".
|
||||
Отличие "<HOSTLIST_NOAUTO>" в том, что стандартный автолист по этому профилю используется как обычный,
|
||||
то есть без автоматического добавления доменов. Однако, добавления в других профилях автоматически
|
||||
отражаются во всех остальных.
|
||||
|
||||
Если стратегии отличаются по версии ip протокола, и вы не можете их обьединить, фильтр пишется так :
|
||||
"--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_NOAUTO> --new
|
||||
--filter-l3=ipv6 --filter-tcp=80 'параметры для http ipv6' <HOSTLIST> --new
|
||||
--filter-l3=ipv6 --filter-tcp=443 'параметры для https ipv6' <HOSTLIST>"
|
||||
|
||||
Но здесь совсем "копи-пастный" вариант.
|
||||
Чем больше вы обьедините стратегий и сократите их общее количество, тем будет лучше.
|
||||
|
||||
Если вам не нужно дурение отдельных протоколов, лучше всего будет их убрать из системы перехвата трафика через
|
||||
параметры TPWS_PORTS, NFQWS_PORTS_TCP, NFQWS_PORTS_UDP и убрать соответствующие им профили мультистратегии.
|
||||
tcp 80 - http, tcp 443 - https, udp 443 - quic.
|
||||
|
||||
Если используются методы нулевой фазы десинхронизации (--mss, --wssize, --dpi-desync=syndata) и режим фильтрации hostlist,
|
||||
то все параметры, относящиеся к этим методам, следует помещать в отдельные профили мульистратегии, которые получат
|
||||
управление до определения имени хоста. Необходимо понимать алгоритм работы мультистратегий.
|
||||
Самым надежным вариантом будет дублирование этих параметров на 2 профиля. Какой-нибудь сработает в зависимости
|
||||
от параметра MODE_FILTER.
|
||||
|
||||
"--filter-tcp=80 'параметры для http' <HOSTLIST> --new
|
||||
--filter-tcp=443 'параметры для https' --wssize 1:6 <HOSTLIST> --new
|
||||
--filter-tcp=443 --wssize 1:6"
|
||||
|
||||
В этом примере wssize будет применяться всегда к порту tcp 443 вне зависимости от параметра MODE_FILTER.
|
||||
Хостлист будет игнорироваться, если таковой имеется. К http применять wssize вредно и бессмысленно.
|
||||
|
||||
Никто не мешает использовать tpws для http, nfqws для https, либо комбинировать действие nfqws и tpws для одного протокола.
|
||||
В текущем варианте скриптов запуска это делается максимально гибко и независимо друг от друга.
|
||||
|
||||
8) Запустите install_easy.sh.
|
||||
Выберите nfqws и/или tpws, затем согласитесь на редактирование параметров.
|
||||
Откроется редактор, куда впишите созданную на предыдущем этапе стратегию.
|
||||
|
||||
9) На все остальные вопросы install_easy.sh отвечайте согласно выводимой аннонтации.
|
||||
|
||||
10) Если ломаются отдельные незаблокированные ресурсы, следует вносить их в исключения, либо пользоваться ограничивающим
|
||||
ipset или хост листом. Читайте основной талмуд readme.txt ради подробностей.
|
||||
Но еще лучше будет подбирать такие стратегии, которые ломают минимум.
|
||||
Есть стратегии довольно безобидные, а есть сильно ломающие, которые подходят только для точечного пробития отдельных ресурсов,
|
||||
когда ничего лучше нет. Хорошая стратегия может сильно ломать из-за плохо подобранных ограничителей для фейков - ttl, fooling.
|
||||
|
||||
Это минимальная инструкция, чтобы соориентироваться с чего начать. Однако, это - не панацея.
|
||||
В некоторых случаях вы не обойдетесь без знаний и основного "талмуда".
|
||||
Подробности и полное техническое описание расписаны в readme.txt
|
216
docs/quick_start_windows.md
Normal file
216
docs/quick_start_windows.md
Normal file
@@ -0,0 +1,216 @@
|
||||
# Быстрая настройка Windows
|
||||
|
||||
Специально для тех, кто хочет побыстрее начать, но не хочет слишком углубляться в простыню [readme.md](./readme.md).
|
||||
> [!CAUTION]
|
||||
> Как обычно, компьютерная грамотность ложится полностью на вас.
|
||||
> Вы должны уметь работать с консолью windows и иметь минимальные навыки обращения с командными файлами `bat`, `cmd`.
|
||||
> Если грамотность отсутствует и возникает куча _"как?"_ на базовых вещах, значит эта программа не для вас.
|
||||
> Разработчик не будет отвечать на вопросы из серии школы компьютерной грамотности.
|
||||
> Если вы все-таки хотите продолжать, задавайте вопросы в дискуссиях на github или на форумах.
|
||||
> Возможно, кто-то вам поможет. Но не надо писать issue на github. Они будут закрываться сразу.
|
||||
|
||||
## Немного разъяснений
|
||||
|
||||
Обход DPI является хакерской методикой. Под этим словом понимается метод, которому сопротивляется окружающая среда,
|
||||
которому автоматически не гарантирована работоспособность в любых условиях и на любых ресурсах,
|
||||
требуется настройка под специфические условия у вашего провайдера. Условия могут меняться со временем,
|
||||
и методика может начинать или переставать работать, может потребоваться повторный анализ ситуации.
|
||||
Могут обнаруживаться отдельные ресурсы, которые заблокированы иначе, и которые не работают или перестали работать.
|
||||
Могут и сломаться отдельные незаблокированные ресурсы.
|
||||
Поэтому очень желательно иметь знания в области сетей, чтобы иметь возможность проанализировать техническую ситуацию.
|
||||
Не будет лишним иметь обходные каналы проксирования трафика на случай, если обход DPI не помогает.
|
||||
|
||||
Вариант, когда вы нашли стратегию где-то в интернете и пытаетесь ее приспособить к своему случаю - заведомо проблемный.
|
||||
Нет универсальной таблетки. Везде ситуация разная. В сети гуляют написанные кем-то откровенные глупости, которые тиражируются массово ничего не понимающей публикой.
|
||||
Такие варианты чаще всего работают нестабильно, только на части ресурсов, только на части провайдеров, не работают вообще или ломают другие ресурсы. В худших случаях еще и устраивают флуд в сети.
|
||||
Если даже вариант когда-то и работал неплохо, завтра он может перестать, а в сети останется устаревшая информация.
|
||||
|
||||
Особо осторожным нужно быть со сторонними сборками. Там могут быть вирусы. Не в каждой сборке, но уже были замечены скаммеры.
|
||||
Видео на ютубе как просто обойти блокировку, прилагающийся архив, в котором какая-то ерунда, написанная на питоне, скачивающая зловред.
|
||||
|
||||
Будем считать, что у вас есть windows 7 или выше. Задача - обойти блокировки с самой системы.
|
||||
|
||||
> [!NOTE]
|
||||
> Есть решение самое простое, а есть "как положено".
|
||||
|
||||
## САМОЕ ПРОСТОЕ РЕШЕНИЕ
|
||||
|
||||
_"Совсем ничего не могу, все очень сложно, дайте мне таблетку."_ ©Простой пользователь
|
||||
|
||||
1) Скачайте и распакуйте архив https://github.com/bol-van/zapret-win-bundle/archive/refs/heads/master.zip.
|
||||
2) Запустите `zapret-winws/preset_russia.cmd` от имени администратора. Возможно, заведется сразу.
|
||||
|
||||
> То же самое с ограничителем по автоматически создаваемому хост-листу `preset_russia_autohostlist.cmd`.
|
||||
> Что такое `autohostlist` - читайте [readme.md](./readme.md). Проще говоря, мы обходим только то, что долго и упорно не хочет открываться.
|
||||
> Сначала не будет, но надо пытаться много раз, и тогда сработает, а дальше будет всегда срабатывать.
|
||||
> Остальное не будет ломаться. Использовать только, если первый вариант тоже работает.
|
||||
|
||||
Не помогла _"таблетка"_ ? Это вовсе не значит, что ничего не получится. Но придется делать по нормальному.
|
||||
|
||||
## НЕ ПОМОГЛО, КАК ТЕПЕРЬ ЭТО УДАЛИТЬ
|
||||
|
||||
Если вы не устанавливали zapret как службу или запланированную задачу (а это требует редактирования cmd файлов),
|
||||
достаточно закрыть окно с winws и запустить windivert_delete.cmd.
|
||||
Альтернатива - перезагрузить компьютер.
|
||||
После чего можно удалить папку с zapret. На этом деинсталляция закончена.
|
||||
Если же вы устанавливали zapret как службу, то вы наверняка знаете как ее удалить.
|
||||
|
||||
## РЕШЕНИЕ "КАК ПОЛОЖЕНО"
|
||||
|
||||
1) Скачайте и распакуйте архив https://github.com/bol-van/zapret-win-bundle/archive/refs/heads/master.zip.
|
||||
|
||||
2) Если у вас Windows 7 x64, читайте [docs/windows.md](./windows.md). Без описанной там подготовки может не работать.
|
||||
|
||||
> [!WARNING]
|
||||
> Для 32-битных систем Windows нет готового полного варианта.
|
||||
|
||||
> На windows 11 arm64 выполните `arm64/install_arm64.cmd` от имени администратора и перезагрузите компьютер.
|
||||
> Читайте [docs/windows.md](./windows.md)
|
||||
>
|
||||
> Имейте в виду, что антивирусы могут плохо реагировать на windivert.
|
||||
> cygwin так же имеет внушительный список несовместимостей с антивирусами, хотя современные антивирусы
|
||||
> более-менее научились с ним дружить.
|
||||
> Если проблема имеет место , используйте исключения. Если не помогает - отключайте антивирус совсем.
|
||||
|
||||
3) Убедитесь, что у вас отключены все средства обхода блокировок, в том числе и сам zapret.
|
||||
|
||||
4) Если вы работаете в виртуальной машине, необходимо использовать соединение с сетью в режиме bridge. nat не подходит
|
||||
|
||||
5) Запустите `blockcheck\blockcheck.cmd`. blockcheck в начале проверяет **DNS**.
|
||||
Если выводятся сообщения о подмене адресов, то нужно будет решить проблему с **DNS**.
|
||||
blockcheck перейдет в этом случае на **DoH** _(DNS over HTTPS)_ и будет пытаться получить и использовать реальные IP адреса.
|
||||
Но если вы не настроите решение этой проблемы, обход будет работать только для тех программ,
|
||||
которые сами реализуют механизмы SecureDNS. Для других программ обход работать не будет.
|
||||
|
||||
> Решение проблемы DNS выходит за рамки проекта. Обычно она решается либо заменой DNS серверов
|
||||
> от провайдера на публичные (`1.1.1.1`, `8.8.8.8`), либо в случае перехвата провайдером обращений
|
||||
> к сторонним серверам - через специальные средства шифрования DNS запросов, такие как [dnscrypt](https://www.dnscrypt.org/), **DoT** _(DNS over TLS)_, **DoH**.
|
||||
> В современных броузерах чаще всего DoH включен по умолчанию, но curl будет использовать обычный системный DNS.
|
||||
> win11 поддерживает системные DoH из коробки. Они не настроены по умолчанию.
|
||||
> В последних билдах win10 существует неофициальный обходной путь для включения DoH.
|
||||
> Для остальных систем нужно стороннее решение, работающие по принципу DNS proxy.
|
||||
>
|
||||
> Тут все разжевано как и где это включается : https://hackware.ru/?p=13707
|
||||
|
||||
6) blockcheck позволяет выявить рабочую стратегию обхода блокировок.
|
||||
Лог скрипта будет сохранен в `blockcheck\blockcheck.log`.
|
||||
Запомните/перепишите найденные стратегии.
|
||||
|
||||
> [!WARNING]
|
||||
> Следует понимать, что blockcheck проверяет доступность только конкретного домена, который вы вводите в начале.
|
||||
> Вероятно, все остальные домены блокированы подобным образом, но не факт.
|
||||
|
||||
> [!TIP]
|
||||
> В большинстве случаев можно обьединить несколько стратегий в одну универсальную, и это крайне желательно.
|
||||
|
||||
> Необходимо понимать [как работают стратегии](./readme.md/#nfqws).
|
||||
> zapret не может пробить блокировку по IP адресу. Для проверки нескольких доменов вводите их через пробел.
|
||||
>
|
||||
> Сейчас блокираторы ставят на магистральных каналах. В сложных случаях у вас может быть несколько маршрутов
|
||||
> с различной длиной по ХОПам, с DPI на разных хопах. Приходится преодолевать целый зоопарк DPI,
|
||||
> которые еще и включаются в работу хаотичным образом или образом, зависящим от направления (IP сервера).
|
||||
> blockcheck не всегда может выдать вам в итогах оптимальную стратегию, которую надо просто переписать в настройки.
|
||||
> В некоторых случаях надо реально думать что происходит, анализируя результат на разных стратегиях.
|
||||
> Если вы применяете большой TTL, чтобы достать до магистрала, то не лишним будет добавить дополнительный ограничитель
|
||||
> `--dpi-desync-fooling`, чтобы не сломать сайты на более коротких дистанциях.
|
||||
> _md5sig_ наиболее совместим, но работатет только на linux серверах.
|
||||
> badseq может работать только на https и не работать на http.
|
||||
> Чтобы выяснить какие дополнительные ограничители работают, смотрите результат теста аналогичных стратегий без TTL
|
||||
> с каждым из этих ограничителей.
|
||||
>
|
||||
> При использовании autottl следует протестировать как можно больше разных доменов. Эта техника
|
||||
> может на одних провайдерах работать стабильно, на других потребуется выяснить при каких параметрах
|
||||
> она стабильна, на третьих полный хаос, и проще отказаться.
|
||||
>
|
||||
> Далее, имея понимание что работает на http, https, quic, нужно сконструировать параметры запуска winws
|
||||
> с использованием мультистратегии. Как работают мультистратегии описано в [readme.md](./readme.md).
|
||||
>
|
||||
> Прежде всего вам нужно собрать фильтр перехватываемого трафика. Это делается через параметры
|
||||
> `--wf-l3`, `--wf-tcp`, `--wf-udp`.
|
||||
> `--wf-l3` относится к версии ip протокола - ipv4 или ipv6.
|
||||
> `--wf-tcp` и `--wf-udp` содержат перечень портов или диапазонов портов через запятую.
|
||||
>
|
||||
> Пример стандартного фильтра для перехвата http, https, quic : `--wf-tcp=80,443` `--wf-udp=443`
|
||||
>
|
||||
> Фильтр должен быть минимально необходимым. Перехват лишнего трафика приведет только к бессмысленному расходованию ресурсов процессора и замедлению интернета.
|
||||
>
|
||||
> Если кратко по мультистратегии, то обычно параметры конструируются так :
|
||||
> ```
|
||||
> --filter-udp=443 'параметры для quic' --new
|
||||
> --filter-tcp=80,443 'обьединенные параметры для http и https'
|
||||
> ```
|
||||
>
|
||||
> Или так :
|
||||
> ```
|
||||
> --filter-udp=443 'параметры для quic' --new
|
||||
> --filter-tcp=80 'параметры для http' --new
|
||||
> --filter-tcp=443 'параметры для https'
|
||||
> ```
|
||||
>
|
||||
> Если стратегии отличаются по версии ip протокола, и вы не можете их обьединить, фильтр пишется так :
|
||||
> ```
|
||||
> --filter-l3=ipv4 --filter-udp=443 "параметры для quic ipv4" --new
|
||||
> --filter-l3=ipv4 --filter-tcp=80 'параметры для http ipv4' --new
|
||||
> --filter-l3=ipv4 --filter-tcp=443 'параметры для https ipv4' --new
|
||||
> --filter-l3=ipv6 --filter-udp=443 "параметры для quic ipv6" --new
|
||||
> --filter-l3=ipv6 --filter-tcp=80 "параметры для http ipv6" --new
|
||||
> --filter-l3=ipv6 --filter-tcp=443 "параметры для https ipv6"
|
||||
> ```
|
||||
>
|
||||
> Но здесь совсем _"копи-пастный"_ вариант.
|
||||
> Чем больше вы обьедините стратегий и сократите их общее количество, тем будет лучше.
|
||||
>
|
||||
> Если вам не нужно дурение отдельных протоколов, лучше всего будет их убрать из системы перехвата трафика через
|
||||
> параметры `--wf-*` и убрать соответствующие им профили мультистратегии.
|
||||
> tcp 80 - http, tcp 443 - https, udp 443 - quic.
|
||||
>
|
||||
> Если используются методы нулевой фазы десинхронизации (`--mss`, `--wssize`, `--dpi-desync=syndata`) и фильтрация hostlist,
|
||||
> то все параметры, относящиеся к этим методам, следует помещать в отдельные профили мультистратегии, которые получат
|
||||
> управление до определения имени хоста. Необходимо понимать алгоритм работы мультистратегий.
|
||||
>
|
||||
> ```
|
||||
> --filter-tcp=80 'параметры для http' --new
|
||||
> --filter-tcp=443 'параметры для https' --hostlist=d:/users/user/temp/list.txt --new
|
||||
> --filter-tcp=443 --wssize 1:6
|
||||
> ```
|
||||
>
|
||||
> autohostlist профиль приоритетен, поэтому wssize нужно писать туда :
|
||||
>
|
||||
> ```
|
||||
> --filter-tcp=80 'параметры для http' --new
|
||||
> --filter-tcp=443 'параметры для https' --wssize 1:6 --hostlist-auto=d:/users/user/temp/autolist.txt
|
||||
> ```
|
||||
>
|
||||
> В этих примерах wssize будет применяться всегда к порту tcp 443, а хостлист будет игнорироваться.
|
||||
> К http применять wssize вредно и бессмысленно.
|
||||
|
||||
7) Протестируйте найденные стратегии на winws. Winws следует брать из zapret-winws.
|
||||
Для этого откройте командную строку windows от имени администратора в директории zapret-winws.
|
||||
Проще всего это сделать через `_CMD_ADMIN.cmd`. Он сам поднимет права и зайдет в нужную директорию.
|
||||
|
||||
8) Обеспечьте удобную загрузку обхода блокировок.
|
||||
|
||||
> Есть 2 варианта. Ручной запуск через ярлык или автоматический при старте системы, вне контекста текущего пользователя.
|
||||
> Последний вариант разделяется на запуск через планировщик задач и через службы windows.
|
||||
>
|
||||
> Если хотите ручной запуск, скопируйте `preset_russia.cmd` в `preset_my.cmd` (`<ваше_название>.cmd`) и адаптируйте его под ваши параметра запуска.
|
||||
> Потом можно создать ярлык на рабочем столе на `preset_my.cmd`. Не забудьте, что требуется запускать от имени администратора.
|
||||
>
|
||||
> Но лучше будет сделать неинтерактивный автоматический запуск вместе с системой.
|
||||
> В zapret-winws есть командные файлы `task_*`, предназначенные для управления задачами планировщика.
|
||||
> Там следует поменять содержимое переменной `WINWS1` на свои параметры запуска winws. Пути с пробелами нужно экранировать кавычками с обратным слэшем : `\"`.
|
||||
> После создания задач запустите их. Проверьте, что обход встает после перезагрузки windows.
|
||||
>
|
||||
> Аналогично настраиваются и службы windows. Смотрите `service_*.cmd`
|
||||
|
||||
9) Если ломаются отдельные незаблокированные ресурсы, нужно пользоваться ограничивающим
|
||||
ipset или хост листом. Читайте основной талмуд [readme.md](./readme.md) ради подробностей.
|
||||
Но еще лучше будет подбирать такие стратегии, которые ломают минимум.
|
||||
Есть стратегии довольно безобидные, а есть сильно ломающие, которые подходят только для точечного пробития отдельных ресурсов,
|
||||
когда ничего лучше нет. Хорошая стратегия может сильно ломать из-за плохо подобранных ограничителей для фейков - ttl, fooling.
|
||||
|
||||
> [!CAUTION]
|
||||
> Это минимальная инструкция, чтобы соориентироваться с чего начать. Однако, это - не панацея.
|
||||
> В некоторых случаях вы не обойдетесь без знаний и основного "талмуда".
|
||||
|
||||
Подробности и полное техническое описание расписаны в [readme.md](./readme.md)
|
@@ -1,181 +0,0 @@
|
||||
Специально для тех, кто хочет побыстрее начать, но не хочет слишком углубляться в простыню readme.txt.
|
||||
|
||||
Как обычно, компьютерная грамотность ложится полностью на вас.
|
||||
Вы должны уметь работать с консолью windows и иметь минимальные навыки обращения с командными файлами bat,cmd.
|
||||
Если грамотность отсутствует и возникает куча "как" на базовых вещах, значит эта программа не для вас.
|
||||
Разработчик не будет отвечать на вопросы из серии школы компьютерной грамотности.
|
||||
Если вы все-таки хотите продолжать, задавайте вопросы в дискуссиях на github или на форумах.
|
||||
Возможно, кто-то вам поможет. Но не надо писать issue на github. Они будут закрываться сразу.
|
||||
|
||||
Обход DPI является хакерской методикой. Под этим словом понимается метод, которому сопротивляется окружающая среда,
|
||||
которому автоматически не гарантирована работоспособность в любых условиях и на любых ресурсах,
|
||||
требуется настройка под специфические условия у вашего провайдера. Условия могут меняться со временем,
|
||||
и методика может начинать или переставать работать, может потребоваться повторный анализ ситуации.
|
||||
Могут обнаруживаться отдельные ресурсы, которые заблокированы иначе, и которые не работают или перестали работать.
|
||||
Могут и сломаться отдельные незаблокированные ресурсы.
|
||||
Поэтому очень желательно иметь знания в области сетей, чтобы иметь возможность проанализировать техническую ситуацию.
|
||||
Не будет лишним иметь обходные каналы проксирования трафика на случай, если обход DPI не помогает.
|
||||
|
||||
Будем считать, что у вас есть windows 7 или выше. Задача - обойти блокировки с самой системы.
|
||||
|
||||
Есть решение самое простое, а есть "как положено".
|
||||
|
||||
САМОЕ ПРОСТОЕ РЕШЕНИЕ
|
||||
|
||||
Совсем ничего не могу, все очень сложно, дайте мне таблетку.
|
||||
|
||||
Скачайте и распакуйте архив https://github.com/bol-van/zapret-win-bundle/archive/refs/heads/master.zip
|
||||
Запустите zapret-winws/preset_russia.cmd от имени администратора.
|
||||
Возможно, заведется сразу. Этот вариант похож на "2_any_country.cmd" из GoodbyeDPI.
|
||||
|
||||
То же самое с ограничителем по автоматически создаваемому хост-листу preset_russia_autohostlist.cmd.
|
||||
Что такое autohostlist - читайте readme.txt. Проще говоря, мы обходим только то, что долго и упорно не хочет открываться.
|
||||
Сначала не будет, но надо пытаться много раз, и тогда сработает, а дальше будет всегда срабатывать.
|
||||
Остальное не будет ломаться. Использовать только, если первый вариант тоже работает.
|
||||
|
||||
Не помогла таблетка ? Это вовсе не значит, что ничего не получится. Но придется делать по-нормальному.
|
||||
|
||||
РЕШЕНИЕ "КАК ПОЛОЖЕНО"
|
||||
|
||||
1) Скачайте и распакуйте архив https://github.com/bol-van/zapret-win-bundle/archive/refs/heads/master.zip
|
||||
|
||||
2) Если у вас Windows 7 x64, читайте docs/windows.txt. Без описанной там подготовки может не работать.
|
||||
Для 32-битных систем Windows нет готового полного варианта, но есть собранные бинарники :
|
||||
https://github.com/bol-van/zapret-win32
|
||||
На windows 11 arm64 выполните arm64/install_arm64.cmd от имени администратора и перезагрузите компьютер.
|
||||
Читайте docs/windows.txt
|
||||
|
||||
Имейте в виду, что антивирусы могут плохо реагировать на windivert.
|
||||
cygwin так же имеет внушительный список несовместимостей с антивирусами, хотя современные антивирусы
|
||||
более-менее научились с ним дружить.
|
||||
Если проблема имеет место , используйте исключения. Если не помогает - отключайте антивирус совсем.
|
||||
|
||||
3) Убедитесь, что у вас отключены все средства обхода блокировок, в том числе и сам zapret.
|
||||
|
||||
4) Если вы работаете в виртуальной машине, необходимо использовать соединение с сетью в режиме bridge. nat не подходит
|
||||
|
||||
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.
|
||||
win11 поддерживает системные DoH из коробки. Они не настроены по умолчанию.
|
||||
В последних билдах win10 существует неофициальный обходной путь для включения DoH.
|
||||
Для остальных систем нужно стороннее решение, работающие по принципу DNS proxy.
|
||||
|
||||
Тут все разжевано как и где это включается : https://hackware.ru/?p=13707
|
||||
|
||||
6) blockcheck позволяет выявить рабочую стратегию обхода блокировок.
|
||||
Лог скрипта будет сохранен в blockcheck\blockcheck.log.
|
||||
Запомните найденные стратегии.
|
||||
|
||||
Следует понимать, что blockcheck проверяет доступность только конкретного домена, который вы вводите в начале.
|
||||
Вероятно, все остальные домены блокированы подобным образом, но не факт.
|
||||
В большинстве случаев можно обьединить несколько стратегий в одну универсальную, и это крайне желательно.
|
||||
Необходимо понимать как работают стратегии.
|
||||
zapret не может пробить блокировку по IP адресу. Для проверки нескольких доменов вводите их через пробел.
|
||||
|
||||
Сейчас блокираторы ставят на магистральных каналах. В сложных случаях у вас может быть несколько маршрутов
|
||||
с различной длиной по ХОПам, с DPI на разных хопах. Приходится преодолевать целый зоопарк DPI,
|
||||
которые еще и включаются в работу хаотичным образом или образом, зависящим от направления (IP сервера).
|
||||
blockcheck не всегда может выдать вам в итогах оптимальную стратегию, которую надо просто переписать в настройки.
|
||||
В некоторых случаях надо реально думать что происходит, анализируя результат на разных стратегиях.
|
||||
Если вы применяете большой TTL, чтобы достать до магистрала, то не лишним будет добавить дополнительный ограничитель
|
||||
--dpi-desync-fooling, чтобы не сломать сайты на более коротких дистанциях.
|
||||
md5sig наиболее совместим, но работатет только на linux серверах.
|
||||
badseq может работать только на https и не работать на http.
|
||||
Чтобы выяснить какие дополнительные ограничители работают, смотрите результат теста аналогичных стратегий без TTL
|
||||
с каждым из этих ограничителей.
|
||||
|
||||
При использовании autottl следует протестировать как можно больше разных доменов. Эта техника
|
||||
может на одних провайдерах работать стабильно, на других потребуется выяснить при каких параметрах
|
||||
она стабильна, на третьих полный хаос, и проще отказаться.
|
||||
|
||||
Далее, имея понимание что работает на http, https, quic, нужно сконструировать параметры запуска winws
|
||||
с использованием мультистратегии. Как работают мультистратегии описано в readme.txt.
|
||||
|
||||
Прежде всего вам нужно собрать фильтр перехватываемого трафика. Это делается через параметры
|
||||
--wf-l3, --wf-tcp, --wf-udp.
|
||||
--wf-l3 относится к версии ip протокола - ipv4 или ipv6.
|
||||
--wf-tcp и --wf-udp содержат перечень портов или диапазонов портов через запятую.
|
||||
|
||||
Пример стандартного фильтра для перехвата http, https, quic : --wf-tcp=80,443 --wf-udp=443
|
||||
|
||||
Фильтр должен быть минимально необходимым. Перехват лишнего трафика приведет только к бессмысленному
|
||||
расходованию ресурсов процессора и замедлению интернета.
|
||||
|
||||
Если кратко по мультистратегии, то обычно параметры конструируются так :
|
||||
"--filter-udp=443 'параметры для quic' --new
|
||||
--filter-tcp=80,443 'обьединенные параметры для http и https'"
|
||||
|
||||
Или так :
|
||||
"--filter-udp=443 "параметры для quic" --new
|
||||
--filter-tcp=80 'параметры для http' --new
|
||||
--filter-tcp=443 'параметры для https'"
|
||||
|
||||
Если стратегии отличаются по версии ip протокола, и вы не можете их обьединить, фильтр пишется так :
|
||||
"--filter-l3=ipv4 --filter-udp=443 "параметры для quic ipv4" --new
|
||||
--filter-l3=ipv4 --filter-tcp=80 'параметры для http ipv4' --new
|
||||
--filter-l3=ipv4 --filter-tcp=443 'параметры для https ipv4' --new
|
||||
--filter-l3=ipv6 --filter-udp=443 "параметры для quic ipv6" --new
|
||||
--filter-l3=ipv6 --filter-tcp=80 'параметры для http ipv6' --new
|
||||
--filter-l3=ipv6 --filter-tcp=443 'параметры для https ipv6'"
|
||||
|
||||
Но здесь совсем "копи-пастный" вариант.
|
||||
Чем больше вы обьедините стратегий и сократите их общее количество, тем будет лучше.
|
||||
|
||||
Если вам не нужно дурение отдельных протоколов, лучше всего будет их убрать из системы перехвата трафика через
|
||||
параметры --wf-* и убрать соответствующие им профили мультистратегии.
|
||||
tcp 80 - http, tcp 443 - https, udp 443 - quic.
|
||||
|
||||
Если используются методы нулевой фазы десинхронизации (--mss, --wssize, --dpi-desync=syndata) и фильтрация hostlist,
|
||||
то все параметры, относящиеся к этим методам, следует помещать в отдельные профили мультистратегии, которые получат
|
||||
управление до определения имени хоста. Необходимо понимать алгоритм работы мультистратегий.
|
||||
|
||||
"--filter-tcp=80 'параметры для http' --new
|
||||
--filter-tcp=443 'параметры для https' --hostlist=d:/users/user/temp/list.txt --new
|
||||
--filter-tcp=443 --wssize 1:6"
|
||||
|
||||
autohostlist профиль приоритетен, поэтому wssize нужно писать туда :
|
||||
|
||||
"--filter-tcp=80 'параметры для http' --new
|
||||
--filter-tcp=443 'параметры для https' --wssize 1:6 --hostlist-auto=d:/users/user/temp/autolist.txt"
|
||||
|
||||
В этих примерах wssize будет применяться всегда к порту tcp 443, а хостлист будет игнорироваться.
|
||||
К http применять wssize вредно и бессмысленно.
|
||||
|
||||
7) Протестируйте найденные стратегии на winws. winws следует брать из zapret-winws.
|
||||
Для этого откройте командную строку windows от имени администратора в директории zapret-winws.
|
||||
Проще всего это сделать через _CMD_ADMIN.cmd. Он сам поднимет права и зайдет в нужную директорию.
|
||||
|
||||
8) Обеспечьте удобную загрузку обхода блокировок.
|
||||
|
||||
Есть 2 варианта. Ручной запуск через ярлык или автоматический при старте системы, вне контекста текущего пользователя.
|
||||
Последний вариант разделяется на запуск через планировщик задач и через службы windows.
|
||||
|
||||
Если хотите ручной запуск, скопируйте preset_russia.cmd в preset_my.cmd и адаптируйте его под ваши параметра запуска.
|
||||
Потом можно создать ярлык на рабочем столе на preset_my.cmd. Не забудьте, что требуется запускать от имени администратора.
|
||||
|
||||
Но лучше будет сделать неинтерактивный автоматический запуск вместе с системой.
|
||||
В zapret-winws есть командные файлы task_*, предназначенные для управления задачами планировщика.
|
||||
Там следует поменять содержимое переменной WINWS1 на свою стратегию.
|
||||
Если вы не можете обьединить несколько стратегий для разных протоколов в одну, дублируйте код в каждом из cmd
|
||||
для поддержки нескольких задач : winws1,winws2,winws3.
|
||||
После создания задач запустите их. Проверьте, что обход встает после перезагрузки windows.
|
||||
|
||||
Аналогично настраиваются и службы windows. Смотрите service_*.cmd
|
||||
|
||||
9) Если ломаются отдельные незаблокированные ресурсы, нужно пользоваться ограничивающим
|
||||
ipset или хост листом. Читайте основной талмуд readme.txt ради подробностей.
|
||||
Но еще лучше будет подбирать такие стратегии, которые ломают минимум.
|
||||
Есть стратегии довольно безобидные, а есть сильно ломающие, которые подходят только для точечного пробития отдельных ресурсов,
|
||||
когда ничего лучше нет. Хорошая стратегия может сильно ломать из-за плохо подобранных ограничителей для фейков - ttl, fooling.
|
||||
|
||||
Это минимальная инструкция, чтобы соориентироваться с чего начать. Однако, это - не панацея.
|
||||
В некоторых случаях вы не обойдетесь без знаний и основного "талмуда".
|
||||
Подробности и полное техническое описание расписаны в readme.txt
|
@@ -1,9 +1,69 @@
|
||||
# zapret v.69
|
||||
|
||||
# SCAMMER WARNING
|
||||
|
||||
This software is free and open source under [MIT license](./LICENSE.txt).
|
||||
If anyone demands you to download this software only from their webpage, telegram channel, forces you to delete links, videos, makes copyright claims, you are dealing with scammers.
|
||||
|
||||
# Multilanguage/Мультиязычный README
|
||||
___
|
||||
[](https://github.com/bol-van/zapret/tree/master/docs/readme.en.md)
|
||||
[](https://github.com/bol-van/zapret/tree/master/docs/readme.md)
|
||||
|
||||
***
|
||||
|
||||
- [What is it for](#what-is-it-for)
|
||||
- [How it works](#how-it-works)
|
||||
- [How to put this into practice in the linux system](#how-to-put-this-into-practice-in-the-linux-system)
|
||||
- [When it will not work](#when-it-will-not-work)
|
||||
- [nfqws](#nfqws)
|
||||
- [DPI desync attack](#dpi-desync-attack)
|
||||
- [Fakes](#fakes)
|
||||
- [TCP segmentation](#tcp-segmentation)
|
||||
- [Sequence numbers overlap](#sequence-numbers-overlap)
|
||||
- [ipv6 specific modes](#ipv6-specific-modes)
|
||||
- [Server reply reaction](#server-reply-reaction)
|
||||
- [SYNDATA mode](#syndata-mode)
|
||||
- [DPI desync combos](#dpi-desync-combos)
|
||||
- [CONNTRACK](#conntrack)
|
||||
- [Reassemble](#reassemble)
|
||||
- [UDP support](#udp-support)
|
||||
- [IP fragmentation](#ip-fragmentation)
|
||||
- [Multiple strategies](#multiple-strategies)
|
||||
- [Virtual machines](#virtual-machines)
|
||||
- [IPTABLES for nfqws](#iptables-for-nfqws)
|
||||
- [NFTABLES for nfqws](#nftables-for-nfqws)
|
||||
- [tpws](#tpws)
|
||||
- [TCP segmentation in tpws](#tcp-segmentation-in-tpws)
|
||||
- [TLSREC](#tlsrec)
|
||||
- [MSS](#mss)
|
||||
- [Other tamper options](#other-tamper-options)
|
||||
- [Supplementary options](#supplementary-options)
|
||||
- [Multiple strategies](#multiple-strategies-1)
|
||||
- [IPTABLES for tpws](#iptables-for-tpws)
|
||||
- [NFTABLES for tpws](#nftables-for-tpws)
|
||||
- [Ways to get a list of blocked IP](#ways-to-get-a-list-of-blocked-ip)
|
||||
- [Domain name filtering](#domain-name-filtering)
|
||||
- [**autohostlist** mode](#autohostlist-mode)
|
||||
- [Choosing parameters](#choosing-parameters)
|
||||
- [Screwing to the firewall control system or your launch system](#screwing-to-the-firewall-control-system-or-your-launch-system)
|
||||
- [Installation](#installation)
|
||||
- [Checking ISP](#checking-isp)
|
||||
- [desktop linux system](#desktop-linux-system)
|
||||
- [OpenWRT](#openwrt)
|
||||
- [Android](#android)
|
||||
- [FreeBSD, OpenBSD, MacOS](#freebsd-openbsd-macos)
|
||||
- [Windows (WSL)](#windows-wsl)
|
||||
- [Other devices](#other-devices)
|
||||
- [Donations](#donations)
|
||||
***
|
||||
|
||||
## What is it for
|
||||
|
||||
A stand-alone (without 3rd party servers) DPI circumvention tool.
|
||||
May allow to bypass http(s) website blocking or speed shaping, resist signature tcp/udp protocol discovery.
|
||||
|
||||
The project is mainly aimed at the Russian audience to fight russian regulator named "Roskomnadzor".
|
||||
The project is mainly aimed at the Russian audience.
|
||||
Some features of the project are russian reality specific (such as getting list of sites
|
||||
blocked by Roskomnadzor), but most others are common.
|
||||
|
||||
@@ -50,94 +110,9 @@ deal with its consequences.
|
||||
2. Modification of the TCP connection at the stream level. Implemented through a proxy or transparent proxy.
|
||||
3. Modification of TCP connection at the packet level. Implemented through the NFQUEUE handler and raw sockets.
|
||||
|
||||
For options 2 and 3, tpws and nfqws programs are implemented, respectively.
|
||||
For options 2 and 3, **tpws** and **nfqws** programs are implemented, respectively.
|
||||
You need to run them with the necessary parameters and redirect certain traffic with iptables or nftables.
|
||||
|
||||
To redirect a TCP connection to a transparent proxy, the following commands are used:
|
||||
|
||||
forwarded traffic :
|
||||
`iptables -t nat -I PREROUTING -i <internal_interface> -p tcp --dport 80 -j DNAT --to 127.0.0.127:988`
|
||||
|
||||
outgoing traffic :
|
||||
`iptables -t nat -I OUTPUT -o <external_interface> -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to 127.0.0.127:988`
|
||||
|
||||
DNAT on localhost works in the OUTPUT chain, but does not work in the PREROUTING chain without enabling the route_localnet parameter:
|
||||
|
||||
`sysctl -w net.ipv4.conf.<internal_interface>.route_localnet=1`
|
||||
|
||||
You can use `-j REDIRECT --to-port 988` instead of DNAT, but in this case the transparent proxy process
|
||||
should listen on the ip address of the incoming interface or on all addresses. Listen all - not good
|
||||
in terms of security. Listening one (local) is possible, but automated scripts will have to recognize it,
|
||||
then dynamically enter it into the command. In any case, additional efforts are required.
|
||||
Using route_localnet can also introduce some security risks. You make available from internal_interface everything
|
||||
bound to `127.0.0.0/8`. Services are usually bound to `127.0.0.1`. Its possible to deny input to `127.0.0.1` from all interfaces except lo
|
||||
or bind tpws to any other IP from `127.0.0.0/8` range, for example to `127.0.0.127`, and allow incomings only to that IP :
|
||||
|
||||
```
|
||||
iptables -A INPUT ! -i lo -d 127.0.0.127 -j ACCEPT
|
||||
iptables -A INPUT ! -i lo -d 127.0.0.0/8 -j DROP
|
||||
```
|
||||
|
||||
Owner filter is necessary to prevent recursive redirection of connections from tpws itself.
|
||||
tpws must be started under OS user `tpws`.
|
||||
|
||||
NFQUEUE redirection of the outgoing traffic and forwarded traffic going towards the external interface,
|
||||
can be done with the following commands:
|
||||
|
||||
`iptables -t mangle -I POSTROUTING -o <external_interface> -p tcp --dport 80 -j NFQUEUE --queue-num 200 --queue-bypass`
|
||||
|
||||
In order not to touch the traffic to unblocked addresses, you can take a list of blocked hosts, resolve it
|
||||
into IP addresses and put them to ipset 'zapret', then add a filter to the command:
|
||||
|
||||
`iptables -t mangle -I POSTROUTING -o <external_interface> -p tcp --dport 80 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass`
|
||||
|
||||
Some DPIs catch only the first http request, ignoring subsequent requests in a keep-alive session.
|
||||
Then we can reduce CPU load, refusing to process unnecessary packets.
|
||||
|
||||
`iptables -t mangle -I POSTROUTING -o <external_interface> -p tcp --dport 80 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass`
|
||||
|
||||
Mark filter does not allow nfqws-generated packets to enter the queue again.
|
||||
Its necessary to use this filter when also using `connbytes`. Without it packet ordering can be changed breaking the whole idea.
|
||||
Also if there's huge packet send from nfqws it may deadlock without mark filter.
|
||||
|
||||
Some attacks require redirection of incoming packets :
|
||||
|
||||
`iptables -t mangle -I PREROUTING -i <external_interface> -p tcp --sport 80 -m connbytes --connbytes-dir=reply --connbytes-mode=packets --connbytes 1:6 -m set --match-set zapret src -j NFQUEUE --queue-num 200 --queue-bypass`
|
||||
|
||||
Incoming packets are filtered by incoming interface, source port and IP. This is opposite to the direct rule.
|
||||
|
||||
Some techniques that break NAT are possible only with nftables.
|
||||
|
||||
|
||||
## ip6tables
|
||||
|
||||
ip6tables work almost exactly the same way as ipv4, but there are a number of important nuances.
|
||||
In DNAT, you should take the address --to in square brackets. For example :
|
||||
|
||||
`ip6tables -t nat -I OUTPUT -o <external_interface> -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to [::1]:988`
|
||||
|
||||
The route_localnet parameter does not exist for ipv6.
|
||||
DNAT to localhost (:: 1) is possible only in the OUTPUT chain.
|
||||
In the PREROUTING DNAT chain, it is possible to any global address or to the link local address of the same interface
|
||||
the packet came from.
|
||||
NFQUEUE works without changes.
|
||||
|
||||
|
||||
## nftables
|
||||
|
||||
nftables are fine except one very big problem.
|
||||
nft requires tons of RAM to load large nf sets (ip lists) with subnets/intervals. Most of the home routers can't afford that.
|
||||
For example, even a 256 Mb system can't load a 100K ip list. nft process will OOM.
|
||||
nf sets do not support overlapping intervals and that's why nft process applies very RAM consuming algorithm to merge intervals so they don't overlap.
|
||||
There're equivalents to iptables for all other functions. Interface and protocol anonymous sets allow not to write multiple similar rules.
|
||||
Flow offloading is built-in into new linux kernels and nft versions.
|
||||
|
||||
nft version `1.0.2` or higher is recommended. But the higher is version the better.
|
||||
|
||||
Some techniques can be fully used only with nftables. It's not possible to queue packets after NAT in iptables.
|
||||
This limits techniques that break NAT.
|
||||
|
||||
|
||||
## When it will not work
|
||||
|
||||
* If DNS server returns false responses. ISP can return false IP addresses or not return anything
|
||||
@@ -149,7 +124,7 @@ follows all standards. For example, we are routed to squid. Connection goes thro
|
||||
## nfqws
|
||||
|
||||
This program is a packet modifier and a NFQUEUE queue handler.
|
||||
For BSD systems there is dvtws. Its built from the same source and has almost the same parameters (see bsd.eng.md).
|
||||
For BSD systems there is dvtws. Its built from the same source and has almost the same parameters (see [bsd.en.md](./bsd.en.md)).
|
||||
nfqws takes the following parameters:
|
||||
|
||||
```
|
||||
@@ -171,7 +146,8 @@ nfqws takes the following parameters:
|
||||
--hostspell ; exact spelling of "Host" header. must be 4 chars. default is "host"
|
||||
--hostnospace ; remove space after Host: and add it to User-Agent: to preserve packet size
|
||||
--domcase ; mix domain case : Host: TeSt.cOm
|
||||
--dpi-desync=[<mode0>,]<mode>[,<mode2>] ; try to desync dpi state. modes : synack fake fakeknown rst rstack hopbyhop destopt ipfrag1 disorder disorder2 split split2 ipfrag2 udplen tamper
|
||||
--methodeol ; add '\n' before method and remove space after Host:
|
||||
--dpi-desync=[<mode0>,]<mode>[,<mode2>] ; try to desync dpi state. modes : synack fake fakeknown rst rstack hopbyhop destopt ipfrag1 multisplit multidisorder fakedsplit fakeddisorder ipfrag2 udplen tamper
|
||||
--dpi-desync-fwmark=<int|0xHEX> ; override fwmark for desync packet. default = 0x40000000 (1073741824)
|
||||
--dpi-desync-ttl=<int> ; set ttl for desync packet
|
||||
--dpi-desync-ttl6=<int> ; set ipv6 hop limit for desync packet. by default ttl value is used.
|
||||
@@ -180,10 +156,11 @@ nfqws takes the following parameters:
|
||||
--dpi-desync-fooling=<mode>[,<mode>] ; can use multiple comma separated values. modes : none md5sig ts badseq badsum datanoack hopbyhop hopbyhop2
|
||||
--dpi-desync-repeats=<N> ; send every desync packet N times
|
||||
--dpi-desync-skip-nosni=0|1 ; 1(default)=do not act on ClientHello without SNI (ESNI ?)
|
||||
--dpi-desync-split-pos=<1..9216> ; data payload split position
|
||||
--dpi-desync-split-http-req=method|host ; split at specified logical part of plain http request
|
||||
--dpi-desync-split-tls=sni|sniext ; split at specified logical part of TLS ClientHello
|
||||
--dpi-desync-split-seqovl=<int> ; use sequence overlap before first sent original split segment
|
||||
--dpi-desync-split-pos=N|-N|marker+N|marker-N ; comma separated list of split positions
|
||||
; markers: method,host,endhost,sld,endsld,midsld,sniext
|
||||
; full list is only used by multisplit and multidisorder
|
||||
; fakedsplit/fakeddisorder use first l7-protocol-compatible parameter if present, first abs value otherwise
|
||||
--dpi-desync-split-seqovl=N|-N|marker+N|marker-N ; use sequence overlap before first sent original split segment
|
||||
--dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; pattern for the fake part of overlap
|
||||
--dpi-desync-ipfrag-pos-tcp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 8.
|
||||
--dpi-desync-ipfrag-pos-udp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 32.
|
||||
@@ -209,7 +186,8 @@ nfqws takes the following parameters:
|
||||
--hostlist-auto-fail-time=<int> ; all failed attemps must be within these seconds (default : 60)
|
||||
--hostlist-auto-retrans-threshold=<int> ; how many request retransmissions cause attempt to fail (default : 3)
|
||||
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
||||
--new ; begin new strategy
|
||||
--new ; begin new strategy (new profile)
|
||||
--skip ; do not use this profile
|
||||
--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. 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.
|
||||
@@ -218,24 +196,21 @@ nfqws takes the following parameters:
|
||||
--ipset-exclude=<filename> ; ipset exclude filter (one ip/CIDR per line, ipv4 and ipv6 accepted, gzip supported, multiple ipsets allowed)
|
||||
```
|
||||
|
||||
The manipulation parameters can be combined in any way.
|
||||
|
||||
WARNING. `--wsize` parameter is now not used anymore in scripts. TCP split can be achieved using DPI desync attack.
|
||||
|
||||
### DPI desync attack
|
||||
|
||||
After completion of the tcp 3-way handshake, the first data packet from the client goes.
|
||||
It usually has `GET / ...` or TLS ClientHello. We drop this packet, replacing with something else.
|
||||
It can be a fake version with another harmless but valid http or https request (`fake`), tcp reset packet (`rst`,`rstack`),
|
||||
split into 2 segments original packet with fake segment in the middle (`split`).
|
||||
`fakeknown` sends fake only in response to known application protocol.
|
||||
In articles these attack have names **TCB desynchronization** and **TCB teardown**.
|
||||
Fake packet must reach DPI, but do not reach the destination server.
|
||||
The following means are available: set a low TTL, send a packet with bad checksum,
|
||||
add tcp option **MD5 signature**. All of them have their own disadvantages :
|
||||
The idea is to take original message, modify it, add additional fake information in such a way that the server OS accepts original data only
|
||||
but DPI cannot recostruct original message or sees what it cannot identify as a prohibited request.
|
||||
|
||||
* md5sig does not work on all servers
|
||||
* badsum doesn't work if your device is behind NAT which does not pass invalid packets.
|
||||
There's a set of instruments to achieve that goal.
|
||||
It can be fake packets that reach DPI but do not reach server or get rejected by server, TCP segmentation or IP fragmentation.
|
||||
There're attacks based on TCP sequence numbers. Methods can be combined in many ways.
|
||||
|
||||
### Fakes
|
||||
|
||||
Fakes are separate generated by nfqws packets carrying false information for DPI. They must either not reach the server or be rejected by it. Otherwise TCP connection or data stream would be broken. There're multiple ways to solve this task.
|
||||
|
||||
* **md5sig** does not work on all servers
|
||||
* **badsum** doesn't work if your device is behind NAT which does not pass invalid packets.
|
||||
The most common Linux NAT router configuration does not pass them. Most home routers are Linux based.
|
||||
The default sysctl configuration `net.netfilter.nf_conntrack_checksum=1` causes contrack to verify tcp and udp checksums
|
||||
and set INVALID state for packets with invalid checksum.
|
||||
@@ -250,25 +225,25 @@ add tcp option **MD5 signature**. All of them have their own disadvantages :
|
||||
This behavior was observed on a Mediatek MT7621 based device.
|
||||
Tried to modify mediatek ethernet driver with no luck, likely hardware enforced limitation.
|
||||
However the device allowed to send badsum packets, problem only existed for passthrough traffic from clients.
|
||||
* badseq packets will be dropped by server, but DPI also can ignore them.
|
||||
* **badseq** packets will be dropped by server, but DPI also can ignore them.
|
||||
default badseq increment is set to -10000 because some DPIs drop packets outside of the small tcp window.
|
||||
But this also can cause troubles when `--dpi-desync-any-protocol` is enabled.
|
||||
To be 100% sure fake packet cannot fit to server tcp window consider setting badseq increment to 0x80000000
|
||||
* TTL looks like the best option, but it requires special tuning for each ISP. If DPI is further than local ISP websites
|
||||
* **TTL** looks like the best option, but it requires special tuning for each ISP. If DPI is further than local ISP websites
|
||||
you can cut access to them. Manual IP exclude list is required. Its possible to use md5sig with ttl.
|
||||
This way you cant hurt anything, but good chances it will help to open local ISP websites.
|
||||
If automatic solution cannot be found then use `zapret-hosts-user-exclude.txt`.
|
||||
Some router stock firmwares fix outgoing TTL. Without switching this option off TTL fooling will not work.
|
||||
* `hopbyhop` is ipv6 only. This fooling adds empty extension header `hop-by-hop options` or two headers in case of `hopbyhop2`.
|
||||
* **hopbyhop** is ipv6 only. This fooling adds empty extension header `hop-by-hop options` or two headers in case of `hopbyhop2`.
|
||||
Packets with two hop-by-hop headers violate RFC and discarded by all operating systems.
|
||||
All OS accept packets with one hop-by-hop header.
|
||||
Some ISPs/operators drop ipv6 packets with hop-by-hop options. Fakes will not be processed by the server either because
|
||||
ISP drops them or because there are two same headers.
|
||||
DPIs may still anaylize packets with one or two hop-by-hop headers.
|
||||
* `datanoack` sends tcp fakes without ACK flag. Servers do not accept this but DPI may accept.
|
||||
* **datanoack** sends tcp fakes without ACK flag. Servers do not accept this but DPI may accept.
|
||||
This mode may break NAT and may not work with iptables if masquerade is used, even from the router itself.
|
||||
Works with nftables properly. Likely requires external IP address (some ISPs pass these packets through their NAT).
|
||||
* `autottl` tries to automatically guess TTL value that allows DPI to receive fakes and does not allow them to reach the server.
|
||||
* **autottl** tries to automatically guess TTL value that allows DPI to receive fakes and does not allow them to reach the server.
|
||||
This tech relies on well known TTL values used by OS : 64,128,255. nfqws takes first incoming packet (YES, you need to redirect it too),
|
||||
guesses path length and decreases by `delta` value (default 1). If resulting value is outside the range (min,max - default 3,20)
|
||||
then its normalized to min or max. If the path shorter than the value then autottl fails and falls back to the fixed value.
|
||||
@@ -278,42 +253,53 @@ add tcp option **MD5 signature**. All of them have their own disadvantages :
|
||||
|
||||
`--dpi-desync-fooling` takes multiple comma separated values.
|
||||
|
||||
For fake,rst,rstack modes original packet is sent after the fake.
|
||||
|
||||
Disorder mode splits original packet and sends packets in the following order :
|
||||
1. 2nd segment
|
||||
2. fake 1st segment, data filled with zeroes
|
||||
3. 1st segment
|
||||
4. fake 1st segment, data filled with zeroes (2nd copy)
|
||||
### TCP segmentation
|
||||
|
||||
Original packet is always dropped. `--dpi-desync-split-pos` sets split position (default 2).
|
||||
If position is higher than packet length, pos=1 is used.
|
||||
This sequence is designed to make reconstruction of critical message as difficult as possible.
|
||||
Fake segments may not be required to bypass some DPIs, but can potentially help if more sophisticated reconstruction
|
||||
algorithms are used.
|
||||
Mode `disorder2` disables sending of fake segments.
|
||||
* `multisplit`. split request at specified in `--dpi-desync-split-pos` positions
|
||||
* `multidisorder`. same as `multisplit` but send in reverse order
|
||||
* `fakedsplit`. split request into 2 segments adding fakes in the middle of them : fake 1st segment, 1st segment, fake 1st segment, 2nd segment
|
||||
* `fakeddisorder`. same as `fakedsplit` but with another order : 2nd segment, fake 1st segment, 1st segment, fake 1st segment
|
||||
|
||||
Split mode is very similar to disorder but without segment reordering :
|
||||
Positions are defined by markers.
|
||||
|
||||
1. fake 1st segment, data filled with zeroes
|
||||
2. 1st segment
|
||||
3. fake 1st segment, data filled with zeroes (2nd copy)
|
||||
4. 2nd segment
|
||||
* **Absolute positive marker** - numeric offset inside one packet or group of packets starting from the start
|
||||
* **Absolute negative marker** - numeric offset inside one packet or group of packets starting from the next byte after the end
|
||||
* **Relative marker** - positive or negative offset relative to a logical position within a packet or group of packets
|
||||
|
||||
Mode `split2` disables sending of fake segments. It can be used as a faster alternative to --wsize.
|
||||
Relative positions :
|
||||
|
||||
In `disorder2` and 'split2` modes no fake packets are sent, so ttl and fooling options are not required.
|
||||
* **method** - HTTP method start ('GET', 'POST', 'HEAD', ...). Method is usually always at position 0 but can shift because of `--methodeol` fooling. If fooled position can become 1 or 2.
|
||||
* **host** - hostname start in a known protocol (http, TLS)
|
||||
* **endhost** - the byte next to the last hostname's byte
|
||||
* **sld** - second level domain start in the hostname
|
||||
* **endsld** - the byte next to the last SLD byte
|
||||
* **midsld** - middle of SLD
|
||||
* **sniext** - start of the data field in the SNI TLS extension. Any extension has 2-byte type and length fields followed by data field.
|
||||
|
||||
`seqovl` adds to the first sent original segment (1st for split, 2nd for disorder) seqovl bytes to the beginning and decreases
|
||||
sequence number.
|
||||
In `split2` mode this creates partially in-window packet. OS receives only in-window part.
|
||||
In `disorder2` mode OS receives fake and real part of the second segment but does not pass received data to the socket until first
|
||||
segment is received. First segment overwrites fake part of the second segment. Then OS passes original data to the socket.
|
||||
Marker list example : `100,midsld,sniext+1,endhost-2,-10`.
|
||||
|
||||
When splitting all markers are resolved to absolute offsets. If a relative position is absent in the current protocol its dropped. Then all resolved offsets are normalized to the current packet offset in multi packet group (multi-packet TLS with kyber, for example). Positions outside of the current packet are dropped. Remaining positions are sorted and deduplicated.
|
||||
|
||||
In `multisplit`or `multidisorder` case split is cancelled if no position remained.
|
||||
|
||||
`fakedsplit` и `fakeddisorder` use only one split position. It's searched from the `--dpi-desync-split-pos` list by a special alorightm.
|
||||
First relative markers are searched. If no suitable found absolute markers are searched. If nothing found position 1 is used.
|
||||
|
||||
For example, `--dpi-desync-split-pos=method+2,midsld,5` means `method+2` for http, `midsld` for TLS and 5 for others.
|
||||
|
||||
### Sequence numbers overlap
|
||||
|
||||
`seqovl` adds to one of the original segment `seqovl` bytes to the beginning and decreases sequence number. For `split` - to the first segment, for `disorder` - to the beginning of the penultimate segment sent (second in the original sequence).
|
||||
|
||||
In `split` mode this creates partially in-window packet. OS receives only in-window part.
|
||||
In `disorder` mode OS receives fake and real part of the second segment but does not pass received data to the socket until first segment is received. First segment overwrites fake part of the second segment. Then OS passes original data to the socket.
|
||||
All unix OS except Solaris preserve last received data. This is not the case for Windows servers and `disorder` with `seqovl` will not work.
|
||||
Disorder requires `seqovl` to be less than `split_pos`. Either statically defined or automatically calculated.
|
||||
Otherwise desync is not possible and will not happen.
|
||||
Disorder requires `seqovl` to be less than split position. Otherwise `seqovl` is not possible and will be cancelled.
|
||||
Method allows to avoid separate fakes. Fakes and real data are mixed.
|
||||
|
||||
### ipv6 specific modes
|
||||
|
||||
`hopbyhop`, `destopt` and `ipfrag1` desync modes (they're not the same as `hopbyhop` fooling !) are ipv6 only. One `hop-by-hop`,
|
||||
`destination options` or `fragment` header is added to all desynced packets.
|
||||
Extra header increases packet size and can't be applied to the maximum size packets.
|
||||
@@ -321,91 +307,36 @@ If it's not possible to send modified packet original one will be sent.
|
||||
The idea here is that DPI sees 0 in the next header field of the main ipv6 header and does not
|
||||
walk through the extension header chain until transport header is found.
|
||||
`hopbyhop`, `destopt`, `ipfrag1` modes can be used with any second phase mode except `ipfrag1+ipfrag2`.
|
||||
For example, `hopbyhop,split2` means split original tcp packet into 2 pieces and add hop-by-hop header to both.
|
||||
For example, `hopbyhop,multisplit` means split original tcp packet into several pieces and add hop-by-hop header to each.
|
||||
With `hopbyhop,ipfrag2` header sequence will be : `ipv6,hop-by-hop,fragment,tcp/udp`.
|
||||
`ipfrag1` mode may not always work without special preparations. See "IP Fragmentation" notices.
|
||||
|
||||
There are DPIs that analyze responses from the server, particularly the certificate from the ServerHello
|
||||
that contain domain name(s). The ClientHello delivery confirmation is an ACK packet from the server
|
||||
with ACK sequence number corresponding to the length of the ClientHello+1.
|
||||
### Server reply reaction
|
||||
|
||||
There are DPIs that analyze responses from the server, particularly the certificate from the ServerHello that contain domain name(s). The ClientHello delivery confirmation is an ACK packet from the server with ACK sequence number corresponding to the length of the ClientHello+1.
|
||||
In the disorder variant, a selective acknowledgement (SACK) usually arrives first, then a full ACK.
|
||||
If, instead of ACK or SACK, there is an RST packet with minimal delay, DPI cuts you off at the request stage.
|
||||
If the RST is after a full ACK after a delay of about ping to the server, then probably DPI acts
|
||||
on the server response. The DPI may be satisfied with good ClientHello and stop monitoring the TCP session
|
||||
without checking ServerHello. Then you were lucky. 'fake' option could work.
|
||||
If it does not stop monitoring and persistently checks the ServerHello, --wssize parameter may help (see CONNTRACK).
|
||||
If the RST is after a full ACK after a delay of about ping to the server, then probably DPI acts on the server response. The DPI may be satisfied with good ClientHello and stop monitoring the TCP session without checking ServerHello. Then you were lucky. 'fake' option could work.
|
||||
If it does not stop monitoring and persistently checks the ServerHello, --wssize parameter may help (see [CONNTRACK](#conntrack)).
|
||||
Otherwise it is hardly possible to overcome this without the help of the server.
|
||||
The best solution is to enable TLS 1.3 support on the server. TLS 1.3 sends the server certificate in encrypted form.
|
||||
This is recommendation to all admins of blocked sites. Enable TLS 1.3. You will give more opportunities to overcome DPI.
|
||||
|
||||
Hosts are extracted from plain http request Host: header and SNI of ClientHello TLS message.
|
||||
Subdomains are applied automatically. gzip lists are supported.
|
||||
|
||||
iptables for performing the attack on the first packet :
|
||||
|
||||
`iptables -t mangle -I POSTROUTING -o <external_interface> -p tcp -m multiport --dports 80,443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass`
|
||||
|
||||
This is good if DPI does not track all requests in http keep-alive session.
|
||||
If it does, then pass all outgoing packets for http and only first data packet for https :
|
||||
|
||||
```
|
||||
iptables -t mangle -I POSTROUTING -o <external_interface> -p tcp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
iptables -t mangle -I POSTROUTING -o <external_interface> -p tcp --dport 80 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
```
|
||||
|
||||
mark is needed to keep away generated packets from NFQUEUE. nfqws sets fwmark when it sends generated packets.
|
||||
nfqws can internally filter marked packets. but when connbytes filter is used without mark filter
|
||||
packet ordering can be changed breaking the whole idea of desync attack.
|
||||
|
||||
### DPI desync combos
|
||||
|
||||
dpi-desync parameter takes up to 3 comma separated arguments.
|
||||
zero phase means tcp connection establishement (before sending data payload). Mode can be `synack`.
|
||||
Hostlist filter is not applicable to the zero phase.
|
||||
Next phases work on packets with data payload.
|
||||
1st phase mode can be `fake`,`rst`,`rstack`, 2nd phase mode - `disorder`,`disorder2`,`split`,`split2`,`ipfrag2`.
|
||||
Can be useful for ISPs with more than one DPI.
|
||||
|
||||
### SYNACK mode
|
||||
|
||||
In geneva docs it's called **TCP turnaround**. Attempt to make the DPI believe the roles of client and server are reversed.
|
||||
|
||||
!!! This mode breaks NAT operation and can be used only if there's no NAT between the attacker's device and the DPI !
|
||||
|
||||
In linux it's required to remove standard firewall rule dropping INVALID packets in the OUTPUT chain,
|
||||
for example : `-A OUTPUT -m state --state INVALID -j DROP`
|
||||
|
||||
In openwrt it's possible to disable the rule for both FORWARD and OUTPUT chains in /etc/config/firewall :
|
||||
```
|
||||
config zone
|
||||
option name 'wan'
|
||||
.........
|
||||
option masq_allow_invalid '1'
|
||||
```
|
||||
Unfortunately there's no OUTPUT only switch. It's not desired to remove the rule from the FORWARD chain.
|
||||
Add the following lines to `/etc/firewall.user` :
|
||||
|
||||
```
|
||||
iptables -D zone_wan_output -m comment --comment '!fw3' -j zone_wan_dest_ACCEPT
|
||||
ip6tables -D zone_wan_output -m comment --comment '!fw3' -j zone_wan_dest_ACCEPT
|
||||
```
|
||||
|
||||
then `/etc/init.d/firewall restart`
|
||||
|
||||
Otherwise raw sending SYN,ACK frame will cause error stopping the further processing.
|
||||
If you realize you don't need the synack mode it's highly suggested to restore drop INVALID rule.
|
||||
|
||||
### SYNDATA mode
|
||||
|
||||
Normally SYNs come without data payload. If it's present it's ignored by all major OS if TCP fast open (TFO) is not involved, but may not be ignored by DPI.
|
||||
Original connections with TFO are not touched because otherwise they would be definitely broken.
|
||||
Without extra parameter payload is 16 zero bytes.
|
||||
|
||||
### Virtual Machines
|
||||
### DPI desync combos
|
||||
|
||||
Most of nfqws packet magic does not work from VMs powered by virtualbox and vmware when network is NATed.
|
||||
Hypervisor forcibly changes ttl and does not forward fake packets.
|
||||
Set up bridge networking.
|
||||
`--dpi-desync` takes up to 3 comma separated modes.
|
||||
|
||||
* 0 phase modes work during the connection establishement : `synack`, `syndata` `--wsize`, `--wssize`. [hostlist](((#multiple-strategies))) filters are not applicable.
|
||||
* In the 1st phase fakes are sent before original data : `fake`, `rst`, `rstack`.
|
||||
* In the 2nd phase original data is sent in a modified way (for example `fakedsplit` or `ipfrag2`).
|
||||
|
||||
Modes must be specified in phase ascending order.
|
||||
|
||||
### CONNTRACK
|
||||
|
||||
@@ -477,7 +408,7 @@ to extract the host name. But it works with auto hostlist profiles.
|
||||
`--dpi-desync-cutoff` allows you to set the threshold at which it stops applying dpi-desync.
|
||||
Can be prefixed with 'n', 'd', 's' symbol the same way as `--wssize-cutoff`.
|
||||
Useful with `--dpi-desync-any-protocol=1`.
|
||||
If the connection falls out of the conntrack and --dpi-desync-cutoff is set, dpi desync will not be applied.
|
||||
If the connection falls out of the conntrack and `--dpi-desync-cutoff` is set, `dpi desync` will not be applied.
|
||||
|
||||
Set conntrack timeouts appropriately.
|
||||
|
||||
@@ -491,11 +422,7 @@ If nfqws receives a partial ClientHello it begins reassemble session. Packets ar
|
||||
Then they go through desync using fully reassembled message.
|
||||
On any error reassemble is cancelled and all delayed packets are sent immediately without desync.
|
||||
|
||||
There is special support for all tcp split options for multi segment TLS. Split position is treated
|
||||
as message-oriented, not packet oriented. For example, if your client sends TLS ClientHello with size 2000
|
||||
and SNI is at 1700, desync mode is fake,split2, then fake is sent first, then original first segment
|
||||
and the last splitted segment. 3 segments total.
|
||||
|
||||
There is special support for all tcp split options for multi segment TLS. Split position is treated as message-oriented, not packet oriented. For example, if your client sends TLS ClientHello with size 2000 and SNI is at 1700, desync mode is `fake,multisplit`, then fake is sent first, then original first segment and the last splitted segment. 3 segments total.
|
||||
|
||||
### UDP support
|
||||
|
||||
@@ -575,9 +502,9 @@ nfqws sees packets with internal network source address. If fragmented NAT does
|
||||
This results in attempt to send packets to internet with internal IP address.
|
||||
You need to use nftables instead with hook priority 101 or higher.
|
||||
|
||||
### multiple strategies
|
||||
### Multiple strategies
|
||||
|
||||
`nfqws` can apply different strategies to different requests. It's done with multiple desync profiles.
|
||||
**nfqws** can apply different strategies to different requests. It's done with multiple desync profiles.
|
||||
Profiles are delimited by the `--new` parameter. First profile is created automatically and does not require `--new`.
|
||||
Each profile has a filter. By default it's empty and profile matches any packet.
|
||||
Filter can have hard parameters : ip version, ipset and tcp/udp port range.
|
||||
@@ -593,7 +520,7 @@ Otherwise verification goes to the next profile.
|
||||
It's possible that before knowing L7 and hostname connection is served by one profile and after
|
||||
this information is revealed it's switched to another profile.
|
||||
If you use 0-phase desync methods think carefully what can happen during strategy switch.
|
||||
Use `--debug` logging to understand better what `nfqws` does.
|
||||
Use `--debug` logging to understand better what **nfqws** does.
|
||||
|
||||
Profiles are numbered from 1 to N. There's last empty profile in the chain numbered 0.
|
||||
It's used when no filter matched.
|
||||
@@ -605,6 +532,99 @@ This way you may never unblock all resources and only confuse yourself.
|
||||
IMPORTANT : user-mode ipset implementation was not designed as a kernel version replacement. Kernel version is much more effective.
|
||||
It's for the systems that lack ipset support : Windows and Linux without nftables and ipset kernel modules (Android, for example).
|
||||
|
||||
### Virtual machines
|
||||
|
||||
Most of nfqws packet magic does not work from VMs powered by virtualbox and vmware when network is NATed.
|
||||
Hypervisor forcibly changes TTL and does not forward fake packets.
|
||||
Set up bridge networking.
|
||||
|
||||
### IPTABLES for nfqws
|
||||
|
||||
This is the common way to redirect some traffic to nfqws :
|
||||
|
||||
```
|
||||
iptables -t mangle -I POSTROUTING -o <wan_interface> -p tcp -m multiport --dports 80,443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
```
|
||||
|
||||
This variant works if DPI is stateful and does not track all packets separately in search for "bad requests". If it's stateless you have to redirect all outgoing plain http packets.
|
||||
|
||||
```
|
||||
iptables -t mangle -I POSTROUTING -o <wan_interface> -p tcp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
iptables -t mangle -I POSTROUTING -o <wan_interface> -p tcp --dport 80 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
```
|
||||
|
||||
mark bit is used to prevent loops. **nfqws** sets this mark in each injected packet.
|
||||
It's also necessary for correct injected packet ordering and for deadlock prevention.
|
||||
|
||||
`autottl` requires incoming `SYN,ACK` packet or first reply packet (it's usually the same).
|
||||
|
||||
`autohostlist` needs incoming `RST` and `http redirect`.
|
||||
|
||||
It's possible to build tcp flags and u32 based filter but connbytes is easier.
|
||||
|
||||
`
|
||||
iptables -t mangle -I PREROUTING -i <wan_interface> -p tcp -m multiport --sports 80,443 -m connbytes --connbytes-dir=reply --connbytes-mode=packets --connbytes 1:3 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
`
|
||||
|
||||
For QUIC :
|
||||
|
||||
```
|
||||
iptables -t mangle -I POSTROUTING -o <wan_interface> -p udp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass
|
||||
```
|
||||
|
||||
6 packets cover possible retransmissions of quic initials and feed `autohostlist` mode.
|
||||
|
||||
### NFTABLES for nfqws
|
||||
|
||||
This is the start configuration :
|
||||
|
||||
```
|
||||
IFACE_WAN=wan
|
||||
|
||||
nft create table inet ztest
|
||||
|
||||
nft add chain inet ztest post "{type filter hook postrouting priority mangle;}"
|
||||
nft add rule inet ztest post oifname $IFACE_WAN meta mark and 0x40000000 == 0 tcp dport "{80,443}" ct original packets 1-6 queue num 200 bypass
|
||||
nft add rule inet ztest post oifname $IFACE_WAN meta mark and 0x40000000 == 0 udp dport 443 ct original packets 1-6 queue num 200 bypass
|
||||
|
||||
# auto hostlist with avoiding wrong ACK numbers in RST,ACK packets sent by russian DPI
|
||||
sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1
|
||||
nft add chain inet ztest pre "{type filter hook prerouting priority filter;}"
|
||||
nft add rule inet ztest pre iifname $IFACE_WAN tcp sport "{80,443}" ct reply packets 1-3 queue num 200 bypass
|
||||
```
|
||||
|
||||
To engage `datanoack` or `ipfrag` for passthrough traffic special POSTNAT configuration is required. Generated packets must be marked as **notrack** in the early stage to avoid being invalidated by linux conntrack.
|
||||
|
||||
```
|
||||
IFACE_WAN=wan
|
||||
|
||||
nft create table inet ztest
|
||||
|
||||
nft add chain inet ztest postnat "{type filter hook postrouting priority srcnat+1;}"
|
||||
nft add rule inet ztest postnat oifname $IFACE_WAN meta mark and 0x40000000 == 0 tcp dport "{80,443}" ct original packets 1-6 queue num 200 bypass
|
||||
nft add rule inet ztest postnat oifname $IFACE_WAN meta mark and 0x40000000 == 0 udp dport 443 ct original packets 1-6 queue num 200 bypass
|
||||
|
||||
nft add chain inet ztest predefrag "{type filter hook output priority -401;}"
|
||||
nft add rule inet ztest predefrag "mark & 0x40000000 != 0x00000000 notrack"
|
||||
```
|
||||
|
||||
Delete nftable :
|
||||
|
||||
```
|
||||
nft delete table inet ztest
|
||||
```
|
||||
|
||||
### Flow offloading
|
||||
|
||||
If your device supports flow offloading (hardware acceleration) iptables and nftables may not work. With offloading enabled packets bypass standard netfilter flow. It must be either disabled or selectively controlled.
|
||||
|
||||
Newer linux kernels have software flow offloading (SFO). The story is the same with SFO.
|
||||
|
||||
In `iptables` flow offloading is controlled by openwrt proprietary extension `FLOWOFFLOAD`. Newer `nftables` implement built-in offloading support.
|
||||
|
||||
Flow offloading does not interfere with **tpws** and `OUTPUT` traffic. It only breaks nfqws that fools `FORWARD` traffic.
|
||||
|
||||
|
||||
## tpws
|
||||
|
||||
tpws is transparent proxy.
|
||||
@@ -637,6 +657,7 @@ tpws is transparent proxy.
|
||||
--skip-nodelay ; do not set TCP_NODELAY for outgoing connections. incompatible with split.
|
||||
--local-tcp-user-timeout=<seconds> ; set tcp user timeout for local leg (default : 10, 0 = system default)
|
||||
--remote-tcp-user-timeout=<seconds> ; set tcp user timeout for remote leg (default : 20, 0 = system default)
|
||||
--fix-seg=<int> ; recover failed TCP segmentation at the cost of slowdown. wait up to N msec.
|
||||
--no-resolve ; disable socks5 remote dns
|
||||
--resolver-threads=<int> ; number of resolver worker threads
|
||||
--maxconn=<max_connections> ; max number of local legs
|
||||
@@ -644,7 +665,8 @@ tpws is transparent proxy.
|
||||
; its worth to make a reserve with 1.5 multiplier. by default maxfiles is (X*connections)*1.5+16
|
||||
--max-orphan-time=<sec> ; if local leg sends something and closes and remote leg is still connecting then cancel connection attempt after N seconds
|
||||
|
||||
--new ; begin new strategy
|
||||
--new ; begin new strategy (new profile)
|
||||
--skip ; do not use this profile
|
||||
--filter-l3=ipv4|ipv6 ; L3 protocol filter. multiple comma separated values allowed.
|
||||
--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.
|
||||
@@ -658,10 +680,9 @@ tpws is transparent proxy.
|
||||
--hostlist-auto-fail-time=<int> ; all failed attemps must be within these seconds (default : 60)
|
||||
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
||||
|
||||
--split-http-req=method|host ; split http request at specified logical position.
|
||||
--split-tls=sni|sniext ; split at specified logical part of TLS ClientHello
|
||||
--split-pos=<numeric_offset> ; split at specified pos. split-http-req takes precedence over split-pos for http reqs.
|
||||
--split-any-protocol ; split not only http and https
|
||||
--split-pos=N|-N|marker+N|marker-N ; comma separated list of split positions
|
||||
; markers: method,host,endhost,sld,endsld,midsld,sniext
|
||||
--split-any-protocol ; split not only http and TLS
|
||||
--disorder[=http|tls] ; when splitting simulate sending second fragment first
|
||||
--oob[=http|tls] ; when splitting send out of band byte. default is HEX 0x00.
|
||||
--oob-data=<char>|0xHEX ; override default 0x00 OOB byte.
|
||||
@@ -675,10 +696,9 @@ tpws is transparent proxy.
|
||||
--methodspace ; add extra space after method
|
||||
--methodeol ; add end-of-line before method
|
||||
--unixeol ; replace 0D0A to 0A
|
||||
--tlsrec=sni|sniext ; make 2 TLS records. split at specified logical part. don't split if SNI is not present.
|
||||
--tlsrec=N|-N|marker+N|marker-N ; make 2 TLS records. split at specified logical part. don't split if SNI is not present.
|
||||
--tlsrec-pos=<pos> ; make 2 TLS records. split at specified pos
|
||||
--mss=<int> ; set client MSS. forces server to split messages but significantly decreases speed !
|
||||
--mss-pf=[~]port1[-port2] ; MSS port filter. ~ means negation
|
||||
--tamper-start=[n]<pos> ; start tampering only from specified outbound stream position. byte pos or block number ('n'). default is 0.
|
||||
--tamper-cutoff=[n]<pos> ; do not tamper anymore after specified outbound stream position. byte pos or block number ('n'). default is unlimited.
|
||||
--daemon ; daemonize
|
||||
@@ -687,13 +707,49 @@ tpws is transparent proxy.
|
||||
--uid=uid[:gid] ; drop root privs
|
||||
```
|
||||
|
||||
The manipulation parameters can be combined in any way.
|
||||
### TCP segmentation in tpws
|
||||
|
||||
`split-http-req` takes precedence over split-pos for http reqs.
|
||||
**tpws** like **nfqws** supports multiple splits. Split [markers](#tcp-segmentation) are specified in `--split-pos` parameter.
|
||||
|
||||
split-pos works by default only on http and TLS ClientHello. use `--split-any-protocol` to act on any packet
|
||||
On the socket level there's no guaranteed way to force OS to send pieces of data in separate packets. OS has a send buffer for each socket. If `TCP_NODELAY` socket option is enabled and send buffer is empty OS will likely send data immediately. If send buffer is not empty OS will coalesce it with new data and send in one packet if possible.
|
||||
|
||||
tpws can bind to multiple interfaces and IP addresses (up to 32).
|
||||
In practice outside of massive transmissions it's usually enough to enable `TCP_NODELAY` and use separate `send()` calls to force custom TCP segmentation. But if there're too many split segments Linux can combined some pieces and break desired behaviour. BSD and Windows are more predictable in this case. That's why it's not recommended to use too many splits. Tests revealed that 8+ can become problematic.
|
||||
|
||||
Since linux kernel 4.6 **tpws** can recognize TCP segmentation failures and warn about them. `--fix-seg` can fix segmentation failures at the cost of some slowdown. It waits for several msec until all previous data is sent. This breaks async processing model and slows down every other connection going through **tpws**. Thus it's not recommended on highly loaded systems. But can be compromise for home systems.
|
||||
|
||||
If you're attempting to split massive transmission with `--split-any-protocol` option it will definitely cause massive segmentation failures. Do not do that without `--tamper-start` and `--tamper-cutoff` limiters.
|
||||
|
||||
**tpws** works on socket level and receives in one shot long requests (TLS with kyber) that should normally require several TCP packets. It tampers entire received block without knowing how much packets it will take. OS will do additional segmenation to meet MTU.
|
||||
|
||||
`--disorder` sends every odd packet with TTL=1. Server receives even packets fastly. Then client OS retransmits odd packets with normal TTL and server receives them. In case of 6 segments server and DPI will see them in this order : `2 4 6 1 3 5`. This way of disorder causes some delays. Default retransmission timeout in Linux is 200 ms.
|
||||
|
||||
`--oob` sends one out-of-band byte in the end of the first split segment.
|
||||
|
||||
`--oob` and `--disorder` can be combined only in Linux. Others OS do not handle this correctly.
|
||||
|
||||
### TLSREC
|
||||
|
||||
`--tlsrec` allow to split TLS ClientHello into 2 TLS records in one TCP segment. It accepts single pos marker.
|
||||
|
||||
`--tlsrec` breaks significant number of sites. Crypto libraries on servers usually accept fine modified ClientHello but middleboxes such as CDNs and ddos guards - not always. Use of `--tlsrec` without filters is discouraged.
|
||||
|
||||
### MSS
|
||||
|
||||
`--mss` sets TCP_MAXSEG socket option. Client sets this value in MSS TCP option in the SYN packet.
|
||||
Server replies with it's own MSS in SYN,ACK packet. Usually servers lower their packet sizes but they still don't fit to supplied MSS. The greater MSS client sets the bigger server's packets will be.
|
||||
If it's enough to split TLS 1.2 ServerHello, it may fool DPI that checks certificate domain name.
|
||||
This scheme may significantly lower speed. Hostlist filter is possible only in socks mode if client uses remote resolving (firefox `network.proxy.socks_remote_dns`).
|
||||
`--mss` is not required for TLS1.3. If TLS1.3 is negotiable then MSS make things only worse. Use only if nothing better is available. Works only in Linux, not BSD or MacOS.
|
||||
|
||||
### Other tamper options
|
||||
|
||||
`--hostpad=<bytes>` adds padding headers before `Host:` with specified number of bytes. If `<bytes>` is too large headers are split by 2K. Padding more that 64K is not supported and not accepted by http servers.
|
||||
|
||||
It's useful against stateful DPI's that reassemble only limited amount of data. Increase padding `<bytes>` until website works. If minimum working `<bytes>` is close to MTU then it's likely DPI is not reassembling packets. Then it's better to use regular split instead of `--hostpad`.
|
||||
|
||||
### Supplementary options
|
||||
|
||||
**tpws** can bind to multiple interfaces and IP addresses (up to 32).
|
||||
|
||||
Port number is always the same.
|
||||
|
||||
@@ -729,44 +785,83 @@ To bind to a specific ip when its interface may not be configured yet do : `--bi
|
||||
|
||||
It's possible to bind to any nonexistent address in transparent mode but in socks mode address must exist.
|
||||
|
||||
In socks proxy mode no additional system privileges are required. Connections to local IPs of the system where tpws runs are prohibited.
|
||||
In socks proxy mode no additional system privileges are required. Connections to local IPs of the system where **tpws** runs are prohibited.
|
||||
tpws supports remote dns resolving (curl : `--socks5-hostname` firefox : `socks_remote_dns=true`) , but does it in blocking mode.
|
||||
|
||||
tpws uses async sockets for all activities. Domain names are resolved in multi threaded pool.
|
||||
**tpws** uses async sockets for all activities. Domain names are resolved in multi threaded pool.
|
||||
Resolving does not freeze other connections. But if there're too many requests resolving delays may increase.
|
||||
Number of resolver threads is choosen automatically proportinally to `--maxconn` and can be overriden using `--resolver-threads`.
|
||||
To disable hostname resolve use `--no-resolve` option.
|
||||
|
||||
`--disorder` is an additional flag to any split option.
|
||||
It tries to simulate `--disorder2` option of `nfqws` using standard socket API without the need of additional privileges.
|
||||
This works fine in Linux and MacOS but unexpectedly in FreeBSD and OpenBSD
|
||||
(system sends second fragment then the whole packet instead of the first fragment).
|
||||
### Multiple strategies
|
||||
|
||||
`--tlsrec` and `--tlsrec-pos` allow to split TLS ClientHello into 2 TLS records in one TCP segment.
|
||||
`--tlsrec=sni` splits between 1st and 2nd chars of the hostname. No split occurs if SNI is not present.
|
||||
`--tlsrec-pos` splits at specified position. If TLS data block size is too small pos=1 is applied.
|
||||
`--tlsrec` can be combined with `--split-pos` and `--disorder`.
|
||||
`--tlsrec` breaks significant number of sites. Crypto libraries on end servers usually accept fine modified ClientHello
|
||||
but middleboxes such as CDNs and ddos guards - not always.
|
||||
Use of `--tlsrec` without filters is discouraged.
|
||||
|
||||
`--mss` sets TCP_MAXSEG socket option. Client sets this value in MSS TCP option in the SYN packet.
|
||||
Server replies with it's own MSS in SYN,ACK packet. Usually servers lower their packet sizes but they still don't
|
||||
fit to supplied MSS. The greater MSS client sets the bigger server's packets will be.
|
||||
If it's enough to split TLS 1.2 ServerHello, it may fool DPI that checks certificate domain name.
|
||||
This scheme may significantly lower speed. Hostlist filter is possible only in socks mode if client uses remote resolving (firefox `network.proxy.socks_remote_dns`).
|
||||
`--mss` is not required for TLS1.3. If TLS1.3 is negotiable then MSS make things only worse.
|
||||
Use only if nothing better is available. Works only in Linux, not BSD or MacOS.
|
||||
|
||||
### multiple strategies
|
||||
|
||||
`tpws` supports multiple strategies as well. They work mostly like with `nfqws` with minimal differences.
|
||||
`filter-udp` is absent because `tpws` does not support udp. 0-phase desync methods (`--mss`) can work with hostlist in socks modes with remote hostname resolve.
|
||||
**tpws** like **nfqws** supports multiple strategies. They work mostly like with **nfqws** with minimal differences.
|
||||
`filter-udp` is absent because **tpws** does not support udp. 0-phase desync methods (`--mss`) can work with hostlist in socks modes with remote hostname resolve.
|
||||
This is the point where you have to plan profiles carefully. If you use `--mss` and hostlist filters, behaviour can be different depending on remote resolve feature enabled or not.
|
||||
Use `--mss` both in hostlist profile and profile without hostlist.
|
||||
Use `curl --socks5` and `curl --socks5-hostname` to issue two kinds of proxy queries.
|
||||
See `--debug` output to test your setup.
|
||||
|
||||
### IPTABLES for tpws
|
||||
|
||||
Use the following rules to redirect TCP connections to 'tpws' :
|
||||
```
|
||||
iptables -t nat -I OUTPUT -o <wan_interface> -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to 127.0.0.127:988
|
||||
iptables -t nat -I PREROUTING -i <lan_interface> -p tcp --dport 80 -j DNAT --to 127.0.0.127:988
|
||||
```
|
||||
|
||||
First rule redirects outgoing from the same system traffic, second redirects passthrough traffic.
|
||||
|
||||
DNAT to localhost works only in the **OUTPUT** chain and does not work in the **PREROUTING** chain without setting this sysctl :
|
||||
|
||||
`sysctl -w net.ipv4.conf.<lan_interface>.route_localnet=1`
|
||||
|
||||
It's also possible to use `-j REDIRECT --to-port 988` instead of DNAT but in the latter case transparent proxy must listen on all IP addresses or on a LAN interface address. It's not too good to listen on all IP and it's not trivial to get specific IP in a shell script. `route_localnet` has it's own security impact if not protected by additional rules. You open `127.0.0.0/8` subnet to the net.
|
||||
|
||||
This is how to open only single `127.0.0.127` address :
|
||||
```
|
||||
iptables -A INPUT ! -i lo -d 127.0.0.127 -j ACCEPT
|
||||
iptables -A INPUT ! -i lo -d 127.0.0.0/8 -j DROP
|
||||
```
|
||||
|
||||
Owner filter is required to avoid redirection loops. **tpws** must be run with `--user tpws` parameter.
|
||||
|
||||
ip6tables work almost the same with minor differences. ipv6 addresses should be enclosed in square brackets :
|
||||
```
|
||||
ip6tables -t nat -I OUTPUT -o <wan_interface> -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to [::1]:988
|
||||
```
|
||||
|
||||
There's no `route_localnet` for ipv6. DNAT to localhost (`::1`) is possible only in **OUTPUT** chain. In **PREROUTING** chain DNAT is possible to any global address or link local address of the interface where packet came from.
|
||||
|
||||
### NFTABLES for tpws
|
||||
|
||||
Base nftables scheme :
|
||||
```
|
||||
IFACE_WAN=wan
|
||||
IFACE_LAN=br-lan
|
||||
|
||||
sysctl -w net.ipv4.conf.$IFACE_LAN.route_localnet=1
|
||||
|
||||
nft create table inet ztest
|
||||
|
||||
nft create chain inet ztest localnet_protect
|
||||
nft add rule inet ztest localnet_protect ip daddr 127.0.0.127 return
|
||||
nft add rule inet ztest localnet_protect ip daddr 127.0.0.0/8 drop
|
||||
nft create chain inet ztest input "{type filter hook input priority filter - 1;}"
|
||||
nft add rule inet ztest input iif != "lo" jump localnet_protect
|
||||
|
||||
nft create chain inet ztest dnat_output "{type nat hook output priority dstnat;}"
|
||||
nft add rule inet ztest dnat_output meta skuid != tpws oifname $IFACE_WAN tcp dport { 80, 443 } dnat ip to 127.0.0.127:988
|
||||
nft create chain inet ztest dnat_pre "{type nat hook prerouting priority dstnat;}"
|
||||
nft add rule inet ztest dnat_pre meta iifname $IFACE_LAN tcp dport { 80, 443 } dnat ip to 127.0.0.127:988
|
||||
```
|
||||
|
||||
Delete nftable :
|
||||
```
|
||||
nft delete table inet ztest
|
||||
```
|
||||
|
||||
|
||||
## Ways to get a list of blocked IP
|
||||
|
||||
nftables can't work with ipsets. Native nf sets require lots of RAM to load large ip lists with subnets and intervals.
|
||||
@@ -834,8 +929,8 @@ LISTS_RELOAD=- disables reloading ip list backend.
|
||||
|
||||
## Domain name filtering
|
||||
|
||||
An alternative to ipset is to use tpws or nfqws with a list(s) of domains.
|
||||
Both `tpws` and `nfqws` take any number of include (`--hostlist`) and exclude (`--hostlist-exclude`) domain lists.
|
||||
An alternative to ipset is to use **tpws** or **nfqws** with a list(s) of domains.
|
||||
Both **tpws** and **nfqws** take any number of include (`--hostlist`) and exclude (`--hostlist-exclude`) domain lists.
|
||||
All lists of the same type are combined internally leaving only 2 lists : include and exclude.
|
||||
|
||||
Exclude list is checked first. Fooling is cancelled if domain belongs to exclude list.
|
||||
@@ -852,13 +947,13 @@ and 1 exclude list
|
||||
|
||||
`ipset/zapret-hosts-users-exclude.txt.gz` or `ipset/zapret-hosts-users-exclude.txt`
|
||||
|
||||
If `MODE_FILTER=hostlist` all present lists are passed to `nfqws` or `tpws`.
|
||||
If `MODE_FILTER=hostlist` all present lists are passed to **nfqws** or **tpws**.
|
||||
If all include lists are empty it works like no include lists exist at all.
|
||||
If you need "all except" mode you dont have to delete zapret-hosts-users.txt. Just make it empty.
|
||||
|
||||
Subdomains auto apply. For example, "ru" in the list affects "*.ru" .
|
||||
|
||||
tpws and nfqws automatically reload lists if their modification date is changed.
|
||||
**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 !
|
||||
@@ -874,7 +969,7 @@ In case of nfqws it's required to redirect both incoming and outgoing traffic to
|
||||
It's strongly recommended to use connbytes filter or nfqws will process gigabytes of incoming traffic.
|
||||
For the same reason it's not recommended to use autohostlist mode in BSDs. BSDs do not support connbytes or similar mechanism.
|
||||
|
||||
nfqws и tpws detect the folowing situations :
|
||||
**nfqws** и **tpws** detect the folowing situations :
|
||||
1) [nfqws] Multiple retransmissions of the first request inside a TCP session having host.
|
||||
2) [nfqws,tpws] RST in response to the first request.
|
||||
3) [nfqws,tpws] HTTP redirect in response to the first http request with 2nd level domain diferent from the original.
|
||||
@@ -920,11 +1015,11 @@ On openwrt by default `nftables` is selected on `firewall4` based systems.
|
||||
`FWTYPE=iptables`
|
||||
|
||||
With `nftables` post-NAT scheme is used by default. It allows more DPI attacks on forwarded traffic.
|
||||
It's possible to use `iptables`-like pre-NAT scheme. `nfqws` will see client source IPs and display them in logs.
|
||||
It's possible to use `iptables`-like pre-NAT scheme. **nfqws** will see client source IPs and display them in logs.
|
||||
|
||||
`#POSTNAT=0`
|
||||
|
||||
There'are 3 standard options configured separately and independently : `tpws-socks`, `tpws`, `nfqws`.
|
||||
There'are 3 standard options configured separately and independently : `tpws-socks`, **tpws**, **nfqws**.
|
||||
They can be used alone or combined. Custom scripts in `init.d/{sysv,openwrt,macos}/custom.d` are always applied.
|
||||
|
||||
`tpws-socks` requires daemon parameter configuration but does not require traffic interception.
|
||||
@@ -943,45 +1038,45 @@ Don't use `<HOSTLIST>` in highly specialized profiles. Use your own filter or ho
|
||||
If any other profile adds something this profile accepts the change automatically.
|
||||
|
||||
|
||||
`tpws` socks proxy mode switch
|
||||
**tpws** socks proxy mode switch
|
||||
|
||||
`TPWS_SOCKS_ENABLE=0`
|
||||
|
||||
Listening tcp port for `tpws` proxy mode.
|
||||
Listening tcp port for **tpws** proxy mode.
|
||||
|
||||
`TPPORT_SOCKS=987`
|
||||
|
||||
`tpws` socks mode parameters
|
||||
**tpws** socks mode parameters
|
||||
|
||||
```
|
||||
TPWS_SOCKS_OPT="
|
||||
--filter-tcp=80 --methodeol <HOSTLIST> --new
|
||||
--filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
|
||||
--filter-tcp=443 --split-pos=1,midsld --disorder <HOSTLIST>"
|
||||
"
|
||||
```
|
||||
|
||||
`tpws` transparent mode switch
|
||||
**tpws** transparent mode switch
|
||||
|
||||
`TPWS_ENABLE=0`
|
||||
|
||||
`tpws` transparent mode target ports
|
||||
**tpws** transparent mode target ports
|
||||
|
||||
`TPWS_PORTS=80,443`
|
||||
|
||||
`tpws` transparent mode parameters
|
||||
**tpws** transparent mode parameters
|
||||
|
||||
```
|
||||
TPWS_OPT="
|
||||
--filter-tcp=80 --methodeol <HOSTLIST> --new
|
||||
--filter-tcp=443 --split-tls=sni --disorder <HOSTLIST>
|
||||
--filter-tcp=443 --split-pos=1,midsld --disorder <HOSTLIST>"
|
||||
"
|
||||
```
|
||||
|
||||
`nfqws` enable switch
|
||||
**nfqws** enable switch
|
||||
|
||||
`NFQWS_ENABLE=0`
|
||||
|
||||
`nfqws` port targets for `connbytes`-limited interception. `connbytes` allows to intercept only starting packets from connections.
|
||||
**nfqws** port targets for `connbytes`-limited interception. `connbytes` allows to intercept only starting packets from connections.
|
||||
This is more effective kernel-mode alternative to `nfqws --dpi-desync-cutoff=nX`.
|
||||
|
||||
```
|
||||
@@ -1009,12 +1104,12 @@ It's advised also to remove these ports from `connbytes`-limited interception li
|
||||
#NFQWS_PORTS_UDP_KEEPALIVE=
|
||||
```
|
||||
|
||||
`nfqws` parameters
|
||||
**nfqws** parameters
|
||||
|
||||
```
|
||||
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-tcp=80 --dpi-desync=fake,multisplit --dpi-desync-split-pos=method+2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
|
||||
--filter-tcp=443 --dpi-desync=fake,multidisorder --dpi-desync-split-pos=1,midsld --dpi-desync-fooling=badseq,md5sig <HOSTLIST> --new
|
||||
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST_NOAUTO>
|
||||
"
|
||||
```
|
||||
@@ -1232,33 +1327,29 @@ For low storage openwrt see `init.d/openwrt-minimal`.
|
||||
|
||||
### Android
|
||||
|
||||
Its not possible to use nfqws and tpws in transparent proxy mode without root privileges.
|
||||
Without root tpws can run in --socks mode.
|
||||
Its not possible to use **nfqws** and **tpws** in transparent proxy mode without root privileges. Without root **tpws** can run in `--socks` mode.
|
||||
|
||||
Android has NFQUEUE and nfqws should work.
|
||||
Android has NFQUEUE and **nfqws** should work.
|
||||
|
||||
There's no ipset support unless you run custom kernel. In common case task of bringing up ipset
|
||||
on android is ranging from "not easy" to "almost impossible", unless you find working kernel
|
||||
image for your device.
|
||||
There's no `ipset` support unless you run custom kernel. In common case task of bringing up `ipset` on android is ranging from "not easy" to "almost impossible", unless you find working kernel image for your device.
|
||||
|
||||
Android does not use /etc/passwd, `tpws --user` won't work. There's replacement.
|
||||
Use numeric uids in `--uid` option.
|
||||
Its recommended to use gid 3003 (AID_INET), otherwise tpws will not have inet access.
|
||||
Although linux binaries work it's recommended to use Android specific ones. They have no problems with user names, local time, DNS, ...
|
||||
Its recommended to use gid 3003 (AID_INET), otherwise **tpws** will not have inet access.
|
||||
|
||||
Example : `--uid 1:3003`
|
||||
|
||||
In iptables use : `! --uid-owner 1` instead of `! --uid-owner tpws`.
|
||||
|
||||
Nfqws should be executed with `--uid 1`. Otherwise on some devices or firmwares kernel may partially hang. Looks like processes with certain uids can be suspended. With buggy chineese cellular interface driver this can lead to device hang.
|
||||
**nfqws** should be executed with `--uid 1`. Otherwise on some devices or firmwares kernel may partially hang. Looks like processes with certain uids can be suspended. With buggy chineese cellular interface driver this can lead to device hang.
|
||||
|
||||
Write your own shell script with iptables and tpws, run it using your root manager.
|
||||
Write your own shell script with iptables and **tpws**, run it using your root manager.
|
||||
Autorun scripts are here :
|
||||
|
||||
magisk : `/data/adb/service.d`
|
||||
|
||||
supersu : `/system/su.d`
|
||||
|
||||
How to run tpws on root-less android.
|
||||
How to run **tpws** on root-less android.
|
||||
You can't write to `/system`, `/data`, can't run from sd card.
|
||||
Selinux prevents running executables in `/data/local/tmp` from apps.
|
||||
Use adb and adb shell.
|
||||
@@ -1274,11 +1365,11 @@ Now its possible to run `/data/local/tmp/zapret/tpws` from any app such as taske
|
||||
|
||||
### FreeBSD, OpenBSD, MacOS
|
||||
|
||||
see docs/bsd.eng.md
|
||||
see [BSD documentation](./bsd.en.md)
|
||||
|
||||
### Windows (WSL)
|
||||
|
||||
see docs/windows.eng.md
|
||||
see [Windows documentation](./windows.en.md)
|
||||
|
||||
### Other devices
|
||||
|
||||
@@ -1292,7 +1383,7 @@ You will need :
|
||||
* root shell access. true sh shell, not microtik-like console
|
||||
* startup hook
|
||||
* r/w partition to store binaries and startup script with executable permission (+x)
|
||||
* tpws can be run almost anywhere but nfqws require kernel support for NFQUEUE. Its missing in most firmwares.
|
||||
* **tpws** can be run almost anywhere but **nfqws** require kernel support for NFQUEUE. Its missing in most firmwares.
|
||||
* too old 2.6 kernels are unsupported and can cause errors. newer 2.6 kernels are OK.
|
||||
If binaries crash with segfault (rare but happens on some kernels) try to unpack upx like this : upx -d tpws.
|
||||
|
||||
@@ -1302,3 +1393,17 @@ Dont ask me how to do it. Its different for all firmwares and requires studying.
|
||||
Find manual or reverse engineer yourself.
|
||||
Check for race conditions. Firmware can clear or modify iptables after your startup script.
|
||||
If this is the case then run another script in background and add some delay there.
|
||||
|
||||
## Donations
|
||||
|
||||
Are welcome here :
|
||||
|
||||
<img src=https://cdn-icons-png.flaticon.com/16/14446/14446252.png alt="USDT" style="vertical-align: middle;"/> USDT
|
||||
```
|
||||
0x3d52Ce15B7Be734c53fc9526ECbAB8267b63d66E
|
||||
```
|
||||
|
||||
<img src=https://cdn-icons-png.flaticon.com/16/5968/5968260.png alt="USDT" style="vertical-align: middle;"/> BTC
|
||||
```
|
||||
bc1qhqew3mrvp47uk2vevt5sctp7p2x9m7m5kkchve
|
||||
```
|
2283
docs/readme.md
Normal file
2283
docs/readme.md
Normal file
File diff suppressed because it is too large
Load Diff
2090
docs/readme.txt
2090
docs/readme.txt
File diff suppressed because it is too large
Load Diff
@@ -1,55 +1,68 @@
|
||||
tpws
|
||||
----
|
||||
# Windows
|
||||
|
||||
Запуск tpws возможен только в Linux варианте под WSL.
|
||||
## tpws
|
||||
|
||||
Запуск tpws возможен только в Linux варианте под **WSL** _(Windows Subsystem for Linux)_.
|
||||
Нативного варианта под Windows нет, поскольку он использует epoll, которого под windows не существует.
|
||||
|
||||
tpws в режиме socks можно запускать под более-менее современными билдами windows 10 и windows server
|
||||
с установленным WSL. Совсем не обязательно устанавливать дистрибутив убунту, как вам напишут почти в каждой
|
||||
статье про WSL, которую вы найдете в сети. tpws - статический бинарик, ему дистрибутив не нужен.
|
||||
|
||||
Установить WSL : dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all
|
||||
Скопировать на целевую систему binaries/x86_64/tpws_wsl.tgz.
|
||||
Выполнить : wsl --import tpws "%USERPROFILE%\tpws" tpws_wsl.tgz
|
||||
Запустить : wsl -d tpws --exec /tpws --uid=1 --no-resolve --socks --bind-addr=127.0.0.1 --port=1080 <параметры_дурения>
|
||||
Прописать socks 127.0.0.1:1080 в броузер или другую программу.
|
||||
Установить WSL :
|
||||
`dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all`
|
||||
|
||||
Удаление : wsl --unregister tpws
|
||||
Скопировать на целевую систему `binaries/x86_64/tpws_wsl.tgz`.
|
||||
|
||||
Проверено на windows 10 build 19041 (20.04).
|
||||
Выполнить :
|
||||
`wsl --import tpws "%USERPROFILE%\tpws" tpws_wsl.tgz`
|
||||
|
||||
Не работают функции --oob и --mss из-за ограничений реализации WSL.
|
||||
--disorder не работает из-за особенностей tcp/ip стека windows.
|
||||
Может не срабатывать детект RST в autohostlist.
|
||||
WSL может глючить со splice, приводя к зацикливанию процесса. Может потребоваться --nosplice.
|
||||
Не поддерживается tcp user timeout.
|
||||
Чтобы избавиться от исообщений об ошибке добавляйте "--local-tcp-user-timeout=0 --remote-tcp-user-timeout=0".
|
||||
Запустить :
|
||||
`wsl -d tpws --exec /tpws --uid=1 --no-resolve --socks --bind-addr=127.0.0.1 --port=1080 <параметры_дурения>`
|
||||
|
||||
Прописать socks `127.0.0.1:1080` в браузер или другую программу.
|
||||
|
||||
Удаление : `wsl --unregister tpws`
|
||||
|
||||
> [!NOTE]
|
||||
> Проверено на windows 10 build 19041 (20.04).
|
||||
|
||||
Возможные проблемы:
|
||||
- Не работают функции `--oob` и `--mss` из-за ограничений реализации WSL.
|
||||
`--disorder` не работает из-за особенностей tcp/ip стека windows.
|
||||
|
||||
- Может не срабатывать детект RST в autohostlist.
|
||||
|
||||
- WSL может глючить со splice, приводя к зацикливанию процесса. Может потребоваться `--nosplice`.
|
||||
|
||||
- Не поддерживается tcp user timeout.
|
||||
Чтобы избавиться от сообщений об ошибке добавляйте :
|
||||
`--local-tcp-user-timeout=0 --remote-tcp-user-timeout=0`.
|
||||
Эти сообщения только информативные, на работу они не влияют.
|
||||
|
||||
|
||||
winws
|
||||
-----
|
||||
## winws
|
||||
|
||||
Это вариант пакетного фильтра nfqws для Windows, построенный на базе windivert.
|
||||
Все функции работоспособны, однако функционал ipset отсутствует. Фильтры по большому количеству IP адресов невозможны.
|
||||
Все функции работоспособны, однако функционал ipset в ядре отсутствует. Он реализован в user mode. Фильтры по большому количеству IP адресов невозможны.
|
||||
Работа с проходящим трафиком, например в случае "расшаривания" соединения, не проверялась и не гарантируется.
|
||||
Для работы с windivert требуются права администратора.
|
||||
Специфические для unix параметры, такие как --uid, --user и тд, исключены. Все остальные параметры аналогичны nfqws и dvtws.
|
||||
Специфические для unix параметры, такие как `--uid`, `--user` и тд, исключены. Все остальные параметры аналогичны nfqws и dvtws.
|
||||
|
||||
Работа с пакетным фильтром основана на двух действиях.
|
||||
Первое - выделение перенаправляемого трафика в режиме ядра и передача его пакетному фильтру в user mode.
|
||||
Второе - собственно обработка перенаправленных пакетов в пакетном фильтре.
|
||||
Работа с пакетным фильтром основана на двух действиях :
|
||||
1) Выделение перенаправляемого трафика в режиме ядра и передача его пакетному фильтру в user mode.
|
||||
2) Собственно обработка перенаправленных пакетов в пакетном фильтре.
|
||||
|
||||
В windows отсутствуют встроенные средства для перенаправления трафика, такие как iptables, nftables, pf или ipfw.
|
||||
В windows отсутствуют встроенные средства для перенаправления трафика, такие как _iptables_, _nftables_, _pf_ или _ipfw_.
|
||||
Поэтому используется сторонний драйвер ядра windivert. Он работает, начиная с windows 7. На системах с включенным
|
||||
secure boot могут быть проблемы из-за подписи драйвера. В этом случае отключите secureboot или включите режим testsigning.
|
||||
На windows 7 вероятно будут проблемы с загрузкой windivert. Читайте ниже соответствующий раздел.
|
||||
secure boot могут быть проблемы из-за подписи драйвера. В этом случае отключите `secureboot` или включите режим `testsigning`.
|
||||
На windows 7, вероятно, будут проблемы с загрузкой windivert. Читайте ниже соответствующий раздел.
|
||||
|
||||
Задача iptables в winws решается внутренними средствами через фильтры windivert.
|
||||
Задача _iptables_ в **winws** решается внутренними средствами через фильтры windivert.
|
||||
У windivert существует собственный язык фильтров, похожий на язык фильтров wireshark.
|
||||
Документация по фильтрам windivert : https://reqrypt.org/windivert-doc.html#filter_language
|
||||
[Документация по фильтрам windivert.](https://reqrypt.org/windivert-doc.html#filter_language)
|
||||
Чтобы не писать сложные фильтры вручную, предусмотрены различные упрощенные варианты автоматического построения фильтров.
|
||||
|
||||
```
|
||||
--wf-iface=<int>[.<int>] ; числовые индексы интерфейса и суб-интерфейса
|
||||
--wf-l3=ipv4|ipv6 ; фильтр L3 протоколов. по умолчанию включены ipv4 и ipv6.
|
||||
--wf-tcp=[~]port1[-port2] ; фильтр портов для tcp. ~ означает отрицание
|
||||
@@ -59,170 +72,187 @@ secure boot могут быть проблемы из-за подписи дра
|
||||
--ssid-filter=ssid1[,ssid2,ssid3,...] ; включать winws только когда подключена любая из указанных wifi сетей
|
||||
--nlm-filter=net1[,net2,net3,...] ; включать winws только когда подключена любая из указанных сетей NLM
|
||||
--nlm-list[=all] ; вывести список сетей NLM. по умолчанию только подключенных, all - всех.
|
||||
Параметры --wf-l3, --wf-tcp, --wf-udp могут брать несколько значений через запятую.
|
||||
```
|
||||
|
||||
Номера интерфейсов можно узнать так : netsh int ip show int.
|
||||
Некоторых типы соединений там не увидеть. В этом случае запускайте winws с параметром --debug и смотрите IfIdx там.
|
||||
SubInterface используется windivert, но практически всегда 0, его можно не указывать. Вероятно он нужен в редких случаях.
|
||||
Параметры `--wf-l3`, `--wf-tcp`, `--wf-udp` могут брать несколько значений через запятую.
|
||||
|
||||
Номера интерфейсов можно узнать так : `netsh int ip show int`.
|
||||
Некоторых типы соединений там не увидеть. В этом случае запускайте **winws** с параметром `--debug` и смотрите IfIdx там.
|
||||
SubInterface используется windivert, но практически всегда **0**, его можно не указывать. Вероятно, он нужен в редких случаях.
|
||||
|
||||
Конструктор фильтров автоматически включает входящие tcp пакеты с tcp synack и tcp rst для корректной работы функций
|
||||
autottl и autohostlist. При включении autohostlist так же перенаправляются пакеты данных с http redirect с кодами 302 и 307.
|
||||
Всегда добавляется фильтр на исключение не-интернет адресов ipv4 и ipv6.
|
||||
Для сложных нестандартных сценариев могут потребоваться свои фильтры. Логично будет начать со стандартного шаблона,
|
||||
сохраненного через --wf-save. Нужно править файл и подсовывать его в параметре --wf-raw. Максимальный размер фильтра - 8 Kb.
|
||||
сохраненного через `--wf-save`. Нужно править файл и подсовывать его в параметре `--wf-raw`. Максимальный размер фильтра - **8 Kb**.
|
||||
|
||||
Можно запускать несколько процессов winws с разными стратегиями. Однако, не следует делать пересекающиеся фильтры.
|
||||
Можно запускать несколько процессов **winws** с разными стратегиями. Однако, не следует делать пересекающиеся фильтры.
|
||||
|
||||
В --ssid-filter можно через запятую задать неограниченное количество имен wifi сетей (SSID). Если задана хотя бы одна сеть,
|
||||
то winws включается только, если подключен указанный SSID. Если SSID исчезает, winws отключается. Если SSID появляется снова,
|
||||
В `--ssid-filter` можно через запятую задать неограниченное количество имен wifi сетей (**SSID**). Если задана хотя бы одна сеть,
|
||||
то winws включается только, если подключен указанный **SSID**. Если **SSID** исчезает, winws отключается. Если **SSID** появляется снова,
|
||||
winws включается. Это нужно, чтобы можно было применять раздельное дурение к каждой отдельной wifi сети.
|
||||
Названия сетей должны быть написаны в том регистре, в котором их видит система. Сравнение идет с учетом регистра!
|
||||
При этом нет никаких проверок куда реально идет трафик. Если одновременно подключен, допустим, ethernet,
|
||||
и трафик идет туда, то дурение включается и выключается просто по факту наличия wifi сети, на которую трафик может и не идти.
|
||||
И это может сломать дурение на ethernet. Поэтому полезно так же будет добавить фильтр --wf-iface на индекс интерфейса wifi адаптера,
|
||||
И это может сломать дурение на ethernet. Поэтому полезно так же будет добавить фильтр `--wf-iface` на индекс интерфейса wifi адаптера,
|
||||
чтобы не трогать другой трафик.
|
||||
|
||||
--nlm-filter аналогичен --ssid-filter, но работает с именами или GUIDами сетей Network List Manager (NLM).
|
||||
`--nlm-filter` аналогичен `--ssid-filter`, но работает с именами или GUIDами сетей Network List Manager (NLM).
|
||||
Это те сети, которые вы видите в панели управления в разделе "Центр управления сетями и общим доступом".
|
||||
Под сетью подразумевается не конкретный адаптер, а именно сетевое окружение конкретного подключения.
|
||||
Обычно проверяется mac адрес шлюза. К сети можно подключиться через любой адаптер, и она останется той же самой.
|
||||
Если подключиться, допустим, к разными роутерам по кабелю, то будут разные сети.
|
||||
А если к одному роутеру через 2 разных сетевых карточки на том же компе - будет одна сеть.
|
||||
NLM абстрагирует типы сетевых адаптеров. Он работает как с wifi, так и с ethernet и любыми другими.
|
||||
Поэтому это более универсальный метод, чем ssid фильтр.
|
||||
Поэтому это более универсальный метод, чем **SSID** фильтр.
|
||||
Однако, есть и неприятная сторона. В windows 7 вы легко могли ткнуть на иконку сети и выбрать тип : private или public.
|
||||
Там же вы могли посмотреть список сетей и обьединить их. Чтобы, допустим, вы могли подключаться по кабелю и wifi
|
||||
к одному роутеру, и система эти подключения воспринимала как одну сеть.
|
||||
В следующих версиях windows они эти возможности сильно порезали. Похоже нет встроенных средств полноценно управлять
|
||||
network locations в win10/11. Кое-что есть в powershell.
|
||||
Можно поковыряться напрямую в реестре здесь : HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList
|
||||
Нужно менять ProfileGUID в Signatures\Unmanaged. Имена можно поменять в Profiles.
|
||||
network locations в win10/11. Кое-что есть в **powershell**.
|
||||
Можно поковыряться напрямую в реестре здесь :
|
||||
`HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList`
|
||||
Нужно менять ProfileGUID в `Signatures\Unmanaged`. Имена можно поменять в Profiles.
|
||||
Есть кое-какие сторонние утилиты. Кое-что находится, позволяющее посмотреть и удалить network profiles, но не обьединить.
|
||||
Факт, что в ms они это сильно испортили. Движок network list все тот же, и он способен на все то, что было в win7.
|
||||
Можно не бороться с этой проблемой, а просто указывать через запятую те названия сетей или GUIDы, которые выбрала система.
|
||||
Или если у вас только wifi, то использовать --ssid-filter. Там хотя бы есть гарантия, что SSID соответствуют реальности,
|
||||
Или если у вас только wifi, то использовать `--ssid-filter`. Там хотя бы есть гарантия, что **SSID** соответствуют реальности,
|
||||
а система их не назвала как-то по-своему.
|
||||
|
||||
Если в путях присутствуют национальные символы, то при вызове winws из cmd или bat кодировку нужно использовать OEM.
|
||||
Если в путях присутствуют национальные символы, то при вызове winws из `cmd` или `bat` кодировку нужно использовать **OEM**.
|
||||
Для русского языка это 866. Пути с пробелами нужно брать в кавычки.
|
||||
При использовании опции @<config_file> кодировка в файле должна быть UTF-8 без BOM mark.
|
||||
При использовании опции @<config_file> кодировка в файле должна быть **UTF-8** без **BOM mark**.
|
||||
|
||||
Существует неочевидный момент, каcаемый запуска winws из cygwin шелла. Если в директории, где находится winws, находится
|
||||
копия cygwin1.dll, winws не запустится.
|
||||
Если нужен запуск под cygwin, то следует удалить или переместить cygwin1.dll из binaries/win64. Это нужно для работы blockcheck.
|
||||
Из cygwin шелла можно посылать winws сигналы через kill точно так же, как в *nix.
|
||||
Существует неочевидный момент, каcаемый запуска **winws** из cygwin shell\`а. Если в директории, где находится winws, находится
|
||||
копия `cygwin1.dll`, **winws** не запустится.
|
||||
Если нужен запуск под cygwin, то следует удалить или переместить `cygwin1.dll` из `binaries/win64`. Это нужно для работы blockcheck.
|
||||
Из cygwin шелла можно посылать winws сигналы через `kill` точно так же, как в `*nix`.
|
||||
|
||||
Как получить совместимый с windows 7 и winws 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
|
||||
Следует выбрать установку curl.
|
||||
|
||||
Для сборки из исходников требуется gcc-core,make,zlib-devel.
|
||||
Собирать из директории nfq командой "make cygwin64" или "make cygwin32" для 64 и 32 битных версий соответственно.
|
||||
winws требует cygwin1.dll, windivert.dll, windivert64.sys или windivert32.sys.
|
||||
Их можно взять из binaries/win64 и binaries/win32.
|
||||
`curl -O https://www.cygwin.com/setup-x86_64.exe`
|
||||
|
||||
Для arm64 windows нет подписанного драйвера windivert и нет cygwin.
|
||||
`setup-x86_64.exe --allow-unsupported-windows --no-verify --site http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2024/01/30/231215`
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Следует выбрать установку curl.
|
||||
|
||||
Для сборки из исходников требуется _gcc-core_,_make_,_zlib-devel_.
|
||||
Собирать из директории 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 без изменений.
|
||||
Но при этом надо заменить WinDivert64.sys на неподписанную arm64 версию и установить режим testsigning.
|
||||
Но при этом надо заменить WinDivert64.sys на неподписанную _arm64_ версию и установить режим testsigning.
|
||||
|
||||
Windows 7 и windivert
|
||||
---------------------
|
||||
## Windows 7 и windivert
|
||||
|
||||
Требования к подписи драйверов windows изменились в 2021 году.
|
||||
Официальные бесплатные обновления windows 7 закончились в 2020.
|
||||
После этого несколько лет продолжали идти платные обновления по программе ESU.
|
||||
Именно в этих ESU обновлениях находится обновление ядра windows 7, позволяющиее загрузить драйвер
|
||||
windivert 2.2.2-A, который идет в поставке zapret.
|
||||
После этого несколько лет продолжали идти платные обновления по программе **ESU**.
|
||||
Именно в этих **ESU** обновлениях находится обновление ядра windows 7, позволяющиее загрузить драйвер
|
||||
_windivert 2.2.2-A_, который идет в поставке zapret.
|
||||
Поэтому варианты следующие :
|
||||
|
||||
1) Взять windivert64.sys и windivert.dll версии 2.2.0-C или 2.2.0-D отсюда : https://reqrypt.org/download
|
||||
1) Взять `windivert64.sys` и `windivert.dll` версии _2.2.0-C_ или _2.2.0-D_ отсюда : https://reqrypt.org/download
|
||||
и заменить эти 2 файла.
|
||||
В zapret-win-bundle есть отдельных 2 места, где находится winws : zapret-winws и blockcheck/zapret/nfq.
|
||||
В [zapret-win-bundle](https://github.com/bol-van/zapret-win-bundle) есть отдельных 2 места, где находится **winws** : [_zapret-winws_](https://github.com/bol-van/zapret-win-bundle/tree/master/zapret-winws) и [_blockcheck/zapret/nfq_](https://github.com/bol-van/zapret-win-bundle/tree/master/blockcheck).
|
||||
Надо менять в обоих местах.
|
||||
Этот вариант проверен и должен работать. Тем не менее патч 10 летней давности, который включает SHA256
|
||||
сигнатуры, все еще необходим.
|
||||
|
||||
2) Взломать ESU :
|
||||
> [!NOTE]
|
||||
> Этот вариант проверен и должен работать. Тем не менее патч 10 летней давности, который включает SHA256 сигнатуры, все еще необходим.
|
||||
|
||||
2) Взломать **ESU** :
|
||||
https://hackandpwn.com/windows-7-esu-patching/
|
||||
http://www.bifido.net/tweaks-and-scripts/8-extended-security-updates-installer.html
|
||||
и обновить систему
|
||||
|
||||
3) Использовать UpdatePack7R2 от simplix : https://blog.simplix.info
|
||||
Но с этим паком есть проблема. Автор из Украины, он очень обиделся на русских.
|
||||
Если в панели управления стоит регион RU или BY, появляется неприятный диалог.
|
||||
Чтобы эту проблему обойти, можно поставить временно любой другой регион, потом вернуть.
|
||||
Так же нет никаких гарантий, что автор не насовал туда какой-то зловредный код.
|
||||
Использовать на свой страх и риск.
|
||||
> [!WARNING]
|
||||
> Но с этим паком есть проблема. Автор из Украины, он очень обиделся на русских.
|
||||
> Если в панели управления стоит регион RU или BY, появляется неприятный диалог.
|
||||
> Чтобы эту проблему обойти, можно поставить временно любой другой регион, потом вернуть.
|
||||
> Так же нет никаких гарантий, что автор не насовал туда какой-то зловредный код.
|
||||
> Использовать на свой страх и риск.
|
||||
|
||||
Более безопасный вариант - скачать последнюю нормальную довоенную версию : 22.2.10
|
||||
https://nnmclub.to/forum/viewtopic.php?t=1530323
|
||||
Ее достаточно, чтобы windivert 2.2.2-A заработал на windows 7.
|
||||
Ее достаточно, чтобы _windivert 2.2.2-A_ заработал на windows 7.
|
||||
|
||||
blockcheck
|
||||
----------
|
||||
## blockcheck
|
||||
|
||||
blockcheck.sh написан на posix shell и требует некоторых стандартных утилит posix. В windows, естественно, этого нет.
|
||||
Потому просто так запустить blockcheck.sh невозможно.
|
||||
Для этого требуется скачать и установить cygwin так , как описано в предыдущем разделе.
|
||||
Следует запустить от имени администратора cygwin shell через cygwin.bat.
|
||||
`blockcheck.sh` написан на _posix shell_ и требует некоторых стандартных утилит _posix_. В windows, естественно, этого нет.
|
||||
Потому просто так запустить `blockcheck.sh` невозможно.
|
||||
Для этого требуется скачать и установить _cygwin_ так , как описано в предыдущем разделе.
|
||||
Следует запустить от имени администратора _cygwin shell_ через `cygwin.bat`.
|
||||
В нем нужно пройти в директорию с zapret.
|
||||
Обратные слэши путей windows нужно удваивать, менять на прямые слэши, либо использовать отображение на unix path.
|
||||
Корректный вариант 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.
|
||||
Корректные варианты :
|
||||
- `cd C:\\Users\\vasya`
|
||||
- `cd C:/Users/vasya`
|
||||
- `cd /cygdrive/c/Users/vasya`
|
||||
|
||||
Существует неочевидный момент, каcаемый запуска **winws** из _cygwin_ шелла. Если в директории, где находится **winws**, есть копия `cygwin1.dll`, **winws** не запустится. Нужно переименовать файл `cygwin1.dll`.
|
||||
Далее все как в _*nix_ : 1 раз `./install_bin.sh` , затем `./blockcheck.sh`.
|
||||
WSL использовать нельзя, это не то же самое.
|
||||
|
||||
cygwin для обычной работы winws не нужен.
|
||||
_cygwin_ для обычной работы **winws** не нужен.
|
||||
|
||||
Однако, хотя такой способ и работает, использование winws сильно облегчает zapret-win-bundle.
|
||||
Там нет проблемы с cygwin.dll.
|
||||
Однако, хотя такой способ и работает, использование **winws** сильно облегчает [zapret-win-bundle](https://github.com/bol-van/zapret-win-bundle).
|
||||
Там нет проблемы с `cygwin.dll`.
|
||||
|
||||
автозапуск winws
|
||||
----------------
|
||||
## Автозапуск winws
|
||||
|
||||
Для запуска winws вместе с windows есть 2 варианта. Планировщик задач или службы windows.
|
||||
Для запуска **winws** вместе с windows есть 2 варианта. Планировщик задач или службы windows.
|
||||
|
||||
Можно создавать задачи и управлять ими через консольную программу schtasks.
|
||||
В директории binaries/win64/winws подготовлены файлы task_*.cmd .
|
||||
В них реализовано создание, удаление, старт и стоп одной копии процесса winws с параметрами из переменной %WINWS1%.
|
||||
В директории `binaries/win64/winws` подготовлены файлы `task_*.cmd` .
|
||||
В них реализовано создание, удаление, старт и стоп одной копии процесса winws с параметрами из переменной `%WINWS1%`.
|
||||
Исправьте параметры на нужную вам стратегию. Если для разных фильтров применяется разная стратегия, размножьте код
|
||||
для задач winws1,winws2,winws3,...
|
||||
для задач _winws1_,_winws2_,_winws3_,_..._
|
||||
|
||||
Аналогично настраивается вариант запуска через службы windows. Смотрите service_*.cmd.
|
||||
Аналогично настраивается вариант запуска через службы windows. Смотрите `service_*.cmd`.
|
||||
|
||||
Все батники требуется запускать от имени администратора.
|
||||
|
||||
Управлять задачами можно так же из графической программы управления планировщиком taskschd.msc
|
||||
Управлять задачами можно так же из графической программы управления планировщиком `taskschd.msc`
|
||||
|
||||
zapret-win-bundle
|
||||
-----------------
|
||||
## Zapret-win-bundle
|
||||
|
||||
Можно не возиться с cygwin, а взять готовый пакет, включающий в себя cygwin и blockcheck : https://github.com/bol-van/zapret-win-bundle
|
||||
Там сделан максимум удобств для сосредоточения на самом zapret, исключая возню с установкой cygwin,
|
||||
Можно не возиться с _cygwin_, а взять готовый пакет, включающий в себя _cygwin_ и _blockcheck_ : https://github.com/bol-van/zapret-win-bundle
|
||||
Там сделан максимум удобств для сосредоточения на самом zapret, исключая возню с установкой _cygwin_,
|
||||
заходами в директории, запусками под администратором и прочими сугубо техническими моментами, в которых могут быть
|
||||
ошибки и непонимания, а новичок без базиса знаний может и вовсе запутаться.
|
||||
|
||||
/zapret-winws - здесь все, что нужно для запуска winws в повседневном рабочем режиме. остальное не нужно.
|
||||
/zapret-winws/_CMD_ADMIN.cmd - получить командную строку cmd в этой директории от имени администратора для тестирования winws
|
||||
с параметрами, вводимыми вручную
|
||||
/blockcheck/blockcheck.cmd - достаточно кликнуть по нему, чтобы пошел blockcheck с записью лога в blockcheck/blockcheck.log
|
||||
/cygwin/cygwin.cmd - запуск среды cygwin bash под текущим пользователем
|
||||
/cygwin/cygwin-admin.cmd - запуск среды cygwin bash под администратором
|
||||
`/zapret-winws` - здесь все, что нужно для запуска winws в повседневном рабочем режиме. остальное не нужно.\
|
||||
`/zapret-winws/_CMD_ADMIN.cmd` - получить командную строку cmd в этой директории от имени администратора для тестирования **winws**
|
||||
с параметрами, вводимыми вручную\
|
||||
`/blockcheck/blockcheck.cmd` - достаточно кликнуть по нему, чтобы пошел _blockcheck_ с записью лога в `blockcheck/blockcheck.log`\
|
||||
`/cygwin/cygwin.cmd` - запуск среды _cygwin bash_ под текущим пользователем\
|
||||
`/cygwin/cygwin-admin.cmd` - запуск среды _cygwin bash_ под администратором
|
||||
|
||||
В среде cygwin уже настроены alias-ы на winws,blockcheck,ip2net,mdig. С путями возиться не нужно !
|
||||
Из cygwin можно не только тестировать winws, но и посылать сигналы.
|
||||
Доступны команды pidof,kill,killall,pgrep,pkill.
|
||||
Но важно понимать, что таким образом не выйдет посылать сигналы winws, запущенному из zapret-winws,
|
||||
поскольку там свой cygwin1.dll, и они не разделяют общее пространство процессов unix.
|
||||
zapret-winws - это отдельный комплект для повседневного использования, не требующий что-то еще, но и не связанный со средой cygwin.
|
||||
В среде _cygwin_ уже настроены alias-ы на winws,blockcheck,ip2net,mdig. С путями возиться не нужно!
|
||||
|
||||
> [!TIP]
|
||||
> Из cygwin можно не только тестировать winws, но и посылать сигналы.
|
||||
> Доступны команды:
|
||||
>- `pidof`
|
||||
>- `kill`
|
||||
>- `killall`
|
||||
>- `pgrep`
|
||||
>- `pkill`
|
||||
|
||||
Но важно понимать, что таким образом не выйдет посылать сигналы **winws**, запущенному из _zapret-winws_,
|
||||
поскольку там свой `cygwin1.dll`, и они не разделяют общее пространство процессов unix.
|
||||
_zapret-winws_ - это отдельный комплект для повседневного использования, не требующий что-то еще, но и не связанный со _средой cygwin_.
|
||||
Специально для посылки сигналов winws в _zapret-winws_ присутствует killall.exe.
|
||||
|
||||
Среду cygwin можно использовать для записи в файл дебаг-лога winws. Для этого пользуйтесь командой tee.
|
||||
winws --debug --wf-tcp=80,443 | tee winws.log
|
||||
winws.log будет в cygwin/home/<имя_пользователя>
|
||||
`winws --debug --wf-tcp=80,443 | tee winws.log`
|
||||
`winws.log` будет в `cygwin/home/<имя_пользователя>`
|
||||
Если у вас windows 7, то блокнот не поймет переводы строк в стиле unix. Воспользуйтесь командой
|
||||
unix2dos winws.log
|
||||
`unix2dos winws.log`
|
||||
|
||||
Поскольку 32-битные windows мало востребованы, zapret-win-bundle существует только в варианте для windows x64/arm64.
|
||||
> [!CAUTION]
|
||||
> Поскольку 32-битные windows мало востребованы, _zapret-win-bundle_ существует только в варианте для windows _x64/arm64_.
|
@@ -1,133 +0,0 @@
|
||||
Index: WireGuard-0.0.20190123/src/cookie.c
|
||||
===================================================================
|
||||
--- WireGuard-0.0.20190123.orig/src/cookie.c
|
||||
+++ WireGuard-0.0.20190123/src/cookie.c
|
||||
@@ -193,6 +193,8 @@ void wg_cookie_message_create(struct mes
|
||||
xchacha20poly1305_encrypt(dst->encrypted_cookie, cookie, COOKIE_LEN,
|
||||
macs->mac1, COOKIE_LEN, dst->nonce,
|
||||
checker->cookie_encryption_key);
|
||||
+ // MOD : randomize trash
|
||||
+ dst->header.trash = gen_trash();
|
||||
}
|
||||
|
||||
void wg_cookie_message_consume(struct message_handshake_cookie *src,
|
||||
Index: WireGuard-0.0.20190123/src/messages.h
|
||||
===================================================================
|
||||
--- WireGuard-0.0.20190123.orig/src/messages.h
|
||||
+++ WireGuard-0.0.20190123/src/messages.h
|
||||
@@ -53,23 +53,41 @@ enum limits {
|
||||
MAX_QUEUED_PACKETS = 1024 /* TODO: replace this with DQL */
|
||||
};
|
||||
|
||||
+/*
|
||||
enum message_type {
|
||||
- MESSAGE_INVALID = 0,
|
||||
- MESSAGE_HANDSHAKE_INITIATION = 1,
|
||||
- MESSAGE_HANDSHAKE_RESPONSE = 2,
|
||||
- MESSAGE_HANDSHAKE_COOKIE = 3,
|
||||
- MESSAGE_DATA = 4
|
||||
+ MESSAGE_INVALID = 0,
|
||||
+ MESSAGE_HANDSHAKE_INITIATION = 1,
|
||||
+ MESSAGE_HANDSHAKE_RESPONSE = 2,
|
||||
+ MESSAGE_HANDSHAKE_COOKIE = 3,
|
||||
+ MESSAGE_DATA = 4
|
||||
};
|
||||
+*/
|
||||
+
|
||||
+// MOD : message type
|
||||
+enum message_type {
|
||||
+ MESSAGE_INVALID = 0xE319CCD0,
|
||||
+ MESSAGE_HANDSHAKE_INITIATION = 0x48ADE198,
|
||||
+ MESSAGE_HANDSHAKE_RESPONSE = 0xFCA6A8F3,
|
||||
+ MESSAGE_HANDSHAKE_COOKIE = 0x64A3BB18,
|
||||
+ MESSAGE_DATA = 0x391820AA
|
||||
+};
|
||||
+
|
||||
+// MOD : generate fast trash without true RNG
|
||||
+__le32 gen_trash(void);
|
||||
|
||||
struct message_header {
|
||||
- /* The actual layout of this that we want is:
|
||||
- * u8 type
|
||||
- * u8 reserved_zero[3]
|
||||
- *
|
||||
- * But it turns out that by encoding this as little endian,
|
||||
- * we achieve the same thing, and it makes checking faster.
|
||||
- */
|
||||
- __le32 type;
|
||||
+ /* The actual layout of this that we want is:
|
||||
+ * u8 type
|
||||
+ * u8 reserved_zero[3]
|
||||
+ *
|
||||
+ * But it turns out that by encoding this as little endian,
|
||||
+ * we achieve the same thing, and it makes checking faster.
|
||||
+ */
|
||||
+
|
||||
+ // MOD : trash field to change message size and add 4 byte offset to all fields
|
||||
+ __le32 trash;
|
||||
+
|
||||
+ __le32 type;
|
||||
};
|
||||
|
||||
struct message_macs {
|
||||
Index: WireGuard-0.0.20190123/src/noise.c
|
||||
===================================================================
|
||||
--- WireGuard-0.0.20190123.orig/src/noise.c
|
||||
+++ WireGuard-0.0.20190123/src/noise.c
|
||||
@@ -17,6 +17,24 @@
|
||||
#include <linux/highmem.h>
|
||||
#include <crypto/algapi.h>
|
||||
|
||||
+
|
||||
+// MOD : trash generator
|
||||
+__le32 gtrash = 0;
|
||||
+__le32 gen_trash(void)
|
||||
+{
|
||||
+ if (gtrash)
|
||||
+ gtrash = gtrash*1103515243 + 12345;
|
||||
+ else
|
||||
+ // first value is true random
|
||||
+ get_random_bytes_wait(>rash, sizeof(gtrash));
|
||||
+ return gtrash;
|
||||
+}
|
||||
+
|
||||
/* This implements Noise_IKpsk2:
|
||||
*
|
||||
* <- s
|
||||
@@ -515,6 +533,10 @@ wg_noise_handshake_create_initiation(str
|
||||
&handshake->entry);
|
||||
|
||||
handshake->state = HANDSHAKE_CREATED_INITIATION;
|
||||
+
|
||||
+ // MOD : randomize trash
|
||||
+ dst->header.trash = gen_trash();
|
||||
+
|
||||
ret = true;
|
||||
|
||||
out:
|
||||
@@ -655,6 +677,10 @@ bool wg_noise_handshake_create_response(
|
||||
&handshake->entry);
|
||||
|
||||
handshake->state = HANDSHAKE_CREATED_RESPONSE;
|
||||
+
|
||||
+ // MOD : randomize trash
|
||||
+ dst->header.trash = gen_trash();
|
||||
+
|
||||
ret = true;
|
||||
|
||||
out:
|
||||
Index: WireGuard-0.0.20190123/src/send.c
|
||||
===================================================================
|
||||
--- WireGuard-0.0.20190123.orig/src/send.c
|
||||
+++ WireGuard-0.0.20190123/src/send.c
|
||||
@@ -200,6 +200,10 @@ static bool encrypt_packet(struct sk_buf
|
||||
header->header.type = cpu_to_le32(MESSAGE_DATA);
|
||||
header->key_idx = keypair->remote_index;
|
||||
header->counter = cpu_to_le64(PACKET_CB(skb)->nonce);
|
||||
+
|
||||
+ // MOD : randomize trash
|
||||
+ header->header.trash = gen_trash();
|
||||
+
|
||||
pskb_put(skb, trailer, trailer_len);
|
||||
|
||||
/* Now we can encrypt the scattergather segments */
|
@@ -1,250 +0,0 @@
|
||||
!!! Эта инструкция написана еще до включения wireguard в ядро linux.
|
||||
!!! Процесс сборки для in-tree модулей отличается.
|
||||
!!! Цель данного чтива - дать идею для программистов как можно исправить исходники wireguard
|
||||
!!! для преодоления DPI. Автор не преследует цели поддерживать готовые патчи для актуальных версий.
|
||||
!!! Вместо патчинга гораздо проще использовать навесное решение ipobfs.
|
||||
|
||||
Посвящено возможной блокировке в РФ VPN протоколов через DPI.
|
||||
Предпосылками являются последние законодательные акты и во всю сочащиеся "секретные" записки.
|
||||
В РФ разрабатываются и готовятся к применению более продвинутые решения по блокировке трафика.
|
||||
Вполне вероятно будут резать стандартные VPN протоколы. Нам надо быть к этому готовыми.
|
||||
|
||||
Один из возможных и перспективных путей решения данного вопроса - кустомная модификация
|
||||
исходников VPN с целью незначительного изменения протокола, ломающего стандартные модули обнаружения в DPI.
|
||||
Это относительно сложно, доступно только для гиков.
|
||||
Никто не будет разрабатывать специальные модули обнаружения в DPI, если только кто-то не сделает простое и
|
||||
удобное решение для всех, и его станут широко применять. Но это маловероятно, и даже если и так,
|
||||
то всегда можно модифицировать протокол чуток по другому. Делать моды для DPI несравненно дольше
|
||||
и дороже, чем клепать на коленке изменения протокола для wireguard.
|
||||
|
||||
|
||||
ЗАМЕЧЕНИЕ : альтернативой модификации конечного софта для VPN является использование "навесных"
|
||||
обфускаторов. см : https://github.com/bol-van/ipobfs
|
||||
|
||||
|
||||
Рассмотрю что нам надо пропатчить в wireguard. Модифицированный wireguard проверен на виртуалках
|
||||
с десктопным linux, он работает, сообщения в wireshark действительно не вписываются в стандартный
|
||||
протокол и не опознаются.
|
||||
|
||||
Wireguard протокол очень простой. Все сообщения описаны в messages.h
|
||||
Поставим себе целью сделать 2 простые модификации :
|
||||
1) Добавим в начало всех сообщений немного мусора, чтобы изменить размер сообщений и смещения полей
|
||||
2) Изменим коды типов сообщений
|
||||
Этого может быть вполне достаточно для обмана DPI
|
||||
|
||||
--messages.h--------------------------
|
||||
/*
|
||||
enum message_type {
|
||||
MESSAGE_INVALID = 0,
|
||||
MESSAGE_HANDSHAKE_INITIATION = 1,
|
||||
MESSAGE_HANDSHAKE_RESPONSE = 2,
|
||||
MESSAGE_HANDSHAKE_COOKIE = 3,
|
||||
MESSAGE_DATA = 4
|
||||
};
|
||||
*/
|
||||
|
||||
// MOD : message type
|
||||
enum message_type {
|
||||
MESSAGE_INVALID = 0xE319CCD0,
|
||||
MESSAGE_HANDSHAKE_INITIATION = 0x48ADE198,
|
||||
MESSAGE_HANDSHAKE_RESPONSE = 0xFCA6A8F3,
|
||||
MESSAGE_HANDSHAKE_COOKIE = 0x64A3BB18,
|
||||
MESSAGE_DATA = 0x391820AA
|
||||
};
|
||||
|
||||
// MOD : generate fast trash without true RNG
|
||||
__le32 gen_trash(void);
|
||||
|
||||
struct message_header {
|
||||
/* The actual layout of this that we want is:
|
||||
* u8 type
|
||||
* u8 reserved_zero[3]
|
||||
*
|
||||
* But it turns out that by encoding this as little endian,
|
||||
* we achieve the same thing, and it makes checking faster.
|
||||
*/
|
||||
|
||||
// MOD : trash field to change message size and add 4 byte offset to all fields
|
||||
__le32 trash;
|
||||
|
||||
__le32 type;
|
||||
};
|
||||
--------------------------------------
|
||||
|
||||
Напишем функцию для генерации trash. Функция должна быть быстрая, важно не замедлить скорость.
|
||||
Мы не расчитываем, что нас будут специально ловить, иначе бы пришлось делать полноценный обфускатор.
|
||||
Задача лишь сломать стандартный модуль обнаружения протокола wireguard. Потому истинная рандомность
|
||||
trash не важна.
|
||||
Но все же немного "трэша" не повредит. Гонки между тредами так же пофигистичны. Это же трэш.
|
||||
|
||||
--noise.c-----------------------------
|
||||
// MOD : trash generator
|
||||
__le32 gtrash = 0;
|
||||
__le32 gen_trash(void)
|
||||
{
|
||||
if (gtrash)
|
||||
gtrash = gtrash*1103515243 + 12345;
|
||||
else
|
||||
// first value is true random
|
||||
get_random_bytes_wait(>rash, sizeof(gtrash));
|
||||
return gtrash;
|
||||
}
|
||||
--------------------------------------
|
||||
|
||||
Теперь осталось найти все места, где создаются сообщения и внести туда заполнение поля trash.
|
||||
Сообщений всего 4. Их можно найти по присваиванию полю type одного из значений enum message_type.
|
||||
|
||||
2 места в noise.c в функциях wg_noise_handshake_create_initiation и wg_noise_handshake_create_response,
|
||||
1 место в cookie.c в функции wg_cookie_message_create
|
||||
Дописываем в конец инициализации структуры сообщения :
|
||||
|
||||
--------------------------------------
|
||||
// MOD : randomize trash
|
||||
dst->header.trash = gen_trash();
|
||||
--------------------------------------
|
||||
|
||||
и 1 место в send.c в функции encrypt_packet
|
||||
|
||||
--------------------------------------
|
||||
// MOD : randomize trash
|
||||
header->header.trash = gen_trash();
|
||||
--------------------------------------
|
||||
|
||||
|
||||
Вот и весь патчинг. Полный patch (версия wireguard 0.0.20190123) лежит в 010-wg-mod.patch.
|
||||
Патчинг кода - самое простое. Для десктопного linux дальше все просто.
|
||||
Пересобираем через make, устанавливаем через make install, перегружаем
|
||||
модуль wireguard, перезапускаем интерфейсы, и все готово.
|
||||
|
||||
Настоящий геморой начнется когда вы это попытаетесь засунуть на роутер под openwrt.
|
||||
Одна из больших проблем linux - отсутствие совместимости драйверов на уровне бинариков.
|
||||
Поэтому собирать необходимо в точности под вашу версию ядра и в точности под его .config.
|
||||
Вам придется либо полностью самостоятельно собирать всю прошивку, либо найти SDK в точности
|
||||
от вашей версии прошивки для вашей архитектуры и собрать модуль с помощью этого SDK.
|
||||
Последний вариант более легкий.
|
||||
Для сборки вам понадобится система на linux x86_64. Ее можно установить в виртуалке.
|
||||
Теоретически можно пользоваться WSL из win10, но на практике там очень медленное I/O,
|
||||
по крайней мере на старых версиях win10. Безумно медленное. Будете собирать вечность.
|
||||
Может в новых win10 что-то и улучшили, но я бы сразу расчитывал на полноценный linux.
|
||||
|
||||
Находим здесь вашу версию : https://downloads.openwrt.org/
|
||||
Скачиваем файл openwrt-sdk-*.tar.xz или lede-sdk-*.tar.xz
|
||||
Например : https://downloads.openwrt.org/releases/18.06.2/targets/ar71xx/generic/openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64.tar.xz
|
||||
Если ваша версия непонятна или стара, то проще будет найти последнюю прошивку и перешить роутер.
|
||||
Распаковываем SDK. Следующими командами можно собрать оригинальный вариант wireguard :
|
||||
|
||||
# scripts/feeds update -a
|
||||
# scripts/feeds install -a
|
||||
# make defconfig
|
||||
# make -j 4 package/wireguard/compile
|
||||
|
||||
Сборка будет довольно долгой. Ведь придется подтащить ядро, собрать его, собрать зависимости.
|
||||
"-j 4" означает использовать 4 потока. Впишите вместо 4 количество доступных cpu cores.
|
||||
|
||||
Получим следующие файлы :
|
||||
|
||||
openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/bin/targets/ar71xx/generic/packages/kmod-wireguard_4.9.152+0.0.20190123-1_mips_24kc.ipk
|
||||
openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/bin/packages/mips_24kc/base/wireguard-tools_0.0.20190123-1_mips_24kc.ipk
|
||||
|
||||
Но это будет оригинальный wireguard. Нам нужен патченый.
|
||||
Установим quilt и mc для нормального редактора вместо vim :
|
||||
|
||||
# sudo apt-get update
|
||||
# sudo apt-get install quilt mc
|
||||
|
||||
# make package/wireguard/clean
|
||||
# make package/wireguard/prepare V=s QUILT=1
|
||||
|
||||
|
||||
Сорцы приготовлены для сборки в :
|
||||
openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/build_dir/target-mips_24kc_musl/linux-ar71xx_generic/WireGuard-0.0.20190123/src
|
||||
|
||||
# cd build_dir/target-mips_24kc_musl/linux-ar71xx_generic/WireGuard-0.0.20190123/src
|
||||
# quilt push -a
|
||||
# quilt new 010-wg-mod.patch
|
||||
# export EDITOR=mcedit
|
||||
|
||||
Далее будет открываться редактор mcedit, в который нужно вносить изменения в каждый файл :
|
||||
|
||||
# quilt edit messages.h
|
||||
# quilt edit cookie.c
|
||||
# quilt edit noise.c
|
||||
# quilt edit send.c
|
||||
# quilt diff
|
||||
# quilt refresh
|
||||
|
||||
Получили файл патча в :
|
||||
openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/build_dir/target-mips_24kc_musl/linux-ar71xx_generic/WireGuard-0.0.20190123/patches/010-wg-mod.patch
|
||||
|
||||
Выходим в корень SDK.
|
||||
|
||||
# make package/wireguard/compile V=99
|
||||
|
||||
Если не было ошибок, то получили измененные ipk.
|
||||
Патч можно зафиксировать в описании пакета :
|
||||
|
||||
# make package/wireguard/update
|
||||
|
||||
Получим :
|
||||
openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/feeds/base/package/network/services/wireguard/patches/010-wg-mod.patch
|
||||
При последующей очистке и пересборке он будет автоматом применяться.
|
||||
|
||||
|
||||
АЛЬТЕРНАТИВА : можно не возиться с quilt.
|
||||
сделайте
|
||||
# make package/wireguard/clean
|
||||
# make package/wireguard/prepare
|
||||
и напрямую модифицируйте или копируйте файлы в
|
||||
openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/build_dir/target-mips_24kc_musl/linux-ar71xx_generic/WireGuard-0.0.20190123/src
|
||||
затем
|
||||
# make package/wireguard/compile
|
||||
|
||||
Если нужно поменять версию wireguard, то идите в
|
||||
openwrt-sdk-18.06.2-ar71xx-generic_gcc-7.3.0_musl.Linux-x86_64/feeds/base/package/network/services/wireguard/Makefile
|
||||
поменяйте там версию в PKG_VERSION на последнюю из : https://git.zx2c4.com/WireGuard
|
||||
скачайте tar.xz с этой версией , вычислите его sha256sum, впишите в PKG_HASH
|
||||
|
||||
1 раз где-нибудь пропатчите файлы последней версии wireguard в текстовом редакторе, скопируйте в build_dir,
|
||||
сделайте версию для openwrt. эти же файлы скопируйте на ваш сервер с десктопным linux, сделайте там make / make install
|
||||
|
||||
Но имейте в виду, что build_dir - локация для временных файлов.
|
||||
make clean оттуда все снесет, включая ваши модификации. Модифицированные файлы лучше сохранить отдельно,
|
||||
чтобы потом было легко скопировать обратно.
|
||||
|
||||
Полученные ipk копируем на роутер в /tmp, устанавливаем через
|
||||
# cd /tmp
|
||||
# rm -r /tmp/opkg-lists
|
||||
# opkg install *.ipk
|
||||
Если требует зависимостей, то
|
||||
# opkg update
|
||||
# opkg install .... <зависимости>
|
||||
# rm -r /tmp/opkg-lists
|
||||
# opkg install *.ipk
|
||||
|
||||
В /tmp/opkg-lists opkg хранит кэш списка пакетов. Если попытаться установить файл ipk, и такой же пакет
|
||||
найдется в репозитории, opkg будет устанавливать из репозитория. А нам это не надо.
|
||||
|
||||
# rmmod wireguard
|
||||
# kmodloader
|
||||
# dmesg | tail
|
||||
должны увидеть что-то вроде :
|
||||
[8985.415490] wireguard: WireGuard 0.0.20190123 loaded. See www.wireguard.com for information.
|
||||
[8985.424178] wireguard: Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||
значит модуль загрузился
|
||||
|
||||
Могут понадобиться ключи opkg --force-reinstall, --force-depends.
|
||||
--force-depends поможет при несоответствии hash версии ядра. То есть версия x.x.x та же самая, но hash конфигурации разный.
|
||||
При несоответствии x.x.x вы что-то делаете не так, работать это не будет.
|
||||
Например : 4.14.56-1-b1186491495127cc6ff81d29c00a91fc, 4.14.56-1-3f8a21a63974cfb7ee67e41f2d4b805d
|
||||
Это свидетельствует о несоответствии .config ядра при сборке прошивки и в SDK.
|
||||
Если несоответствие легкое, то может все прокатить, но при более серьезной разнице в .config модуль может не загрузиться
|
||||
или вызвать стабильные или хаотические падения ядра и перезагрузки (включая вариант беcконечной перезагрузки - bootloop).
|
||||
Так что перед --force-depends убедитесь, что знаете как лечится такая ситуация, и не стоит это делать при отсутствии физического
|
||||
доступа к девайсу.
|
||||
|
||||
Когда поднимите линк, и вдруг ничего не будет работать, то посмотрите в wireshark udp пакеты
|
||||
на порт endpoint. Они не должны начинаться с 0,1,2,3,4. В первых 4 байтах должен быть рандом,
|
||||
в следующих 4 байтах - значения из измененного enum message_type. Если пакет все еще начинается с 0..4,
|
||||
значит модуль wireguard оригинальный, что-то не собралось, не скопировалось, не перезапустилось.
|
||||
В противном случае должен подняться линк, пинги ходить. Значит вы победили, поздравляю.
|
||||
Регулятору будет намного сложнее поймать ваш VPN.
|
@@ -236,7 +236,7 @@ config rule
|
||||
|
||||
--- Подготовка zapret ---
|
||||
|
||||
Выполните install_easy.sh. Он настроит режим обхода DPI. Если обход DPI не нужен - выберите MODE=filter.
|
||||
Выполните install_easy.sh. Он настроит режим обхода DPI. Если обход DPI не нужен - не включайте tpws и nfqws.
|
||||
Так же инсталятор заресолвит домены из ipset/zapret-hosts-user-ipban.txt и внесет крон-джоб для периодического обновления ip.
|
||||
|
||||
Если вы используете в своих правилах ipset zapret, то он ресолвится и обновляется только, если выбран режим фильтрации обхода DPI по ipset.
|
@@ -19,7 +19,8 @@ check_need_to_reload_tpws6()
|
||||
# interface ifsets (wanif, wanif6, lanif) can be reloaded independently
|
||||
check_lan
|
||||
RELOAD_TPWS6=
|
||||
[ "$ACTION" = "ifup" -a "$DISABLE_IPV6" != 1 -a -n "$IS_LAN" ] && [ "$MODE" = "tpws" -o "$MODE" = "custom" ] && RELOAD_TPWS6=1
|
||||
[ "$ACTION" = "ifup" -a "$DISABLE_IPV6" != 1 -a -n "$IS_LAN" ] && \
|
||||
if [ "$TPWS_ENABLE" = 1 ] || dir_is_not_empty "$CUSTOM_DIR/custom.d"; then RELOAD_TPWS6=1; fi
|
||||
}
|
||||
|
||||
|
||||
@@ -33,15 +34,16 @@ check_need_to_reload_tpws6()
|
||||
fi
|
||||
ZAPRET_RW=${ZAPRET_RW:-"$ZAPRET_BASE"}
|
||||
ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
|
||||
CUSTOM_DIR="$ZAPRET_RW/init.d/openwrt"
|
||||
. "$ZAPRET_CONFIG"
|
||||
. "$ZAPRET_BASE/common/base.sh"
|
||||
. "$ZAPRET_BASE/common/fwtype.sh"
|
||||
|
||||
check_need_to_reload_tpws6
|
||||
[ -n "$RELOAD_TPWS6" ] && {
|
||||
logger -t zapret restarting daemons due to $ACTION of $INTERFACE to update tpws6 dnat target
|
||||
"$ZAPRET" restart_daemons
|
||||
}
|
||||
. "$ZAPRET_BASE/common/base.sh"
|
||||
. "$ZAPRET_BASE/common/fwtype.sh"
|
||||
linux_fwtype
|
||||
case "$FWTYPE" in
|
||||
nftables)
|
||||
|
22
init.d/sysv/custom.d.examples/10-keenetic-udp-fix
Normal file
22
init.d/sysv/custom.d.examples/10-keenetic-udp-fix
Normal file
@@ -0,0 +1,22 @@
|
||||
# This script fixes keenetic issue with nfqws generated udp packets
|
||||
# Keenetic uses proprietary ndmmark and does not masquerade without this mark
|
||||
# If not masqueraded packets go to WAN with LAN IP and get dropped by ISP
|
||||
|
||||
# It's advised to set IFACE_WAN in config
|
||||
|
||||
zapret_custom_firewall()
|
||||
{
|
||||
# $1 - 1 - add, 0 - stop
|
||||
|
||||
local wan wanif rule
|
||||
|
||||
[ "$DISABLE_IPV4" = "1" ] || {
|
||||
# use IFACE_WAN if defined. if not - search for interfaces with default route.
|
||||
wanif=${IFACE_WAN:-$(sed -nre 's/^([^\t]+)\t00000000\t[0-9A-F]{8}\t[0-9A-F]{4}\t[0-9]+\t[0-9]+\t[0-9]+\t00000000.*$/\1/p' /proc/net/route | sort -u | xargs)}
|
||||
for wan in $wanif; do
|
||||
rule="-o $wan -p udp -m mark --mark $DESYNC_MARK/$DESYNC_MARK"
|
||||
ipt_print_op $1 "$rule" "keenetic udp fix"
|
||||
ipt_add_del $1 POSTROUTING -t nat $rule -j MASQUERADE
|
||||
done
|
||||
}
|
||||
}
|
@@ -167,15 +167,18 @@ run_daemon()
|
||||
# use $PIDDIR/$DAEMONBASE$1.pid as pidfile
|
||||
|
||||
local DAEMONBASE="$(basename "$2")"
|
||||
local PIDFILE=$PIDDIR/$DAEMONBASE$1.pid
|
||||
local PID= PIDFILE=$PIDDIR/$DAEMONBASE$1.pid
|
||||
echo "Starting daemon $1: $2 $3"
|
||||
if exists start-stop-daemon ; then
|
||||
start-stop-daemon -S -p "$PIDFILE" -m -b -x "$2" -- $3
|
||||
else
|
||||
if [ -f "$PIDFILE" ] && pgrep -F "$PIDFILE" "$DAEMONBASE" >/dev/null; then
|
||||
|
||||
[ -f "$PIDFILE" ] && {
|
||||
read PID <"$PIDFILE"
|
||||
[ -d "/proc/$PID" ] || PID=
|
||||
}
|
||||
|
||||
if [ -n "$PID" ]; then
|
||||
echo already running
|
||||
else
|
||||
"$2" $3 >/dev/null 2>/dev/null &
|
||||
"$2" $3 >/dev/null &
|
||||
PID=$!
|
||||
if [ -n "$PID" ]; then
|
||||
echo $PID >$PIDFILE
|
||||
@@ -184,7 +187,6 @@ run_daemon()
|
||||
false
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
stop_daemon()
|
||||
{
|
||||
@@ -192,11 +194,8 @@ stop_daemon()
|
||||
# $2 - daemon
|
||||
# use $PIDDIR/$DAEMONBASE$1.pid as pidfile
|
||||
local DAEMONBASE="$(basename "$2")"
|
||||
local PIDFILE=$PIDDIR/$DAEMONBASE$1.pid
|
||||
local PID PIDFILE=$PIDDIR/$DAEMONBASE$1.pid
|
||||
echo "Stopping daemon $1: $2"
|
||||
if exists start-stop-daemon ; then
|
||||
start-stop-daemon -K -p "$PIDFILE" -x "$2"
|
||||
else
|
||||
if [ -f "$PIDFILE" ]; then
|
||||
read PID <"$PIDFILE"
|
||||
kill $PID
|
||||
@@ -204,7 +203,6 @@ stop_daemon()
|
||||
else
|
||||
echo no pidfile : $PIDFILE
|
||||
fi
|
||||
fi
|
||||
}
|
||||
do_daemon()
|
||||
{
|
||||
|
@@ -25,7 +25,11 @@ check_dir()
|
||||
# find does not use its own shell exec
|
||||
# it uses execvp(). in musl libc it does not call shell, in glibc it DOES call /bin/sh
|
||||
# that's why prefer bash or zsh if present. otherwise it's our last chance
|
||||
out=$(echo 0.0.0.0 | find "$dir" -maxdepth 1 -name ip2net -exec {} \; 2>/dev/null)
|
||||
local FIND=find
|
||||
if ! exists find && exists busybox; then
|
||||
FIND="busybox find"
|
||||
fi
|
||||
out=$(echo 0.0.0.0 | $FIND "$dir" -maxdepth 1 -name ip2net -exec {} \; 2>/dev/null)
|
||||
fi
|
||||
[ -n "$out" ]
|
||||
else
|
||||
|
@@ -206,12 +206,12 @@ select_mode()
|
||||
|
||||
select_getlist()
|
||||
{
|
||||
if [ "$MODE_FILTER" = "ipset" -o "$MODE_FILTER" = "hostlist" ]; then
|
||||
if [ "$MODE_FILTER" = "ipset" -o "$MODE_FILTER" = "hostlist" -o "$MODE_FILTER" = "autohostlist" ]; then
|
||||
local D=N
|
||||
[ -n "$GETLIST" ] && D=Y
|
||||
echo
|
||||
if ask_yes_no $D "do you want to auto download ip/host list"; then
|
||||
if [ "$MODE_FILTER" = "hostlist" ] ; then
|
||||
if [ "$MODE_FILTER" = "hostlist" -o "$MODE_FILTER" = "autohostlist" ] ; then
|
||||
GETLISTS="get_refilter_domains.sh get_antizapret_domains.sh get_reestr_resolvable_domains.sh get_reestr_hostlist.sh"
|
||||
GETLIST_DEF="get_antizapret_domains.sh"
|
||||
else
|
||||
@@ -549,7 +549,7 @@ service_install_systemd()
|
||||
|
||||
if [ -w "$SYSTEMD_SYSTEM_DIR" ] ; then
|
||||
rm -f "$INIT_SCRIPT"
|
||||
ln -fs "$EXEDIR/init.d/systemd/zapret.service" "$SYSTEMD_SYSTEM_DIR"
|
||||
cp -f "$EXEDIR/init.d/systemd/zapret.service" "$SYSTEMD_SYSTEM_DIR"
|
||||
"$SYSTEMCTL" daemon-reload
|
||||
"$SYSTEMCTL" enable zapret || {
|
||||
echo could not enable systemd service
|
||||
@@ -567,8 +567,8 @@ timer_install_systemd()
|
||||
if [ -w "$SYSTEMD_SYSTEM_DIR" ] ; then
|
||||
"$SYSTEMCTL" disable zapret-list-update.timer
|
||||
"$SYSTEMCTL" stop zapret-list-update.timer
|
||||
ln -fs "$EXEDIR/init.d/systemd/zapret-list-update.service" "$SYSTEMD_SYSTEM_DIR"
|
||||
ln -fs "$EXEDIR/init.d/systemd/zapret-list-update.timer" "$SYSTEMD_SYSTEM_DIR"
|
||||
cp -f "$EXEDIR/init.d/systemd/zapret-list-update.service" "$SYSTEMD_SYSTEM_DIR"
|
||||
cp -f "$EXEDIR/init.d/systemd/zapret-list-update.timer" "$SYSTEMD_SYSTEM_DIR"
|
||||
"$SYSTEMCTL" daemon-reload
|
||||
"$SYSTEMCTL" enable zapret-list-update.timer || {
|
||||
echo could not enable zapret-list-update.timer
|
||||
|
@@ -1,5 +1,5 @@
|
||||
CC ?= gcc
|
||||
CFLAGS += -std=gnu99 -O3
|
||||
CFLAGS += -std=gnu99 -Os -flto=auto
|
||||
CFLAGS_BSD = -Wno-address-of-packed-member
|
||||
CFLAGS_WIN = -static
|
||||
LIBS =
|
||||
@@ -9,7 +9,9 @@ SRC_FILES = ip2net.c qsort.c
|
||||
all: ip2net
|
||||
|
||||
ip2net: $(SRC_FILES)
|
||||
$(CC) -s $(CFLAGS) -o $@ $(SRC_FILES) $(LDFLAGS) $(LIBS)
|
||||
$(CC) -s $(CFLAGS) -o ip2net $(SRC_FILES) $(LDFLAGS) $(LIBS)
|
||||
|
||||
android: ip2net
|
||||
|
||||
bsd: $(SRC_FILES)
|
||||
$(CC) -s $(CFLAGS) $(CFLAGS_BSD) -o ip2net $(SRC_FILES) $(LDFLAGS) $(LIBS)
|
||||
|
@@ -1,15 +1,19 @@
|
||||
CC ?= gcc
|
||||
CFLAGS += -std=gnu99 -O3
|
||||
CFLAGS += -std=gnu99 -Os
|
||||
CFLAGS_BSD = -Wno-address-of-packed-member
|
||||
CFLAGS_WIN = -static
|
||||
LIBS = -lpthread
|
||||
LIBS_ANDROID =
|
||||
LIBS_WIN = -lws2_32
|
||||
SRC_FILES = *.c
|
||||
|
||||
all: mdig
|
||||
|
||||
mdig: $(SRC_FILES)
|
||||
$(CC) -s $(CFLAGS) -o $@ $(SRC_FILES) $(LDFLAGS) $(LIBS)
|
||||
$(CC) -s $(CFLAGS) -o mdig $(SRC_FILES) $(LDFLAGS) $(LIBS)
|
||||
|
||||
android: $(SRC_FILES)
|
||||
$(CC) -s $(CFLAGS) -o mdig $(SRC_FILES) $(LDFLAGS) $(LIBS_ANDROID)
|
||||
|
||||
bsd: $(SRC_FILES)
|
||||
$(CC) -s $(CFLAGS) $(CFLAGS_BSD) -o mdig $(SRC_FILES) $(LDFLAGS) $(LIBS)
|
||||
|
11
mdig/mdig.c
11
mdig/mdig.c
@@ -12,7 +12,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <getopt.h>
|
||||
#ifdef _WIN32
|
||||
@@ -21,7 +20,9 @@
|
||||
#include <winsock2.h>
|
||||
#include <ws2ipdef.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <fcntl.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
@@ -364,6 +365,9 @@ int dns_make_query(const char *dom, char family)
|
||||
fprintf(stderr, "could not make DNS query\n");
|
||||
return 1;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
_setmode(_fileno(stdout), _O_BINARY);
|
||||
#endif
|
||||
if (fwrite(q,l,1,stdout)!=1)
|
||||
{
|
||||
fprintf(stderr, "could not write DNS query blob to stdout\n");
|
||||
@@ -420,8 +424,11 @@ bool dns_parse_print(const uint8_t *a, size_t len)
|
||||
}
|
||||
int dns_parse_query()
|
||||
{
|
||||
uint8_t a[1500];
|
||||
uint8_t a[8192];
|
||||
size_t l;
|
||||
#ifdef _WIN32
|
||||
_setmode(_fileno(stdin), _O_BINARY);
|
||||
#endif
|
||||
l = fread(a,1,sizeof(a),stdin);
|
||||
if (!l || !feof(stdin))
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user