|
1.0.3
! Fix: RADIUS authentication: the reply digest copied the shared secret right after the received bytes, so a reply of 4100 bytes with a secret of 17 or more characters wrote up to 47 bytes of it past the reply buffer on the stack, before the reply was authenticated; the digest is hashed over the reply and the secret in place now, with nothing written past the reply, and a reply is taken only from the address and port of the server the request went to, with the request's identifier and length, which was never checked before
! Fix: the PTR answer of a name server could write past the answer buffer on the stack: the label walk ran to the end of the whole message instead of the end of the record's data and could take a compression pointer for a label length (an answer of 3841 bytes or more reached past the buffer itself); the walk now stops at the end of the record's data, and a compressed, empty or truncated name is not accepted
! Fix: every connection matching a pcre: (or regex:) rule matched on the one match data block of the rule, which pcre2_match() writes into: two connections matching at the same time raced and corrupted memory, bringing the process down under load; a connection now makes a match data block of its own
! Fix: TLS: a read which could only be done once a write was, or a write once a read was (a TLS 1.3 key update answered while the socket cannot take more, for example), ended the connection with an error; each TLS socket remembers now what its pending read and write wait for, and the poll of the TLS layer waits for that
! Fix: Windows: a TLS read or write which wanted the socket again was not seen as one and dropped the connection with an unrelated error: the C library's errno was set where the socket error is read
! Fix: a client of a connect back (-R) service stayed in accept() for the connection another client of the same service took, until the next one came, past its time out and through a configuration reload; the connect back socket is non-blocking now, and an accept() with nothing to take does not count as one of the client's tries
! Fix: ftppr: the answer of a server which logs in on USER alone (230, as anonymous FTP often does) or refuses the login was read but never handed to the client, which was left waiting for the answer to its PASS until the time out (#1284)
! Fix: plugins: StringsPlugin, cutting a string table line at its end, wrote NULs past the line, into what the buffer kept of longer lines read before or past its end; FilePlugin passed the TLS state of the connection where the client's parameters were expected, so sending a string table over a TLS connection read a TLS state as a clientparam
+ -B (for TCP services) splits the TLS ClientHello passed through tlspr in the middle of the server name (SNI), so DPI systems which do not reassemble it do not see the host name; TCP_NODELAY, set by default, must not be turned off, or the kernel may join the segments again; -s keeps the same effect where -s is not splice (#1283)
+ 3proxy --help (and the usage message of a bad invocation) lists what the build was made with: TLS and its backend, RADIUS, PCRE, IPv6, UNIX sockets, the built-in HTTP server, transparency, ODBC and the optional proxy services
+ An outgoing connection bound to an external address is bound with IP_BIND_ADDRESS_NO_PORT on Linux 4.2 and later: the port is chosen by connect() for the pair with the destination, so ports in use towards other destinations or closing in TIME_WAIT do not run the ephemeral range out; bind() no longer failed with result 12 or searched long for a port under many connections
1.0.2
! Fix: dnspr relayed to the client whatever came first to the socket it asked the name server from, from any address and under any id, so a forged answer could be passed on; the query now goes out under a random id, and only an answer from the name server asked, with that id and the same question, is relayed
! Fix: a client sending a part of a TLS record and then nothing kept a thread taking all of a CPU, and the read never timed out
! Fix: without -Ne, the reply to SOCKS CONNECT and BIND gave the address of the client's connection to the proxy instead of the socket towards the destination: a BIND client was told the proxy's own port and the peer could never reach it (since 0.9.6)
! Fix: a client which shut down its sending side (half-close) could get the answer cut short, megabytes short with large answers; likewise an upload after the server half-closed
! Fix: with chroot every local time was UTC and every syslog message was lost: the time zone is loaded and syslog connected before chroot; the chroot entry of 3proxy.cfg(5) lists what PAM, LDAP and ODBC still need inside the chroot
! Fix: the HTTP proxy closed the server connection of a kept-alive client and opened another one when only the request method changed (a POST after a GET to the same host)
! Fix: the last ssl_client_mode in the configuration applied to every service, and a reload changed it for the services still running
! Fix: memory leaks: on every refused configuration reload, on every failed TLS handshake, the server CA paths of every TLS service, compiled pcre: / regex: host names of access rules and patterns of httpsrv rules
! Fix: Unix sockets: on Linux a proxy listening on a Unix socket relayed only the first bytes of an answer (result 95); an abstract socket (unix:@NAME) was bound under a name padded with zeros, which clients did not reach; tcppm refused port 0 for a unix: target, as given in the manual's example; on a reload the socket file of a listening service was removed
! Fix: SIGPIPE could kill 3proxy when a client was gone while services were starting, and standalone services (proxy, socks, ...) at any time; sends use MSG_NOSIGNAL where the system has it
! Fix: TLS MitM failed for every connection with wolfSSL built with WOLFSSL_QT (wolfSSL 5.9.1 of Ubuntu 26.04): the source certificate's serial number could not be copied; a serial number made from the hash of the source certificate is used then
! Fix: Windows: closing a connection could leave its socket open (SO_LINGER on a non-blocking socket) or reset it while the peer still sent, so the end of an answer could be lost
! Fix: httpsrv: the body of a request answered without being read (for example when authentication is required) was read as the next request; a client still sending when a connection without keep-alive closed could get a reset instead of the answer
! Fix: httpsrv on Windows: UNC paths (\\server\share) did not work
! Fix: httpsrv and admin services and their clients were named ZOMBIE on the admin services page, in %N of logs and in RADIUS
! Fix: the Watcom (lite) build did not compile, 1.0.1 had no binaries for it
+ -s (splice) per direction: -s1 splices what the server sends (downloads), -s2 what the client sends (uploads), -s3 both; -s alone splices only where it pays (large bodies, long streams); pipes are kept with the connection for its next requests. splice() is built by default on Linux again and is used only by services given -s
+ Socket options (-oc, -os, -ol, -or, -oR) take NAME=VALUE; NAME=0 turns an option off, also one set by default; an unknown name or a value which is not a number is an error
+ The HTTP proxy frees its 64 KB request buffer while a CONNECT tunnel relays data and while a kept-alive connection waits for its next request: 2000 tunnels take 213 MB instead of 339 MB
+ TLS records are read ahead with OpenSSL 1.1.0 and later: decrypting takes 9-14% less CPU
+ Faster service stop and configuration reload, no fixed delays; a connection waiting for a free maxconn slot gets it at once
- TCP_NODELAY is set by default on proxy-to-client and proxy-to-server sockets; -ocTCP_NODELAY=0 / -osTCP_NODELAY=0 turns it off
- The HTTP proxy fetches ftp:// URLs only when the service is given the new -Xftp option (in a build with FTP=true)
1.0.1
! Fix: crash (segmentation fault) on configuration reload (SIGUSR1) on a busy server: a closing session could still use its service after the reload had freed it; the race existed since 0.9.7, the 5 second linger added in 0.9.9 made it much more likely (#1278)
! Fix: -Di and -De (bind to interface) were not applied to SOCKSv5 UDP ASSOCIATE and BIND sockets, the FTP proxy data connection and connect back (#1277)
! Fix: SOCKSv5 UDP ASSOCIATE over IPv6: the source address of a datagram was truncated and the reply was sent to the wrong address (#1279)
! Fix: SOCKSv5 UDP ASSOCIATE: an access rule with host names matched any datagram sent to a literal address; the address is used as the host name now, as it is for TCP requests
! Fix: a request rewritten with pcre_rewrite was only logged and was sent unchanged to the server on a direct connection; the rewritten path and query are what the server receives now
! Fix: buffer could be insufficient for the headers the HTTP proxy adds after a pcre_rewrite had grown the request
! Fix: heap buffer overflow in pcre_rewrite: a $N reference to a group which did not match was written out as its digits, which the space allocated for the result did not count
! Fix: pcre_extend did nothing, the rules it appended were never consulted; the manual described an argument the command does not take
! Fix: certificates generated for TLS MitM (openssl) carried no subject and authority key identifiers and were refused by strict verifiers, including macOS clients, OpenSSL with x509_strict and Python 3.13
! Fix: null pointer dereference in ftppr on PASS without USER and in smtpp on a user name without a host
! Fix: no service started with wolfSSL on glibc: the default thread stack was too small for wolfSSL thread-local storage, pthread_create() failed and the failure was not reported
! Fix: dnspr did not work on Windows; Windows builds answer UDP from a socket of their own again
+ Built-in HTTP server: httpsrv service with http rules to serve files (cached or with sendfile / TransmitFile), redirects, rewrites, fixed replies and proxypass to forward requests as the proxy does, so one port can serve both a site and a proxy; admin is httpsrv with the administration pages
+ Host names in access rules may be regular expressions with a pcre: (or regex:) prefix
+ transparent / notransparent commands: transparent proxying is built in (netfilter on Linux, pf on BSD, socket for divert-to and ipfw fwd), TransparentPlugin is removed and a configuration loading it keeps working
+ parent: weight may be written as a fraction (.5) or a percentage (50%); weight 0 is a fallback parent used only when every weighted parent of its group has failed; a failed parent is left out of the next attempt of the same connection
+ parent extport / intport: range of local ports for outgoing connections and for sockets facing the client (UDP ASSOCIATE, FTP data)
+ A parent given by host name is resolved for each connection when nserver is used, instead of once on configuration load
+ $$ in the configuration stands for a single dollar sign, a dollar inside quotes is ordinary text
+ OpenWrt package (procd init script, UCI configuration) and OpenWrt builds for mipsel_24kc, mips_24kc, arm_cortex-a7_neon-vfpv4 and aarch64_cortex-a53
- pop3p, imapp, smtpp and ftppr are not in a default build: build with MAILPROXY=true and FTP=true (CMake: 3PROXY_USE_MAILPROXY, 3PROXY_USE_FTP); without them the mail proxies run as tlspr negotiating STARTTLS, and ftppr refuses clients
- FTP over HTTP proxy (ftp:// URLs) is not in a default build either and has to be enabled explicitly: build with FTP=true (CMake: 3PROXY_USE_FTP), without it the HTTP proxy does not fetch ftp:// URLs
- Windows binaries are no longer signed with a self-signed Authenticode certificate, it gave no trust and triggered antivirus false positives
1.0.0
No changes in 3proxy code, this release only changes how packages are built, signed and published.
! Fix: TLS, PCRE2 and PAM support was silently left out when 3proxy was built on a system whose /bin/sh is not dash, which is every RPM based distribution and macOS; the library checks built their test program with echo and escape sequences, which only dash expands, so every check failed and the features were dropped without a diagnostic
! Fix: rpm packages were built on Ubuntu and required glibc 2.38, libssl.so.3 and libpcre2-8, which no RPM based distribution provides, so they could not be installed anywhere; they are built against AlmaLinux 8, 9 and 10 now and carry an el8, el9 or el10 tag, covering RHEL, AlmaLinux, Rocky and CentOS Stream of the same version
! Fix: the rpm package depended on its own interpreter, /bin/3proxy, taken from the first line of the installed configuration file, and could not be installed on el9 or el10 because rpm resolves that dependency to /usr/bin/3proxy
! Fix: deb packages required glibc 2.38 and libssl3t64 and installed on Ubuntu 24.04 and newer only; they are built against Ubuntu 22.04 now and install on Ubuntu 22.04 and later as well as Debian 12 and later
+ Signed apt and dnf repositories are published at https://3proxy.org/repo/ in two channels: current, built from the master branch, and lts, built from the 0.9 branch; packages and repository metadata are both signed
+ Release binaries are published with SHA256 checksums, an OpenPGP signature and a GitHub build provenance attestation; docker images are signed and attested as well
+ The release signing key is an RSA-4096 key published as 3proxy-release-key.asc in the repository; rpm 4.14 and earlier can not import an Ed25519 key at all, which would leave RHEL 8 and its derivatives unable to verify anything
+ Packages are reproducible: rebuilding a release produces byte identical deb and rpm files, every timestamp is derived from the build date recorded for the release
- 32-bit ARM (armhf) is published as a deb package only, Enterprise Linux has no 32-bit ARM build
Branches: 1.0 (master) is the current stable branch, recommended for every use and for updating from any older version;
0.9 (0.9.9.x) is the long term support branch, which gets bug fixes; 1.1 (devel) is the development branch, not for production;
2.0 (experimental) is the experimental one.
Download: http://3proxy.ru/download/
|