Extract source code files from 3proxy.tgz (with WinZip or another utility) or use git.
nmake /f Makefile.msvcBinaries will be placed in the
bin/ directory.
CMake provides a cross-platform build system. It works on Windows (MSVC, MinGW), Linux, macOS, and BSD.
Basic build steps:
mkdir build cd build cmake .. cmake --build .On Windows with Visual Studio, you can also generate a solution file:
cmake -G "Visual Studio 17 2022" -A x64 .. cmake --build . --config ReleaseOptional features can be controlled with cmake options:
cmake -D3PROXY_USE_OPENSSL=ON -D3PROXY_USE_PCRE2=ON ..Available options: 3PROXY_USE_OPENSSL, 3PROXY_USE_PCRE2, 3PROXY_USE_PAM, 3PROXY_USE_ODBC.
build/bin/ directory.
For Linux, use:
ln -sf Makefile.Linux Makefile makeFor FreeBSD, use:
ln -sf Makefile.FreeBSD Makefile makeFor other Unix-like systems, use Makefile.unix. On BSD-derived systems, make sure to use GNU make; sometimes it's called gmake instead of make.
bin/ directory.
Unpack 3proxy.zip to any directory, for example c:\Program Files\3proxy. If needed, create a directory for storing log files, ODBC sources, etc. Create 3proxy.cfg in the 3proxy installation directory (see Server configuration). Now, start a command prompt (cmd.exe). Change to the 3proxy installation directory and run 3proxy.exe --install:
D:\>C: C:\>cd C:\Program Files\3proxy C:\Program Files\3proxy>3proxy.exe --installNow, you should have the 3proxy service installed and running. If the service is not started, run 3proxy.exe manually and correct all errors.
To remove 3proxy, run 3proxy --remove:
D:\>C: C:\>cd C:\Program Files\3proxy C:\Program Files\3proxy>net stop 3proxy C:\Program Files\3proxy>3proxy.exe --removeNow you can simply remove the 3proxy installation directory.
Using Makefile:
Compile 3proxy (see Compilation) then run:
sudo make installThis installs binaries to
/usr/local/3proxy/sbin/, configuration to /etc/3proxy/,
and sets up chroot directories. Default configuration file is /etc/3proxy/3proxy.cfg.
Using CMake:
mkdir build && cd build cmake .. cmake --build . sudo cmake --install .
Using pre-built packages from GitHub:
Download .deb or .rpm packages from GitHub Releases.
For Debian/Ubuntu:
sudo dpkg -i 3proxy_*.debFor RHEL/CentOS/Fedora:
sudo rpm -i 3proxy-*.rpm
Add 3proxy to the system startup scripts or use systemd:
sudo systemctl enable 3proxy sudo systemctl start 3proxy
Using CMake (recommended):
mkdir build && cd build cmake .. cmake --build . sudo cmake --install .This installs:
/usr/local/bin//etc/3proxy//usr/local/lib/3proxy//Library/LaunchDaemons/org.3proxy.3proxy.plistUsing Makefile:
ln -sf Makefile.FreeBSD Makefile make sudo make installThis 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.plistThe service runs as user
proxy (created during installation).
Configuration file: /etc/3proxy/3proxy.cfg
Using pre-built images from GitHub Container Registry:
docker pull ghcr.io/3proxy/3proxy:latest
Building Docker images:
Two Dockerfiles are provided:
Dockerfile.minimal - minimal static build, no plugins, configuration from stdin:
docker build -f Dockerfile.minimal -t 3proxy.minimal . docker run -i -p 3129:3129 --name 3proxy 3proxy.minimalThen enter configuration followed by "end" command.
Dockerfile.full - full build with plugins (SSL, PCRE, Transparent):
docker build -f Dockerfile.full -t 3proxy.full . docker run -p 3129:3129 -v /path/to/config:/usr/local/3proxy/conf 3proxy.fullThe configuration file must be placed at
/path/to/config/3proxy.cfg.
By default, 3proxy runs in chroot environment with uid/gid 65535. Use nserver in config for DNS resolution in chroot.
For non-chroot execution, mount config to /etc/3proxy.
A valid configuration file is required.
The most probable reasons for non-working limitations: 'auth none' or no auth is used. For any ACL-based feature, one of 'iponly', 'nbname', or 'strong' auth is required. The sequence of commands may be invalid. Commands are executed one-by-one, and 'proxy', 'tcppm', 'socks', or another service commands must follow a valid configuration. An invalid sequence of ACLs. The first matching ACL is used (except for internal redirections, see below). If an ACL contains at least one record, the last record is assumed to be 'deny *'.
Possible reasons for 3proxy starting manually but failing to start as a service:
3proxy --install full_path_to_configuration_file
How to understand internal and external
Both internal and external IPs are IPs of the host running 3proxy itself. This configuration option is useful in situations where 3proxy is running on a border host with 2 (or more) connections: e.g., LAN and WAN with different IPs
LAN connection +-------------+ Internet connection
LAN <-------------->| 3proxy host |<-------------------> INTERNET
^+-------------+^
| |
Internal IP External IP
If 3proxy is used on a host with a single connection, both internal and
external are usually the same IP.
Check that you are using a system DSN. Check that the SQL request is valid. The best way to check is to use file or stdout logging, get the SQL request from the log file or console, and execute this request manually. Under Unix, you may also want to adjust the 'stacksize' parameter.
The proxy cannot access a destination directly over IPv6 if the client requests an IPv4 address. To access an IPv6 destination, either an IPv6 address or a hostname must be used in the request. The best solution is to enable the option to resolve hostnames via the proxy on the client side.
The default stacksize may be insufficient if some non-default plugins are used (e.g., PAM and ODBC on Linux) or if compiled on some platforms with invalid system-defined values (a few versions of FreeBSD on amd64). The problem can be resolved with the 'stacksize' command or '-S' option starting with 3proxy 0.8.4.
A server configuration example, 3proxy.cfg.sample, is included in every 3proxy distribution.
3proxy can log to stdout, a file, an ODBC datasource, or syslog (Unix/Linux/Cygwin only). To use ODBC under Unix/Linux, you must compile 3proxy with Unix ODBC libraries; see Compilation. You can control logging from 3proxy.cfg for all services, or you can control logging for an individual service. For example, /usr/local/sbin/socks -l/var/log/socks.log starts a SOCKS proxy with logging to a file. For the universal proxy (3proxy), log file rotation and archiving are supported. The log type is defined with the "log" configuration file command or with the -l switch on individual service invocation. log or -l with no argument is stdout logging.
log filenameand
-lfilenamespecify a filename for logging.
log @identand
-l@identspecify an ident for syslog logging. If the filename within the "log" command contains '%' characters, it is processed as a format specifier (see "logformat"). E.g., log c:\3proxy\logs\%y%m%d.log D creates a file like c:\3proxy\logs\060729.log; the date is generated based on local time.
log &connstring;specifies an ODBC connection string; connstring is in the format datasource,username,password (the last two are optional if the datasource does not require or already has authentication information). Also, you must specify logformat to build the SQL query to insert a record into the log; see How to set up logging format
Rotation and archiving may be set up with log, rotate, and archiver commands.
log filename LOGTYPEsets the rotation type. LOGTYPE may be:
rotate NUMBERspecifies the number of files in rotation (i.e., how many files to keep).
archiver EXT COMMAND PARAMETERSSets an external archiver. EXT is the extension of archived files (for example, zip, gz, Z, rar, etc.). COMMAND and PARAMETERS are the command to execute and its command-line parameters. The original file is not deleted by 3proxy; this work is left for the archiver. You can pass the original filename to the archiver with the %F macro and the archive filename with %A. Examples are located in 3proxy.cfg.sample
Since version 0.3, the log format may be set with the "logformat" command. The first symbol of the log format specifies the format of the date and time and should be L (LOCAL) or G (GMT - Greenwich Meridian Time). The format string may contain some macro substitutions:
logformat "L%t.%. %N.%p %E %U %C:%c %R:%r %O %I %h %T"generates something like
1042454727.0296 SOCK4.1080 000 3APA3A 127.0.0.1:4739 195.122.226.28:4739 505 18735 1 GET http://3proxy.org/ HTTP/1.1
(no line breaks)
If ODBC is used, logformat should specify the SQL command to insert a record into the log, for example:
logformat "-\'+_GINSERT INTO proxystat VALUES (%t, '%c', '%U', %I)"
Just make the format of 3proxy logs compatible with a format supported by your
favorite log analyzer. Examples of compatible logformats are:
For Squid access.log:
"- +_G%t.%. %D %C TCP_MISS/200 %I %1-1T %2-2T %U DIRECT/%R application/unknown"
or, a more compatible format without %D:"- +_G%t.%. 1 %C TCP_MISS/200 %I %1-1T %2-2T %U DIRECT/%R application/unknown"ISA 2000 proxy WEBEXTD.LOG (fields are TAB-delimited):
"- + L%C %U Unknown Y %Y-%m-%d %H:%M:%S w3proxy 3PROXY - %n %R %r %D %O %I http TCP %1-1T %2-2T - - %E - - -"ISA 2004 proxy WEB.w3c (fields are TAB-delimited):
"- + L%C %U Unknown %Y-%m-%d %H:%M:%S 3PROXY - %n %R %r %D %O %I http %1-1T %2-2T - %E - - Internal External 0x0 Allowed"ISA 2000/2004 firewall FWSEXTD.log (fields are TAB-delimited):
"- + L%C %U unknown:0:0.0 N %Y-%m-%d %H:%M:%S fwsrv 3PROXY - %n %R %r %D %O %I %r TCP Connect - - - %E - - - - -"HTTPD standard log (Apache and others):
"-""+_L%C - %U [%d/%o/%Y:%H:%M:%S %z] ""%T"" %E %I"
or a more compatible format without the error code:"-""+_L%C - %U [%d/%o/%Y:%H:%M:%S %z] ""%T"" 200 %I"
3proxy is distributed in 2 variants: as a set of standalone modules (proxy,
socks, pop3p, tcppm, udppm) and as a universal proxy server. These services are
absolutely independent, and if you use 3proxy, you don't need any of the standalone
modules.
Standalone modules are only configurable via the command line interface, while
3proxy uses a configuration file. Many functions, such as ODBC logging, log
rotation, access control, etc., are only available in 3proxy, not in standalone
proxies.
A standalone module may be started from the command line, for example:
$/sbin/socks -l/var/log/socks.log -i127.0.0.1Starts a SOCKS server bound to localhost IP, port 1080, with logging to /var/log/socks.log. You can get help for any standalone service with the -? command line option.
If 3proxy is used, you should start all services in the 3proxy.cfg file. 3proxy.cfg is executed by 3proxy as a batch file. An example of 3proxy.cfg and command syntax can be found in 3proxy.cfg.sample.
log /var/log/3proxy.log D rotate 30 internal 127.0.0.1 external 192.168.1.1 proxy socks -p3129 pop3pStarts 3 services: HTTP PROXY, SOCKS, and POP3 PROXY. Each listens on the localhost interface with the default port (3128 for HTTP, 1080 for SOCKS, and 110 for POP3P) except socks, which is started with port 3129. All logs are in the file /var/log/3proxy.log (with daily date modification and rotation). The 30 most recent files are stored.
The -i option specifies the internal interface; -p specifies the listening port. No spaces are allowed. To bind the 'proxy' service to port 8080 on interfaces 192.168.1.1 and 192.168.2.1, use:
proxy -p8080 -i192.168.1.1 proxy -p8080 -i192.168.2.1
A: Use one of proxy, connect+, socks4+, or socks5+ as the parent type. 3proxy itself still performs name resolution; it's required, e.g., for ACL matching. So, if no name resolution must be performed by 3proxy itself, add the command
fakeresolveThis command resolves any name to the 127.0.0.2 address.
There is FTP over HTTP (what is called FTP proxy in browsers) and FTP over FTP (what is called FTP proxy in file managers and FTP clients). For browsers, there is no need to start an additional proxy service; 'proxy' supports FTP over HTTP. Configure the 'proxy' port as an FTP proxy. For FTP clients and file managers, use ftppr. The FTP proxy supports both active and passive mode with the client but always uses passive mode with FTP servers.
An SNI proxy can be used to transparently redirect any TLS traffic with an external router or via local redirection rules. It can also be used to extract hostnames from TLS to use in ACLs in combination with SOCKS or HTTP(s) proxy and/or the Transparent plugin. It can also be used to require TLS or mTLS between services. The TLS handshake contains no port information; if tlspr is used as a standalone service, the destination port may be either detected with the Transparent plugin or configured with the -P option (default 443). Note: tlspr does not support user authentication (there are no credentials in the TLS handshake to authenticate against); use ACLs by IP or a parent proxy with authentication if access control is required.
Options:
-P <port> - destination port (default: 443) -c <level> - TLS check level: 0 (default) - allow non-TLS traffic 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) -Ximap | -Xpop3 | -Xsmtp - explicit TLS (STARTTLS) mode: tlspr speaks the plaintext protocol with the client (greeting, STARTTLS command), then upgrades both sides to TLS
Implicit vs explicit TLS:
Implicit TLS means TLS from the first byte of the connection: https (443), imaps (993), SMTP submission secure (submissions) (465). Explicit TLS means the connection starts in plaintext and is upgraded with a STARTTLS/STLS command: imap (143), SMTP submission (587), pop3 (110). tlspr supports both: for implicit TLS the destination host is taken from SNI and the port from -P; for explicit TLS the -X option makes tlspr speak the plaintext protocol phase with the client (greeting, STARTTLS command) before upgrading both sides to TLS. Example:
# https (implicit) tlspr -p443 -P443 -c1 # imaps (implicit) tlspr -p993 -P993 -c1 # submissions (implicit) tlspr -p465 -P465 -c1 # imap STARTTLS (explicit) tlspr -p143 -P143 -Ximap # submission STARTTLS (explicit) tlspr -p587 -P587 -Xsmtp # pop3 STLS (explicit) tlspr -p110 -P110 -Xpop3
Note: for explicit TLS the protocol services smtpp, imapp and pop3p can be used instead of tlspr -X; they also support STARTTLS.
Recommended setup - traffic redirection: the most universal configuration is to redirect TLS traffic (ports 443, 993, 465, 143, 587, 110) to tlspr with external router rules or local redirection (Transparent plugin). The original destination address and port are preserved, no -P or per-port services are required, and both implicit and explicit TLS work with the same installation.
auth iponly allow * tlspr -p1443 -c1
with, for example, iptables:
iptables -t nat -A PREROUTING -p tcp -m multiport --dports 443,993,465 -j REDIRECT --to-port 1443
Alternatively, if clients use dnspr as their DNS resolver, traffic can be redirected via DNS — see How to set up a DNS proxy (dnspr).
SNI Break (DPI Bypass):
tlspr can be used as a parent with the "tls" type to implement SNI splitting for DPI bypass (similar to NoDPI/GoodByeDPI).
The client sends the first part of the TLS ClientHello, tlspr splits it at the SNI extension and sends it in two TCP packets,
which can bypass some DPI systems that look for blocked hostnames in TLS handshakes.
To enable SNI break, use parent ... tls 0.0.0.0 0 and the -s option on the listening service with TCP_NODELAY:
auth iponly allow * parent 1000 tls 0.0.0.0 0 allow * proxy -s -i127.0.0.1 -ocTCP_NODELAY -osTCP_NODELAY -p1443
TCP_NODELAY is required to prevent the kernel from merging the split packets.
Configuration examples:
1. Standalone SNI proxy on port 1443 redirecting to destination port 443:
tlspr -p1443 -P443 -c1
2. Using tlspr as parent in SOCKS to detect destination hostname from TLS (even when client connects by IP):
allow * * * 80 parent 1000 http 0.0.0.0 0 allow * * * * CONNECT parent 1000 tls 0.0.0.0 0 deny * * some.not.allowed.host allow * socks
3. Using tlspr with HTTP proxy for TLS hostname-based ACL:
allow * * * * HTTP_CONNECT parent 1000 tls 0.0.0.0 0 deny * * blocked.example.com allow * proxy
dnspr is a DNS forwarding service. It answers queries from the 3proxy name cache (including static nsrecord entries), forwards other queries to the resolvers configured with nserver, and caches the results if nscache/nscache6 are configured. Options:
-s - simple DNS forwarding: do not use 3proxy resolver / name cache -F<ip> - fake: answer all A (or AAAA) queries with the given IP address. May be given twice - once with an IPv4 and once with an IPv6 address.
dnspr can be used to redirect traffic by hostname, e.g. to point mail clients to a tlspr installation, by adding nsrecord entries for the service hostnames (nscache/nscache6 keep the answers for all other names intact):
nscache 65536 nscache6 65536 dnspr -p53 # google nsrecord smtp.gmail.com 10.0.0.1 nsrecord imap.gmail.com 10.0.0.1 nsrecord pop.gmail.com 10.0.0.1 # mail.ru nsrecord smtp.mail.ru 10.0.0.1 nsrecord imap.mail.ru 10.0.0.1 nsrecord pop.mail.ru 10.0.0.1 # yandex.ru nsrecord smtp.yandex.ru 10.0.0.1 nsrecord imap.yandex.ru 10.0.0.1 nsrecord pop.yandex.ru 10.0.0.1
where 10.0.0.1 is the address tlspr listens on. If every hostname must be redirected, a single fake address can be used instead of individual nsrecords:
nscache 65536 nscache6 65536 dnspr -p53 -F10.0.0.1
Since version 0.9.7, SSL/TLS support is built into 3proxy when compiled with OpenSSL (WITH_SSL). Previously available as SSLPlugin, the functionality is now integrated into the main binary. The plugin line is no longer required. SSL/TLS support can be used to:
Creating an https:// proxy:
To create an https:// proxy, you need a server certificate and key. The certificate must not be self-signed
and should contain Subject Alternative Names (SAN) for the proxy hostname/IP.
ssl_server_cert /etc/3proxy/certs/server.crt ssl_server_key /etc/3proxy/certs/server.key ssl_serv proxy -p3129 ssl_noserv proxy -p3128
This creates an https:// proxy on port 3129 and an http:// proxy on port 3128. Configure clients to use https://proxy-host:3129/ as the proxy URL.
Client certificate authentication (mTLS):
To require clients to authenticate with a certificate, use ssl_server_verify and provide the CA certificate:
ssl_server_cert /etc/3proxy/certs/server.crt ssl_server_key /etc/3proxy/certs/server.key ssl_server_ca_file /etc/3proxy/certs/ca.crt ssl_server_verify ssl_serv proxy -p3129
Only clients with a valid certificate signed by the CA can connect.
MITM for TLS traffic inspection:
To intercept and decrypt TLS traffic, you need a CA certificate to generate spoofed server certificates:
ssl_server_ca_file /etc/3proxy/certs/ca.crt ssl_server_ca_key /etc/3proxy/certs/ca.key ssl_client_verify ssl_client_ca_file /etc/ssl/certs/ca-certificates.crt ssl_mitm proxy -p3128 ssl_nomitm proxy -p3129
The CA certificate must be trusted by clients. ssl_client_verify ensures the real server certificates are validated. Without ssl_client_verify, the proxy is vulnerable to MITM attacks.
TLS client (connect to upstream via TLS):
To connect to upstream servers via TLS with client certificate authentication:
ssl_client_cert /etc/3proxy/certs/client.crt ssl_client_key /etc/3proxy/certs/client.key ssl_client_verify ssl_client_ca_file /etc/ssl/certs/ca-certificates.crt ssl_cli proxy -p3128
Conditional TLS for parent proxy (ssl_client_mode 3):
With ssl_client_mode 3, TLS handshake to parent proxy is performed only if the parent type ends with 's' (secure types). This allows mixing secure and non-secure parent proxies in the same configuration:
ssl_server_cert /etc/3proxy/certs/server.crt ssl_server_key /etc/3proxy/certs/server.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
This creates an HTTPS proxy (ssl_serv) that accepts TLS connections from clients. For parent proxy connections, user1's traffic goes through an https parent with TLS encryption (secure type), 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.
Creating a Certificate Authority (CA):
For MITM or mTLS, you need a CA. Generate a CA private key and certificate:
# Generate CA private key
openssl genrsa -out ca.key 4096
# Extensions that make the certificate usable as a CA
cat > ca.ext << 'EOF'
basicConstraints=critical,CA:TRUE
keyUsage=critical,keyCertSign,cRLSign
subjectKeyIdentifier=hash
EOF
# Generate CA certificate (valid for 10 years)
openssl req -new -nodes -key ca.key \
-subj "/C=US/ST=State/L=City/O=MyOrg/CN=My CA" \
-out ca.csr
openssl x509 -req -in ca.csr -signkey ca.key -sha256 -days 3650 \
-extfile ca.ext -out ca.crt
The extensions are not optional. Without basicConstraints=CA:TRUE and keyCertSign the certificate is not accepted as a CA, and clients report that they cannot get the local issuer certificate. subjectKeyIdentifier is what certificates signed by this CA point back at.
They are given in a file rather than with -addext because LibreSSL, the openssl command on macOS and some BSDs, does not apply -addext the same way OpenSSL does. The form above behaves the same on both.
For MITM, import ca.crt into client browsers/OS as a trusted root CA.
Creating a server certificate for https:// proxy:
The server certificate must have proper Subject Alternative Names (SAN):
# Generate server private key
openssl genrsa -out server.key 2048
# Create a certificate signing request (CSR)
openssl req -new -key server.key \
-subj "/C=US/ST=State/L=City/O=MyOrg/CN=proxy.example.com" \
-out server.csr
# Create extensions file for SAN
cat > server.ext << 'EOF'
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = proxy.example.com
DNS.2 = proxy
IP.1 = 192.168.1.100
EOF
# Sign the certificate with CA
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt -days 365 -sha256 \
-extfile server.ext
# Check it the way a current client will
openssl verify -x509_strict -CAfile ca.crt server.crt
Verify strictly, because that is what the client does. OpenSSL 3 adds the subject and authority key identifiers when it signs and LibreSSL does not, which is why the extensions file asks for them by name. Python has verified strictly since 3.13 and refuses a certificate carrying no authorityKeyIdentifier; other clients are moving the same way.
For a public https:// proxy, use a CA like Let's Encrypt instead of self-signed.
Creating a client certificate for mTLS:
# Generate client private key
openssl genrsa -out client1.key 2048
# Create CSR
openssl req -new -key client1.key \
-subj "/C=US/ST=State/L=City/O=MyOrg/CN=client1" \
-out client1.csr
# Create extensions file
cat > client.ext << 'EOF'
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment
extendedKeyUsage = clientAuth
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
EOF
# Sign with CA
openssl x509 -req -in client1.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out client1.crt -days 365 -sha256 \
-extfile client.ext
# Create PKCS#12 bundle for browser import
openssl pkcs12 -export -out client1.p12 \
-inkey client1.key -in client1.crt -certfile ca.crt
Import client1.p12 into the client browser or OS certificate store.
Quick setup script for development/testing:
#!/bin/sh
# Creates CA, server, and client certificates for SSLPlugin testing
# CA
openssl genrsa -out ca.key 4096
cat > ca.ext << 'EOF'
basicConstraints=critical,CA:TRUE
keyUsage=critical,keyCertSign,cRLSign
subjectKeyIdentifier=hash
EOF
openssl req -new -nodes -key ca.key -subj "/CN=3proxy CA" -out ca.csr
openssl x509 -req -in ca.csr -signkey ca.key -sha256 -days 3650 \
-extfile ca.ext -out ca.crt
# Server
openssl genrsa -out server.key 2048
openssl req -new -key server.key -subj "/CN=localhost" -out server.csr
cat > server.ext << 'EOF'
basicConstraints=CA:FALSE
keyUsage = keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = DNS:localhost,DNS:proxy,IP:127.0.0.1
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
EOF
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt -days 365 -sha256 -extfile server.ext
# Client
openssl genrsa -out client.key 2048
openssl req -new -key client.key -subj "/CN=client" -out client.csr
cat > client.ext << 'EOF'
basicConstraints=CA:FALSE
extendedKeyUsage = clientAuth
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
EOF
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out client.crt -days 365 -sha256 -extfile client.ext
openssl pkcs12 -export -out client.p12 -passout pass: \
-inkey client.key -in client.crt -certfile ca.crt
# Both must pass the checks a current client applies
openssl verify -x509_strict -CAfile ca.crt server.crt
openssl verify -x509_strict -CAfile ca.crt client.crt
A transparent proxy serves clients that were never configured to use one. A packet filter redirects their connections to 3proxy, and the transparent command tells the service to take the destination from the filter instead of from the request. Every other feature applies as usual: access rules, parent proxies, limits and logging all see the real destination. It works on Linux and on the BSDs. Since 1.0.1 it is part of the binary; before that it was the separate TransparentPlugin, and the plugin line it needed is no longer required.
The command supplies both the address and the port the client was trying to reach, so a service can serve whatever was redirected to it rather than one port with one target.
Without it a service has to get a destination from somewhere else: an HTTP proxy falls back to the Host header, and a port mapper uses the address it was configured with. Taking the destination from the filter is what makes the other protocols work, and what makes the address authoritative rather than something the client claimed.
tlspr is the clearest case. Nothing reaches it at all unless traffic is redirected to it, or the clients resolve the names to it through DNS. With a redirection it gets the address as well as the name from the handshake, and that is what lets access rules be written with host names: the name from the handshake is matched, and the connection still goes to the address the client was going to. Without the address it would have to resolve the name itself, which is a second lookup and a second answer.
A configuration for web and TLS traffic:
log /var/log/3proxy.log D auth iponly allow * # the destination comes from the redirection for the services below transparent # ordinary web traffic, redirected here from port 80 proxy -p3129 -e192.0.2.10 # TLS, redirected here from port 443: tlspr would otherwise have only the # name in the handshake, and this gives it the address as well tlspr -p3143 -e192.0.2.10 notransparent
-e gives those services an address of their own to connect from. That address is what the redirection rules exclude, and excluding it is what stops the proxy's own connections from being redirected back into it. Without an exclusion the connection 3proxy makes to the origin matches the same rule, returns to 3proxy, and the traffic goes round until something gives out. Running 3proxy as its own account and excluding that account works too, and is the better choice when the machine has one address.
Linux, iptables. For traffic the machine forwards for others:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-ports 3129 iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-ports 3143
Traffic the machine generates itself passes through OUTPUT instead, where the proxy's own connections have to be excluded:
# by the address the services connect from
iptables -t nat -A OUTPUT -p tcp --dport 80 ! -s 192.0.2.10 -j REDIRECT --to-ports 3129
# or by the account 3proxy runs as
iptables -t nat -A OUTPUT -p tcp --dport 80 -m owner ! --uid-owner proxy3 \
-j REDIRECT --to-ports 3129
Linux, nftables (Debian 11+, Ubuntu 22.04+, RHEL 8+, Fedora, Arch, where nftables is what iptables is a front end for):
table ip proxy3 {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
iif "eth0" tcp dport 80 redirect to :3129
iif "eth0" tcp dport 443 redirect to :3143
}
chain output {
type nat hook output priority dstnat; policy accept;
meta skuid != "proxy3" tcp dport 80 redirect to :3129
meta skuid != "proxy3" tcp dport 443 redirect to :3143
}
}
Load it with nft -f, and keep it across reboots in /etc/nftables.conf (Debian, Ubuntu) or /etc/sysconfig/nftables.conf (RHEL, Fedora). A table name cannot begin with a digit, which is why the table above is not called 3proxy.
Linux, firewalld (RHEL, CentOS Stream, Fedora, openSUSE). Redirect an incoming port on a zone:
firewall-cmd --permanent --zone=internal --add-forward-port=port=80:proto=tcp:toport=3129 firewall-cmd --permanent --zone=internal --add-forward-port=port=443:proto=tcp:toport=3143 firewall-cmd --reload
firewalld has no exclusion for the proxy's own traffic in that form, so put that part in a direct rule:
firewall-cmd --permanent --direct --add-rule ipv4 nat OUTPUT 0 \
-p tcp --dport 80 -m owner ! --uid-owner proxy3 -j REDIRECT --to-ports 3129
firewall-cmd --reload
Linux, ufw (Ubuntu, Debian). ufw has no command for redirection; add the rules to /etc/ufw/before.rules, above the *filter block:
*nat :PREROUTING ACCEPT [0:0] -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-ports 3129 -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-ports 3143 COMMIT
On Linux 3proxy asks the kernel where the connection was going. On the BSDs it asks pf, which keeps the original destination in its state table, through /dev/pf - so rdr rules work, and 3proxy has to be able to read that device. Where a redirection leaves the destination on the socket instead, that is used: OpenBSD divert-to and FreeBSD ipfw fwd both do.
The mechanism is chosen automatically, and transparent takes an argument for the installations that need to pin it: auto (the default), netfilter, pf, or socket for reading it off the socket. A mode the build has no code for is refused, so a configuration written for another platform fails where it is wrong instead of quietly doing something else.
FreeBSD, NetBSD and OpenBSD, pf. Redirect in /etc/pf.conf, excluding the address the proxy connects from:
rdr pass on em0 inet proto tcp from ! 192.0.2.10 to any port 80 -> 127.0.0.1 port 3129 rdr pass on em0 inet proto tcp from ! 192.0.2.10 to any port 443 -> 127.0.0.1 port 3143
Load with pfctl -f /etc/pf.conf. 3proxy looks the destination up in pf's state table, so it needs to read /dev/pf: either run it as root, or give its account access to that device.
OpenBSD, divert-to is an alternative which leaves the destination on the socket, and needs no access to /dev/pf:
pass in on em0 inet proto tcp to any port 80 divert-to 127.0.0.1 port 3129 pass in on em0 inet proto tcp to any port 443 divert-to 127.0.0.1 port 3143
FreeBSD, ipfw. fwd delivers the connection locally without rewriting it, which also leaves the destination on the socket:
ipfw add fwd 127.0.0.1,3129 tcp from any to any 80 in recv em0 ipfw add fwd 127.0.0.1,3143 tcp from any to any 443 in recv em0
macOS has /dev/pf but ships no header for it, so a macOS build has no pf lookup, and macOS has neither divert-to nor ipfw to leave the address on the socket. Transparent proxying is not usable there, even though the commands exist in a macOS build.
Check the result by asking for a host through a redirected port and reading the log: the request should appear with the address the client asked for, which is what it would look like through a configured proxy.
Since version 0.9.7, PCRE (Perl Compatible Regular Expressions) filtering is built into 3proxy when compiled with PCRE2 support (WITH_PCRE). Previously available as PCREPlugin, the functionality is now integrated into the main binary. The plugin line is no longer required.
PCRE filtering can be used to create matching and replacement rules with regular expressions for client requests, client and server headers, and client and server data.
Commands:
pcre TYPE FILTER_ACTION REGEXP [ACE] pcre_rewrite TYPE FILTER_ACTION REGEXP REWRITE_EXPRESSION [ACE] pcre_extend FILTER_ACTION [ACE] pcre_options OPTION1 [...]
Examples:
# Block requests containing specific keywords for certain users pcre request deny "porn|sex" user1,user2,user3 192.168.0.0/16 # Block responses with specific content type pcre srvheader deny "Content-type: application" # Replace content in both directions (censorship) pcre_rewrite clidata,srvdata dunno "porn|sex|pussy" "***" baduser pcre_extend deny * 192.168.0.1/16
Note: Regular expressions don't require authentication and cannot replace authentication and/or allow/deny ACLs.
First, always specify the internal interface to accept incoming connections with the 'internal' configuration command or '-i' service command. (See How to start any of the proxy services (HTTP, SOCKS, etc.)). If no internal interface is specified, your proxy will act as an open proxy.
It's also important to specify the external interface to prevent access to the internal network with 'external' or -e.
3proxy with configuration files allows you to use authentication and authorization for user access. Authentication is possible by username/password or the user's NetBIOS name. The authentication type is specified by the 'auth' command.
auth noneDisables both authentication and authorization. You cannot use ACLs.
auth iponlySpecifies no authentication; ACL-based authorization is used.
auth nbnameAuthentication by NetBIOS name + ACLs. The NetBIOS name of the 'messenger' service is obtained before ACL validation. If no name is obtained, it's assumed to be empty. Messenger is started by default in Windows NT/2000/XP. For Win9x, WinPopUP needs to be launched. This type of authentication may be spoofed by a privileged local user.
auth strongAuthentication by username/password. If the user is not registered, their access is denied regardless of ACLs.
Different services can have different authentication levels.
auth none pop3p auth iponly proxy auth strong socksIt's possible to authorize access by client IP address, IP address or requested resource, target port, time, etc., after authentication. (See How to limit resource access).
Since version 0.6, double authentication is possible, e.g.:
auth iponly strong allow * * 192.168.0.0/16 allow user1,user2 proxyStrong authentication will only be used if the ACL requires a username to decide if access must be granted. That is, in the example, strong username authentication is not required to access 192.168.0.0/16.
Version 0.6 introduces authentication (username) caching to increase performance. It's recommended to use authentication caching with resource- or time-consuming authentication types, such as nbname or external plugins (WindowsAuthentication). Caching can be set with the 'authcache' command with 2 parameters: caching type and caching time (in seconds). The caching type defines the type of cached access: 'ip' - after successful authentication, all connections during the caching time from the same IP are assigned to the same user; the username is not requested. "ip,user" - the username is requested, and all connections from the same IP are assigned to the same user without actual authentication. "user" - same as above, but IP is not checked. "user,password" - username and password are checked against cached ones. For authentication, the special authentication type 'cache' must be used. Example:
authcache ip 60 auth cache strong windows proxy -nPlease note that caching affects security. Never use caching for access to critical resources, such as web administration.
authcache can be used to bind a user's sessions to an IP with the 'limit' option. With
authcache ip,user,pass,limit 120 auth cache strongthe user will not be able to use more than a single IP during the cache time (120 sec).
The user list is created with the 'users' command.
users USERDESC ...With a single command, it's possible to define a few users, or you can use multiple 'users' commands. USERDESC is a user description. The description consists of three semicolon-delimited parts - login, password type, and
users admin:CL:bigsecret test:CL:password test1:CL:password1 users "test2:CR:$1$lFDGlder$pLRb4cU2D7GAT58YQvY49." users test3:NT:BD7DFBF29A93F93C63CB84790DA00E63Please note the usage of quotation marks: they're required to escape the $ sign, which is otherwise used as a file inclusion macro. The following password types are available:
users $/etc/.3proxypasswdor
users $"c:\Program Files\3proxy\passwords"It's possible to create NT and crypt passwords with the 3proxy_crypt utility included in the distribution.
The commands allow, deny, and flush are used to manage ACLs:
allow <userlist> <sourcelist> <targetlist> <targetportlist> <commandlist> <weekdaylist> <timeperiodlist>
deny <userlist> <sourcelist> <targetlist> <weekdaylist> <timeperiodlist>
flush
Redirections are useful to, e.g., forward requests from specific clients
to different servers or proxy servers. Additionally, redirections are useful
to convert the proxy interface from one format to another, e.g., requests from
a SOCKS proxy can be redirected to a parent HTTP proxy, or a SOCKSv5 client can be
redirected to a SOCKSv4 proxy.
Because 3proxy understands "transparent" web requests, it can be used as an
intermediate software between an HTTP proxy and a NAT server for transparent HTTP
forwarding, because it can convert a "Web server" request issued by a client to a
"proxy request" required by a proxy server. A simple redirection is:
auth iponly allow * parent 1000 http 192.168.1.1 3128 proxyAll traffic of the HTTP proxy is redirected to the parent proxy 192.168.1.1 port 3128.
auth iponly allow * * * 80 parent 1000 http 0.0.0.0 0 allow * * * 21 parent 1000 ftp 0.0.0.0 0 allow * * * 110 parent 1000 pop3 0.0.0.0 0 socksIn this case, all SOCKS traffic with destination port 80 is forwarded to the local 'proxy' service, destination port 21 to 'ftppr', and 110 to 'pop3pr'. There is no need to run these services explicitly. Local redirections are useful if you want to see and control via ACLs protocol-specific parameters, e.g., filenames requested through FTP while clients are using SOCKS.
Q: What is it for?
A: To have control based on the request and to have URLs and other protocol-specific parameters logged.Q: What are the restrictions?
A: It's hard to redirect services for non-default ports; Internet Explorer supports only SOCKSv4 with no password authentication (Internet Explorer sends the username, but not the password); for SOCKSv5, only cleartext password authentication is supported.Q: What are the advantages?
A: You only need to set up a SOCKS proxy in browser settings. You can use a socksifier, e.g., FreeCAP or SocksCAP, with an application that is not proxy-aware.Q: How to set it up?
A: You should specify a parent proxy with an IP of 0.0.0.0 and port 0. Examples:auth iponly allow * * * 80,8080-8088 parent 1000 http 0.0.0.0 0 allow * * * 80,8080-8088 #redirect ports 80 and 8080-8088 to local HTTP proxy #Second allow is required, because ACLs are checked #twice: first time by socks and second by http proxy. allow * * * 21,2121 parent 1000 ftp 0.0.0.0 0 allow * * * 21,2121 #redirect ports 21 and 2121 to local #ftp proxy allow * #allow the rest of connections directly socks #now let the socks server start
Q: How does it affect different ACL rules?
A: After local redirections, rules are applied again to the protocol-level request. The redirection rule itself is skipped. This makes it possible to redirect the request again to an external proxy depending on the request itself.allow * * * 80,8080-8088 parent 1000 http 0.0.0.0 0 #redirect http traffic to internal proxy allow * * $c:\3proxy\local.nets 80,8080-8088 #allow direct access to local.nets networks allow * * * 80,8080-8088 parent 1000 http proxy.3proxy.org 3128 #use parent caching proxy for the rest of the networks allow * #allow direct connections for the rest of socks #requests
The proxy itself doesn't manage network-level routing. The only way to control the outgoing channel is to select the external interface. It's possible to make the external interface (what is usually selected with the 'external' command or '-e' option) random by using local redirection with an external port of 0.
auth iponly allow * parent 500 http 10.1.1.101 0 parent 500 http 10.2.1.102 0Now the external interface is randomly selected with 0.5 probability between 10.1.1.101 and 10.2.1.102. To work as expected, different default routes must be used between the 2 interfaces.
If both interface addresses are in the same network, e.g., 10.1.1.101 and 10.1.1.102, and you want to select a random gateway between 10.1.1.1 and 10.1.1.2, you must control it by using the routing table, in case there is no default gateway route for Windows:
route add -p 10.1.1.1 10.1.1.101 route add -p 10.1.1.2 10.1.1.102 route add -p 0.0.0.0 mask 0.0.0.0 192.168.1.1 route add -p 0.0.0.0 mask 0.0.0.0 192.168.1.2If you don't have a second address yet, just add it. Under Linux/Unix, it's better to use source routing.
The parent command may also be used to build proxy chains. In this case, multiple 'parent' commands are used for a single 'allow' rule with different weights (the first argument of the parent command). A chain may contain any number of proxy servers, but it should be noted that every hop significantly reduces performance. It's possible to mix different types of proxies within a single chain: HTTPS (HTTP connect), SOCKS4, SOCKS5. A weight different from 1000 is used to build random chains. If weight W is below 1000, this proxy will be used as the next chain hop with a probability of W/1000. That is, if the weight is 250, the probability that this proxy will be used for the next hop is 25%. 'parent' records with a combined weight of 1000 establish a group; one of these records will be used for the hop with a probability according to the weight. Warning: each group must have a weight that is a multiple of 1000. As follows, the combined weight of all 'parent' records must also be a multiple of 1000. If the combined weight of 'parent' records in the chain is 3000, the chain has 3 hops and must be formed of 3 groups. Example:
allow * parent 500 socks5 192.168.1.1 1080 parent 500 connect 192.168.10.1 3128In this case, we have 1 parent proxy (1 hop) which is randomly chosen between 2 hosts: 192.168.1.1 and 192.168.10.1. The 2 records form a single group.
allow * * * 80 parent 1000 socks5 192.168.10.1 1080 parent 1000 connect 192.168.20.1 3128 parent 300 socks4 192.168.30.1 1080 parent 700 socks5 192.168.40.1 1080In this case, we have 3 groups (3 hops in the chain). The first hop is 192.168.10.1, the second hop is 192.168.20.1, and the 3rd one is either 192.168.30.1 with a probability of 30% or 192.168.40.1 with a probability of 70%.
A SOCKSv5 UDP ASSOCIATE request only asks 3proxy to open a relay port, it carries no destination. The destination is taken from every datagram the client sends afterwards, so a single association may reach any number of destinations. 3proxy authorizes the destination of every datagram, so ACLs limiting the destination address, host name or port do apply to UDP traffic.
Differences from TCP:
socks5 and
socks5+ parents can be used for UDP.
nscache for host names and the
authentication cache for anything more expensive than 'iponly'. The
-U option of the socks service turns the logging
and/or the re-authorization off; with -U0 or -U1
only the first destination of an association is authorized.
Limit the destinations a client may send datagrams to:
auth iponly allow * * 8.8.8.8 53 deny * socks -p1080
The ASSOCIATE request succeeds, datagrams to 8.8.8.8:53 are relayed, datagrams to any other destination are dropped.
The same with 'strong' (or RADIUS, or plugin) authentication, where every new destination would otherwise be authenticated again:
users user1:CL:password authcache user,pass,dstaddr,dstport 60 auth cacheacl strong allow user1 * 8.8.8.8 53 deny * socks -p1080
With 'cacheacl' the ACL result is not re-evaluated on a cache hit, so every field the ACL limits must be a part of the cache key: 'user' and 'pass' for the userlist, 'dstaddr' and 'dstport' for the targetlist and the targetportlist, 'ip' for the sourcelist, 'dsthost' for host names in the targetlist, 'dstoper' for the operationlist. Without the destination in the key the result cached for one destination is applied to any other destination and the destination is not checked at all. Use plain 'cache' instead of 'cacheacl' if ACLs may change during the cache lifetime, or if a parent proxy is used: on a 'cacheacl' hit the ACL is not walked, so no parent proxy is selected and datagrams are sent directly.
3proxy supports bandwidth filters. Use the bandlimin/bandlimout and nobandlimin/nobandlimout commands to manage filters. 'in' means incoming and 'out' means outgoing traffic.
bandlimin <bitrate> <userlist> <sourcelist> <targetlist> <targetportlist> <commandlist>
nobandlimin <userlist> <sourcelist> <targetlist> <targetportlist> <commandlist>
bandlimin 57600 * 192.168.10.16 bandlimin 57600 * 192.168.10.17 bandlimin 57600 * 192.168.10.18 bandlimin 57600 * 192.168.10.19Create 4 separate pipes for 4 clients with emulation of a modem connection.
bandlimin 57600 * 192.168.10.16/30Create a single pipe for all 4 clients. That is, 4 clients share a modem connection. In this example:
nobandlimin * * * 110 bandlimin 57600 * 192.168.10.16/32mail traffic from POP3 servers bypasses the pipe and has no bandwidth limitation.
counter <filename> <type> <reportpath>
countin <number> <type> <amount> <userlist> <sourcelist> <targetlist> <targetportlist> <commandlist>
nocountin <userlist> <sourcelist> <targetlist> <targetportlist> <commandlist>
countout <number> <type> <amount> <userlist> <sourcelist> <targetlist> <targetportlist> <commandlist>
nocountout <userlist> <sourcelist> <targetlist> <targetportlist> <commandlist>
You can set a traffic limit per day (D), week (W), month (M), year (Y), or absolute ('N'), as specified by the 'type' argument of the counterin command. Traffic information is stored in a binary file specified by the 'filename' argument. The countersutil utility can be used to manage this file. The reportpath specifies the location of text reports; the type parameter of the 'counter' command controls how often text reports are created. The amount is the amount of allowed traffic in megabytes (MB). nocountin allows you to set exclusions.
3proxy accounts for protocol-level traffic. Providers count channel- or IP-level traffic with network and transport headers. In addition, 3proxy does not count DNS resolutions, pings, floods, scans, etc. This accounts for approximately a 10% difference. That is why you should have a 15% reserve if you use 3proxy to limit your traffic. If the difference with your provider is significantly above 10%, you should look for traffic bypassing the proxy server, for example connections through NAT, traffic originating from the host with the proxy installed, traffic from server applications, etc.
For name resolution and caching, use the commands nserver, nscache / nscache6, and nsrecord.
nserver 192.168.1.2 nserver 192.168.1.3:5353/tcpsets DNS resolvers. 192.168.1.3 will be used via TCP/5353 (instead of default UDP/53) only if 192.168.1.2 fails. Up to 5 nservers may be specified. If no nserver is configured, default system name resolution functions are used.
nscache 65535 nscache6 65535sets name cache size for IPv4 and IPv6. The name cache must be large enough, if present. The name cache is only used if nserver is configured.
nsrecord server.mycompany.example.com 192.168.1.1 nsrecord www.porno.com 127.0.0.2 ... deny * * 127.0.0.2adds static nsrecords. Also, static nsrecords are used for dnspr, unless the -s option is specified. Since version 0.8, a parent proxy may be configured for dnspr.
IPv6 is supported since version 0.8. Please note that some proxy protocols, e.g., SOCKSv4,
do not support IPv6. SOCKSv5 supports IPv6 with a special request type (which must be
implemented by the client).
3proxy supports proxying from IPv4 and IPv6 networks to IPv4,
IPv6, and mixed networks. An IPv6 address may be used in
internal, external, and parent commands, ACLs, -i and -e options, etc.
The external command and -e options may be given twice for each service—once with an IPv4
and once with an IPv6 address. internal can be given only once; to bind to all IPv4 and
IPv6 addresses, use [0:0:0:0:0:0:0:0] or [::].
Any service may be configured with -4, -46, -64, or -6 options to specify the desired
priority for name-to-IPv4/IPv6 address resolution (IPv4 only, IPv4 priority,
IPv6 priority, IPv6 only).
For example, a user needs access from an external network to a proxy server located on the host 192.168.1.2. This host cannot be accessed from the external network, but it has access to the external network with an external address 1.1.1.1. Also, the user has access to the host 2.2.2.2 (IP address may be dynamic) with hostname host.dyndns.example.org via the external network. The user needs 2 instances of 3proxy, the first one on the host 192.168.1.2 with the config
users user:CL:password auth strong allow user proxy -rhost.dyndns.example.org:1234and the second one on host.dyndns.example.org (2.2.2.2) with the config
auth iponly allow * * 1.1.1.1 tcppm -R0.0.0.0:1234 3128 1.1.1.1 3128For browser settings, the proxy is host.dyndns.example.org:3128.
3proxy supports HAProxy PROXY protocol v1 for both receiving and sending client IP information. This is useful when 3proxy is behind a load balancer or when passing client information to a parent proxy.
Receiving PROXY protocol header:
Use the -H option to make 3proxy expect a PROXY protocol v1 header
on incoming connections. This allows 3proxy to receive the real client IP address
from HAProxy or another load balancer:
proxy -H -p3128 socks -H -p1080
The PROXY protocol header must be sent before any protocol-specific data.
Sending PROXY protocol header to parent proxy:
Use the ha parent type to send a PROXY protocol v1 header to
the parent proxy. Place ha before the parent that should receive
the header; after the header is sent, parent protocol negotiation continues:
allow * parent 1000 ha 0.0.0.0 0 parent 1000 socks5 parent.example.com 1080 proxy
This configuration connects to the SOCKS5 parent, sends the PROXY protocol
header with the original client IP, then performs SOCKS5 negotiation before
relaying the client payload. The parent should use -H to accept
the header (for example socks -H).
Use the maxseg command to set the TCP maximum segment size (MSS)
for outgoing connections. This can be useful to work around path MTU discovery
issues or to optimize traffic for specific network conditions:
maxseg 1400 proxy -p3128 -OcTCP_NODELAY,TCP_MAXSEG -OsTCP_NODELAY,TCP_MAXSEG
The value is specified in bytes. This setting uses the TCP_MAXSEG socket option and may not be supported on all platforms. A typical use case is to reduce MSS to avoid fragmentation in VPN tunnels or to work around MTU issues with certain network paths.
The latest version of 3proxy may be obtained here. A new version may have changes and incompatibilities with the previous one in file formats or commands. Please read the CHANGELOG file and other documentation before installing a new version.
If installed as a system service, 3proxy understands Windows service commands for START, STOP, PAUSE, and RESUME. If the service is PAUSEd, no new connections are accepted while older connections are processed. Currently, there is no support for dynamic configuration changes, so you have to restart the service completely if you have changed any configuration. You can control the 3proxy service via "Services" administration or via the "net" command:
net start 3proxy net stop 3proxy net pause 3proxy net continue 3proxy
Ask it in Github. Please read this document before asking a question.