From dc83562700eccd86e8a5f6bd3bfda0e22ca978e4 Mon Sep 17 00:00:00 2001 From: Vladimir Dubrovin <3proxy@3proxy.ru> Date: Sun, 5 Apr 2026 12:46:57 +0300 Subject: [PATCH] Use syslog for non-chroot configuration, support MacOS launchd --- CMakeLists.txt | 44 ++++++++++-- README | 53 ++++++++++++-- doc/html/howtoe.html | 46 ++++++++++++ doc/html/howtor.html | 43 ++++++++++++ scripts/3proxy.cfg | 4 +- scripts/3proxy.service.in | 4 ++ scripts/3proxy.tmpfiles.in | 2 +- scripts/init.d/3proxy.in | 109 +++++++++++++++++++++++++++++ scripts/org.3proxy.3proxy.plist.in | 35 +++++++++ scripts/postinstall.sh | 45 ++++++++++++ scripts/rc.d/3proxy.in | 2 + 11 files changed, 376 insertions(+), 11 deletions(-) create mode 100644 scripts/init.d/3proxy.in create mode 100644 scripts/org.3proxy.3proxy.plist.in create mode 100644 scripts/postinstall.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index efcaba8..9d9dc64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -509,10 +509,22 @@ if(NOT WIN32) install(FILES scripts/add3proxyuser.sh DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() -# Install service files (systemd, init.d, or rc.d) +# Install service files (systemd, launchd, init.d, or rc.d) if(NOT WIN32) - if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD|Darwin|OpenBSD|NetBSD") - # BSD/macOS - install rc.d script + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + # macOS - install launchd plist + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/scripts/org.3proxy.3proxy.plist.in + ${CMAKE_CURRENT_BINARY_DIR}/org.3proxy.3proxy.plist + @ONLY + ) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.3proxy.3proxy.plist + DESTINATION /Library/LaunchDaemons + ) + + message(STATUS " launchd: YES (/Library/LaunchDaemons)") + elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD|OpenBSD|NetBSD") + # BSD - install rc.d script set(RCD_DIR "/usr/local/etc/rc.d") configure_file( @@ -566,7 +578,12 @@ if(NOT WIN32) message(STATUS " systemd: YES (${SYSTEMD_UNIT_DIR})") else() # No systemd - install init.d script - install(FILES scripts/init.d/3proxy.sh + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/scripts/init.d/3proxy.in + ${CMAKE_CURRENT_BINARY_DIR}/3proxy.init + @ONLY + ) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/3proxy.init DESTINATION /etc/init.d RENAME 3proxy PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE @@ -576,7 +593,12 @@ if(NOT WIN32) endif() else() # Other Unix - install init.d script - install(FILES scripts/init.d/3proxy.sh + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/scripts/init.d/3proxy.in + ${CMAKE_CURRENT_BINARY_DIR}/3proxy.init + @ONLY + ) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/3proxy.init DESTINATION /etc/init.d RENAME 3proxy PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE @@ -584,6 +606,18 @@ if(NOT WIN32) message(STATUS " init.d: YES (/etc/init.d)") endif() + + # Create proxy user and group during installation + install(FILES scripts/postinstall.sh + DESTINATION ${CMAKE_INSTALL_BINDIR} + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + ) + install(CODE " + execute_process( + COMMAND ${CMAKE_INSTALL_FULL_BINDIR}/postinstall.sh + RESULT_VARIABLE POSTINSTALL_RESULT + ) + ") endif() # Install man pages diff --git a/README b/README index 84e2117..4a813a8 100644 --- a/README +++ b/README @@ -21,10 +21,10 @@ Devel branch - 3proxy 10 (don't use it) * Windows installation -3proxy --install +3proxy [path_to_config_file] --install installs and starts proxy as Windows service - (config file should be located in the same directory) + (config file should be located in the same directory or may be optionally specified) 3proxy --remove @@ -33,13 +33,14 @@ Devel branch - 3proxy 10 (don't use it) * To build in Linux -install git and build-essential packages, use - +With Makefile: +
 git clone https://github.com/z3apa3a/3proxy
 cd 3proxy
 ln -s Makefile.Linux Makefile
 make
 sudo make install
+
Default configuration (for Linux/Unix): 3proxy uses 2 configuration files: @@ -58,15 +59,59 @@ usage: /etc/3proxy/conf/add3proxyuser.sh username password [day_limit] [bandwidt or modify /etc/3proxy/conf/ files directly. + +With CMake: +
+git clone https://github.com/z3apa3a/3proxy
+cd 3proxy
+mkdir build && cd build
+cmake ..
+cmake --build .
+sudo cmake --install .
+
+ +CMake does not use chroot configuration, config file is /etc/3proxy/3proxy.cfg + * For MacOS X / FreeBSD / *BSD +With Makefile: +
 git clone https://github.com/z3apa3a/3proxy
 cd 3proxy
 ln -s Makefile.FreeBSD Makefile
 make
+
(binaries are in bin/ directory) +With CMake (recommended): +
+git clone https://github.com/z3apa3a/3proxy
+cd 3proxy
+mkdir build && cd build
+cmake ..
+cmake --build .
+sudo cmake --install .
+
+ +This installs binaries to /usr/local/bin/, configuration to /etc/3proxy/, +plugins to /usr/local/lib/3proxy/, rc scripts to rc.d for BSD and launchd plist to /Library/LaunchDaemons/ for MacOS. + +Service management on macOS: +
+# Load and start service
+sudo launchctl load /Library/LaunchDaemons/org.3proxy.3proxy.plist
+
+# Stop service
+sudo launchctl stop org.3proxy.3proxy
+
+# Start service
+sudo launchctl start org.3proxy.3proxy
+
+# Unload and disable service
+sudo launchctl unload /Library/LaunchDaemons/org.3proxy.3proxy.plist
+
+ Features: 1. General + IPv6 support for incoming and outgoing connection, diff --git a/doc/html/howtoe.html b/doc/html/howtoe.html index 60c9358..cbeb0e6 100644 --- a/doc/html/howtoe.html +++ b/doc/html/howtoe.html @@ -12,6 +12,7 @@
  • Server configuration @@ -182,6 +183,51 @@ Add 3proxy to the system startup scripts or use systemd: sudo systemctl enable 3proxy sudo systemctl start 3proxy +

    +
  • How to install/remove 3proxy under macOS +

    +Using CMake (recommended): +

    +mkdir build && cd build
    +cmake ..
    +cmake --build .
    +sudo cmake --install .
    +
    +This installs: + +

    +

    +Using Makefile: +

    +ln -sf Makefile.FreeBSD Makefile
    +make
    +sudo make install
    +
    +This installs binaries to /usr/local/3proxy/bin/ and configuration to /usr/local/etc/3proxy/. +

    +

    +Service management with launchd: +
    After installation via cmake, the service can be managed with launchctl: +

    +# Load and start the service
    +sudo launchctl load /Library/LaunchDaemons/org.3proxy.3proxy.plist
    +
    +# Stop the service
    +sudo launchctl stop org.3proxy.3proxy
    +
    +# Start the service
    +sudo launchctl start org.3proxy.3proxy
    +
    +# Unload and disable the service
    +sudo launchctl unload /Library/LaunchDaemons/org.3proxy.3proxy.plist
    +
    +The service runs as user proxy (created during installation). +Configuration file: /etc/3proxy/3proxy.cfg

  • How to use 3proxy with Docker

    diff --git a/doc/html/howtor.html b/doc/html/howtor.html index 1be2b14..6433c6b 100644 --- a/doc/html/howtor.html +++ b/doc/html/howtor.html @@ -12,6 +12,7 @@

  • Конфигурация сервера @@ -178,6 +179,48 @@ sudo systemctl enable 3proxy sudo systemctl start 3proxy

    +
  • Как установить/удалить 3proxy под macOS +

    + С помощью CMake (рекомендуется): +

    +  mkdir build && cd build
    +  cmake ..
    +  cmake --build .
    +  sudo cmake --install .
    + Это установит: + +

    +

    + С помощью Makefile: +

    +  ln -sf Makefile.FreeBSD Makefile
    +  make
    +  sudo make install
    + Это установит исполняемые файлы в /usr/local/3proxy/bin/ и конфигурацию в /usr/local/etc/3proxy/. +

    +

    + Управление службой через launchd: +
    После установки через cmake службой можно управлять с помощью launchctl: +

    +  # Загрузить и запустить службу
    +  sudo launchctl load /Library/LaunchDaemons/org.3proxy.3proxy.plist
    +
    +  # Остановить службу
    +  sudo launchctl stop org.3proxy.3proxy
    +
    +  # Запустить службу
    +  sudo launchctl start org.3proxy.3proxy
    +
    +  # Выгрузить и отключить службу
    +  sudo launchctl unload /Library/LaunchDaemons/org.3proxy.3proxy.plist
    + Служба запускается от имени пользователя proxy (создаётся при установке). + Файл конфигурации: /etc/3proxy/3proxy.cfg +

  • Как использовать 3proxy с Docker

    Использование готовых образов из GitHub Container Registry: diff --git a/scripts/3proxy.cfg b/scripts/3proxy.cfg index 74b6342..660467b 100644 --- a/scripts/3proxy.cfg +++ b/scripts/3proxy.cfg @@ -1,2 +1,4 @@ #!/usr/local/bin/3proxy -#path to plugins: \ No newline at end of file + +#use standard syslog logging +log @3proxy diff --git a/scripts/3proxy.service.in b/scripts/3proxy.service.in index 52a73b2..917e088 100644 --- a/scripts/3proxy.service.in +++ b/scripts/3proxy.service.in @@ -4,6 +4,9 @@ Documentation=man:3proxy(1) After=network.target [Service] +Type=simple +User=proxy +Group=proxy Environment=CONFIGFILE=/etc/3proxy/3proxy.cfg ExecStart=@CMAKE_INSTALL_FULL_BINDIR@/3proxy ${CONFIGFILE} ExecReload=/bin/kill -SIGUSR1 $MAINPID @@ -13,6 +16,7 @@ RestartSec=60s LimitNOFILE=65536 LimitNPROC=32768 RuntimeDirectory=3proxy +RuntimeDirectoryMode=0755 [Install] WantedBy=multi-user.target diff --git a/scripts/3proxy.tmpfiles.in b/scripts/3proxy.tmpfiles.in index a2f7ed4..a021fc3 100644 --- a/scripts/3proxy.tmpfiles.in +++ b/scripts/3proxy.tmpfiles.in @@ -1,3 +1,3 @@ # tmpfiles.d configuration for 3proxy # This creates the runtime directory for 3proxy -d /run/3proxy 0755 root root - +d /run/3proxy 0755 proxy proxy - diff --git a/scripts/init.d/3proxy.in b/scripts/init.d/3proxy.in new file mode 100644 index 0000000..494ec08 --- /dev/null +++ b/scripts/init.d/3proxy.in @@ -0,0 +1,109 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: 3proxy +# Required-Start: $network $local_fs +# Required-Stop: $network $local_fs +# Should-Start: +# Should-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start/stop 3proxy +# Description: Start/stop 3proxy, tiny proxy server +### END INIT INFO +# chkconfig: 2345 20 80 +# description: 3proxy tiny proxy server + +DAEMON=@CMAKE_INSTALL_FULL_BINDIR@/3proxy +CONFIGFILE=/etc/3proxy/3proxy.cfg +PIDFILE=/var/run/3proxy/3proxy.pid +USER=proxy +GROUP=proxy + +# Source function library if available +if [ -f /etc/init.d/functions ]; then + . /etc/init.d/functions +fi + +case "$1" in + start) + echo -n "Starting 3Proxy: " + + if [ ! -d /var/run/3proxy ]; then + mkdir -p /var/run/3proxy + chown $USER:$GROUP /var/run/3proxy 2>/dev/null || true + fi + + if command -v start-stop-daemon >/dev/null 2>&1; then + # Debian/Ubuntu style + start-stop-daemon --start --quiet --pidfile $PIDFILE \ + --chuid $USER:$GROUP --exec $DAEMON -- $CONFIGFILE + elif [ -f /etc/init.d/functions ]; then + # RedHat/CentOS style + daemon --user=$USER $DAEMON $CONFIGFILE + else + # Fallback + su -s /bin/sh $USER -c "$DAEMON $CONFIGFILE" + fi + + RETVAL=$? + echo + [ $RETVAL = 0 ] && touch /var/lock/subsys/3proxy + ;; + + stop) + echo -n "Stopping 3Proxy: " + + if command -v start-stop-daemon >/dev/null 2>&1; then + # Debian/Ubuntu style + start-stop-daemon --stop --quiet --pidfile $PIDFILE + elif [ -f /etc/init.d/functions ]; then + # RedHat/CentOS style + killproc -p $PIDFILE $DAEMON + else + # Fallback + if [ -f $PIDFILE ]; then + kill `cat $PIDFILE` 2>/dev/null + else + killall 3proxy 2>/dev/null + fi + fi + + RETVAL=$? + echo + [ $RETVAL = 0 ] && rm -f /var/lock/subsys/3proxy + ;; + + restart|reload) + echo -n "Reloading 3Proxy: " + if [ -f $PIDFILE ]; then + kill -s USR1 `cat $PIDFILE` 2>/dev/null + RETVAL=$? + else + echo "PID file not found, cannot reload" + RETVAL=1 + fi + echo + ;; + + status) + if command -v status >/dev/null 2>&1; then + status -p $PIDFILE $DAEMON + elif [ -f $PIDFILE ]; then + if kill -0 `cat $PIDFILE` 2>/dev/null; then + echo "3proxy is running (pid `cat $PIDFILE`)" + RETVAL=0 + else + echo "3proxy is dead but pid file exists" + RETVAL=1 + fi + else + echo "3proxy is not running" + RETVAL=3 + fi + ;; + + *) + echo "Usage: $0 {start|stop|restart|reload|status}" + exit 1 +esac +exit ${RETVAL:-0} diff --git a/scripts/org.3proxy.3proxy.plist.in b/scripts/org.3proxy.3proxy.plist.in new file mode 100644 index 0000000..1e53129 --- /dev/null +++ b/scripts/org.3proxy.3proxy.plist.in @@ -0,0 +1,35 @@ + + + + + Label + org.3proxy.3proxy + ProgramArguments + + @CMAKE_INSTALL_FULL_BINDIR@/3proxy + /etc/3proxy/3proxy.cfg + + UserName + proxy + GroupName + proxy + RunAtLoad + + KeepAlive + + StandardOutPath + /var/log/3proxy.log + StandardErrorPath + /var/log/3proxy.log + SoftResourceLimits + + NumberOfFiles + 65536 + + HardResourceLimits + + NumberOfFiles + 65536 + + + diff --git a/scripts/postinstall.sh b/scripts/postinstall.sh new file mode 100644 index 0000000..3fbd223 --- /dev/null +++ b/scripts/postinstall.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# Post-install script for 3proxy +# Creates proxy user and group if they don't exist + +set -e + +# Check if user already exists +if id proxy >/dev/null 2>&1; then + echo "User 'proxy' already exists" + exit 0 +fi + +echo "Creating proxy user and group..." + +# Determine which commands are available +if command -v groupadd >/dev/null 2>&1; then + # Linux (shadow-utils) + groupadd -r proxy 2>/dev/null || true + useradd -r -g proxy -d /var/run/3proxy -s /usr/sbin/nologin proxy 2>/dev/null || true +elif command -v addgroup >/dev/null 2>&1; then + # Alpine Linux / BusyBox + addgroup -S proxy 2>/dev/null || true + adduser -S -D -H -G proxy -s /sbin/nologin proxy 2>/dev/null || true +elif command -v pw >/dev/null 2>&1; then + # FreeBSD + pw groupadd proxy 2>/dev/null || true + pw useradd proxy -g proxy -d /var/run/3proxy -s /usr/sbin/nologin 2>/dev/null || true +elif command -v dscl >/dev/null 2>&1; then + # macOS + dscl . create /Groups/proxy 2>/dev/null || true + dscl . create /Users/proxy 2>/dev/null || true + dscl . create /Users/proxy UserShell /usr/bin/false 2>/dev/null || true + dscl . create /Users/proxy NFSHomeDirectory /var/run/3proxy 2>/dev/null || true +else + echo "Warning: Could not create proxy user - no suitable user management tool found" + exit 0 +fi + +if id proxy >/dev/null 2>&1; then + echo "User 'proxy' created successfully" +else + echo "Warning: Failed to create user 'proxy'" +fi + +exit 0 diff --git a/scripts/rc.d/3proxy.in b/scripts/rc.d/3proxy.in index c3690ac..7d77e0f 100644 --- a/scripts/rc.d/3proxy.in +++ b/scripts/rc.d/3proxy.in @@ -13,6 +13,7 @@ command="@CMAKE_INSTALL_FULL_BINDIR@/3proxy" pidfile="/var/run/3proxy/${name}.pid" command_args="${3proxy_config:-/etc/3proxy/3proxy.cfg}" required_files="${3proxy_config:-/etc/3proxy/3proxy.cfg}" +command_user="proxy:proxy" start_precmd="3proxy_precmd" @@ -20,6 +21,7 @@ start_precmd="3proxy_precmd" { if [ ! -d /var/run/3proxy ]; then mkdir -p /var/run/3proxy + chown proxy:proxy /var/run/3proxy fi }