From eab5758b51c187802131e36f2e4b7e563ee4b509 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sat, 30 May 2026 16:18:40 +0300 Subject: [PATCH 01/41] Fix deb/rpm builds --- CMakeLists.txt | 24 ++++++++++++------------ debian/3proxy.manpages | 11 ----------- debian/conffiles | 4 ++++ debian/rules | 21 +++++++++++++++++---- scripts/rh/3proxy.spec | 2 +- 5 files changed, 34 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 39cd177..db41fe4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,20 +64,20 @@ endif() # For crypt: if prefix is empty, "my" is used instead (→ mycrypt) set(3PROXY_BINARY_PREFIX "3proxy_" CACHE STRING "Prefix for standalone module and crypt binary names") -# Standalone module build options (OFF by default) -option(3PROXY_BUILD_ALL "Build all standalone binaries" OFF) -option(3PROXY_BUILD_PROXY "Build standalone proxy binary" OFF) -option(3PROXY_BUILD_SOCKS "Build standalone socks binary" OFF) -option(3PROXY_BUILD_POP3P "Build standalone pop3p binary" OFF) -option(3PROXY_BUILD_SMTPP "Build standalone smtpp binary" OFF) -option(3PROXY_BUILD_FTPPR "Build standalone ftppr binary" OFF) -option(3PROXY_BUILD_TCPPM "Build standalone tcppm binary" OFF) -option(3PROXY_BUILD_UDPPM "Build standalone udppm binary" OFF) -option(3PROXY_BUILD_TLSPR "Build standalone tlspr binary" OFF) +# Standalone module build options (ON by default) +option(3PROXY_BUILD_NONE "Do not build standalone binaries" OFF) +option(3PROXY_BUILD_PROXY "Build standalone proxy binary" ON) +option(3PROXY_BUILD_SOCKS "Build standalone socks binary" ON) +option(3PROXY_BUILD_POP3P "Build standalone pop3p binary" ON) +option(3PROXY_BUILD_SMTPP "Build standalone smtpp binary" ON) +option(3PROXY_BUILD_FTPPR "Build standalone ftppr binary" ON) +option(3PROXY_BUILD_TCPPM "Build standalone tcppm binary" ON) +option(3PROXY_BUILD_UDPPM "Build standalone udppm binary" ON) +option(3PROXY_BUILD_TLSPR "Build standalone tlspr binary" ON) -if(3PROXY_BUILD_ALL) +if(3PROXY_BUILD_NONE) foreach(_M PROXY SOCKS POP3P SMTPP FTPPR TCPPM UDPPM TLSPR) - set(3PROXY_BUILD_${_M} ON) + set(3PROXY_BUILD_${_M} OFF) endforeach() endif() diff --git a/debian/3proxy.manpages b/debian/3proxy.manpages index e7e4124..e69de29 100644 --- a/debian/3proxy.manpages +++ b/debian/3proxy.manpages @@ -1,11 +0,0 @@ -man/3proxy.8 -man/3proxy.cfg.5 -man/3proxy_ftppr.8 -man/3proxy_pop3p.8 -man/3proxy_tlspr.8 -man/3proxy_proxy.8 -man/3proxy_smtpp.8 -man/3proxy_socks.8 -man/3proxy_tcppm.8 -man/3proxy_udppm.8 -man/3proxy_crypt.8 diff --git a/debian/conffiles b/debian/conffiles index e69de29..41544e6 100644 --- a/debian/conffiles +++ b/debian/conffiles @@ -0,0 +1,4 @@ +/etc/3proxy/3proxy.cfg +/usr/local/3proxy/conf/3proxy.cfg +/usr/local/3proxy/conf/bandlimiters +/usr/local/3proxy/conf/counters diff --git a/debian/rules b/debian/rules index aacf054..ffae8d6 100644 --- a/debian/rules +++ b/debian/rules @@ -3,8 +3,21 @@ %: dh $@ -override_dh_auto_clean: - find src/ -type f -name "*.o" -delete - find src/ -type f -name "Makefile.var" -delete - find bin/ -type f -executable -delete +override_dh_auto_configure: + ln -sf Makefile.Linux Makefile +override_dh_auto_build: + $(MAKE) + +override_dh_auto_install: + $(MAKE) DESTDIR=debian/3proxy install + +override_dh_installman: + +override_dh_usrlocal: + +override_dh_auto_clean: + find src/ -type f -name "*.o" -delete + find src/ -type f -name "Makefile.var" -delete + find bin/ -type f -executable -delete + rm -f Makefile diff --git a/scripts/rh/3proxy.spec b/scripts/rh/3proxy.spec index efbabde..bd537ef 100644 --- a/scripts/rh/3proxy.spec +++ b/scripts/rh/3proxy.spec @@ -50,7 +50,7 @@ make clean %config(noreplace) /usr/local/3proxy/conf/bandlimiters %config(noreplace) /usr/local/3proxy/conf/counters /usr/local/3proxy/libexec/*.ld.so -/usr/share/man/man5/3proxy.cfg.5 +/usr/share/man/man5/3proxy.cfg.5* /usr/share/man/man8/* /var/log/3proxy From bdf9946fe5812a4b91708625e31f04b8f992cd6b Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sat, 30 May 2026 17:05:43 +0300 Subject: [PATCH 02/41] Add dockers build --- .github/workflows/build-rpm-arm64.yml | 3 + .github/workflows/build-rpm-armhf.yml | 3 + .github/workflows/build-rpm-x86-64.yml | 3 + .github/workflows/build-watcom.yml | 3 + .github/workflows/build-win32.yml | 3 + .github/workflows/build-win64.yml | 3 + .github/workflows/build-winarm64.yml | 3 + .github/workflows/docker-ghcr.yml | 81 ++++++++++++++++++++++++++ .github/workflows/docker.yml | 78 +++++++++++++++++++++++++ 9 files changed, 180 insertions(+) create mode 100644 .github/workflows/docker-ghcr.yml create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/build-rpm-arm64.yml b/.github/workflows/build-rpm-arm64.yml index f5aa94e..f085c8b 100644 --- a/.github/workflows/build-rpm-arm64.yml +++ b/.github/workflows/build-rpm-arm64.yml @@ -1,6 +1,9 @@ name: RPM/DEB build aarch64 on: + push: + paths: + - 'RELEASE' workflow_dispatch: jobs: diff --git a/.github/workflows/build-rpm-armhf.yml b/.github/workflows/build-rpm-armhf.yml index b7f33fa..4afff3c 100644 --- a/.github/workflows/build-rpm-armhf.yml +++ b/.github/workflows/build-rpm-armhf.yml @@ -1,6 +1,9 @@ name: RPM/DEB build armhf on: + push: + paths: + - 'RELEASE' workflow_dispatch: jobs: diff --git a/.github/workflows/build-rpm-x86-64.yml b/.github/workflows/build-rpm-x86-64.yml index c4295a5..9d9cf4d 100644 --- a/.github/workflows/build-rpm-x86-64.yml +++ b/.github/workflows/build-rpm-x86-64.yml @@ -1,6 +1,9 @@ name: RPM/DEB build x86-64 on: + push: + paths: + - 'RELEASE' workflow_dispatch: jobs: diff --git a/.github/workflows/build-watcom.yml b/.github/workflows/build-watcom.yml index 1e472a2..d6caf0f 100644 --- a/.github/workflows/build-watcom.yml +++ b/.github/workflows/build-watcom.yml @@ -1,6 +1,9 @@ name: Build Win32 3proxy-lite with Watcom on: + push: + paths: + - 'RELEASE' workflow_dispatch: jobs: diff --git a/.github/workflows/build-win32.yml b/.github/workflows/build-win32.yml index 367595d..34107f2 100644 --- a/.github/workflows/build-win32.yml +++ b/.github/workflows/build-win32.yml @@ -1,6 +1,9 @@ name: Build Win32 3proxy with MSVC on: + push: + paths: + - 'RELEASE' workflow_dispatch: jobs: diff --git a/.github/workflows/build-win64.yml b/.github/workflows/build-win64.yml index 055c57d..ca38ba6 100644 --- a/.github/workflows/build-win64.yml +++ b/.github/workflows/build-win64.yml @@ -1,6 +1,9 @@ name: Build Win64 3proxy with MSVC on: + push: + paths: + - 'RELEASE' workflow_dispatch: jobs: diff --git a/.github/workflows/build-winarm64.yml b/.github/workflows/build-winarm64.yml index 4c8dd7c..9abf7ba 100644 --- a/.github/workflows/build-winarm64.yml +++ b/.github/workflows/build-winarm64.yml @@ -1,6 +1,9 @@ name: Build Win-arm64 3proxy with MSVC on: + push: + paths: + - 'RELEASE' workflow_dispatch: jobs: diff --git a/.github/workflows/docker-ghcr.yml b/.github/workflows/docker-ghcr.yml new file mode 100644 index 0000000..041e84a --- /dev/null +++ b/.github/workflows/docker-ghcr.yml @@ -0,0 +1,81 @@ +name: Build Docker images (GHCR) + +on: + push: + branches: [master] + paths: + - 'RELEASE' + workflow_dispatch: + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build: + name: Build and push Docker images + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Determine tags + id: tags + env: + REF: ${{ github.ref }} + IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + run: | + if [[ "$REF" == refs/tags/* ]]; then + RELEASE=$(cat RELEASE) + echo "minimal=${IMAGE}:${RELEASE}.minimal,${IMAGE}:minimal" >> "$GITHUB_OUTPUT" + echo "busybox=${IMAGE}:${RELEASE}.busybox,${IMAGE}:busybox" >> "$GITHUB_OUTPUT" + echo "full=${IMAGE}:${RELEASE},${IMAGE}:latest" >> "$GITHUB_OUTPUT" + else + echo "minimal=${IMAGE}:devel.minimal" >> "$GITHUB_OUTPUT" + echo "busybox=${IMAGE}:devel.busybox" >> "$GITHUB_OUTPUT" + echo "full=${IMAGE}:devel" >> "$GITHUB_OUTPUT" + fi + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GHCR + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push minimal + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.minimal + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.tags.outputs.minimal }} + + - name: Build and push busybox + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.busybox + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.tags.outputs.busybox }} + + - name: Build and push full + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.full + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.tags.outputs.full }} diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..07a1b12 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,78 @@ +name: Build Docker images (Docker Hub) + +on: + push: + branches: [master] + paths: + - 'RELEASE' + workflow_dispatch: + +env: + REGISTRY: docker.io + IMAGE_NAME: 3proxy/3proxy + +jobs: + build: + name: Build and push Docker images + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Determine tags + id: tags + env: + REF: ${{ github.ref }} + run: | + if [[ "$REF" == refs/tags/* ]]; then + RELEASE=$(cat RELEASE) + echo "minimal=${REGISTRY}/${IMAGE_NAME}:${RELEASE}.minimal,${REGISTRY}/${IMAGE_NAME}:minimal" >> "$GITHUB_OUTPUT" + echo "busybox=${REGISTRY}/${IMAGE_NAME}:${RELEASE}.busybox,${REGISTRY}/${IMAGE_NAME}:busybox" >> "$GITHUB_OUTPUT" + echo "full=${REGISTRY}/${IMAGE_NAME}:${RELEASE},${REGISTRY}/${IMAGE_NAME}:latest" >> "$GITHUB_OUTPUT" + else + echo "minimal=${REGISTRY}/${IMAGE_NAME}:devel.minimal" >> "$GITHUB_OUTPUT" + echo "busybox=${REGISTRY}/${IMAGE_NAME}:devel.busybox" >> "$GITHUB_OUTPUT" + echo "full=${REGISTRY}/${IMAGE_NAME}:devel" >> "$GITHUB_OUTPUT" + fi + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push minimal + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.minimal + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.tags.outputs.minimal }} + + - name: Build and push busybox + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.busybox + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.tags.outputs.busybox }} + + - name: Build and push full + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.full + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.tags.outputs.full }} From 3dde2de498b9c84e88b1a911c9c88c1fafab1ed2 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sun, 31 May 2026 13:10:26 +0300 Subject: [PATCH 03/41] do not keep untagged dockers --- .github/workflows/docker-ghcr.yml | 18 +++++++++++++++--- .github/workflows/docker.yml | 10 +++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docker-ghcr.yml b/.github/workflows/docker-ghcr.yml index 041e84a..fda9026 100644 --- a/.github/workflows/docker-ghcr.yml +++ b/.github/workflows/docker-ghcr.yml @@ -34,9 +34,10 @@ jobs: echo "busybox=${IMAGE}:${RELEASE}.busybox,${IMAGE}:busybox" >> "$GITHUB_OUTPUT" echo "full=${IMAGE}:${RELEASE},${IMAGE}:latest" >> "$GITHUB_OUTPUT" else - echo "minimal=${IMAGE}:devel.minimal" >> "$GITHUB_OUTPUT" - echo "busybox=${IMAGE}:devel.busybox" >> "$GITHUB_OUTPUT" - echo "full=${IMAGE}:devel" >> "$GITHUB_OUTPUT" + DATETIME=$(date +%d%m%y%H%M%S) + echo "minimal=${IMAGE}:${DATETIME}-devel.minimal,${IMAGE}:devel.minimal" >> "$GITHUB_OUTPUT" + echo "busybox=${IMAGE}:${DATETIME}-devel.busybox,${IMAGE}:devel.busybox" >> "$GITHUB_OUTPUT" + echo "full=${IMAGE}:${DATETIME}-devel,${IMAGE}:devel" >> "$GITHUB_OUTPUT" fi - name: Set up QEMU @@ -60,6 +61,7 @@ jobs: file: Dockerfile.minimal platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} + no-cache: true tags: ${{ steps.tags.outputs.minimal }} - name: Build and push busybox @@ -69,6 +71,7 @@ jobs: file: Dockerfile.busybox platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} + no-cache: true tags: ${{ steps.tags.outputs.busybox }} - name: Build and push full @@ -78,4 +81,13 @@ jobs: file: Dockerfile.full platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} + no-cache: true tags: ${{ steps.tags.outputs.full }} + + - name: Delete untagged GHCR images + if: github.event_name != 'pull_request' + uses: actions/delete-package-versions@v5 + with: + package-name: 3proxy + package-type: container + delete-untagged-versions: true diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 07a1b12..a3fdf40 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -32,9 +32,10 @@ jobs: echo "busybox=${REGISTRY}/${IMAGE_NAME}:${RELEASE}.busybox,${REGISTRY}/${IMAGE_NAME}:busybox" >> "$GITHUB_OUTPUT" echo "full=${REGISTRY}/${IMAGE_NAME}:${RELEASE},${REGISTRY}/${IMAGE_NAME}:latest" >> "$GITHUB_OUTPUT" else - echo "minimal=${REGISTRY}/${IMAGE_NAME}:devel.minimal" >> "$GITHUB_OUTPUT" - echo "busybox=${REGISTRY}/${IMAGE_NAME}:devel.busybox" >> "$GITHUB_OUTPUT" - echo "full=${REGISTRY}/${IMAGE_NAME}:devel" >> "$GITHUB_OUTPUT" + DATETIME=$(date +%d%m%y%H%M%S) + echo "minimal=${REGISTRY}/${IMAGE_NAME}:${DATETIME}-devel.minimal,${REGISTRY}/${IMAGE_NAME}:devel.minimal" >> "$GITHUB_OUTPUT" + echo "busybox=${REGISTRY}/${IMAGE_NAME}:${DATETIME}-devel.busybox,${REGISTRY}/${IMAGE_NAME}:devel.busybox" >> "$GITHUB_OUTPUT" + echo "full=${REGISTRY}/${IMAGE_NAME}:${DATETIME}-devel,${REGISTRY}/${IMAGE_NAME}:devel" >> "$GITHUB_OUTPUT" fi - name: Set up QEMU @@ -57,6 +58,7 @@ jobs: file: Dockerfile.minimal platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} + no-cache: true tags: ${{ steps.tags.outputs.minimal }} - name: Build and push busybox @@ -66,6 +68,7 @@ jobs: file: Dockerfile.busybox platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} + no-cache: true tags: ${{ steps.tags.outputs.busybox }} - name: Build and push full @@ -75,4 +78,5 @@ jobs: file: Dockerfile.full platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} + no-cache: true tags: ${{ steps.tags.outputs.full }} From 34e9c453fa6c820d91ba6326fef772046dc3dc11 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sun, 31 May 2026 13:47:41 +0300 Subject: [PATCH 04/41] Workflows update --- .github/workflows/c-cpp-Linux.yml | 3 --- .github/workflows/c-cpp-MacOS.yml | 3 --- .github/workflows/c-cpp-Windows.yml | 3 --- .github/workflows/c-cpp-cmake.yml | 3 --- .github/workflows/docker-ghcr.yml | 8 ++++---- .github/workflows/docker.yml | 6 +++--- 6 files changed, 7 insertions(+), 19 deletions(-) diff --git a/.github/workflows/c-cpp-Linux.yml b/.github/workflows/c-cpp-Linux.yml index 9883d6a..c26ec16 100644 --- a/.github/workflows/c-cpp-Linux.yml +++ b/.github/workflows/c-cpp-Linux.yml @@ -4,9 +4,6 @@ on: push: branches: [ "master" ] paths: [ '**.c', '**.h', 'Makefile.Linux', '.github/configs', '.github/workflows/c-cpp-Linux.yml' ] - pull_request: - branches: [ "master" ] - paths: [ '**.c', '**.h', 'Makefile.Linux', '.github/configs', '.github/workflows/c-cpp-Linux.yml' ] workflow_dispatch: jobs: diff --git a/.github/workflows/c-cpp-MacOS.yml b/.github/workflows/c-cpp-MacOS.yml index b23cd04..2b618a2 100644 --- a/.github/workflows/c-cpp-MacOS.yml +++ b/.github/workflows/c-cpp-MacOS.yml @@ -4,9 +4,6 @@ on: push: branches: [ "master" ] paths: [ '**.c', '**.h', 'Makefile.FreeBSD', '.github/configs', '.github/workflows/c-cpp-MacOS.yml' ] - pull_request: - branches: [ "master" ] - paths: [ '**.c', '**.h', 'Makefile.FreeBSD', '.github/configs', '.github/workflows/c-cpp-MacOS.yml' ] workflow_dispatch: jobs: diff --git a/.github/workflows/c-cpp-Windows.yml b/.github/workflows/c-cpp-Windows.yml index b4a0ff4..83aa8e8 100644 --- a/.github/workflows/c-cpp-Windows.yml +++ b/.github/workflows/c-cpp-Windows.yml @@ -4,9 +4,6 @@ on: push: branches: [ "master" ] paths: [ '**.c', '**.h', 'Makefile.msvc', '.github/configs', '.github/workflows/c-cpp-Windows.yml' ] - pull_request: - branches: [ "master" ] - paths: [ '**.c', '**.h', 'Makefile.msvc', '.github/configs', '.github/workflows/c-cpp-Windows.yml' ] workflow_dispatch: jobs: diff --git a/.github/workflows/c-cpp-cmake.yml b/.github/workflows/c-cpp-cmake.yml index be7dcc7..ac0af19 100644 --- a/.github/workflows/c-cpp-cmake.yml +++ b/.github/workflows/c-cpp-cmake.yml @@ -4,9 +4,6 @@ on: push: branches: [ "master", "unix_socket" ] paths: [ '**.c', '**.h', '**.cmake', 'CMakeLists.txt', '.github/configs', '.github/workflows/c-cpp-cmake.yml' ] - pull_request: - branches: [ "master" ] - paths: [ '**.c', '**.h', '**.cmake', 'CMakeLists.txt', '.github/configs', '.github/workflows/c-cpp-cmake.yml' ] workflow_dispatch: jobs: diff --git a/.github/workflows/docker-ghcr.yml b/.github/workflows/docker-ghcr.yml index fda9026..adbb88c 100644 --- a/.github/workflows/docker-ghcr.yml +++ b/.github/workflows/docker-ghcr.yml @@ -41,14 +41,14 @@ jobs: fi - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: Login to GHCR if: github.event_name != 'pull_request' - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} @@ -90,4 +90,4 @@ jobs: with: package-name: 3proxy package-type: container - delete-untagged-versions: true + delete-only-untagged-versions: true diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a3fdf40..0d6155a 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -39,14 +39,14 @@ jobs: fi - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v4 - name: Login to Docker Hub if: github.event_name != 'pull_request' - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} From 997671ee16ecb71c6d8ec10cc0b899e8eaca2dd9 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sun, 31 May 2026 15:29:11 +0300 Subject: [PATCH 05/41] publish builds on release --- .github/workflows/build-rpm-arm64.yml | 19 +++++++++++++++---- .github/workflows/build-rpm-armhf.yml | 19 +++++++++++++++---- .github/workflows/build-rpm-x86-64.yml | 17 ++++++++++++++--- .github/workflows/build-watcom.yml | 15 ++++++++++++--- .github/workflows/build-win32.yml | 15 ++++++++++++--- .github/workflows/build-win64.yml | 15 ++++++++++++--- .github/workflows/build-winarm64.yml | 15 ++++++++++++--- .github/workflows/docker-ghcr.yml | 22 +++++++++------------- .github/workflows/docker.yml | 22 +++++++++------------- 9 files changed, 110 insertions(+), 49 deletions(-) diff --git a/.github/workflows/build-rpm-arm64.yml b/.github/workflows/build-rpm-arm64.yml index f085c8b..6ee2ca3 100644 --- a/.github/workflows/build-rpm-arm64.yml +++ b/.github/workflows/build-rpm-arm64.yml @@ -1,9 +1,8 @@ name: RPM/DEB build aarch64 on: - push: - paths: - - 'RELEASE' + release: + types: [published] workflow_dispatch: jobs: @@ -45,11 +44,17 @@ jobs: rpmbuild -ba 3proxy-$RELEASE.spec cd $ret mv ~/rpmbuild/RPMS/aarch64/3proxy-$RELEASE-1.aarch64.rpm 3proxy-$RELEASE.arm64.rpm - - name: Get artifact arp + - name: Get artifact rpm uses: actions/upload-artifact@v6 with: name: "3proxy-${{ env.RELEASE }}-arm64.rpm" path: "*.rpm" + - name: Upload rpm to release + if: github.event_name == 'release' + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.event.release.tag_name }} + run: gh release upload "$TAG" 3proxy-${{ env.RELEASE }}.arm64.rpm - name: debbuild run: | ret=`pwd` @@ -70,3 +75,9 @@ jobs: with: name: "3proxy-${{ env.RELEASE }}-arm64.deb" path: "*.deb" + - name: Upload deb to release + if: github.event_name == 'release' + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.event.release.tag_name }} + run: gh release upload "$TAG" 3proxy-${{ env.RELEASE }}.arm64.deb diff --git a/.github/workflows/build-rpm-armhf.yml b/.github/workflows/build-rpm-armhf.yml index 4afff3c..e3e05ea 100644 --- a/.github/workflows/build-rpm-armhf.yml +++ b/.github/workflows/build-rpm-armhf.yml @@ -1,9 +1,8 @@ name: RPM/DEB build armhf on: - push: - paths: - - 'RELEASE' + release: + types: [published] workflow_dispatch: jobs: @@ -72,11 +71,17 @@ jobs: rpmbuild -ba --define "PAMLIB pam0g" --define "_arch arm" --define "cross yes" --target=arm-linux-gnueabi 3proxy-$RELEASE.spec cd $ret mv ~/rpmbuild/RPMS/arm/3proxy-$RELEASE-1.arm.rpm 3proxy-$RELEASE.arm.rpm - - name: Get artifact + - name: Get artifact rpm uses: actions/upload-artifact@v6 with: name: "3proxy-${{ env.RELEASE }}-arm.rpm" path: "*.rpm" + - name: Upload rpm to release + if: github.event_name == 'release' + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.event.release.tag_name }} + run: gh release upload "$TAG" 3proxy-${{ env.RELEASE }}.arm.rpm - name: debbuild run: | ret=`pwd` @@ -103,3 +108,9 @@ jobs: with: name: "3proxy-${{ env.RELEASE }}-arm.deb" path: "*.deb" + - name: Upload deb to release + if: github.event_name == 'release' + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.event.release.tag_name }} + run: gh release upload "$TAG" 3proxy-${{ env.RELEASE }}.arm.deb diff --git a/.github/workflows/build-rpm-x86-64.yml b/.github/workflows/build-rpm-x86-64.yml index 9d9cf4d..11a6442 100644 --- a/.github/workflows/build-rpm-x86-64.yml +++ b/.github/workflows/build-rpm-x86-64.yml @@ -1,9 +1,8 @@ name: RPM/DEB build x86-64 on: - push: - paths: - - 'RELEASE' + release: + types: [published] workflow_dispatch: jobs: @@ -50,6 +49,12 @@ jobs: with: name: "3proxy-${{ env.RELEASE }}-x86_64.rpm" path: "*.rpm" + - name: Upload rpm to release + if: github.event_name == 'release' + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.event.release.tag_name }} + run: gh release upload "$TAG" 3proxy-${{ env.RELEASE }}.x86_64.rpm - name: debbuild run: | ret=`pwd` @@ -70,4 +75,10 @@ jobs: with: name: "3proxy-${{ env.RELEASE }}-x86_64.deb" path: "*.deb" + - name: Upload deb to release + if: github.event_name == 'release' + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.event.release.tag_name }} + run: gh release upload "$TAG" 3proxy-${{ env.RELEASE }}.x86_64.deb diff --git a/.github/workflows/build-watcom.yml b/.github/workflows/build-watcom.yml index d6caf0f..73541fe 100644 --- a/.github/workflows/build-watcom.yml +++ b/.github/workflows/build-watcom.yml @@ -1,9 +1,8 @@ name: Build Win32 3proxy-lite with Watcom on: - push: - paths: - - 'RELEASE' + release: + types: [published] workflow_dispatch: jobs: @@ -80,3 +79,13 @@ jobs: with: name: "3proxy-${{ env.RELEASE }}-lite" path: dist/ + - name: Create zip + if: github.event_name == 'release' + shell: pwsh + run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-lite.zip + - name: Upload to release + if: github.event_name == 'release' + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.event.release.tag_name }} + run: gh release upload "$TAG" 3proxy-${{ env.RELEASE }}-lite.zip diff --git a/.github/workflows/build-win32.yml b/.github/workflows/build-win32.yml index 34107f2..e7b14c3 100644 --- a/.github/workflows/build-win32.yml +++ b/.github/workflows/build-win32.yml @@ -1,9 +1,8 @@ name: Build Win32 3proxy with MSVC on: - push: - paths: - - 'RELEASE' + release: + types: [published] workflow_dispatch: jobs: @@ -86,3 +85,13 @@ jobs: with: name: "3proxy-${{ env.RELEASE }}" path: dist/ + - name: Create zip + if: github.event_name == 'release' + shell: pwsh + run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-x86.zip + - name: Upload to release + if: github.event_name == 'release' + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.event.release.tag_name }} + run: gh release upload "$TAG" 3proxy-${{ env.RELEASE }}-x86.zip diff --git a/.github/workflows/build-win64.yml b/.github/workflows/build-win64.yml index ca38ba6..c6ab8ce 100644 --- a/.github/workflows/build-win64.yml +++ b/.github/workflows/build-win64.yml @@ -1,9 +1,8 @@ name: Build Win64 3proxy with MSVC on: - push: - paths: - - 'RELEASE' + release: + types: [published] workflow_dispatch: jobs: @@ -87,3 +86,13 @@ jobs: with: name: "3proxy-${{ env.RELEASE }}-x64" path: dist/ + - name: Create zip + if: github.event_name == 'release' + shell: pwsh + run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-x64.zip + - name: Upload to release + if: github.event_name == 'release' + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.event.release.tag_name }} + run: gh release upload "$TAG" 3proxy-${{ env.RELEASE }}-x64.zip diff --git a/.github/workflows/build-winarm64.yml b/.github/workflows/build-winarm64.yml index 9abf7ba..9e8198c 100644 --- a/.github/workflows/build-winarm64.yml +++ b/.github/workflows/build-winarm64.yml @@ -1,9 +1,8 @@ name: Build Win-arm64 3proxy with MSVC on: - push: - paths: - - 'RELEASE' + release: + types: [published] workflow_dispatch: jobs: @@ -86,3 +85,13 @@ jobs: with: name: "3proxy-${{ env.RELEASE }}-arm64" path: dist/ + - name: Create zip + if: github.event_name == 'release' + shell: pwsh + run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-arm64.zip + - name: Upload to release + if: github.event_name == 'release' + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.event.release.tag_name }} + run: gh release upload "$TAG" 3proxy-${{ env.RELEASE }}-arm64.zip diff --git a/.github/workflows/docker-ghcr.yml b/.github/workflows/docker-ghcr.yml index adbb88c..7622b14 100644 --- a/.github/workflows/docker-ghcr.yml +++ b/.github/workflows/docker-ghcr.yml @@ -1,10 +1,8 @@ name: Build Docker images (GHCR) on: - push: - branches: [master] - paths: - - 'RELEASE' + release: + types: [published] workflow_dispatch: env: @@ -25,19 +23,20 @@ jobs: - name: Determine tags id: tags env: - REF: ${{ github.ref }} + RELEASE_TAG: ${{ github.event.release.tag_name }} IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} run: | - if [[ "$REF" == refs/tags/* ]]; then - RELEASE=$(cat RELEASE) + if [[ "$RELEASE_TAG" != "" ]]; then + RELEASE="${RELEASE_TAG#v}" echo "minimal=${IMAGE}:${RELEASE}.minimal,${IMAGE}:minimal" >> "$GITHUB_OUTPUT" echo "busybox=${IMAGE}:${RELEASE}.busybox,${IMAGE}:busybox" >> "$GITHUB_OUTPUT" echo "full=${IMAGE}:${RELEASE},${IMAGE}:latest" >> "$GITHUB_OUTPUT" else DATETIME=$(date +%d%m%y%H%M%S) - echo "minimal=${IMAGE}:${DATETIME}-devel.minimal,${IMAGE}:devel.minimal" >> "$GITHUB_OUTPUT" - echo "busybox=${IMAGE}:${DATETIME}-devel.busybox,${IMAGE}:devel.busybox" >> "$GITHUB_OUTPUT" - echo "full=${IMAGE}:${DATETIME}-devel,${IMAGE}:devel" >> "$GITHUB_OUTPUT" + BRANCH=$(echo "${GITHUB_REF#refs/heads/}" | tr "/" "-") + echo "minimal=${IMAGE}:${DATETIME}-${BRANCH}.minimal,${IMAGE}:${BRANCH}.minimal" >> "$GITHUB_OUTPUT" + echo "busybox=${IMAGE}:${DATETIME}-${BRANCH}.busybox,${IMAGE}:${BRANCH}.busybox" >> "$GITHUB_OUTPUT" + echo "full=${IMAGE}:${DATETIME}-${BRANCH},${IMAGE}:${BRANCH}" >> "$GITHUB_OUTPUT" fi - name: Set up QEMU @@ -61,7 +60,6 @@ jobs: file: Dockerfile.minimal platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} - no-cache: true tags: ${{ steps.tags.outputs.minimal }} - name: Build and push busybox @@ -71,7 +69,6 @@ jobs: file: Dockerfile.busybox platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} - no-cache: true tags: ${{ steps.tags.outputs.busybox }} - name: Build and push full @@ -81,7 +78,6 @@ jobs: file: Dockerfile.full platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} - no-cache: true tags: ${{ steps.tags.outputs.full }} - name: Delete untagged GHCR images diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 0d6155a..df1ac87 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,10 +1,8 @@ name: Build Docker images (Docker Hub) on: - push: - branches: [master] - paths: - - 'RELEASE' + release: + types: [published] workflow_dispatch: env: @@ -24,18 +22,19 @@ jobs: - name: Determine tags id: tags env: - REF: ${{ github.ref }} + RELEASE_TAG: ${{ github.event.release.tag_name }} run: | - if [[ "$REF" == refs/tags/* ]]; then - RELEASE=$(cat RELEASE) + if [[ "$RELEASE_TAG" != "" ]]; then + RELEASE="${RELEASE_TAG#v}" echo "minimal=${REGISTRY}/${IMAGE_NAME}:${RELEASE}.minimal,${REGISTRY}/${IMAGE_NAME}:minimal" >> "$GITHUB_OUTPUT" echo "busybox=${REGISTRY}/${IMAGE_NAME}:${RELEASE}.busybox,${REGISTRY}/${IMAGE_NAME}:busybox" >> "$GITHUB_OUTPUT" echo "full=${REGISTRY}/${IMAGE_NAME}:${RELEASE},${REGISTRY}/${IMAGE_NAME}:latest" >> "$GITHUB_OUTPUT" else DATETIME=$(date +%d%m%y%H%M%S) - echo "minimal=${REGISTRY}/${IMAGE_NAME}:${DATETIME}-devel.minimal,${REGISTRY}/${IMAGE_NAME}:devel.minimal" >> "$GITHUB_OUTPUT" - echo "busybox=${REGISTRY}/${IMAGE_NAME}:${DATETIME}-devel.busybox,${REGISTRY}/${IMAGE_NAME}:devel.busybox" >> "$GITHUB_OUTPUT" - echo "full=${REGISTRY}/${IMAGE_NAME}:${DATETIME}-devel,${REGISTRY}/${IMAGE_NAME}:devel" >> "$GITHUB_OUTPUT" + BRANCH=$(echo "${GITHUB_REF#refs/heads/}" | tr "/" "-") + echo "minimal=${REGISTRY}/${IMAGE_NAME}:${DATETIME}-${BRANCH}.minimal,${REGISTRY}/${IMAGE_NAME}:${BRANCH}.minimal" >> "$GITHUB_OUTPUT" + echo "busybox=${REGISTRY}/${IMAGE_NAME}:${DATETIME}-${BRANCH}.busybox,${REGISTRY}/${IMAGE_NAME}:${BRANCH}.busybox" >> "$GITHUB_OUTPUT" + echo "full=${REGISTRY}/${IMAGE_NAME}:${DATETIME}-${BRANCH},${REGISTRY}/${IMAGE_NAME}:${BRANCH}" >> "$GITHUB_OUTPUT" fi - name: Set up QEMU @@ -58,7 +57,6 @@ jobs: file: Dockerfile.minimal platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} - no-cache: true tags: ${{ steps.tags.outputs.minimal }} - name: Build and push busybox @@ -68,7 +66,6 @@ jobs: file: Dockerfile.busybox platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} - no-cache: true tags: ${{ steps.tags.outputs.busybox }} - name: Build and push full @@ -78,5 +75,4 @@ jobs: file: Dockerfile.full platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} - no-cache: true tags: ${{ steps.tags.outputs.full }} From 56fdbd6e8a6be64bc7956cf360f537ddf454cc70 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sun, 31 May 2026 15:33:07 +0300 Subject: [PATCH 06/41] remove debugging ls in dockerfiles --- Dockerfile.busybox | 3 +-- Dockerfile.full | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Dockerfile.busybox b/Dockerfile.busybox index 8bff530..af1ffab 100644 --- a/Dockerfile.busybox +++ b/Dockerfile.busybox @@ -44,8 +44,7 @@ RUN cd /dist &&\ ln -s /lib usr/lib64 RUN cp /lib/ld-*.so.* /dist/usr/local/3proxy/libexec || true RUN cp /lib64/ld-*.so.* /dist/usr/local/3proxy/libexec || true -RUN cp "/lib/`gcc -dumpmachine`"/libdl.so.* /dist/usr/local/3proxy/libexec &&\ - ls -lR /dist +RUN cp "/lib/`gcc -dumpmachine`"/libdl.so.* /dist/usr/local/3proxy/libexec FROM docker.io/busybox:glibc COPY --from=buildenv /dist / diff --git a/Dockerfile.full b/Dockerfile.full index 829aaa4..33f6f51 100644 --- a/Dockerfile.full +++ b/Dockerfile.full @@ -54,8 +54,7 @@ RUN cd /dist/usr/local/3proxy/ &&\ RUN cd /dist/usr/local/3proxy/usr &&\ ln -s ../libexec lib &&\ ln -s ../libexec lib64 &&\ - strip /dist/usr/local/3proxy/libexec/*.so &&\ - ls -lR /dist + strip /dist/usr/local/3proxy/libexec/*.so FROM scratch COPY --from=buildenv /dist / From 5cae5dc866a85c08c366f19e88eb0ef0346f8235 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sun, 31 May 2026 16:07:53 +0300 Subject: [PATCH 07/41] Keep provenance --- .github/workflows/docker-ghcr.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/docker-ghcr.yml b/.github/workflows/docker-ghcr.yml index 7622b14..b4005df 100644 --- a/.github/workflows/docker-ghcr.yml +++ b/.github/workflows/docker-ghcr.yml @@ -80,10 +80,3 @@ jobs: push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.full }} - - name: Delete untagged GHCR images - if: github.event_name != 'pull_request' - uses: actions/delete-package-versions@v5 - with: - package-name: 3proxy - package-type: container - delete-only-untagged-versions: true From 254112cfde334eae98d40d0bd3adfc5c350e5afd Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Mon, 1 Jun 2026 10:48:02 +0300 Subject: [PATCH 08/41] send provenance to github only --- .github/workflows/docker.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index df1ac87..bfd5f7d 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -58,6 +58,7 @@ jobs: platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.minimal }} + provenance: false - name: Build and push busybox uses: docker/build-push-action@v6 @@ -67,6 +68,7 @@ jobs: platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.busybox }} + provenance: false - name: Build and push full uses: docker/build-push-action@v6 @@ -76,3 +78,4 @@ jobs: platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.full }} + provenance: false From 5ab63a0b683a2e0cead0c963247bef4c81ae170c Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Mon, 1 Jun 2026 11:36:16 +0300 Subject: [PATCH 09/41] Update README.md --- README.md | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f1a613f..6ddb21a 100644 --- a/README.md +++ b/README.md @@ -9,19 +9,81 @@ ## Download -Binaries and sources for released (master) versions (Windows, Linux): +# Binaries and sources for released (master) versions (Windows, Linux) https://github.com/z3APA3A/3proxy/releases -Docker images: +# Docker images https://hub.docker.com/r/3proxy/3proxy +https://github.com/3proxy/3proxy/pkgs/container/3proxy -Archive of old versions: +# Archive of old versions https://github.com/z3APA3A/3proxy-archive + ## Documentation Documentation (man pages and HTML) available with download, on https://3proxy.org/ and in github wiki https://github.com/3proxy/3proxy/wiki +## Docker images for https://github.com/z3APA3A/3proxy + +3 docker configurations are provided, default (full) also tagged as `:latest`, `:busybox` and `:minimal`, all refer to newest stable version. Except busybox, images are distroless and contain only binaries, you can not sh inside the container. `:busybox` contains busybox shell. + +# Default image (`:latest`): + +Full installation requires to mount /etc/3proxy directory with 3proxy.cfg files. + +to run: + +``` +echo log >/path/to/local/config/directory/3proxy.cfg +echo nserver 8.8.8.8 >>/path/to/local/config/directory/3proxy.cfg +echo nscache 65536 >>/path/to/local/config/directory/3proxy.cfg +echo proxy -p3129 >>/path/to/local/config/directory/3proxy.cfg +docker run --read-only -p 3129:3129 -v /path/to/local/config/directory:/etc/3proxy --name 3proxy.full docker.io/3proxy/3proxy +``` + + /path/to/local/config/directory in this example must contain 3proxy.cfg + + use `log` without pathname in config to log to stdout. + plugins are located in /usr/local/3proxy/libexec (/libexec for chroot config) and since 0.9.6 symlinked by /lib and /lib64 in both chroot and non-chroot configurations, so no full path is required in `plugin` command. Use e.g. `plugin SSLPlugin.ls.so ssl_plugin`. SSLPlugin is supported since 0.9.6. Some proxy types (e.g. SOCKSv5 UDPASSCOC, SOCKSv5 BIND functionality, ftp proxy) require access to ephemeral port, you may use e.g. -`-network host` mode or `-P` for `docker run`. + +since 0.9.6 images are distroless (except :busybox) it's recommended to use with read only file system, there are no benefits from chroot. For compatibility, you still can use chroot installation by mounting directory with 3proxy.cfg to /usr/local/3proxy/config. + +# Busybox image (`:busybox`): +Full with busybox added, to allow shell commands inside container. All libraries are in /lib, so chroot configuration can not use plugins. + +# Interactive `:minimal` image: + + Dockerfile for "interactive" minimal 3proxy execution, no configuration mounting is required, configuration + is accepted from stdin. Use `end` command to indicate the end of configuration. Use `log` for stdout logging. + + + `plugin` is not supported, `nserver` or `fakeresolve` are mandatory, because system resolver is not supported, no support for RADIUS and IPv6. + + Run example: + + `docker run --read-only -i -p 3129:3129 --name 3proxy docker.io/3proxy/3proxy:minimal` +or + `docker start -ai 3proxy` to start existing container + +send this to standard input (example): +``` +nserver 8.8.8.8 +nscache 65535 +log +proxy -p3129 +end +``` + `nserver` is required for DNS resolutions. + +Some proxy types (e.g. SOCKSv5 UDPASSCOC, SOCKSv5 BIND functionality, ftp proxy) require access to ephemeral port, you may use e.g. `--network host` mode or `-P` to `docker run`. + +`:minimal` without version specified uses current stable version. + +# Binaries (deb / rpm / Windows zip) + +https://github.com/3proxy/3proxy/releases + ## Windows Installation Install and start proxy as Windows service: @@ -38,7 +100,7 @@ Remove the service (should be stopped before via `net stop 3proxy`): 3proxy --remove ``` -## Building on Linux +## Building and installation on Linux ### With Makefile @@ -64,10 +126,10 @@ By default, socks is started on 0.0.0.0:1080 and proxy on 0.0.0.0:3128 with basi ### Adding Users -Use `/etc/3proxy/conf/add3proxyuser.sh` script to add users: +Use `add3proxyuser` script to add users: ```bash -/etc/3proxy/conf/add3proxyuser.sh username password [day_limit] [bandwidth] +add3proxyuser username password [day_limit] [bandwidth] ``` Parameters: @@ -136,6 +198,8 @@ sudo launchctl start org.3proxy.3proxy sudo launchctl unload /Library/LaunchDaemons/org.3proxy.3proxy.plist ``` + + ## Features ### 1. General From dd5fe3994ed158339761268411ec9010817393b7 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Mon, 1 Jun 2026 11:38:15 +0300 Subject: [PATCH 10/41] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ddb21a..10a66f0 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ https://github.com/z3APA3A/3proxy-archive Documentation (man pages and HTML) available with download, on https://3proxy.org/ and in github wiki https://github.com/3proxy/3proxy/wiki -## Docker images for https://github.com/z3APA3A/3proxy +## Docker images 3 docker configurations are provided, default (full) also tagged as `:latest`, `:busybox` and `:minimal`, all refer to newest stable version. Except busybox, images are distroless and contain only binaries, you can not sh inside the container. `:busybox` contains busybox shell. From 2695d83847a3c76ce6e679585e648c13843166b7 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Mon, 1 Jun 2026 11:40:18 +0300 Subject: [PATCH 11/41] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 10a66f0..71f6ba5 100644 --- a/README.md +++ b/README.md @@ -9,14 +9,17 @@ ## Download -# Binaries and sources for released (master) versions (Windows, Linux) -https://github.com/z3APA3A/3proxy/releases +# Binaries (deb / rpm / Windows zip) + +https://github.com/3proxy/3proxy/releases # Docker images + https://hub.docker.com/r/3proxy/3proxy https://github.com/3proxy/3proxy/pkgs/container/3proxy # Archive of old versions + https://github.com/z3APA3A/3proxy-archive @@ -80,9 +83,6 @@ Some proxy types (e.g. SOCKSv5 UDPASSCOC, SOCKSv5 BIND functionality, ftp proxy `:minimal` without version specified uses current stable version. -# Binaries (deb / rpm / Windows zip) - -https://github.com/3proxy/3proxy/releases ## Windows Installation From 086d4cbd6a8b29ac900aad0e88a305e3f39f9479 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Mon, 1 Jun 2026 11:49:32 +0300 Subject: [PATCH 12/41] Update README.md --- README.md | 59 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 71f6ba5..dc25a31 100644 --- a/README.md +++ b/README.md @@ -2,28 +2,28 @@ (c) 2002-2026 by Vladimir '3APA3A' Dubrovin -## Branches +## Repository + +### Branches - **Master** (stable) branch - 3proxy 0.9 - **Devel** branch - 3proxy 10 (don't use it) -## Download - -# Binaries (deb / rpm / Windows zip) +### Binaries (deb / rpm / Windows zip) https://github.com/3proxy/3proxy/releases -# Docker images +### Docker images https://hub.docker.com/r/3proxy/3proxy https://github.com/3proxy/3proxy/pkgs/container/3proxy -# Archive of old versions +### Archive of old versions https://github.com/z3APA3A/3proxy-archive -## Documentation +### Documentation Documentation (man pages and HTML) available with download, on https://3proxy.org/ and in github wiki https://github.com/3proxy/3proxy/wiki @@ -31,7 +31,7 @@ Documentation (man pages and HTML) available with download, on https://3proxy.or 3 docker configurations are provided, default (full) also tagged as `:latest`, `:busybox` and `:minimal`, all refer to newest stable version. Except busybox, images are distroless and contain only binaries, you can not sh inside the container. `:busybox` contains busybox shell. -# Default image (`:latest`): +### Default image (`:latest`): Full installation requires to mount /etc/3proxy directory with 3proxy.cfg files. @@ -52,10 +52,10 @@ docker run --read-only -p 3129:3129 -v /path/to/local/config/directory:/etc/3pro since 0.9.6 images are distroless (except :busybox) it's recommended to use with read only file system, there are no benefits from chroot. For compatibility, you still can use chroot installation by mounting directory with 3proxy.cfg to /usr/local/3proxy/config. -# Busybox image (`:busybox`): +### Busybox image (`:busybox`): Full with busybox added, to allow shell commands inside container. All libraries are in /lib, so chroot configuration can not use plugins. -# Interactive `:minimal` image: +### Interactive `:minimal` image: Dockerfile for "interactive" minimal 3proxy execution, no configuration mounting is required, configuration is accepted from stdin. Use `end` command to indicate the end of configuration. Use `log` for stdout logging. @@ -83,8 +83,9 @@ Some proxy types (e.g. SOCKSv5 UDPASSCOC, SOCKSv5 BIND functionality, ftp proxy `:minimal` without version specified uses current stable version. +## Building and installation -## Windows Installation +### Windows Installation Install and start proxy as Windows service: @@ -100,9 +101,9 @@ Remove the service (should be stopped before via `net stop 3proxy`): 3proxy --remove ``` -## Building and installation on Linux +### Building and installation on Linux -### With Makefile +#### With Makefile ```bash git clone https://github.com/z3apa3a/3proxy @@ -112,9 +113,9 @@ make sudo make install ``` -### Default Configuration (Linux/Unix) +#### Default Configuration (for Makefile.Linux installation) -3proxy uses 2 configuration files: +3proxy uses 2 configuration files in : - `/etc/3proxy/3proxy.cfg` (before-chroot) - This configuration file is executed before chroot and should not be modified. - `/usr/local/3proxy/conf/3proxy.cfg` symlinked from `/etc/3proxy/conf/3proxy.cfg` (after-chroot) - Main configuration file. Modify this file if required. @@ -124,7 +125,7 @@ Log files are created in `/usr/local/3proxy/logs` symlinked from `/var/log/3prox By default, socks is started on 0.0.0.0:1080 and proxy on 0.0.0.0:3128 with basic auth, no users are added by default. -### Adding Users +#### Adding Users Use `add3proxyuser` script to add users: @@ -138,7 +139,7 @@ Parameters: Or modify `/etc/3proxy/conf/` files directly. -### With CMake +#### With CMake ```bash git clone https://github.com/z3apa3a/3proxy @@ -151,9 +152,9 @@ sudo cmake --install . CMake does not use chroot configuration, config file is `/etc/3proxy/3proxy.cfg` -## MacOS X / FreeBSD / *BSD +### MacOS X / FreeBSD / *BSD -### With Makefile +#### With Makefile ```bash git clone https://github.com/z3apa3a/3proxy @@ -164,7 +165,7 @@ make Binaries are in `bin/` directory. -### With CMake (recommended) +#### With CMake (recommended) ```bash git clone https://github.com/z3apa3a/3proxy @@ -182,7 +183,7 @@ This installs: - rc scripts to `rc.d` for BSD - launchd plist to `/Library/LaunchDaemons/` for MacOS -### Service Management on macOS +#### Service Management on macOS ```bash # Load and start service @@ -322,32 +323,32 @@ sudo launchctl unload /Library/LaunchDaemons/org.3proxy.3proxy.plist ### 3proxy Combined proxy server may be used as executable or service (supports installation and removal). It uses config file to read its configuration (see `3proxy.cfg.sample` for details). `3proxy.exe` is all-in-one, it doesn't require all others .exe to work. See `3proxy.cfg.sample` for examples, see `man 3proxy.cfg` -### proxy +### 3proxy_proxy HTTP proxy server, binds to port 3128 -### ftppr +### 3proxy_ftppr FTP proxy server, binds to port 21. Please do not mess it with FTP over HTTP proxy used in browsers -### socks +### 3proxy_socks SOCKS 4/5 proxy server, binds to port 1080 -### pop3p +### 3proxy_pop3p POP3 proxy server, binds to port 110. You must specify POP3 username as `username@popserver[:port]` (port is 110 by default). Example: in Username configuration for your e-mail reader set `someuser@pop.somehost.ru`, to obtain mail for someuser from pop.somehost.ru via proxy. -### smtpp +### 3proxy_smtpp SMTP proxy server, binds to port 25. You must specify SMTP username as `username@smtpserver[:port]` (port is 25 by default). Example: in Username configuration for your e-mail reader set `someuser@mail.somehost.ru`, to send mail as someuser via mail.somehost.ru via proxy. -### tcppm +### 3proxy_tcppm TCP port mapping. Maps some TCP port on local machine to TCP port on remote host. -### tlspr +### 3proxy_tlspr TLS proxy (SNI proxy) - sniffs hostname from TLS handshake -### udppm +### 3proxy_udppm UDP port mapping. Maps some UDP port on local machine to UDP port on remote machine. Only one user simultaneously can use UDP mapping, so it can't be used for public service in large networks. It's OK to use it to map to DNS server in small network or to map Counter-Strike server for single client (you can use few mappings on different ports for different clients in last case). ### 3proxy_crypt From fe2b2fd544727e5878a2c5df172834d4863890ce Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Mon, 1 Jun 2026 13:27:41 +0300 Subject: [PATCH 13/41] Revert "send provenance to github only" This reverts commit 254112cfde334eae98d40d0bd3adfc5c350e5afd. --- .github/workflows/docker.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index bfd5f7d..df1ac87 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -58,7 +58,6 @@ jobs: platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.minimal }} - provenance: false - name: Build and push busybox uses: docker/build-push-action@v6 @@ -68,7 +67,6 @@ jobs: platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.busybox }} - provenance: false - name: Build and push full uses: docker/build-push-action@v6 @@ -78,4 +76,3 @@ jobs: platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.full }} - provenance: false From 9734b54f56a7c3a915adad845a4e9b082cbabea2 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Mon, 1 Jun 2026 14:29:32 +0300 Subject: [PATCH 14/41] Add permissions to workflows --- .github/workflows/build-rpm-arm64.yml | 3 +++ .github/workflows/build-rpm-armhf.yml | 3 +++ .github/workflows/build-rpm-x86-64.yml | 3 +++ .github/workflows/build-watcom.yml | 3 +++ .github/workflows/build-win32.yml | 3 +++ .github/workflows/build-win64.yml | 3 +++ .github/workflows/build-winarm64.yml | 3 +++ .github/workflows/c-cpp-Linux.yml | 6 +++++- .github/workflows/c-cpp-MacOS.yml | 6 +++++- .github/workflows/c-cpp-Windows.yml | 6 +++++- .github/workflows/c-cpp-cmake.yml | 6 +++++- .github/workflows/docker-ghcr.yml | 7 ++++--- .github/workflows/docker.yml | 5 +++-- 13 files changed, 48 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-rpm-arm64.yml b/.github/workflows/build-rpm-arm64.yml index 6ee2ca3..6ab0735 100644 --- a/.github/workflows/build-rpm-arm64.yml +++ b/.github/workflows/build-rpm-arm64.yml @@ -5,6 +5,9 @@ on: types: [published] workflow_dispatch: +permissions: + contents: write + jobs: ci: name: "${{ matrix.target }}" diff --git a/.github/workflows/build-rpm-armhf.yml b/.github/workflows/build-rpm-armhf.yml index e3e05ea..2a586e1 100644 --- a/.github/workflows/build-rpm-armhf.yml +++ b/.github/workflows/build-rpm-armhf.yml @@ -5,6 +5,9 @@ on: types: [published] workflow_dispatch: +permissions: + contents: write + jobs: ci: name: "${{ matrix.target }}" diff --git a/.github/workflows/build-rpm-x86-64.yml b/.github/workflows/build-rpm-x86-64.yml index 11a6442..a6a3dba 100644 --- a/.github/workflows/build-rpm-x86-64.yml +++ b/.github/workflows/build-rpm-x86-64.yml @@ -5,6 +5,9 @@ on: types: [published] workflow_dispatch: +permissions: + contents: write + jobs: ci: name: "${{ matrix.target }}" diff --git a/.github/workflows/build-watcom.yml b/.github/workflows/build-watcom.yml index 73541fe..648f370 100644 --- a/.github/workflows/build-watcom.yml +++ b/.github/workflows/build-watcom.yml @@ -5,6 +5,9 @@ on: types: [published] workflow_dispatch: +permissions: + contents: write + jobs: ci: name: "${{ matrix.target }}" diff --git a/.github/workflows/build-win32.yml b/.github/workflows/build-win32.yml index e7b14c3..10eaf21 100644 --- a/.github/workflows/build-win32.yml +++ b/.github/workflows/build-win32.yml @@ -5,6 +5,9 @@ on: types: [published] workflow_dispatch: +permissions: + contents: write + jobs: ci: name: "${{ matrix.target }}" diff --git a/.github/workflows/build-win64.yml b/.github/workflows/build-win64.yml index c6ab8ce..fb91517 100644 --- a/.github/workflows/build-win64.yml +++ b/.github/workflows/build-win64.yml @@ -5,6 +5,9 @@ on: types: [published] workflow_dispatch: +permissions: + contents: write + jobs: ci: name: "${{ matrix.target }}" diff --git a/.github/workflows/build-winarm64.yml b/.github/workflows/build-winarm64.yml index 9e8198c..c042960 100644 --- a/.github/workflows/build-winarm64.yml +++ b/.github/workflows/build-winarm64.yml @@ -5,6 +5,9 @@ on: types: [published] workflow_dispatch: +permissions: + contents: write + jobs: ci: name: "${{ matrix.target }}" diff --git a/.github/workflows/c-cpp-Linux.yml b/.github/workflows/c-cpp-Linux.yml index c26ec16..98dfc16 100644 --- a/.github/workflows/c-cpp-Linux.yml +++ b/.github/workflows/c-cpp-Linux.yml @@ -2,10 +2,14 @@ name: C/C++ CI Linux on: push: - branches: [ "master" ] paths: [ '**.c', '**.h', 'Makefile.Linux', '.github/configs', '.github/workflows/c-cpp-Linux.yml' ] + pull_request: + paths: [ "**.c", "**.h", "Makefile.Linux", ".github/configs", ".github/workflows/c-cpp-Linux.yml" ] workflow_dispatch: +permissions: + contents: read + jobs: ci: name: "${{ matrix.target }}" diff --git a/.github/workflows/c-cpp-MacOS.yml b/.github/workflows/c-cpp-MacOS.yml index 2b618a2..6989bea 100644 --- a/.github/workflows/c-cpp-MacOS.yml +++ b/.github/workflows/c-cpp-MacOS.yml @@ -2,10 +2,14 @@ name: C/C++ CI MacOS on: push: - branches: [ "master" ] paths: [ '**.c', '**.h', 'Makefile.FreeBSD', '.github/configs', '.github/workflows/c-cpp-MacOS.yml' ] + pull_request: + paths: [ "**.c", "**.h", "Makefile.FreeBSD", ".github/configs", ".github/workflows/c-cpp-MacOS.yml" ] workflow_dispatch: +permissions: + contents: read + jobs: ci: name: "${{ matrix.target }}" diff --git a/.github/workflows/c-cpp-Windows.yml b/.github/workflows/c-cpp-Windows.yml index 83aa8e8..4fa80b0 100644 --- a/.github/workflows/c-cpp-Windows.yml +++ b/.github/workflows/c-cpp-Windows.yml @@ -2,10 +2,14 @@ name: C/C++ CI Windows on: push: - branches: [ "master" ] paths: [ '**.c', '**.h', 'Makefile.msvc', '.github/configs', '.github/workflows/c-cpp-Windows.yml' ] + pull_request: + paths: [ "**.c", "**.h", "Makefile.msvc", ".github/configs", ".github/workflows/c-cpp-Windows.yml" ] workflow_dispatch: +permissions: + contents: read + jobs: ci: name: "${{ matrix.target }}" diff --git a/.github/workflows/c-cpp-cmake.yml b/.github/workflows/c-cpp-cmake.yml index ac0af19..89585a0 100644 --- a/.github/workflows/c-cpp-cmake.yml +++ b/.github/workflows/c-cpp-cmake.yml @@ -2,10 +2,14 @@ name: C/C++ CI cmake on: push: - branches: [ "master", "unix_socket" ] paths: [ '**.c', '**.h', '**.cmake', 'CMakeLists.txt', '.github/configs', '.github/workflows/c-cpp-cmake.yml' ] + pull_request: + paths: [ "**.c", "**.h", "**.cmake", "CMakeLists.txt", ".github/configs", ".github/workflows/c-cpp-cmake.yml" ] workflow_dispatch: +permissions: + contents: read + jobs: ci: name: "${{ matrix.target }}" diff --git a/.github/workflows/docker-ghcr.yml b/.github/workflows/docker-ghcr.yml index b4005df..bccbe8b 100644 --- a/.github/workflows/docker-ghcr.yml +++ b/.github/workflows/docker-ghcr.yml @@ -5,6 +5,10 @@ on: types: [published] workflow_dispatch: +permissions: + contents: read + packages: write + env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} @@ -13,9 +17,6 @@ jobs: build: name: Build and push Docker images runs-on: ubuntu-latest - permissions: - contents: read - packages: write steps: - name: Checkout uses: actions/checkout@v5 diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index df1ac87..da54520 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -5,6 +5,9 @@ on: types: [published] workflow_dispatch: +permissions: + contents: read + env: REGISTRY: docker.io IMAGE_NAME: 3proxy/3proxy @@ -13,8 +16,6 @@ jobs: build: name: Build and push Docker images runs-on: ubuntu-latest - permissions: - contents: read steps: - name: Checkout uses: actions/checkout@v5 From 0259b58b953141f1f5e03367362f06a028b6ca25 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Mon, 1 Jun 2026 19:18:51 +0300 Subject: [PATCH 15/41] Start proxy as root in chroot --- debian/postinst | 4 ++-- scripts/rh/3proxy.spec | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/debian/postinst b/debian/postinst index a2218c0..f802dda 100644 --- a/debian/postinst +++ b/debian/postinst @@ -1,6 +1,6 @@ [ -f /bin/add3proxyuser ] && sed -i -e 's|@CMAKE_INSTALL_FULL_BINDIR@|/bin|g' -e 's|@3PROXY_CONFDIR@|/etc/3proxy/conf|g' -e 's|@CRYPT_PREFIX@|3proxy_|g' /bin/add3proxyuser; \ -[ -f /etc/init.d/3proxy ] && sed -i -e 's|@CMAKE_INSTALL_FULL_BINDIR@|/bin|g' -e 's|@CMAKE_INSTALL_FULL_SYSCONFDIR@|/etc|g' /etc/init.d/3proxy; \ -[ -f /usr/lib/systemd/system/3proxy.service ] && sed -i -e 's|@CMAKE_INSTALL_FULL_BINDIR@|/bin|g' -e 's|@CMAKE_INSTALL_FULL_SYSCONFDIR@|/etc|g' /usr/lib/systemd/system/3proxy.service; \ +[ -f /etc/init.d/3proxy ] && sed -i -e 's|@CMAKE_INSTALL_FULL_BINDIR@|/bin|g' -e 's|@CMAKE_INSTALL_FULL_SYSCONFDIR@|/etc|g' -e 's|USER=proxy|USER=root|g' /etc/init.d/3proxy; \ +[ -f /usr/lib/systemd/system/3proxy.service ] && sed -i -e 's|@CMAKE_INSTALL_FULL_BINDIR@|/bin|g' -e 's|@CMAKE_INSTALL_FULL_SYSCONFDIR@|/etc|g' -e 's|User=proxy|User=root|g' /usr/lib/systemd/system/3proxy.service; \ if [ -d /etc/3proxy ]; then \ chmod -R o-rwx /etc/3proxy; \ diff --git a/scripts/rh/3proxy.spec b/scripts/rh/3proxy.spec index bd537ef..9d32698 100644 --- a/scripts/rh/3proxy.spec +++ b/scripts/rh/3proxy.spec @@ -67,8 +67,8 @@ if [ ! -f /usr/local/3proxy/conf/passwd ]; then \ touch /usr/local/3proxy/conf/passwd;\ fi [ -f /bin/add3proxyuser ] && sed -i -e 's|@CMAKE_INSTALL_FULL_BINDIR@|/bin|g' -e 's|@3PROXY_CONFDIR@|/etc/3proxy/conf|g' -e 's|@CRYPT_PREFIX@|3proxy_|g' /bin/add3proxyuser; \ -[ -f /etc/init.d/3proxy ] && sed -i -e 's|@CMAKE_INSTALL_FULL_BINDIR@|/bin|g' -e 's|@CMAKE_INSTALL_FULL_SYSCONFDIR@|/etc|g' /etc/init.d/3proxy; \ -[ -f /usr/lib/systemd/system/3proxy.service ] && sed -i -e 's|@CMAKE_INSTALL_FULL_BINDIR@|/bin|g' -e 's|@CMAKE_INSTALL_FULL_SYSCONFDIR@|/etc|g' /usr/lib/systemd/system/3proxy.service; \ +[ -f /etc/init.d/3proxy ] && sed -i -e 's|@CMAKE_INSTALL_FULL_BINDIR@|/bin|g' -e 's|@CMAKE_INSTALL_FULL_SYSCONFDIR@|/etc|g' -e 's|USER=proxy|USER=root|g' /etc/init.d/3proxy; \ +[ -f /usr/lib/systemd/system/3proxy.service ] && sed -i -e 's|@CMAKE_INSTALL_FULL_BINDIR@|/bin|g' -e 's|@CMAKE_INSTALL_FULL_SYSCONFDIR@|/etc|g' -e 's|User=proxy|User=root|g' /usr/lib/systemd/system/3proxy.service; \ if [ -d /etc/3proxy ]; then \ chown -R proxy:proxy /etc/3proxy; \ chmod -R o-rwx /etc/3proxy; \ From 794f667eea6b62231cd7441c1f55cfaa0dc163d0 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Mon, 1 Jun 2026 20:16:19 +0300 Subject: [PATCH 16/41] Add more docker platforms --- .github/dependabot.yml | 11 +++++++++++ .github/workflows/docker-ghcr.yml | 12 ++++++------ .github/workflows/docker.yml | 12 ++++++------ README.md | 13 ++++++------- 4 files changed, 29 insertions(+), 19 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..84da8d0 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + + - package-ecosystem: docker + directory: / + schedule: + interval: weekly diff --git a/.github/workflows/docker-ghcr.yml b/.github/workflows/docker-ghcr.yml index bccbe8b..21a80ad 100644 --- a/.github/workflows/docker-ghcr.yml +++ b/.github/workflows/docker-ghcr.yml @@ -55,29 +55,29 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push minimal - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: . file: Dockerfile.minimal - platforms: linux/amd64,linux/arm64 + platforms: linux/amd64,linux/arm64,linux/arm/v7,riscv64,ppc64le push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.minimal }} - name: Build and push busybox - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: . file: Dockerfile.busybox - platforms: linux/amd64,linux/arm64 + platforms: linux/amd64,linux/arm64,linux/arm/v7,riscv64,ppc64le push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.busybox }} - name: Build and push full - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: . file: Dockerfile.full - platforms: linux/amd64,linux/arm64 + platforms: linux/amd64,linux/arm64,linux/arm/v7,riscv64,ppc64le push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.full }} diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index da54520..6f9bd76 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -52,28 +52,28 @@ jobs: password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push minimal - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: . file: Dockerfile.minimal - platforms: linux/amd64,linux/arm64 + platforms: linux/amd64,linux/arm64,linux/arm/v7,riscv64,ppc64le push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.minimal }} - name: Build and push busybox - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: . file: Dockerfile.busybox - platforms: linux/amd64,linux/arm64 + platforms: linux/amd64,linux/arm64,linux/arm/v7,riscv64,ppc64le push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.busybox }} - name: Build and push full - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v7 with: context: . file: Dockerfile.full - platforms: linux/amd64,linux/arm64 + platforms: linux/amd64,linux/arm64,linux/arm/v7,riscv64,ppc64le push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.full }} diff --git a/README.md b/README.md index dc25a31..e7b5068 100644 --- a/README.md +++ b/README.md @@ -38,15 +38,14 @@ Full installation requires to mount /etc/3proxy directory with 3proxy.cfg files. to run: ``` -echo log >/path/to/local/config/directory/3proxy.cfg -echo nserver 8.8.8.8 >>/path/to/local/config/directory/3proxy.cfg -echo nscache 65536 >>/path/to/local/config/directory/3proxy.cfg -echo proxy -p3129 >>/path/to/local/config/directory/3proxy.cfg -docker run --read-only -p 3129:3129 -v /path/to/local/config/directory:/etc/3proxy --name 3proxy.full docker.io/3proxy/3proxy +echo " +log +nserver 8.8.8.8 +nscache 65536 +proxy -p3129" | docker config create 3proxy +docker run --read-only -p 3129:3129 --config source=3proxy,target=/etc/3proxy/3proxy.cfg --name 3proxy.full docker.io/3proxy/3proxy ``` - /path/to/local/config/directory in this example must contain 3proxy.cfg - use `log` without pathname in config to log to stdout. plugins are located in /usr/local/3proxy/libexec (/libexec for chroot config) and since 0.9.6 symlinked by /lib and /lib64 in both chroot and non-chroot configurations, so no full path is required in `plugin` command. Use e.g. `plugin SSLPlugin.ls.so ssl_plugin`. SSLPlugin is supported since 0.9.6. Some proxy types (e.g. SOCKSv5 UDPASSCOC, SOCKSv5 BIND functionality, ftp proxy) require access to ephemeral port, you may use e.g. -`-network host` mode or `-P` for `docker run`. From c5affd2db46b2fac008f527210d526fe71fc7c92 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jun 2026 20:21:37 +0300 Subject: [PATCH 17/41] Bump actions/upload-artifact from 6 to 7 (#1232) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-rpm-arm64.yml | 4 ++-- .github/workflows/build-rpm-armhf.yml | 4 ++-- .github/workflows/build-rpm-x86-64.yml | 4 ++-- .github/workflows/build-watcom.yml | 2 +- .github/workflows/build-win32.yml | 2 +- .github/workflows/build-win64.yml | 2 +- .github/workflows/build-winarm64.yml | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-rpm-arm64.yml b/.github/workflows/build-rpm-arm64.yml index 6ab0735..855fc10 100644 --- a/.github/workflows/build-rpm-arm64.yml +++ b/.github/workflows/build-rpm-arm64.yml @@ -48,7 +48,7 @@ jobs: cd $ret mv ~/rpmbuild/RPMS/aarch64/3proxy-$RELEASE-1.aarch64.rpm 3proxy-$RELEASE.arm64.rpm - name: Get artifact rpm - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: "3proxy-${{ env.RELEASE }}-arm64.rpm" path: "*.rpm" @@ -74,7 +74,7 @@ jobs: cd $ret cp ~/debian/3proxy_$RELEASE-"$VERSION"_arm64.deb ./3proxy-$RELEASE.arm64.deb - name: Get artifact deb - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: "3proxy-${{ env.RELEASE }}-arm64.deb" path: "*.deb" diff --git a/.github/workflows/build-rpm-armhf.yml b/.github/workflows/build-rpm-armhf.yml index 2a586e1..2b4adc3 100644 --- a/.github/workflows/build-rpm-armhf.yml +++ b/.github/workflows/build-rpm-armhf.yml @@ -75,7 +75,7 @@ jobs: cd $ret mv ~/rpmbuild/RPMS/arm/3proxy-$RELEASE-1.arm.rpm 3proxy-$RELEASE.arm.rpm - name: Get artifact rpm - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: "3proxy-${{ env.RELEASE }}-arm.rpm" path: "*.rpm" @@ -107,7 +107,7 @@ jobs: cd $ret cp ~/debian/3proxy_$RELEASE-"$VERSION"_armhf.deb ./3proxy-$RELEASE.arm.deb - name: Get artifact deb - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: "3proxy-${{ env.RELEASE }}-arm.deb" path: "*.deb" diff --git a/.github/workflows/build-rpm-x86-64.yml b/.github/workflows/build-rpm-x86-64.yml index a6a3dba..ebe57d2 100644 --- a/.github/workflows/build-rpm-x86-64.yml +++ b/.github/workflows/build-rpm-x86-64.yml @@ -48,7 +48,7 @@ jobs: cd $ret mv ~/rpmbuild/RPMS/x86_64/3proxy-$RELEASE-1.x86_64.rpm 3proxy-$RELEASE.x86_64.rpm - name: Get artifact rpm - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: "3proxy-${{ env.RELEASE }}-x86_64.rpm" path: "*.rpm" @@ -74,7 +74,7 @@ jobs: cd $ret cp ~/debian/3proxy_$RELEASE-"$VERSION"_amd64.deb ./3proxy-$RELEASE.x86_64.deb - name: Get artifact deb - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: "3proxy-${{ env.RELEASE }}-x86_64.deb" path: "*.deb" diff --git a/.github/workflows/build-watcom.yml b/.github/workflows/build-watcom.yml index 648f370..a5cb515 100644 --- a/.github/workflows/build-watcom.yml +++ b/.github/workflows/build-watcom.yml @@ -78,7 +78,7 @@ jobs: copy README.md dist\3proxy\ copy rus.3ps dist\3proxy\ - name: Get artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: "3proxy-${{ env.RELEASE }}-lite" path: dist/ diff --git a/.github/workflows/build-win32.yml b/.github/workflows/build-win32.yml index 10eaf21..4b7037e 100644 --- a/.github/workflows/build-win32.yml +++ b/.github/workflows/build-win32.yml @@ -84,7 +84,7 @@ jobs: copy README.md dist\3proxy\ copy rus.3ps dist\3proxy\ - name: Get artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: "3proxy-${{ env.RELEASE }}" path: dist/ diff --git a/.github/workflows/build-win64.yml b/.github/workflows/build-win64.yml index fb91517..3e3dd1b 100644 --- a/.github/workflows/build-win64.yml +++ b/.github/workflows/build-win64.yml @@ -85,7 +85,7 @@ jobs: copy README.md dist\3proxy\ copy rus.3ps dist\3proxy\ - name: Get artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: "3proxy-${{ env.RELEASE }}-x64" path: dist/ diff --git a/.github/workflows/build-winarm64.yml b/.github/workflows/build-winarm64.yml index c042960..2eb7539 100644 --- a/.github/workflows/build-winarm64.yml +++ b/.github/workflows/build-winarm64.yml @@ -84,7 +84,7 @@ jobs: copy README.md dist\3proxy\ copy rus.3ps dist\3proxy\ - name: Get artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: "3proxy-${{ env.RELEASE }}-arm64" path: dist/ From 9e7246e8649f920f7645ad77113798992193d358 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jun 2026 20:22:03 +0300 Subject: [PATCH 18/41] Bump open-watcom/setup-watcom from 0 to 1 (#1233) Bumps [open-watcom/setup-watcom](https://github.com/open-watcom/setup-watcom) from 0 to 1. - [Changelog](https://github.com/open-watcom/setup-watcom/blob/master/release.py) - [Commits](https://github.com/open-watcom/setup-watcom/compare/v0...v1) --- updated-dependencies: - dependency-name: open-watcom/setup-watcom dependency-version: '1' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-watcom.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-watcom.yml b/.github/workflows/build-watcom.yml index a5cb515..29a2b17 100644 --- a/.github/workflows/build-watcom.yml +++ b/.github/workflows/build-watcom.yml @@ -21,7 +21,7 @@ jobs: # - name: configure # run: ./configure - name: Setup Open Watcom - uses: open-watcom/setup-watcom@v0 + uses: open-watcom/setup-watcom@v1 - name: set date run: | $NOW = Get-Date -Format "yyMMddHHmmss" From 6d8643b70e4e8ae50be70ee4eb94e91e73ddbb52 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jun 2026 20:22:52 +0300 Subject: [PATCH 19/41] Bump actions/checkout from 5 to 6 (#1234) Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-rpm-arm64.yml | 2 +- .github/workflows/build-rpm-armhf.yml | 2 +- .github/workflows/build-rpm-x86-64.yml | 2 +- .github/workflows/build-watcom.yml | 2 +- .github/workflows/build-win32.yml | 2 +- .github/workflows/build-win64.yml | 2 +- .github/workflows/build-winarm64.yml | 2 +- .github/workflows/c-cpp-Linux.yml | 2 +- .github/workflows/c-cpp-MacOS.yml | 2 +- .github/workflows/c-cpp-Windows.yml | 2 +- .github/workflows/c-cpp-cmake.yml | 2 +- .github/workflows/docker-ghcr.yml | 2 +- .github/workflows/docker.yml | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build-rpm-arm64.yml b/.github/workflows/build-rpm-arm64.yml index 855fc10..901b80a 100644 --- a/.github/workflows/build-rpm-arm64.yml +++ b/.github/workflows/build-rpm-arm64.yml @@ -17,7 +17,7 @@ jobs: - ubuntu-24.04-arm runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: env run: | pwd diff --git a/.github/workflows/build-rpm-armhf.yml b/.github/workflows/build-rpm-armhf.yml index 2b4adc3..e2ea58b 100644 --- a/.github/workflows/build-rpm-armhf.yml +++ b/.github/workflows/build-rpm-armhf.yml @@ -17,7 +17,7 @@ jobs: - ubuntu-latest runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: env run: | pwd diff --git a/.github/workflows/build-rpm-x86-64.yml b/.github/workflows/build-rpm-x86-64.yml index ebe57d2..6ed6495 100644 --- a/.github/workflows/build-rpm-x86-64.yml +++ b/.github/workflows/build-rpm-x86-64.yml @@ -17,7 +17,7 @@ jobs: - ubuntu-latest runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: env run: | pwd diff --git a/.github/workflows/build-watcom.yml b/.github/workflows/build-watcom.yml index 29a2b17..0f49bcd 100644 --- a/.github/workflows/build-watcom.yml +++ b/.github/workflows/build-watcom.yml @@ -17,7 +17,7 @@ jobs: - windows-2022 runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 # - name: configure # run: ./configure - name: Setup Open Watcom diff --git a/.github/workflows/build-win32.yml b/.github/workflows/build-win32.yml index 4b7037e..66c1b97 100644 --- a/.github/workflows/build-win32.yml +++ b/.github/workflows/build-win32.yml @@ -17,7 +17,7 @@ jobs: - windows-2022 runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 # - name: configure # run: ./configure - name: set date diff --git a/.github/workflows/build-win64.yml b/.github/workflows/build-win64.yml index 3e3dd1b..55c7e50 100644 --- a/.github/workflows/build-win64.yml +++ b/.github/workflows/build-win64.yml @@ -17,7 +17,7 @@ jobs: - windows-2022 runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 # - name: configure # run: ./configure - name: set date diff --git a/.github/workflows/build-winarm64.yml b/.github/workflows/build-winarm64.yml index 2eb7539..b37faf2 100644 --- a/.github/workflows/build-winarm64.yml +++ b/.github/workflows/build-winarm64.yml @@ -17,7 +17,7 @@ jobs: - windows-2022 runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 # - name: configure # run: ./configure - name: set date diff --git a/.github/workflows/c-cpp-Linux.yml b/.github/workflows/c-cpp-Linux.yml index 98dfc16..610f992 100644 --- a/.github/workflows/c-cpp-Linux.yml +++ b/.github/workflows/c-cpp-Linux.yml @@ -20,7 +20,7 @@ jobs: - ubuntu-24.04-arm runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 # - name: configure # run: ./configure - name: Linux libraries diff --git a/.github/workflows/c-cpp-MacOS.yml b/.github/workflows/c-cpp-MacOS.yml index 6989bea..ab8db07 100644 --- a/.github/workflows/c-cpp-MacOS.yml +++ b/.github/workflows/c-cpp-MacOS.yml @@ -19,7 +19,7 @@ jobs: - macos-15 runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 # - name: configure # run: ./configure - name: Mac libraries diff --git a/.github/workflows/c-cpp-Windows.yml b/.github/workflows/c-cpp-Windows.yml index 4fa80b0..ac02038 100644 --- a/.github/workflows/c-cpp-Windows.yml +++ b/.github/workflows/c-cpp-Windows.yml @@ -19,7 +19,7 @@ jobs: - windows-2022 runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: install Windows libraries run: vcpkg install pcre2:x64-windows && c:\msys64\usr\bin\pacman.exe -S --noconfirm mingw-w64-x86_64-pcre2 mingw-w64-x86_64-openssl - name: make Windows diff --git a/.github/workflows/c-cpp-cmake.yml b/.github/workflows/c-cpp-cmake.yml index 89585a0..45aa854 100644 --- a/.github/workflows/c-cpp-cmake.yml +++ b/.github/workflows/c-cpp-cmake.yml @@ -22,7 +22,7 @@ jobs: - windows-2022 runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 # - name: configure # run: ./configure - name: Linux libraries diff --git a/.github/workflows/docker-ghcr.yml b/.github/workflows/docker-ghcr.yml index 21a80ad..9a69ba4 100644 --- a/.github/workflows/docker-ghcr.yml +++ b/.github/workflows/docker-ghcr.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Determine tags id: tags diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 6f9bd76..2c01731 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Determine tags id: tags From 74d5b67ef4fd4b27dd54f20eb3c04fe9f6b75923 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Mon, 1 Jun 2026 20:27:47 +0300 Subject: [PATCH 20/41] riscv64 removed due to lack of gcc image --- .github/workflows/docker-ghcr.yml | 6 +++--- .github/workflows/docker.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docker-ghcr.yml b/.github/workflows/docker-ghcr.yml index 9a69ba4..2638c93 100644 --- a/.github/workflows/docker-ghcr.yml +++ b/.github/workflows/docker-ghcr.yml @@ -59,7 +59,7 @@ jobs: with: context: . file: Dockerfile.minimal - platforms: linux/amd64,linux/arm64,linux/arm/v7,riscv64,ppc64le + platforms: linux/amd64,linux/arm64,linux/arm/v7,ppc64le push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.minimal }} @@ -68,7 +68,7 @@ jobs: with: context: . file: Dockerfile.busybox - platforms: linux/amd64,linux/arm64,linux/arm/v7,riscv64,ppc64le + platforms: linux/amd64,linux/arm64,linux/arm/v7,ppc64le push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.busybox }} @@ -77,7 +77,7 @@ jobs: with: context: . file: Dockerfile.full - platforms: linux/amd64,linux/arm64,linux/arm/v7,riscv64,ppc64le + platforms: linux/amd64,linux/arm64,linux/arm/v7,ppc64le push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.full }} diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 2c01731..dbc54f3 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -56,7 +56,7 @@ jobs: with: context: . file: Dockerfile.minimal - platforms: linux/amd64,linux/arm64,linux/arm/v7,riscv64,ppc64le + platforms: linux/amd64,linux/arm64,linux/arm/v7,ppc64le push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.minimal }} @@ -65,7 +65,7 @@ jobs: with: context: . file: Dockerfile.busybox - platforms: linux/amd64,linux/arm64,linux/arm/v7,riscv64,ppc64le + platforms: linux/amd64,linux/arm64,linux/arm/v7,ppc64le push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.busybox }} @@ -74,6 +74,6 @@ jobs: with: context: . file: Dockerfile.full - platforms: linux/amd64,linux/arm64,linux/arm/v7,riscv64,ppc64le + platforms: linux/amd64,linux/arm64,linux/arm/v7,ppc64le push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.full }} From ab11e6c4a35bfba5d5d47b8f02c7a09cdd441c8b Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Tue, 2 Jun 2026 13:06:53 +0300 Subject: [PATCH 21/41] Fix deadlock in ftppr --- src/ftppr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ftppr.c b/src/ftppr.c index 30c1739..f4a3f63 100644 --- a/src/ftppr.c +++ b/src/ftppr.c @@ -215,6 +215,11 @@ void * ftpprchild(struct clientparam* param) { sasize = sizeof(param->sincr); ss = param->srv->so._accept(param->sostate, clidatasock, (struct sockaddr *)¶m->sincr, &sasize); if (ss == INVALID_SOCKET) { RETURN (858);} +#ifdef _WIN32 + { unsigned long ul = 1; ioctlsocket(ss, FIONBIO, &ul); } +#else + fcntl(ss, F_SETFL, O_NONBLOCK | fcntl(ss, F_GETFL)); +#endif param->srv->so._shutdown(param->sostate, clidatasock, SHUT_RDWR); param->srv->so._closesocket(param->sostate, clidatasock); clidatasock = ss; From fd7b25bf06d511683f82d5bf331f101fd3dacdc1 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Tue, 2 Jun 2026 13:43:56 +0300 Subject: [PATCH 22/41] Use non-blocking sockets for UDP --- src/dnspr.c | 4 ++-- src/socks.c | 10 ++++++++++ src/udpsockmap.c | 2 ++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/dnspr.c b/src/dnspr.c index 9a3fb01..532a13a 100644 --- a/src/dnspr.c +++ b/src/dnspr.c @@ -147,9 +147,9 @@ void * dnsprchild(struct clientparam* param) { } else { #ifdef _WIN32 -/* ioctlsocket(param->remsock, FIONBIO, &ul); */ + ioctlsocket(param->remsock, FIONBIO, &ul); #else -/* fcntl(param->remsock,F_SETFL,O_NONBLOCK); */ + fcntl(param->remsock, F_SETFL, O_NONBLOCK | fcntl(param->remsock, F_GETFL)); #endif } diff --git a/src/socks.c b/src/socks.c index 61b656b..7597708 100644 --- a/src/socks.c +++ b/src/socks.c @@ -255,6 +255,11 @@ void * sockschild(struct clientparam* param) { if(switch_ns(param->srv, param->srv->o_nsfd)) {RETURN(11);} #endif if ((param->remsock=param->srv->so._socket(param->sostate, SASOCK(¶m->req), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);} +#ifdef _WIN32 + { unsigned long ul = 1; ioctlsocket(param->remsock, FIONBIO, &ul); } +#else + fcntl(param->remsock, F_SETFL, O_NONBLOCK | fcntl(param->remsock, F_GETFL)); +#endif } if(command > 1) { @@ -275,6 +280,11 @@ fflush(stderr); #endif param->clisock = param->srv->so._socket(param->sostate, SASOCK(¶m->sincr), SOCK_DGRAM, IPPROTO_UDP); if(param->clisock == INVALID_SOCKET) {RETURN(11);} +#ifdef _WIN32 + { unsigned long ul = 1; ioctlsocket(param->clisock, FIONBIO, &ul); } +#else + fcntl(param->clisock, F_SETFL, O_NONBLOCK | fcntl(param->clisock, F_GETFL)); +#endif sin = param->sincl; *SAPORT(&sin) = 0; if(param->srv->so._bind(param->sostate, param->clisock,(struct sockaddr *)&sin,SASIZE(&sin))) {RETURN (12);} diff --git a/src/udpsockmap.c b/src/udpsockmap.c index ec7c346..f450a0e 100644 --- a/src/udpsockmap.c +++ b/src/udpsockmap.c @@ -106,6 +106,7 @@ int udpsockmap(struct clientparam *param, int timeo) len = param->srv->so._recvfrom(param->sostate, param->clisock, (char *)param->srvbuf + recvoff, UDPBUFSIZE - recvoff, 0, (struct sockaddr *)&sin, &sasize); + if (len < 0 && (errno == EAGAIN || errno == EINTR)) continue; if (len <= 0) return 482; if (SAADDRLEN(&sin) != SAADDRLEN(¶m->sincr) || @@ -182,6 +183,7 @@ int udpsockmap(struct clientparam *param, int timeo) len = param->srv->so._recvfrom(param->sostate, param->remsock, (char *)param->srvbuf + hdrsize, UDPBUFSIZE - hdrsize, 0, (struct sockaddr *)&from, &sasize); + if (len < 0 && (errno == EAGAIN || errno == EINTR)) continue; if (len <= 0) return 486; if (nhops >= 1) { if (!SAISNULL(¶m->sinsr) && *SAPORT(¶m->sinsr)) { From 69862b67cb4a75b8c715e960550e1e623cba7e8b Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Tue, 2 Jun 2026 14:23:52 +0300 Subject: [PATCH 23/41] Check bandlims for UDP traffic --- src/proxymain.c | 22 ++++++++++++---------- src/udppm.c | 20 +++++++++++--------- src/udpsockmap.c | 3 +++ 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/proxymain.c b/src/proxymain.c index 4f21237..d32afc2 100644 --- a/src/proxymain.c +++ b/src/proxymain.c @@ -1020,17 +1020,19 @@ int MODULEMAINFUNC (int argc, char** argv){ if(hashresolv(&udp_table, &defparam, &toparam, NULL)) { int i, len=0; - if(toparam->udp_nhops){ - for(i=1; i < toparam->udp_nhops; i++){ - len+=socks5_udp_build_hdr(srv.udpbuf2+len, &toparam->udp_relay[i-1]); - } - len += socks5_udp_build_hdr(srv.udpbuf2+len, &toparam->req); + if(!toparam->bandlimfunc || !(*toparam->bandlimfunc)(toparam, 0, srv.udplen)){ + if(toparam->udp_nhops){ + for(i=1; i < toparam->udp_nhops; i++){ + len+=socks5_udp_build_hdr(srv.udpbuf2+len, &toparam->udp_relay[i-1]); + } + len += socks5_udp_build_hdr(srv.udpbuf2+len, &toparam->req); + } + memcpy(srv.udpbuf2+len, srv.udpbuf, srv.udplen > UDPBUFSIZE - len?UDPBUFSIZE - len : srv.udplen); + len += srv.udplen > UDPBUFSIZE - len?UDPBUFSIZE - len : srv.udplen; + srv.so._sendto(toparam->sostate, toparam->remsock, (char *)srv.udpbuf2, len, 0, (struct sockaddr *)&toparam->sinsr, SASIZE(&toparam->sinsr)); + toparam->statscli64 += srv.udplen; + toparam->nwrites++; } - memcpy(srv.udpbuf2+len, srv.udpbuf, srv.udplen > UDPBUFSIZE - len?UDPBUFSIZE - len : srv.udplen); - len += srv.udplen > UDPBUFSIZE - len?UDPBUFSIZE - len : srv.udplen; - srv.so._sendto(toparam->sostate, toparam->remsock, (char *)srv.udpbuf2, len, 0, (struct sockaddr *)&toparam->sinsr, SASIZE(&toparam->sinsr)); - toparam->statscli64 += srv.udplen; - toparam->nwrites++; _3proxy_sem_unlock(udpinit); continue; } diff --git a/src/udppm.c b/src/udppm.c index dacdd7c..454e8d1 100644 --- a/src/udppm.c +++ b/src/udppm.c @@ -61,19 +61,21 @@ void * udppmchild(struct clientparam* param) { if(!(param->srvbuf = malloc(UDPBUFSIZE)))RETURN(11); param->srvbufsize = UDPBUFSIZE; } - if(param->udp_nhops){ - for(i=1; i < param->udp_nhops; i++){ - len+=socks5_udp_build_hdr(param->srvbuf+len, ¶m->udp_relay[i-1]); + if(!param->bandlimfunc || !(*param->bandlimfunc)(param, 0, param->srv->udplen)){ + if(param->udp_nhops){ + for(i=1; i < param->udp_nhops; i++){ + len+=socks5_udp_build_hdr(param->srvbuf+len, ¶m->udp_relay[i-1]); + } + len += socks5_udp_build_hdr(param->srvbuf+len, ¶m->req); } - len += socks5_udp_build_hdr(param->srvbuf+len, ¶m->req); + memcpy(param->srvbuf+len, param->srv->udpbuf, param->srv->udplen > UDPBUFSIZE - len?UDPBUFSIZE - len : param->srv->udplen); + len += param->srv->udplen > UDPBUFSIZE - len?UDPBUFSIZE - len : param->srv->udplen; + param->srv->so._sendto(param->sostate, param->remsock, (char *)param->srvbuf, len, 0, (struct sockaddr *)¶m->sinsr, SASIZE(¶m->sinsr)); + param->statscli64 += param->srvinbuf; + param->nwrites++; } - memcpy(param->srvbuf+len, param->srv->udpbuf, param->srv->udplen > UDPBUFSIZE - len?UDPBUFSIZE - len : param->srv->udplen); - len += param->srv->udplen > UDPBUFSIZE - len?UDPBUFSIZE - len : param->srv->udplen; - param->srv->so._sendto(param->sostate, param->remsock, (char *)param->srvbuf, len, 0, (struct sockaddr *)¶m->sinsr, SASIZE(¶m->sinsr)); _3proxy_sem_unlock(udpinit); - param->statscli64 += param->srvinbuf; param->srvinbuf = 0; - param->nwrites++; param->clisock = param->srv->srvsock; param->waitserver64 = 0x7fffffffffffffff; param->res = udpsockmap(param, conf.timeouts[STRING_L]); diff --git a/src/udpsockmap.c b/src/udpsockmap.c index f450a0e..af2c39f 100644 --- a/src/udpsockmap.c +++ b/src/udpsockmap.c @@ -124,6 +124,8 @@ int udpsockmap(struct clientparam *param, int timeo) continue; } + if(param->bandlimfunc && (*param->bandlimfunc)(param, 0, len)) continue; + if (nhops == 0) { int i; if (len < 10 || param->srvbuf[0] || param->srvbuf[1] || param->srvbuf[2]) @@ -195,6 +197,7 @@ int udpsockmap(struct clientparam *param, int timeo) } param->statssrv64 += len; param->nreads++; + if(param->bandlimfunc && (*param->bandlimfunc)(param, len, 0)) continue; sendlen = len; if (nhops == 0) { param->srvbuf[0] = param->srvbuf[1] = param->srvbuf[2] = 0; From fbc3ed5a18f056da0bb9775e5674200e75bdbbbf Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Tue, 2 Jun 2026 16:36:38 +0300 Subject: [PATCH 24/41] Update README.md --- README.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e7b5068..914c33e 100644 --- a/README.md +++ b/README.md @@ -33,26 +33,38 @@ Documentation (man pages and HTML) available with download, on https://3proxy.or ### Default image (`:latest`): -Full installation requires to mount /etc/3proxy directory with 3proxy.cfg files. +Full installation requires to mount /etc/3proxy/3proxy.cfg files. -to run: +For docker, config can be provided via `docker config` ``` -echo " -log +echo "log nserver 8.8.8.8 nscache 65536 proxy -p3129" | docker config create 3proxy docker run --read-only -p 3129:3129 --config source=3proxy,target=/etc/3proxy/3proxy.cfg --name 3proxy.full docker.io/3proxy/3proxy ``` + `podman` does not support `config` as above. + Mounts may be used as config alternative. `podman` used in example below can be replaced with `docker`: + +``` +echo "log +nserver 8.8.8.8 +nscache 65536 +proxy -p3129" >/path/to/local/config/directory/3proxy.cfg +podman run --read-only -p 3129:3129 -v /path/to/local/config/directory/3proxy.cfg:/etc/3proxy/3proxy.cfg --name 3proxy.full 3proxy.full +``` + + use `log` without pathname in config to log to stdout. plugins are located in /usr/local/3proxy/libexec (/libexec for chroot config) and since 0.9.6 symlinked by /lib and /lib64 in both chroot and non-chroot configurations, so no full path is required in `plugin` command. Use e.g. `plugin SSLPlugin.ls.so ssl_plugin`. SSLPlugin is supported since 0.9.6. Some proxy types (e.g. SOCKSv5 UDPASSCOC, SOCKSv5 BIND functionality, ftp proxy) require access to ephemeral port, you may use e.g. -`-network host` mode or `-P` for `docker run`. since 0.9.6 images are distroless (except :busybox) it's recommended to use with read only file system, there are no benefits from chroot. For compatibility, you still can use chroot installation by mounting directory with 3proxy.cfg to /usr/local/3proxy/config. ### Busybox image (`:busybox`): -Full with busybox added, to allow shell commands inside container. All libraries are in /lib, so chroot configuration can not use plugins. + +`full` with busybox added, to allow `sh` and few more commands like `sed` inside container. All libraries are in /lib, so chroot configuration can not use plugins. ### Interactive `:minimal` image: From 757ad916ecb80e30f9d07339cb33d83f139afcd6 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Tue, 2 Jun 2026 18:12:48 +0300 Subject: [PATCH 25/41] Sign docker images --- .github/workflows/docker-ghcr.yml | 16 ++++++++++++++++ .github/workflows/docker.yml | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/.github/workflows/docker-ghcr.yml b/.github/workflows/docker-ghcr.yml index 2638c93..a2bbd1f 100644 --- a/.github/workflows/docker-ghcr.yml +++ b/.github/workflows/docker-ghcr.yml @@ -8,6 +8,7 @@ on: permissions: contents: read packages: write + id-token: write env: REGISTRY: ghcr.io @@ -46,6 +47,9 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 + - name: Install cosign + uses: sigstore/cosign-installer@v3 + - name: Login to GHCR if: github.event_name != 'pull_request' uses: docker/login-action@v4 @@ -81,3 +85,15 @@ jobs: push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.full }} + - name: Sign images + if: github.event_name != 'pull_request' + env: + TAGS_MINIMAL: ${{ steps.tags.outputs.minimal }} + TAGS_BUSYBOX: ${{ steps.tags.outputs.busybox }} + TAGS_FULL: ${{ steps.tags.outputs.full }} + run: | + IFS=',' read -ra TAGS <<< "$TAGS_MINIMAL,$TAGS_BUSYBOX,$TAGS_FULL" + for tag in "${TAGS[@]}"; do + cosign sign --yes "$tag" + done + diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index dbc54f3..5464775 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -7,6 +7,7 @@ on: permissions: contents: read + id-token: write env: REGISTRY: docker.io @@ -44,6 +45,9 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 + - name: Install cosign + uses: sigstore/cosign-installer@v3 + - name: Login to Docker Hub if: github.event_name != 'pull_request' uses: docker/login-action@v4 @@ -77,3 +81,15 @@ jobs: platforms: linux/amd64,linux/arm64,linux/arm/v7,ppc64le push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.tags.outputs.full }} + + - name: Sign images + if: github.event_name != 'pull_request' + env: + TAGS_MINIMAL: ${{ steps.tags.outputs.minimal }} + TAGS_BUSYBOX: ${{ steps.tags.outputs.busybox }} + TAGS_FULL: ${{ steps.tags.outputs.full }} + run: | + IFS=',' read -ra TAGS <<< "$TAGS_MINIMAL,$TAGS_BUSYBOX,$TAGS_FULL" + for tag in "${TAGS[@]}"; do + cosign sign --yes "$tag" + done From 84879cc0babe1cd51aa657a71479d337a9ee684e Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Wed, 3 Jun 2026 10:34:38 +0300 Subject: [PATCH 26/41] Add public cert to build --- .github/workflows/build-win32.yml | 8 ++++++++ .github/workflows/build-win64.yml | 8 ++++++++ .github/workflows/build-winarm64.yml | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/.github/workflows/build-win32.yml b/.github/workflows/build-win32.yml index 66c1b97..22ad121 100644 --- a/.github/workflows/build-win32.yml +++ b/.github/workflows/build-win32.yml @@ -47,6 +47,13 @@ jobs: run: | $pfx_cert_byte = [System.Convert]::FromBase64String("${{ secrets.WINDOWS_CERTIFICATE }}") [System.IO.File]::WriteAllBytes("${{ github.workspace }}\cert.pfx", $pfx_cert_byte) + - name: Extract public certificate + shell: pwsh + env: + CERT_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} + run: | + $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("${{ github.workspace }}\cert.pfx", "$env:CERT_PASSWORD") + [System.IO.File]::WriteAllBytes("${{ github.workspace }}\3proxy.crt", $cert.Export("Cert")) - name: Sign shell: pwsh run: | @@ -83,6 +90,7 @@ jobs: copy authors dist\3proxy\ copy README.md dist\3proxy\ copy rus.3ps dist\3proxy\ + copy 3proxy.crt dist\3proxy\ - name: Get artifact uses: actions/upload-artifact@v7 with: diff --git a/.github/workflows/build-win64.yml b/.github/workflows/build-win64.yml index 55c7e50..84ee682 100644 --- a/.github/workflows/build-win64.yml +++ b/.github/workflows/build-win64.yml @@ -48,6 +48,13 @@ jobs: run: | $pfx_cert_byte = [System.Convert]::FromBase64String("${{ secrets.WINDOWS_CERTIFICATE }}") [System.IO.File]::WriteAllBytes("${{ github.workspace }}\cert.pfx", $pfx_cert_byte) + - name: Extract public certificate + shell: pwsh + env: + CERT_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} + run: | + $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("${{ github.workspace }}\cert.pfx", "$env:CERT_PASSWORD") + [System.IO.File]::WriteAllBytes("${{ github.workspace }}\3proxy.crt", $cert.Export("Cert")) - name: Sign shell: pwsh run: | @@ -84,6 +91,7 @@ jobs: copy authors dist\3proxy\ copy README.md dist\3proxy\ copy rus.3ps dist\3proxy\ + copy 3proxy.crt dist\3proxy\ - name: Get artifact uses: actions/upload-artifact@v7 with: diff --git a/.github/workflows/build-winarm64.yml b/.github/workflows/build-winarm64.yml index b37faf2..e5a940d 100644 --- a/.github/workflows/build-winarm64.yml +++ b/.github/workflows/build-winarm64.yml @@ -47,6 +47,13 @@ jobs: run: | $pfx_cert_byte = [System.Convert]::FromBase64String("${{ secrets.WINDOWS_CERTIFICATE }}") [System.IO.File]::WriteAllBytes("${{ github.workspace }}\cert.pfx", $pfx_cert_byte) + - name: Extract public certificate + shell: pwsh + env: + CERT_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} + run: | + $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("${{ github.workspace }}\cert.pfx", "$env:CERT_PASSWORD") + [System.IO.File]::WriteAllBytes("${{ github.workspace }}\3proxy.crt", $cert.Export("Cert")) - name: Sign shell: pwsh run: | @@ -83,6 +90,7 @@ jobs: copy authors dist\3proxy\ copy README.md dist\3proxy\ copy rus.3ps dist\3proxy\ + copy 3proxy.crt dist\3proxy\ - name: Get artifact uses: actions/upload-artifact@v7 with: From 1dfe9e718b0de30ed1c80d7f123cb742839e26bd Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Wed, 3 Jun 2026 11:00:47 +0300 Subject: [PATCH 27/41] Sign DLLs --- .github/workflows/build-win32.yml | 5 +++-- .github/workflows/build-win64.yml | 5 +++-- .github/workflows/build-winarm64.yml | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-win32.yml b/.github/workflows/build-win32.yml index 22ad121..ee9f54e 100644 --- a/.github/workflows/build-win32.yml +++ b/.github/workflows/build-win32.yml @@ -56,10 +56,11 @@ jobs: [System.IO.File]::WriteAllBytes("${{ github.workspace }}\3proxy.crt", $cert.Export("Cert")) - name: Sign shell: pwsh + env: + CERT_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} run: | $signtool = (Get-ChildItem "C:\Program Files (x86)\Windows Kits\10\bin\*\x64\signtool.exe" | Sort-Object { [version]$_.Directory.Parent.Name } -Descending | Select-Object -First 1).FullName - & $signtool sign /f "${{ github.workspace }}\cert.pfx" /p "${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}" /tr http://timestamp.digicert.com /td sha256 /fd sha256 "bin\3proxy.exe" - & $signtool sign /f "${{ github.workspace }}\cert.pfx" /p "${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}" /tr http://timestamp.digicert.com /td sha256 /fd sha256 "bin\3proxy_crypt.exe" + Get-ChildItem bin\*.exe, bin\*.dll | ForEach-Object { & $signtool sign /f "${{ github.workspace }}\cert.pfx" /p "$env:CERT_PASSWORD" /tr http://timestamp.digicert.com /td sha256 /fd sha256 $_.FullName } - name: make dist dir shell: cmd run: | diff --git a/.github/workflows/build-win64.yml b/.github/workflows/build-win64.yml index 84ee682..c75769f 100644 --- a/.github/workflows/build-win64.yml +++ b/.github/workflows/build-win64.yml @@ -57,10 +57,11 @@ jobs: [System.IO.File]::WriteAllBytes("${{ github.workspace }}\3proxy.crt", $cert.Export("Cert")) - name: Sign shell: pwsh + env: + CERT_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} run: | $signtool = (Get-ChildItem "C:\Program Files (x86)\Windows Kits\10\bin\*\x64\signtool.exe" | Sort-Object { [version]$_.Directory.Parent.Name } -Descending | Select-Object -First 1).FullName - & $signtool sign /f "${{ github.workspace }}\cert.pfx" /p "${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}" /tr http://timestamp.digicert.com /td sha256 /fd sha256 "bin\3proxy.exe" - & $signtool sign /f "${{ github.workspace }}\cert.pfx" /p "${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}" /tr http://timestamp.digicert.com /td sha256 /fd sha256 "bin\3proxy_crypt.exe" + Get-ChildItem bin\*.exe, bin\*.dll | ForEach-Object { & $signtool sign /f "${{ github.workspace }}\cert.pfx" /p "$env:CERT_PASSWORD" /tr http://timestamp.digicert.com /td sha256 /fd sha256 $_.FullName } - name: make dist dir shell: cmd run: | diff --git a/.github/workflows/build-winarm64.yml b/.github/workflows/build-winarm64.yml index e5a940d..e163c09 100644 --- a/.github/workflows/build-winarm64.yml +++ b/.github/workflows/build-winarm64.yml @@ -56,10 +56,11 @@ jobs: [System.IO.File]::WriteAllBytes("${{ github.workspace }}\3proxy.crt", $cert.Export("Cert")) - name: Sign shell: pwsh + env: + CERT_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} run: | $signtool = (Get-ChildItem "C:\Program Files (x86)\Windows Kits\10\bin\*\x64\signtool.exe" | Sort-Object { [version]$_.Directory.Parent.Name } -Descending | Select-Object -First 1).FullName - & $signtool sign /f "${{ github.workspace }}\cert.pfx" /p "${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}" /tr http://timestamp.digicert.com /td sha256 /fd sha256 "bin\3proxy.exe" - & $signtool sign /f "${{ github.workspace }}\cert.pfx" /p "${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}" /tr http://timestamp.digicert.com /td sha256 /fd sha256 "bin\3proxy_crypt.exe" + Get-ChildItem bin\*.exe, bin\*.dll | ForEach-Object { & $signtool sign /f "${{ github.workspace }}\cert.pfx" /p "$env:CERT_PASSWORD" /tr http://timestamp.digicert.com /td sha256 /fd sha256 $_.FullName } - name: make dist dir shell: cmd run: | From 101125de36aea6c24da1355addc423cd20adf0c8 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sun, 14 Jun 2026 19:49:59 +0300 Subject: [PATCH 28/41] ssl code cleanup --- src/ssl.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 65f38c2..355f1da 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -338,7 +338,11 @@ SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CONFIG *config, X509 *server_cert return NULL; } - SSL_set_fd(conn->ssl, s); + if(!SSL_set_fd(conn->ssl, s)){ + *errSSL = getSSLErr(); + ssl_conn_free(conn); + return NULL; + } do { struct pollfd fds[1] = {{INVALID_SOCKET}}; @@ -509,6 +513,7 @@ SSL_CTX * ssl_cli_ctx(SSL_CONFIG *config, X509 *server_cert, EVP_PKEY *server_ke SSL_CTX_free(ctx); return NULL; } + SSL_CTX_set_session_id_context(ctx, (const unsigned char *)"3proxy", 6); if(config->server_min_proto_version)SSL_CTX_set_min_proto_version(ctx, config->server_min_proto_version); if(config->server_max_proto_version)SSL_CTX_set_max_proto_version(ctx, config->server_max_proto_version); if(config->server_cipher_list)SSL_CTX_set_cipher_list(ctx, config->server_cipher_list); @@ -786,7 +791,7 @@ static void ssl_filter_close(void *fo){ X509_free(CONFIG->server_cert); } if ( CONFIG->client_cert != NULL ) { - X509_free(CONFIG->server_cert); + X509_free(CONFIG->client_cert); } if ( CONFIG->CA_key != NULL ) { EVP_PKEY_free(CONFIG->CA_key); @@ -795,7 +800,7 @@ static void ssl_filter_close(void *fo){ EVP_PKEY_free(CONFIG->server_key); } if ( CONFIG->client_key != NULL ) { - EVP_PKEY_free(CONFIG->server_key); + EVP_PKEY_free(CONFIG->client_key); } if ( CONFIG->srv_ctx != NULL ) { SSL_CTX_free(CONFIG->srv_ctx); From d77dc00fd167a42c90b9b10c041fd39b04e2081f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jun 2026 11:54:36 +0300 Subject: [PATCH 29/41] Bump actions/checkout from 6 to 7 (#1241) Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-rpm-arm64.yml | 2 +- .github/workflows/build-rpm-armhf.yml | 2 +- .github/workflows/build-rpm-x86-64.yml | 2 +- .github/workflows/build-watcom.yml | 2 +- .github/workflows/build-win32.yml | 2 +- .github/workflows/build-win64.yml | 2 +- .github/workflows/build-winarm64.yml | 2 +- .github/workflows/c-cpp-Linux.yml | 2 +- .github/workflows/c-cpp-MacOS.yml | 2 +- .github/workflows/c-cpp-Windows.yml | 2 +- .github/workflows/c-cpp-cmake.yml | 2 +- .github/workflows/docker-ghcr.yml | 2 +- .github/workflows/docker.yml | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build-rpm-arm64.yml b/.github/workflows/build-rpm-arm64.yml index 901b80a..43c7eb9 100644 --- a/.github/workflows/build-rpm-arm64.yml +++ b/.github/workflows/build-rpm-arm64.yml @@ -17,7 +17,7 @@ jobs: - ubuntu-24.04-arm runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: env run: | pwd diff --git a/.github/workflows/build-rpm-armhf.yml b/.github/workflows/build-rpm-armhf.yml index e2ea58b..82ab648 100644 --- a/.github/workflows/build-rpm-armhf.yml +++ b/.github/workflows/build-rpm-armhf.yml @@ -17,7 +17,7 @@ jobs: - ubuntu-latest runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: env run: | pwd diff --git a/.github/workflows/build-rpm-x86-64.yml b/.github/workflows/build-rpm-x86-64.yml index 6ed6495..2a5c6e0 100644 --- a/.github/workflows/build-rpm-x86-64.yml +++ b/.github/workflows/build-rpm-x86-64.yml @@ -17,7 +17,7 @@ jobs: - ubuntu-latest runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: env run: | pwd diff --git a/.github/workflows/build-watcom.yml b/.github/workflows/build-watcom.yml index 0f49bcd..1d3835e 100644 --- a/.github/workflows/build-watcom.yml +++ b/.github/workflows/build-watcom.yml @@ -17,7 +17,7 @@ jobs: - windows-2022 runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 # - name: configure # run: ./configure - name: Setup Open Watcom diff --git a/.github/workflows/build-win32.yml b/.github/workflows/build-win32.yml index ee9f54e..9b98209 100644 --- a/.github/workflows/build-win32.yml +++ b/.github/workflows/build-win32.yml @@ -17,7 +17,7 @@ jobs: - windows-2022 runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 # - name: configure # run: ./configure - name: set date diff --git a/.github/workflows/build-win64.yml b/.github/workflows/build-win64.yml index c75769f..0a9a4a4 100644 --- a/.github/workflows/build-win64.yml +++ b/.github/workflows/build-win64.yml @@ -17,7 +17,7 @@ jobs: - windows-2022 runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 # - name: configure # run: ./configure - name: set date diff --git a/.github/workflows/build-winarm64.yml b/.github/workflows/build-winarm64.yml index e163c09..89add3d 100644 --- a/.github/workflows/build-winarm64.yml +++ b/.github/workflows/build-winarm64.yml @@ -17,7 +17,7 @@ jobs: - windows-2022 runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 # - name: configure # run: ./configure - name: set date diff --git a/.github/workflows/c-cpp-Linux.yml b/.github/workflows/c-cpp-Linux.yml index 610f992..c293dbd 100644 --- a/.github/workflows/c-cpp-Linux.yml +++ b/.github/workflows/c-cpp-Linux.yml @@ -20,7 +20,7 @@ jobs: - ubuntu-24.04-arm runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 # - name: configure # run: ./configure - name: Linux libraries diff --git a/.github/workflows/c-cpp-MacOS.yml b/.github/workflows/c-cpp-MacOS.yml index ab8db07..e29069e 100644 --- a/.github/workflows/c-cpp-MacOS.yml +++ b/.github/workflows/c-cpp-MacOS.yml @@ -19,7 +19,7 @@ jobs: - macos-15 runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 # - name: configure # run: ./configure - name: Mac libraries diff --git a/.github/workflows/c-cpp-Windows.yml b/.github/workflows/c-cpp-Windows.yml index ac02038..49b9307 100644 --- a/.github/workflows/c-cpp-Windows.yml +++ b/.github/workflows/c-cpp-Windows.yml @@ -19,7 +19,7 @@ jobs: - windows-2022 runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - name: install Windows libraries run: vcpkg install pcre2:x64-windows && c:\msys64\usr\bin\pacman.exe -S --noconfirm mingw-w64-x86_64-pcre2 mingw-w64-x86_64-openssl - name: make Windows diff --git a/.github/workflows/c-cpp-cmake.yml b/.github/workflows/c-cpp-cmake.yml index 45aa854..1777668 100644 --- a/.github/workflows/c-cpp-cmake.yml +++ b/.github/workflows/c-cpp-cmake.yml @@ -22,7 +22,7 @@ jobs: - windows-2022 runs-on: ${{ matrix.target }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 # - name: configure # run: ./configure - name: Linux libraries diff --git a/.github/workflows/docker-ghcr.yml b/.github/workflows/docker-ghcr.yml index a2bbd1f..abff4bb 100644 --- a/.github/workflows/docker-ghcr.yml +++ b/.github/workflows/docker-ghcr.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Determine tags id: tags diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 5464775..2658f91 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Determine tags id: tags From af9f23ece7e157a959e833be8a15504c03bd52cb Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sun, 28 Jun 2026 13:49:52 +0300 Subject: [PATCH 30/41] Fix: invalid socket in poll(): can break sockmap() on Windows --- src/sockmap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sockmap.c b/src/sockmap.c index 8540162..9998a75 100644 --- a/src/sockmap.c +++ b/src/sockmap.c @@ -544,6 +544,7 @@ log("done read from server to buf"); } // if(!CLIENTTERMREAD || !CLIENTTERMWRITE){ if(!after){ + fds[fdsc].fd = param->clisock; if(fromclient && !CLIENTTERMREAD && !FROMCLIENT && (( #ifdef WITHSPLICE !usesplice && @@ -603,6 +604,7 @@ log("ready to write to client"); // if(!SERVERTERMREAD || !SERVERTERMWRITE){ if(!after){ + fds[fdsc].fd = param->remsock; if(fromserver && !SERVERTERMREAD && !FROMSERVER && (( #ifdef WITHSPLICE !usesplice && From 8f1358232980ab204e1893f1aeb865bdcda5a6b5 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sun, 28 Jun 2026 21:09:36 +0300 Subject: [PATCH 31/41] Fix invalid offset in datafilters --- src/sockmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sockmap.c b/src/sockmap.c index 9998a75..24ff59f 100644 --- a/src/sockmap.c +++ b/src/sockmap.c @@ -201,7 +201,7 @@ log(logbuf); log("send to server from buf"); #endif if(!param->nolongdatfilter){ - action = handledatfltcli(param, ¶m->clibuf, (int *)¶m->clibufsize, param->cliinbuf - res, (int *)¶m->cliinbuf); + action = handledatfltcli(param, ¶m->clibuf, (int *)¶m->clibufsize, param->clioffset, (int *)¶m->cliinbuf); if(action == HANDLED){ RETURN(0); } @@ -247,7 +247,7 @@ log("done send to server from buf"); log("send to client from buf"); #endif if(!param->nolongdatfilter){ - action = handledatfltsrv(param, ¶m->srvbuf, (int *)¶m->srvbufsize, param->srvinbuf - res, (int *)¶m->srvinbuf); + action = handledatfltsrv(param, ¶m->srvbuf, (int *)¶m->srvbufsize, param->srvoffset, (int *)¶m->srvinbuf); if(action == HANDLED){ RETURN(0); } From e41ab58b2c2453ffc1653de95be89efaecad7f2c Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sun, 28 Jun 2026 21:10:45 +0300 Subject: [PATCH 32/41] Fix: invalid error in ssl server handshake can lead to broken service state --- src/proxymain.c | 47 ++++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/src/proxymain.c b/src/proxymain.c index d32afc2..8520d9a 100644 --- a/src/proxymain.c +++ b/src/proxymain.c @@ -18,6 +18,19 @@ DWORD WINAPI threadfunc(LPVOID p) { void * threadfunc (void *p) { #endif int i = -1; +#ifndef STDMAIN + if(makefilters(param->srv, param) > CONTINUE){ +#ifndef NOUDPMAIN + if(param->srv->service == S_UDPPM) _3proxy_sem_unlock(udpinit); +#endif + freeparam(param); +#ifdef _WIN32 + return 0; +#else + return NULL; +#endif + } +#endif if(param->srv->cbsock != INVALID_SOCKET){ SASIZETYPE size = sizeof(param->sinsr); struct pollfd fds; @@ -1054,17 +1067,6 @@ int MODULEMAINFUNC (int argc, char** argv){ if(defparam.hostname)newparam->hostname=(unsigned char *)strdup((char *)defparam.hostname); clearstat(newparam); if(!isudp) newparam->clisock = new_sock; -#ifndef STDMAIN - if(makefilters(&srv, newparam) > CONTINUE){ - freeparam(newparam); -#ifndef NOUDPMAIN - if(isudp) { - _3proxy_sem_unlock(udpinit); - } -#endif - continue; - } -#endif newparam->prev = newparam->next = NULL; error = 0; _3proxy_mutex_lock(&srv.counter_mutex); @@ -1099,6 +1101,11 @@ int MODULEMAINFUNC (int argc, char** argv){ if(newparam->prev) newparam->prev->next = newparam->next; else srv.child = newparam->next; if(newparam->next) newparam->next->prev = newparam->prev; + if(newparam->clisock != INVALID_SOCKET){ + srv.so._shutdown(srv.so.state, newparam->clisock, SHUT_RDWR); + srv.so._closesocket(srv.so.state, newparam->clisock); + newparam->clisock = INVALID_SOCKET; + } newparam->srv = NULL; #ifndef NOUDPMAIN if(isudp){ @@ -1289,15 +1296,17 @@ void freeparam(struct clientparam * param) { #ifndef STDMAIN if(param->srv->service == S_UDPPM) hashdelete(&udp_table, param); #endif - if(param->prev){ - param->prev->next = param->next; + if(param->prev || param->next || param->srv->child == param){ + if(param->prev){ + param->prev->next = param->next; + } + else + param->srv->child = param->next; + if(param->next){ + param->next->prev = param->prev; + } + (param->srv->childcount)--; } - else - param->srv->child = param->next; - if(param->next){ - param->next->prev = param->prev; - } - (param->srv->childcount)--; _3proxy_mutex_unlock(¶m->srv->counter_mutex); } if(param->clibuf) free(param->clibuf); From c462963d8e5545bab593e24e25fa922676dac55c Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sun, 28 Jun 2026 21:15:38 +0300 Subject: [PATCH 33/41] Fix standalone services link --- src/proxymain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/proxymain.c b/src/proxymain.c index 8520d9a..fe938f8 100644 --- a/src/proxymain.c +++ b/src/proxymain.c @@ -18,7 +18,7 @@ DWORD WINAPI threadfunc(LPVOID p) { void * threadfunc (void *p) { #endif int i = -1; -#ifndef STDMAIN +#ifdef MODULEMAINFUNC if(makefilters(param->srv, param) > CONTINUE){ #ifndef NOUDPMAIN if(param->srv->service == S_UDPPM) _3proxy_sem_unlock(udpinit); From 4f99443750cf7b8c1eb2cadb4b666d4d0346fb7e Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sat, 4 Jul 2026 11:38:47 +0300 Subject: [PATCH 34/41] Authcache fix --- src/auth.c | 15 ++++++++------- src/hashtables.c | 13 +++++++------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/auth.c b/src/auth.c index 68b9bdc..cfb04ee 100644 --- a/src/auth.c +++ b/src/auth.c @@ -72,31 +72,32 @@ int alwaysauth(struct clientparam * param){ int cacheauth(struct clientparam * param){ struct authcache ac; uint32_t ttl; + unsigned type = param->srv->authcachetype; if( - ((conf.authcachetype & 2) && !param->username) || - ((conf.authcachetype & 4) && !param->password) || + ((type & 2) && !param->username) || + ((type & 4) && !param->password) || ( - (conf.authcachetype & 1) && *SAFAMILY(¶m->sincr) != AF_INET + (type & 1) && *SAFAMILY(¶m->sincr) != AF_INET #ifndef NOIPv6 && *SAFAMILY(¶m->sincr) != AF_INET6 #endif ) || (!hashresolv(&auth_table, param, &ac, &ttl))) { return 4; } - if((conf.authcachetype & 1) &&(conf.authcachetype & 8) && + if((type & 1) &&(type & 8) && (ac.sincr_family != *SAFAMILY(¶m->sincr) || memcmp(ac.sincr_addr, SAADDR(¶m->sincr), SAADDRLEN(¶m->sincr)) )) { return 10; } - if(!(conf.authcachetype&2) && *ac.username){ + if(!(type&2) && *ac.username){ if(param->username) free(param->username); param->username = (unsigned char *)strdup((char *)ac.username); } - if((conf.authcachetype & 32)){ + if((type & 32)){ memset(¶m->sinsl, 0, sizeof(param->sinsl)); *(SAFAMILY(¶m->sinsl)) = ac.sinsl_family; memcpy(SAADDR(¶m->sinsl), ac.sinsl_addr, SAADDRLEN(¶m->sinsl)); @@ -116,7 +117,7 @@ int doauth(struct clientparam * param){ if(authfuncs->authorize && (res = (*authfuncs->authorize)(param))) return res; - if(conf.authcachetype && authfuncs->authenticate && authfuncs->authenticate != cacheauth && param->username && (!(conf.authcachetype&4) || (!param->pwtype && param->password))){ + if(param->srv->authcachetype && authfuncs->authenticate && authfuncs->authenticate != cacheauth && param->username && (!(param->srv->authcachetype&4) || (!param->pwtype && param->password))){ struct authcache ac={.username=""}; if(param->username) { diff --git a/src/hashtables.c b/src/hashtables.c index eed8022..e46d10b 100644 --- a/src/hashtables.c +++ b/src/hashtables.c @@ -17,6 +17,12 @@ static void char_index2hash(const struct hashtable *ht, void *index, uint8_t *ha } static void param2hash_add(const struct hashtable *ht, void *index, uint8_t *hash){ + struct clientparam *param = (struct clientparam *)index; + + memcpy(hash, param->hash, ht->hash_size); +} + +void param2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){ blake2b_state S; struct clientparam *param = (struct clientparam *)index; unsigned type = param->srv->authcachetype; @@ -62,12 +68,7 @@ static void param2hash_add(const struct hashtable *ht, void *index, uint8_t *has if((type & 2048))blake2b_update(&S, SAPORT(¶m->srv->intsa), 2); blake2b_final(&S, hash, ht->hash_size); } -} - -void param2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){ - struct clientparam *param = (struct clientparam *)index; - - memcpy(hash, param->hash, ht->hash_size); + memcpy(param->hash, hash, ht->hash_size); } static void udpparam2hash(const struct hashtable *ht, void *index, uint8_t *hash){ From 6b944f3fa9ebc28d2b3044469b8069872740400c Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sat, 4 Jul 2026 11:51:40 +0300 Subject: [PATCH 35/41] Documentation update --- .github/workflows/build-win64.yml | 2 +- .github/workflows/build-winarm64.yml | 2 +- doc/html/man5/3proxy.cfg.5.html | 45 +++++++--- doc/html/man8/tlspr.8.html | 14 +++ doc/html/plugins/PCREPlugin.html | 90 ------------------- doc/html/plugins/PCREPlugin.ru.html | 89 ------------------- doc/html/plugins/SSLPlugin.html | 124 --------------------------- doc/html/plugins/SSLPlugin.ru.html | 120 -------------------------- man/3proxy.cfg.5 | 40 +++++++-- man/tlspr.8 | 3 + 10 files changed, 88 insertions(+), 441 deletions(-) delete mode 100644 doc/html/plugins/PCREPlugin.html delete mode 100644 doc/html/plugins/PCREPlugin.ru.html delete mode 100644 doc/html/plugins/SSLPlugin.html delete mode 100644 doc/html/plugins/SSLPlugin.ru.html diff --git a/.github/workflows/build-win64.yml b/.github/workflows/build-win64.yml index 0a9a4a4..520df69 100644 --- a/.github/workflows/build-win64.yml +++ b/.github/workflows/build-win64.yml @@ -87,7 +87,7 @@ jobs: copy doc\html\plugins\*.* dist\3proxy\doc\html\plugins\ copy doc\html\man8\*.* dist\3proxy\doc\html\man8\ copy doc\html\man5\*.* dist\3proxy\doc\html\man5\ - copy doc\html\devel\*.rtf dist\3proxy\doc\html\devel\ + copy doc\html\devel\*.* dist\3proxy\doc\html\devel\ copy copying dist\3proxy\ copy authors dist\3proxy\ copy README.md dist\3proxy\ diff --git a/.github/workflows/build-winarm64.yml b/.github/workflows/build-winarm64.yml index 89add3d..bf2d5d4 100644 --- a/.github/workflows/build-winarm64.yml +++ b/.github/workflows/build-winarm64.yml @@ -86,7 +86,7 @@ jobs: copy doc\html\plugins\*.* dist\3proxy\doc\html\plugins\ copy doc\html\man8\*.* dist\3proxy\doc\html\man8\ copy doc\html\man5\*.* dist\3proxy\doc\html\man5\ - copy doc\html\devel\*.rtf dist\3proxy\doc\html\devel\ + copy doc\html\devel\*.* dist\3proxy\doc\html\devel\ copy copying dist\3proxy\ copy authors dist\3proxy\ copy README.md dist\3proxy\ diff --git a/doc/html/man5/3proxy.cfg.5.html b/doc/html/man5/3proxy.cfg.5.html index 3bc1d51..62f30a0 100644 --- a/doc/html/man5/3proxy.cfg.5.html +++ b/doc/html/man5/3proxy.cfg.5.html @@ -552,8 +552,7 @@ username ignored.
Appropriate for most cases
useronly
- authentication by username without checking for any password with authorization by ACLs. Useful for e.g. -SOCKSv4 proxy and icqpr (icqpr set UIN / AOL screen name as -a username)
+SOCKSv4 proxy.
dnsname
- authentication by DNS hostname with authorization by ACLs. The DNS hostname is resolved via a PTR (reverse) record and validated (the resolved name must @@ -564,6 +563,12 @@ strong
- username/password authentication required. It will work with SOCKSv5, FTP, POP3 and HTTP proxy.
cache
- cached authentication, may be used with ´authcache´.
+cacheacl
- cached authentication, same as cache +but the ACL authorization result is also cached and not +re-evaluated on each request. Faster than cache, but +ACL changes do not take effect for cached users until the +cache entry expires. Use cache if ACLs may change +during the cache lifetime.
radius
- authentication with RADIUS.
Plugins may add additional authentication types.

@@ -598,10 +603,20 @@ user,password - both username and password are checked against cached ones.
limit
- limit user to use only one ip, ´ip´ and ´user´ are required
-ack
- only use cached auth if user access service with +acl - only use cached auth if user access service with same ACL
-ext
- cache external IP
-Use auth type cache for cached authentication

+ext - cache external IP
+dstaddr
- cache by destination IP address
+dstport
- cache by destination port
+dsthost
- cache by destination hostname
+dstoper
- cache by destination operation (e.g. HTTP +method)
+srvaddr
- cache by service (listener) address
+srvport
- cache by service (listener) port
+Multiple types can be combined (e.g. +ip,user,dstaddr,dstport).
+Use auth type cache (or cacheacl) for cached +authentication

allow <userlist> <sourcelist> <targetlist> @@ -746,8 +761,14 @@ ha send HAProxy PROXY protocol v1 header to parent proxy. Must be the last in the proxy chain. Useful for passing client IP information to the parent proxy. Example: parent 1000 ha
-Use "+" proxy only with fakeresolve -option

+Use "+" proxy only with fakeresolve option +
+Any parent type above can be suffixed with s (e.g. +https, tcps, socks5s, connect+s) +to establish a TLS-encrypted connection to the parent proxy. +Requires SSL/TLS support (WITH_SSL) and is used with +ssl_client_mode 3, which only handshakes TLS for +s-suffixed parents.

IP and port are ip addres and port of parent proxy server. If IP is zero, ip @@ -946,12 +967,16 @@ The rest of parameters is identical to pwtype is one of:
none (empty) - use system authentication
CL
- password is cleartext
-CR
- password is crypt-style password
+CR
- password is crypt-style password. $1$ prefix +uses MD5-crypt (requires OpenSSL), $3$ prefix uses +BLAKE2b-crypt (always available, see 3proxy_crypt(8)) +
NT
- password is NT password (in hex)
example:
users test1:CL:password1 "test2:CR:$1$lFDGlder$pLRb4cU2D7GAT58YQvY49."
users test3:NT:BD7DFBF29A93F93C63CB84790DA00E63
+users "test4:CR:$3$salt$G47yV9w...."
Note: double quotes are required because the password contains a $ sign.

@@ -1268,8 +1293,8 @@ to 3proxy@3proxy.org

3proxy(8), -proxy(8), ftppr(8), socks(8), pop3p(8), tcppm(8), udppm(8), -syslogd(8),
+3proxy_crypt(8), proxy(8), ftppr(8), socks(8), pop3p(8), +smtpp(8), tlspr(8), tcppm(8), udppm(8), syslogd(8),
https://3proxy.org/

AUTHORS diff --git a/doc/html/man8/tlspr.8.html b/doc/html/man8/tlspr.8.html index 79747bf..83de805 100644 --- a/doc/html/man8/tlspr.8.html +++ b/doc/html/man8/tlspr.8.html @@ -232,6 +232,20 @@ with TLS 1.3)

+

-s

+ + + + +

Split the TLS Client HELLO +packet across multiple TCP segments to make SNI-based DPI +detection harder. An optional numeric value can follow (e.g. +-s1) to control the splitting behaviour.

+ + + + +

-l

diff --git a/doc/html/plugins/PCREPlugin.html b/doc/html/plugins/PCREPlugin.html deleted file mode 100644 index 64297c6..0000000 --- a/doc/html/plugins/PCREPlugin.html +++ /dev/null @@ -1,90 +0,0 @@ -

3proxy PCRE (Perl Compatible Regular Expressions) Filtering

- -

Note: Since version 0.9.7, PCRE filtering is built into 3proxy and does not require -a separate plugin. All pcre_* commands are available directly when 3proxy is compiled with -PCRE2 support (WITH_PCRE). The plugin line is no longer needed.

- -

This filtering functionality can be used to create matching and replacement -rules with regular expressions for client requests, client and -server headers, and client and server data. It adds 3 additional -configuration commands:

- -
-pcre TYPE FILTER_ACTION REGEXP [ACE]
-pcre_rewrite TYPE FILTER_ACTION REGEXP REWRITE_EXPRESSION [ACE]
-pcre_extend FILTER_ACTION [ACE]
-pcre_options OPTION1 [...]
-
-pcre - allows applying a rule for matching -
pcre_rewrite - in addition to 'pcre', allows substituting substrings -
pcre_extend - extends the ACL of the last pcre or pcre_rewrite command by -adding an additional ACE (like with allow/deny configuration commands). -
pcre_options - allows setting matching options. Available options are: -PCRE_CASELESS, -PCRE_MULTILINE, -PCRE_DOTALL, -PCRE_EXTENDED, -PCRE_ANCHORED, -PCRE_DOLLAR_ENDONLY, -PCRE_EXTRA, -PCRE_NOTBOL, -PCRE_NOTEOL, -PCRE_UNGREEDY, -PCRE_NOTEMPTY, -PCRE_UTF8, -PCRE_NO_AUTO_CAPTURE, -PCRE_NO_UTF8_CHECK, -PCRE_AUTO_CALLOUT, -PCRE_PARTIAL, -PCRE_DFA_SHORTEST, -PCRE_DFA_RESTART, -PCRE_FIRSTLINE, -PCRE_DUPNAMES, -PCRE_NEWLINE_CR, -PCRE_NEWLINE_LF, -PCRE_NEWLINE_CRLF, -PCRE_NEWLINE_ANY, -PCRE_NEWLINE_ANYCRLF, -PCRE_BSR_ANYCRLF, -PCRE_BSR_UNICODE - -
    -
  • TYPE - type of filtered data. May contain one or more -(comma-delimited list) values: -
      -
    • request - content of the client's request, e.g., the HTTP GET request string. -(known problem: changing the request string doesn't change the IP of the host to connect to) -
    • cliheader - content of the client request headers, e.g., HTTP request headers. -
    • srvheader - content of the server's reply headers, e.g., HTTP status and headers. -
    • clidata - data received from the client, e.g., HTTP POST request data -
    • srvdata - data received from the server, e.g., an HTML page -
    -
  • FILTER_ACTION - action on match -
    • allow - allow this request without checking the rest of the rules for the given type -
    • deny - deny this request without checking the rest of the rules -
    • dunno - continue with the rest of the rules (useful with pcre_rewrite) -
    -
  • REGEXP - PCRE (Perl) regular expression. Use * if no regexp matching -is required. -
  • REWRITE_EXPRESSION - substitution string. May contain Perl-style -substrings -(not tested) $1, $2. $0 means the whole matched string. \r and \n may be used -to insert new strings; the string may be empty (""). -
  • ACE - access control entry (user names, source IPs, destination IPs, -ports, etc.), absolutely identical to allow/deny/bandlimin commands. -The regular expression is only matched if the ACL matches the connection data. -Warning: -Regular expressions don't require authentication and cannot replace -authentication and/or allow/deny ACLs. -
- - -

Example:

-
-pcre request deny "porn|sex" user1,user2,user3 192.168.0.0/16
-pcre srvheader deny "Content-type: application"
-pcre_rewrite clidata,srvdata dunno "porn|sex|pussy" "***" baduser
-pcre_extend deny * 192.168.0.1/16
-
- -© Vladimir Dubrovin, License: BSD style diff --git a/doc/html/plugins/PCREPlugin.ru.html b/doc/html/plugins/PCREPlugin.ru.html deleted file mode 100644 index cff579e..0000000 --- a/doc/html/plugins/PCREPlugin.ru.html +++ /dev/null @@ -1,89 +0,0 @@ -

Фильтрация PCRE (Perl Compatible Regular Expressions) в 3proxy

- -

Примечание: Начиная с версии 0.9.7 фильтрация PCRE встроена в 3proxy и не требует -отдельного плагина. Все команды pcre_* доступны напрямую при компиляции 3proxy с поддержкой -PCRE2 (WITH_PCRE). Строка plugin больше не нужна.

- -

Фильтрующий плагин используется для создания правил поиска и замены -регулярных выражений в запросе, заголовков запроса и ответа и данных. -Добавляет поддержку 3х новых команд в файле конфигурации:

- -
-pcre TYPE FILTER_ACTION REGEXP [ACE]
-pcre_rewrite TYPE FILTER_ACTION REGEXP REWRITE_EXPRESSION [ACE]
-pcre_extend FILTER_ACTION [ACE]
-pcre_options OPTION1 [...]
-
-pcre - позволяет искать совпадения -
pcre_rewrite - дополнительно позволяет производить замену подстрок -
pcre_extend - расширяет ACL последней команды pcre или pcre_rewrite путем -добавления еще одной ACE (аналогично списку правил allow/deny). -
pcre_options - позволяет устанавливать опции поиска, доступны следующие опции: -PCRE_CASELESS, -PCRE_MULTILINE, -PCRE_DOTALL, -PCRE_EXTENDED, -PCRE_ANCHORED, -PCRE_DOLLAR_ENDONLY, -PCRE_EXTRA, -PCRE_NOTBOL, -PCRE_NOTEOL, -PCRE_UNGREEDY, -PCRE_NOTEMPTY, -PCRE_UTF8, -PCRE_NO_AUTO_CAPTURE, -PCRE_NO_UTF8_CHECK, -PCRE_AUTO_CALLOUT, -PCRE_PARTIAL, -PCRE_DFA_SHORTEST, -PCRE_DFA_RESTART, -PCRE_FIRSTLINE, -PCRE_DUPNAMES, -PCRE_NEWLINE_CR, -PCRE_NEWLINE_LF, -PCRE_NEWLINE_CRLF, -PCRE_NEWLINE_ANY, -PCRE_NEWLINE_ANYCRLF, -PCRE_BSR_ANYCRLF, -PCRE_BSR_UNICODE - - -
    -
  • TYPE - тип фильтруемых данных. Может содержать одно или -несколько (список через запятую) значений: -
      -
    • request - содержимое запроса клиента (например строка HTTP GET-запроса). -(в настоящий момент изменение запроса не приводит к изменению адреса запрашиваемого хоста) -
    • cliheader - содержимое заголовков запроса клиента, например заголовки HTTP -
    • srvheader - содержимое заголовков ответа сервера, например заголовки HTTP -
    • clidata - данные полученные от клиента, например данные POST-запроса -
    • srvdata - данные полученные от сервера, например содержимое HTML-страницы -
    -
  • FILTER_ACTION - действие при совпадении. Может принимать значение -
    • allow - разрешить данный запрос без просмотра дальнейших правил -
    • deny - запретить данный запрос без просмотра дальнейших правил -
    • dunno - продолжить анализ правил (полезно для pcre_rewrite) -
    -
  • REGEXP - регулярное выражение в формате PCRE (perl). Используйте * если не -требуется проерка регулярного выражения. -
  • REWRITE_EXPRESSION - строка замены. Может содержать макроподстановки -(не тестировалось) $1, $2 и т.д. аналогично perl. $0 - полная найденная -подстрока. В строке замены можно использовать сочетания \r, \n для вставки -новых строк. Строка может быть пустой (""). -
  • ACE - Список контроля доступа (имя пользователя, IP источника, IP назначения, порт и т.д.), -полностью аналогичный ACE в командах allow, deny, bandlimin и т.п. Регулярное -выражение проверяется только при совпадении ACE с запросом. ВНИМАНИЕ: -использование регулярных выражений не требует авторизации и не заменяет ее. -Авторизацию необходимо конфигурировать отдельно. -
- - -

Пример:

-
-pcre request deny "porn|sex" user1,user2,user3 192.168.0.0/16
-pcre srvheader deny "Content-type: application"
-pcre_rewrite clidata,srvdata dunno "porn|sex|pussy" "***" baduser
-pcre_extend deny * 192.168.0.1/16
-
- -© Vladimir Dubrovin, License: BSD style diff --git a/doc/html/plugins/SSLPlugin.html b/doc/html/plugins/SSLPlugin.html deleted file mode 100644 index b33c070..0000000 --- a/doc/html/plugins/SSLPlugin.html +++ /dev/null @@ -1,124 +0,0 @@ -

3proxy SSL/TLS Support

- -

Note: Since version 0.9.7, SSL/TLS support is built into 3proxy and does not require -a separate plugin. All ssl_* commands are available directly when 3proxy is compiled with -OpenSSL support (WITH_SSL). The plugin line is no longer needed.

- -

SSL/TLS support can be used to transparently decrypt SSL/TLS data, provide TLS encryption -for proxy traffic, and authenticate using client certificates.

- -

For transparent certificate spoofing (MITM):

- -
ssl_mitm - spoof certificates for services started below. Usage without ssl_client_verify is insecure. -
ssl_nomitm - do not spoof certificates for services started below - -

To protect traffic to the server (https:// proxy):

- -ssl_serv (or ssl_server) - require TLS connection from clients for services below -
ssl_noserv (or ssl_noserver) - do not require TLS connection from clients for services below - -

To use TLS for upstream connections:

- -ssl_cli (or ssl_client) - establish TLS connection to upstream server for services below -
ssl_nocli (or ssl_noclient) - do not establish TLS connection to upstream server for services below - -

Parameters:

- -
ssl_server_cert /path/to/cert - Server certificate (should not be self-signed and must contain an Alternative Name) for ssl_serv -
ssl_server_key /path/to/key - Server certificate key for ssl_server_cert or generated MITM certificate -
ssl_client_cert /path/to/cert - Client certificate for authentication on upstream server (used with ssl_cli) -
ssl_client_key /path/to/key - Client certificate key for ssl_client_cert -
ssl_client_ciphersuites ciphersuites_list - TLS client ciphers for TLS 1.3, e.g., ssl_client_ciphersuites TLS_AES_128_GCM_SHA256 -
ssl_server_ciphersuites ciphersuites_list - TLS server ciphers for TLS 1.3 -
ssl_client_cipher_list ciphers_list - TLS client ciphers for TLS 1.2 and below, e.g., ssl_client_cipher_list ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305 -
ssl_server_cipher_list ciphers_list - TLS server ciphers for TLS 1.2 and below -
ssl_client_min_proto_version tls_version - TLS client minimum TLS version (e.g., TLSv1.2) -
ssl_server_min_proto_version tls_version - TLS server minimum TLS version (e.g., TLSv1.2) -
ssl_client_max_proto_version tls_version - TLS client maximum TLS version (e.g., TLSv1.2) -
ssl_server_max_proto_version tls_version - TLS server maximum TLS version (e.g., TLSv1.2) -
ssl_client_verify - verify the certificate for the upstream server in TLS client functionality (used with ssl_mitm or ssl_cli) -
ssl_client_no_verify - do not verify the certificate for the upstream server in TLS client functionality (default) -
ssl_server_verify - require client certificate authentication (mTLS) for ssl_serv -
ssl_server_no_verify - do not require client certificate (default) -
ssl_server_ca_file /path/to/cafile - CA certificate file for MITM -
ssl_server_ca_key /path/to/cakey - key for ssl_server_ca_file MITM CA -
ssl_server_ca_dir /path/to/cadir - CA directory for ssl_server_verify -
ssl_server_ca_store /path/to/castore - CA store for ssl_server_verify (OpenSSL 3.0+) -
ssl_client_ca_file /path/to/cafile - CA file for ssl_client_verify -
ssl_client_ca_dir /path/to/cadir - CA directory for ssl_client_verify -
ssl_client_ca_store /path/to/castore - CA store for ssl_client_verify (OpenSSL 3.0+) -
ssl_client_sni hostname - SNI hostname to send to upstream server (overrides the requested hostname) -
ssl_client_alpn protocol1 protocol2 ... - ALPN protocols to negotiate with upstream server (e.g., ssl_client_alpn h2 http/1.1) -
ssl_client_mode mode - when to establish TLS connection: 0 - on connect (default), 1 - after authentication, 2 - before data, 3 - only for secure parent types (ending with 's') -
ssl_certcache /path/to/cache/ - location for the generated MITM certificates cache, optional if ssl_server_ca_file / ssl_server_ca_key are configured. -The cache may contain 3 files: 3proxy.pem - public -self-signed certificates (used if ssl_server_ca_file is not configured), -3proxy.key - key for public certificates, used if ssl_server_ca_key is not configured, server.key - this key is used if ssl_server_key is not configured to generate -spoofed certificates. If server.key is absent, 3proxy.key is used to generate certificates. -Generated certificates are placed in the same path. - - -

MITM example:

-
-ssl_server_ca_file /path/to/cafile
-ssl_server_ca_key /path/to/cakey
-ssl_mitm
-proxy -p3128
-ssl_nomitm
-proxy -p3129
-
-MITM's traffic with a spoofed certificate for the port 3128 proxy. - -

https:// proxy example:

-
-ssl_server_cert path_to_cert
-ssl_server_key path_to_key
-ssl_serv
-proxy -p33128
-ssl_noserv
-proxy -p3128
-
-Creates an https:// proxy on port 33128 and an http:// proxy on port 3128 - -

TLS client example (connect to upstream via TLS):

-
-ssl_client_cert /path/to/client.crt
-ssl_client_key /path/to/client.key
-ssl_client_verify
-ssl_client_ca_file /path/to/ca.crt
-ssl_cli
-proxy -p3128
-
-Creates an HTTP proxy that connects to upstream servers via TLS with client certificate authentication. - -

Conditional TLS for parent proxy (ssl_client_mode 3):

-
-ssl_server_cert /path/to/server.crt
-ssl_server_key /path/to/key
-ssl_client_mode 3
-
-auth strong
-allow user1
-parent 1000 https parent1.example.com 443
-allow user2
-parent 1000 socks5 parent2.example.com 1080
-ssl_serv
-ssl_cli
-proxy -p3128
-ssl_noserv
-ssl_nocli
-
-Creates an HTTP proxy on port 3128 that uses TLS for client connections (ssl_serv). With ssl_client_mode 3, TLS handshake to parent proxy is performed only if the parent type ends with 's' (secure types). In this example, user1's traffic goes through an https parent proxy with TLS encryption, while user2's traffic goes through a regular socks5 parent without TLS. Secure parent types include: tcps, https, connects, connect+s, socks4s, socks5s, socks4+s, socks5+s, pop3s, smtps, ftps. - -

mTLS example (require client certificate):

-
-ssl_server_cert /path/to/server.crt
-ssl_server_key /path/to/server.key
-ssl_server_ca_file /path/to/ca.crt
-ssl_server_verify
-ssl_serv
-proxy -p3128
-
-Creates an https:// proxy that requires client certificate authentication. - -© Vladimir Dubrovin, License: BSD style diff --git a/doc/html/plugins/SSLPlugin.ru.html b/doc/html/plugins/SSLPlugin.ru.html deleted file mode 100644 index dc9238b..0000000 --- a/doc/html/plugins/SSLPlugin.ru.html +++ /dev/null @@ -1,120 +0,0 @@ -

3proxy SSL/TLS поддержка

- -

Примечание: Начиная с версии 0.9.7 поддержка SSL/TLS встроена в 3proxy и не требует -отдельного плагина. Все команды ssl_* доступны напрямую при компиляции 3proxy с поддержкой -OpenSSL (WITH_SSL). Строка plugin больше не нужна.

- -

Плагин можно использовать для перехвата и дешифровки SSL/TLS трафика, для шифрования трафика прокси-сервера и аутентификации с помощью клиентских сертификатов.

- -

Для прозрачного перехвата трафика (MITM):

- -
ssl_mitm - подменять сертификаты для сервисов, запущенных ниже. Использование без ssl_client_verify небезопасно. -
ssl_nomitm - не подменять сертификаты для сервисов, запущенных ниже. - -

Для защиты трафика прокси-сервера (https:// proxy):

- -ssl_serv (или ssl_server) - требовать TLS-соединение от клиентов для сервисов, запущенных ниже -
ssl_noserv (или ssl_noserver) - не требовать TLS-соединение от клиентов для сервисов, запущенных ниже - -

Для использования TLS при соединении к вышестоящему серверу:

- -ssl_cli (или ssl_client) - устанавливать TLS-соединение к вышестоящему серверу для сервисов, запущенных ниже -
ssl_nocli (или ssl_noclient) - не устанавливать TLS-соединение к вышестоящему серверу для сервисов, запущенных ниже - -

Параметры:

- -
ssl_server_cert /path/to/cert - сертификат сервера (не должен быть самоподписанным, должен содержать альтернативные имена) для ssl_serv -
ssl_server_key /path/to/key - ключ сертификата сервера для ssl_server_cert или сгенерированного MITM-сертификата -
ssl_client_cert /path/to/cert - клиентский сертификат для аутентификации на вышестоящем сервере (используется с ssl_cli) -
ssl_client_key /path/to/key - ключ клиентского сертификата для ssl_client_cert -
ssl_client_ciphersuites ciphersuites_list - наборы шифров TLS для TLS 1.3 (клиент), пример: ssl_client_ciphersuites TLS_AES_128_GCM_SHA256 -
ssl_server_ciphersuites ciphersuites_list - наборы шифров TLS для TLS 1.3 (сервер) -
ssl_client_cipher_list ciphers_list - наборы шифров TLS для TLS 1.2 и ниже (клиент), пример: ssl_client_cipher_list ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305 -
ssl_server_cipher_list ciphers_list - наборы шифров TLS для TLS 1.2 и ниже (сервер) -
ssl_client_min_proto_version tls_version - минимальная версия TLS клиента (например, ssl_client_min_proto_version TLSv1.2) -
ssl_server_min_proto_version tls_version - минимальная версия TLS сервера -
ssl_client_max_proto_version tls_version - максимальная версия TLS клиента -
ssl_server_max_proto_version tls_version - максимальная версия TLS сервера -
ssl_client_verify - проверять сертификат вышестоящего сервера (используется с ssl_mitm или ssl_cli) -
ssl_client_no_verify - не проверять сертификат вышестоящего сервера (по умолчанию) -
ssl_server_verify - требовать клиентский сертификат (mTLS) для ssl_serv -
ssl_server_no_verify - не требовать клиентский сертификат (по умолчанию) -
ssl_server_ca_file /path/to/cafile - файл CA-сертификата для MITM -
ssl_server_ca_key /path/to/cakey - ключ CA-сертификата ssl_server_ca_file для MITM -
ssl_server_ca_dir /path/to/cadir - директория CA-сертификатов для ssl_server_verify -
ssl_server_ca_store /path/to/castore - хранилище CA-сертификатов для ssl_server_verify (OpenSSL 3.0+) -
ssl_client_ca_file /path/to/cafile - файл CA-сертификатов для ssl_client_verify -
ssl_client_ca_dir /path/to/cadir - директория CA-сертификатов для ssl_client_verify -
ssl_client_ca_store /path/to/castore - хранилище CA-сертификатов для ssl_client_verify (OpenSSL 3.0+) -
ssl_client_sni hostname - SNI-имя хоста для отправки вышестоящему серверу (переопределяет запрошенное имя хоста) -
ssl_client_alpn протокол1 протокол2 ... - ALPN-протоколы для согласования с вышестоящим сервером (например, ssl_client_alpn h2 http/1.1) -
ssl_client_mode режим - когда устанавливать TLS-соединение: 0 - при подключении (по умолчанию), 1 - после аутентификации, 2 - перед передачей данных, 3 - только для защищённых типов parent прокси (заканчивающихся на 's') -
ssl_certcache /path/to/cache/ - расположение кеша сгенерированных MITM-сертификатов. Кеш может содержать -файлы 3proxy.pem, 3proxy.key, server.key, которые используются как ssl_server_ca_file, -ssl_server_ca_key и ssl_server_key соответственно, если они не заданы. Если server.key не задан, -3proxy.key используется для генерации серверного сертификата. - -

Пример MITM:

-
-ssl_server_ca_file /path/to/cafile
-ssl_server_ca_key /path/to/cakey
-ssl_mitm
-proxy -p3128
-ssl_nomitm
-proxy -p3129
-
-Перехватывается трафик в прокси на порту 3128. - -

Пример конфигурации https:// прокси:

-
-ssl_server_cert path_to_cert
-ssl_server_key path_to_key
-ssl_serv
-proxy -p33128
-ssl_noserv
-proxy -p3128
-
-На порту 33128 создается https:// прокси, на порту 3128 - http:// прокси. - -

Пример TLS-клиента (соединение к вышестоящему серверу через TLS):

-
-ssl_client_cert /path/to/client.crt
-ssl_client_key /path/to/client.key
-ssl_client_verify
-ssl_client_ca_file /path/to/ca.crt
-ssl_cli
-proxy -p3128
-
-Создается HTTP-прокси, который соединяется с вышестоящими серверами через TLS с аутентификацией по клиентскому сертификату. - -

Условное TLS для parent прокси (ssl_client_mode 3):

-
-ssl_server_cert /path/to/server.crt
-ssl_server_key /path/to/key
-ssl_client_mode 3
-
-auth strong
-allow user1
-parent 1000 https parent1.example.com 443
-allow user2
-parent 1000 socks5 parent2.example.com 1080
-ssl_serv
-ssl_cli
-proxy -p3128
-ssl_noserv
-ssl_nocli
-
-Создается HTTP-прокси на порту 3128, использующий TLS для клиентских соединений (ssl_serv). При ssl_client_mode 3 TLS-рукопожатие с родительским прокси выполняется только если тип parent прокси заканчивается на 's' (защищённые типы). В данном примере трафик user1 идёт через https родительский прокси с TLS-шифрованием, а трафик user2 — через обычный socks5 родитель без TLS. Защищённые типы parent прокси: tcps, https, connects, connect+s, socks4s, socks5s, socks4+s, socks5+s, pop3s, smtps, ftps. - -

Пример mTLS (требование клиентского сертификата):

-
-ssl_server_cert /path/to/server.crt
-ssl_server_key /path/to/server.key
-ssl_server_ca_file /path/to/ca.crt
-ssl_server_verify
-ssl_serv
-proxy -p3128
-
-Создается https:// прокси, требующий аутентификацию по клиентскому сертификату. - -© Vladimir Dubrovin, License: BSD style diff --git a/man/3proxy.cfg.5 b/man/3proxy.cfg.5 index f536b41..d238a65 100644 --- a/man/3proxy.cfg.5 +++ b/man/3proxy.cfg.5 @@ -591,8 +591,7 @@ This is the default authentication type Appropriate for most cases .br \fBuseronly\fR - authentication by username without checking for any password with -authorization by ACLs. Useful for e.g. SOCKSv4 proxy and icqpr (icqpr set UIN / -AOL screen name as a username) +authorization by ACLs. Useful for e.g. SOCKSv4 proxy. .br \fBdnsname\fR - authentication by DNS hostname with authorization by ACLs. The DNS hostname is resolved via a PTR (reverse) record and validated (the resolved @@ -604,6 +603,11 @@ NB: there is no password check; the name may be spoofed. SOCKSv5, FTP, POP3 and HTTP proxy. .br \fBcache\fR - cached authentication, may be used with \'authcache\'. +.br + \fBcacheacl\fR - cached authentication, same as \fBcache\fR but the ACL +authorization result is also cached and not re-evaluated on each request. Faster +than \fBcache\fR, but ACL changes do not take effect for cached users until the +cache entry expires. Use \fBcache\fR if ACLs may change during the cache lifetime. .br \fBradius\fR - authentication with RADIUS. .br @@ -641,11 +645,25 @@ assigned to the same user without actual authentication. .br \fBlimit\fR - limit user to use only one ip, \'ip\' and \'user\' are required .br - \fBack\fR - only use cached auth if user access service with same ACL + \fBacl\fR - only use cached auth if user access service with same ACL .br \fBext\fR - cache external IP .br -Use auth type \fBcache\fR for cached authentication + \fBdstaddr\fR - cache by destination IP address +.br + \fBdstport\fR - cache by destination port +.br + \fBdsthost\fR - cache by destination hostname +.br + \fBdstoper\fR - cache by destination operation (e.g. HTTP method) +.br + \fBsrvaddr\fR - cache by service (listener) address +.br + \fBsrvport\fR - cache by service (listener) port +.br +Multiple types can be combined (e.g. \fBip,user,dstaddr,dstport\fR). +.br +Use auth type \fBcache\fR (or \fBcacheacl\fR) for cached authentication .br .BR allow @@ -808,6 +826,12 @@ in the proxy chain. Useful for passing client IP information to the parent proxy Example: parent 1000 ha .br Use "+" proxy only with \fBfakeresolve\fR option +.br +Any parent type above can be suffixed with \fBs\fR (e.g. \fBhttps\fR, +\fBtcps\fR, \fBsocks5s\fR, \fBconnect+s\fR) to establish a TLS-encrypted +connection to the parent proxy. Requires SSL/TLS support (WITH_SSL) and is +used with \fBssl_client_mode 3\fR, which only handshakes TLS for \fBs\fR-suffixed +parents. .br IP and port are ip addres and port of parent proxy server. @@ -1047,7 +1071,9 @@ the format: .br \fBCL\fR - password is cleartext .br - \fBCR\fR - password is crypt-style password + \fBCR\fR - password is crypt-style password. \fB$1$\fR prefix uses MD5-crypt +(requires OpenSSL), \fB$3$\fR prefix uses BLAKE2b-crypt (always available, see +.BR 3proxy_crypt (8)) .br \fBNT\fR - password is NT password (in hex) .br @@ -1056,6 +1082,8 @@ the format: users test1:CL:password1 "test2:CR:$1$lFDGlder$pLRb4cU2D7GAT58YQvY49." .br users test3:NT:BD7DFBF29A93F93C63CB84790DA00E63 +.br + users "test4:CR:$3$salt$G47yV9w...." .br Note: double quotes are required because the password contains a $ sign. @@ -1356,7 +1384,7 @@ authentication and/or allow/deny ACLs. Report all bugs to .BR 3proxy@3proxy.org .SH SEE ALSO -3proxy(8), proxy(8), ftppr(8), socks(8), pop3p(8), tcppm(8), udppm(8), syslogd(8), +3proxy(8), 3proxy_crypt(8), proxy(8), ftppr(8), socks(8), pop3p(8), smtpp(8), tlspr(8), tcppm(8), udppm(8), syslogd(8), .br https://3proxy.org/ .SH AUTHORS diff --git a/man/tlspr.8 b/man/tlspr.8 index d9a30c9..ede7847 100644 --- a/man/tlspr.8 +++ b/man/tlspr.8 @@ -75,6 +75,9 @@ destination_port. Port to establish outgoing connections. Required unless the Tr .B -c TLS_CHECK_LEVEL. 0 (default) - allow non-TLS traffic to pass, 1 - require TLS, only check client HELLO packet, 2 - require TLS, check both client and server HELLO, 3 - require TLS, check that the server sends a certificate (not compatible with TLS 1.3), 4 - require mutual TLS, check that the server sends a certificate request and the client sends a certificate (not compatible with TLS 1.3) .TP +.B -s +Split the TLS Client HELLO packet across multiple TCP segments to make SNI-based DPI detection harder. An optional numeric value can follow (e.g. \fB-s1\fR) to control the splitting behaviour. +.TP .B -l Log. By default logging is to stdout. If .I logfile From 27d5d8d102dfb5d4490c54dd1a5a1b4b7bfabda6 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sat, 4 Jul 2026 12:14:54 +0300 Subject: [PATCH 36/41] Update build-rpm-armhf.yml --- .github/workflows/build-rpm-armhf.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-rpm-armhf.yml b/.github/workflows/build-rpm-armhf.yml index 82ab648..363266b 100644 --- a/.github/workflows/build-rpm-armhf.yml +++ b/.github/workflows/build-rpm-armhf.yml @@ -71,7 +71,7 @@ jobs: export CC=$CC export RPATH=/usr/arm-linux-gnueabihf/lib:$RPATH export LD_LIBRARY_PATH=/usr/arm-linux-gnueabihf/lib:$LD_LIBRARY_PATH - rpmbuild -ba --define "PAMLIB pam0g" --define "_arch arm" --define "cross yes" --target=arm-linux-gnueabi 3proxy-$RELEASE.spec + rpmbuild -ba --define "PAMLIB pam0g" --define "_arch arm" --define "cross yes" --target=arm-linux-gnueabihf 3proxy-$RELEASE.spec cd $ret mv ~/rpmbuild/RPMS/arm/3proxy-$RELEASE-1.arm.rpm 3proxy-$RELEASE.arm.rpm - name: Get artifact rpm From 19cacf0bd9022d29362101dd292c0eea42129a5d Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sat, 4 Jul 2026 13:51:28 +0300 Subject: [PATCH 37/41] Commit as 0.9.7 --- CHANGELOG | 34 ++++++++++++++++++++++++---------- CHANGELOG.rus | 34 ++++++++++++++++++++++++---------- RELEASE | 2 +- debian/changelog | 6 ++++++ doc/changelog/0/9/7 | 23 +++++++++++++++++++++++ scripts/rh/3proxy.spec | 2 +- src/version.h | 6 +++--- 7 files changed, 82 insertions(+), 25 deletions(-) create mode 100644 doc/changelog/0/9/7 diff --git a/CHANGELOG b/CHANGELOG index 747638d..ad99846 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,11 +1,25 @@ -3proxy-0.9.6 Released April, 11 2026 +3proxy-0.9.7 Released July, 4 2026 -+ ssl_client and multiple configuration options added to SSLPlugin, SSLPlugin code significantly improved and bugfixed. See https://github.com/3proxy/3proxy/wiki/SSLPlugin. 3proxy can now be used as stunnel replacement for many scenarios. -+ HAProxy proxy protocol v1 support as client and server, add -H option for service to expect HA proxy v1 protocol header, use ha parent type: parent 1000 ha 0.0.0.0 0 to send v1 header. -+ tlspr is supported in auto -+ tlspr supports -s option, it breaks HELLO packet to prevent some DPIs from detecting SNI -+ maxseg configuration option and TCP_MAXSEG socket flag support added. It sets maximum size of TCP segment to fix PathMTU discovery problems -+ -Ne / -Ni options added to specify external / internal NAT address for SOCKSv5 -+ cmake environment added -! External pcre2 (pcre2-8) library is used for PCRE, pcre code is removed from 3proxy -! Multiple minor bugfixes \ No newline at end of file ++ PCRE2 and SSL/TLS code moved from plugins into main 3proxy binary; dynamic linking with ssl/pcre by default, STATIC/LIBSTATIC options for static linking ++ Unix sockets support for parent proxies, tcppm, internal listeners and -i option; abstract (fileless) unix sockets on Linux ++ ssl_client_mode = 3 to use 'secure' parent types: https, tcps, socks5s, connect+s, etc. ++ New authcache types: cacheacl, dstaddr, dstport, dsthost, dstoper, srvaddr, srvport; authcache is now configurable per service ++ Hashtables for password lists and authcache, faster password lookups ++ 3proxy_crypt: new internal password hashing replacing mycrypt ++ udppm switched to hashtables and supports multiple connections ++ SOCKSv5 UDP parent support; -Ne/-Ni NAT options ++ Docker images for more platforms, signed; DLLs signed; public cert added to build ++ Grace sleep and linger on connection close; correctly process half-closed connections ++ Allow setting internal/external network namespaces on Linux +- icqpr/OSCAR code removed +! Fix: invalid error in SSL server handshake could break service state +! Fix: invalid offset in datafilters +! Fix: invalid socket in poll() could break sockmap() on Windows +! Fix: deadlock in ftppr +! Fix: crash on standalone services +! Fix: non-initialized mutex crash under Windows +! Fix: socks v5 parent with no auth +! Fix: hanging connections in sockmap; unneeded poll in sockmap +! Fix: symbols collision with OpenSSL could lead to crash +! Fix: compatibility with older SSL versions and older Windows (7 and below) +! Multiple minor bugfixes and code cleanup diff --git a/CHANGELOG.rus b/CHANGELOG.rus index a0da305..c01e782 100644 --- a/CHANGELOG.rus +++ b/CHANGELOG.rus @@ -1,11 +1,25 @@ -3proxy-0.9.6 Вышел 11 Апреля 2026 +3proxy-0.9.7 Вышел 4 Июля 2026 -+ В SSLPlugin добавлены ssl_client и множество опций конфигурации, код SSLPlugin значительно улучшен и исправлен. См. https://github.com/3proxy/3proxy/wiki/SSLPlugin. 3proxy теперь может использоваться как замена stunnel во многих сценариях. -+ Поддержка прокси-протокола HAProxy v1 на стороне клиента и сервера. Добавлена опция -H для сервиса, чтобы ожидать заголовок прокси-протокола HA v1. Используйте тип родителя ha: parent 1000 ha 0.0.0.0 0 для отправки заголовка v1. -+ tlspr поддерживается в режиме auto -+ tlspr поддерживает опцию -s, которая разбивает HELLO-пакет для предотвращения обнаружения SNI некоторыми DPI -+ Добавлена опция конфигурации maxseg и поддержка флага сокета TCP_MAXSEG. Устанавливает максимальный размер TCP-сегмента для решения проблем с обнаружением PathMTU -+ Добавлены опции -Ne / -Ni для указания внешнего/внутреннего NAT-адреса для SOCKSv5 -+ Добавлено окружение cmake -! Внешняя библиотека pcre2 (pcre2-8) используется для PCRE, код pcre удалён из 3proxy -! Множество мелких исправлений ошибок \ No newline at end of file ++ Код PCRE2 и SSL/TLS перенесён из плагинов в основной бинарный файл 3proxy; по умолчанию динамическое связывание с ssl/pcre, опции STATIC/LIBSTATIC для статического связывания ++ Поддержка unix-сокетов для родительских прокси, tcppm, внутренних слушателей и опции -i; абстрактные (безфайловые) unix-сокеты в Linux ++ ssl_client_mode = 3 для использования «безопасных» типов родителя: https, tcps, socks5s, connect+s и т.д. ++ Новые типы authcache: cacheacl, dstaddr, dstport, dsthost, dstoper, srvaddr, srvport; authcache настраивается для каждого сервиса ++ Хеш-таблицы для списков паролей и authcache, более быстрый поиск паролей ++ 3proxy_crypt: новое внутреннее хеширование паролей, заменяющее mycrypt ++ udppm переведён на хеш-таблицы и поддерживает множество соединений ++ Поддержка UDP-родителя для SOCKSv5; опции NAT -Ne/-Ni ++ Docker-образы для большего числа платформ, подписанные; подписанные DLL; публичный сертификат добавлен в сборку ++ Grace sleep и linger при закрытии соединения; корректная обработка полузакрытых соединений ++ Разрешено задавать внутренние/внешние сетевые пространства имён (network namespaces) в Linux +- Код icqpr/OSCAR удалён +! Исправление: некорректная ошибка в SSL server handshake могла ломать состояние сервиса +! Исправление: некорректное смещение в datafilters +! Исправление: некорректный сокет в poll() мог ломать sockmap() в Windows +! Исправление: взаимоблокировка (deadlock) в ftppr +! Исправление: падение на standalone-сервисах +! Исправление: падение из-за неинициализированного mutex в Windows +! Исправление: родитель socks v5 без аутентификации +! Исправление: зависающие соединения в sockmap; лишний poll в sockmap +! Исправление: конфликт символов с OpenSSL мог приводить к падению +! Исправление: совместимость со старыми версиями SSL и старыми версиями Windows (7 и ниже) +! Множество мелких исправлений и очистка кода diff --git a/RELEASE b/RELEASE index 9cf0386..bae256f 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -0.9.6 \ No newline at end of file +0.9.7 \ No newline at end of file diff --git a/debian/changelog b/debian/changelog index 1020ba0..46dcbd6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +3proxy (0.9.7-1) buster; urgency=medium + + *3proxy 0.9.7 initial build + + -- z3APA3A <3apa3a@3proxy.org> Sat, 04 Jul 2026 11:55:03 +0300 + 3proxy (0.9.6-1) buster; urgency=medium *3proxy 0.9.6 initial build diff --git a/doc/changelog/0/9/7 b/doc/changelog/0/9/7 new file mode 100644 index 0000000..1d6c005 --- /dev/null +++ b/doc/changelog/0/9/7 @@ -0,0 +1,23 @@ ++ PCRE2 and SSL/TLS code moved from plugins into main 3proxy binary; dynamic linking with ssl/pcre by default, STATIC/LIBSTATIC options for static linking ++ Unix sockets support for parent proxies, tcppm, internal listeners and -i option; abstract (fileless) unix sockets on Linux ++ ssl_client_mode = 3 to use 'secure' parent types: https, tcps, socks5s, connect+s, etc. ++ New authcache types: cacheacl, dstaddr, dstport, dsthost, dstoper, srvaddr, srvport; authcache is now configurable per service ++ Hashtables for password lists and authcache, faster password lookups ++ 3proxy_crypt: new internal password hashing replacing mycrypt ++ udppm switched to hashtables and supports multiple connections ++ SOCKSv5 UDP parent support; -Ne/-Ni NAT options ++ Docker images for more platforms, signed; DLLs signed; public cert added to build ++ Grace sleep and linger on connection close; correctly process half-closed connections ++ Allow setting internal/external network namespaces on Linux +- icqpr/OSCAR code removed +! Fix: invalid error in SSL server handshake could break service state +! Fix: invalid offset in datafilters +! Fix: invalid socket in poll() could break sockmap() on Windows +! Fix: deadlock in ftppr +! Fix: crash on standalone services +! Fix: non-initialized mutex crash under Windows +! Fix: socks v5 parent with no auth +! Fix: hanging connections in sockmap; unneeded poll in sockmap +! Fix: symbols collision with OpenSSL could lead to crash +! Fix: compatibility with older SSL versions and older Windows (7 and below) +! Multiple minor bugfixes and code cleanup diff --git a/scripts/rh/3proxy.spec b/scripts/rh/3proxy.spec index 9d32698..aa4ba22 100644 --- a/scripts/rh/3proxy.spec +++ b/scripts/rh/3proxy.spec @@ -1,5 +1,5 @@ Name: 3proxy -Version: 0.9.6 +Version: 0.9.7 Release: 1%{?dist} Summary: 3proxy tiny proxy server License: GPL/LGPL/Apache/BSD diff --git a/src/version.h b/src/version.h index 05a8bf9..b71d3f9 100644 --- a/src/version.h +++ b/src/version.h @@ -1,14 +1,14 @@ #ifndef VERSION -#define VERSION "3proxy-0.9.6" +#define VERSION "3proxy-0.9.7" #endif #ifndef BUILDDATE #define BUILDDATE "" #endif #define MAJOR3PROXY 0 #define SUBMAJOR3PROXY 9 -#define MINOR3PROXY 6 +#define MINOR3PROXY 7 #define SUBMINOR3PROXY 0 -#define RELEASE3PROXY "3proxy-0.9.6(" BUILDDATE ")\0" +#define RELEASE3PROXY "3proxy-0.9.7(" BUILDDATE ")\0" #ifndef YEAR3PROXY #define YEAR3PROXY "2026" #endif From a04cd67eaa84f2fa6b45600e6ffd32ad0820bd91 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sat, 4 Jul 2026 14:15:01 +0300 Subject: [PATCH 38/41] Fix release artefact uploads in Windows workflows --- .github/workflows/build-watcom.yml | 1 + .github/workflows/build-win32.yml | 1 + .github/workflows/build-win64.yml | 1 + .github/workflows/build-winarm64.yml | 1 + 4 files changed, 4 insertions(+) diff --git a/.github/workflows/build-watcom.yml b/.github/workflows/build-watcom.yml index 1d3835e..9f6e1ed 100644 --- a/.github/workflows/build-watcom.yml +++ b/.github/workflows/build-watcom.yml @@ -88,6 +88,7 @@ jobs: run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-lite.zip - name: Upload to release if: github.event_name == 'release' + shell: bash env: GH_TOKEN: ${{ github.token }} TAG: ${{ github.event.release.tag_name }} diff --git a/.github/workflows/build-win32.yml b/.github/workflows/build-win32.yml index 9b98209..19edbfd 100644 --- a/.github/workflows/build-win32.yml +++ b/.github/workflows/build-win32.yml @@ -103,6 +103,7 @@ jobs: run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-x86.zip - name: Upload to release if: github.event_name == 'release' + shell: bash env: GH_TOKEN: ${{ github.token }} TAG: ${{ github.event.release.tag_name }} diff --git a/.github/workflows/build-win64.yml b/.github/workflows/build-win64.yml index 520df69..5c3e5b3 100644 --- a/.github/workflows/build-win64.yml +++ b/.github/workflows/build-win64.yml @@ -104,6 +104,7 @@ jobs: run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-x64.zip - name: Upload to release if: github.event_name == 'release' + shell: bash env: GH_TOKEN: ${{ github.token }} TAG: ${{ github.event.release.tag_name }} diff --git a/.github/workflows/build-winarm64.yml b/.github/workflows/build-winarm64.yml index bf2d5d4..b6dfc0f 100644 --- a/.github/workflows/build-winarm64.yml +++ b/.github/workflows/build-winarm64.yml @@ -103,6 +103,7 @@ jobs: run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-arm64.zip - name: Upload to release if: github.event_name == 'release' + shell: bash env: GH_TOKEN: ${{ github.token }} TAG: ${{ github.event.release.tag_name }} From d6dea13a6f6ea6b9fe3a15d363a6674e58c4fabe Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sat, 4 Jul 2026 14:37:24 +0300 Subject: [PATCH 39/41] Fix zip name in win32 build action --- .github/workflows/build-win32.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-win32.yml b/.github/workflows/build-win32.yml index 19edbfd..15c5f38 100644 --- a/.github/workflows/build-win32.yml +++ b/.github/workflows/build-win32.yml @@ -95,7 +95,7 @@ jobs: - name: Get artifact uses: actions/upload-artifact@v7 with: - name: "3proxy-${{ env.RELEASE }}" + name: "3proxy-${{ env.RELEASE }}-x86" path: dist/ - name: Create zip if: github.event_name == 'release' From de5acb2abd4463346f7da581dccb505014ee3229 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Mon, 6 Jul 2026 11:41:12 +0300 Subject: [PATCH 40/41] Do not use getrandom for glibc < 2.25 --- src/common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common.c b/src/common.c index 9b251a2..3444dcd 100644 --- a/src/common.c +++ b/src/common.c @@ -17,6 +17,8 @@ char * copyright = COPYRIGHT; # define MYRAND_ARC4RANDOM 1 #elif defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 36))) # define MYRAND_ARC4RANDOM 1 +#elif defined(__GLIBC__) && ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 25))) +# define MYRAND_FALLBACK 1 #elif defined(__linux__) # define MYRAND_GETRANDOM 1 # include From b59c044663104d1df9cfc3317345af59e0ae850d Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Fri, 10 Jul 2026 10:53:58 +0300 Subject: [PATCH 41/41] Update CMakeLists.txt --- CMakeLists.txt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index db41fe4..8ca40e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -661,16 +661,18 @@ foreach(PROXY_NAME proxy socks pop3p smtpp ftppr tcppm udppm tlspr) endforeach() # Install plugins -file(GLOB PLUGINFILES "${PLUGIN_OUTPUT_DIR}/*${PLUGIN_SUFFIX}") +# Use install(DIRECTORY ... FILES_MATCHING) so the glob resolves at install +# time, after plugin targets have been built. A configure-time file(GLOB) +# would run before any plugin exists and install nothing. if(WIN32) - install(FILES - ${PLUGINFILES} + install(DIRECTORY ${PLUGIN_OUTPUT_DIR}/ DESTINATION ${CMAKE_INSTALL_BINDIR} + FILES_MATCHING PATTERN "*${PLUGIN_SUFFIX}" ) else() - install(FILES - ${PLUGINFILES} + install(DIRECTORY ${PLUGIN_OUTPUT_DIR}/ DESTINATION ${CMAKE_INSTALL_LIBDIR}/3proxy + FILES_MATCHING PATTERN "*${PLUGIN_SUFFIX}" ) endif()