Repository navigation
Upgrading from 2.1 (behaviour changes)
These changes affect you if you override the image's command or healthcheck, or parse its logs:
- Healthcheck command. The image healthcheck runs
python -m simple_socks5.healthcheck. If
you copiedpython -m src.healthcheckinto a compose file or Kubernetes probe, update it. - Default command. The image runs
python -m simple_socks5 --host 0.0.0.0 --port 1080.
Overrides that runpython app.py ...keep working. - Log file logger names.
SOCKS5_LOG_FILElines name loggers[simple_socks5.…]instead of
[src.…]. Console lines are unchanged. - Log levels. ERROR now means a fault in the proxy: client mistakes log at DEBUG and
unreachable destinations at INFO.Authenticated userlogs at DEBUG. - Rate-limited warnings. Handshake-timeout and failed-login warnings are logged at most once
every 10 s. SetLOGGING_LEVEL=debugto see every failure with the client's IP. - CONNECTION lines. A CONNECT logs its
CONNECTIONline only once the destination has
connected, so these lines no longer count failed attempts. - Keep 2.1 entirely. Pin
jcaponigro20/simple-socks5:2.1.0(or
:2.1.0-logging-disabled).
Added
pip install .installs asimple-socks5command, which takes the same flags as
python3 app.py.python -m simple_socks5works too.- The package ships a
py.typedmarker, so type checkers use its annotations. SECURITY.mdsays how to report a vulnerability privately and which versions get fixes;
CONTRIBUTING.mdcovers development and releases.python -m benchmarksmeasures the proxy against direct connections, profiles it and charts the
results, from a checkout.benchmarks/README.mdhas the results and the optimizations they point to.
Changed
- The code is now the
simple_socks5package undersrc/, andpip install .installs it.
python3 app.pykeeps working from a clone and in the image. - Behaviour change: the image healthcheck runs
python -m simple_socks5.healthcheck. If
you copiedpython -m src.healthcheckinto a compose file or Kubernetes probe, update it. - Behaviour change: logger names in
SOCKS5_LOG_FILElines change from[src.…]to
[simple_socks5.…], which matters if you parse that file. Console lines are unchanged. - Behaviour change: the image's default command is now
python -m simple_socks5 --host 0.0.0.0 --port 1080. Commands that override it with
python app.py ...keep working. - The version is read from the installed package, so
pyproject.tomlis the only place it's
written.--versionfrom a clone that was never installed prints0+unknown; run
pip install -e .to fix it. - Contributors lint and format with Ruff instead of flake8:
pip install -e '.[dev]', then
ruff check .andruff format .. - Contributors type-check with mypy in strict mode:
pip install -e '.[dev]', thenmypy. - CI tests on Python 3.10 to 3.14.
- Behaviour change: ERROR now means a fault in the proxy. Malformed requests, unsupported
commands and clients hanging up log at DEBUG, and a destination that refuses or doesn't answer
logs at INFO with the reply code.SOCKS5_LOG_FILE, which keeps ERROR and above, no longer
fills up with client mistakes. - Behaviour change: handshake-timeout and failed-login warnings are rate-limited to one line
every 10 s, with a count of how many happened since the last one, so idle or brute-force clients
can't flood the log. If you ban IPs from those lines, setLOGGING_LEVEL=debug(or-L debug):
every failure is still logged there, with the client's IP. - Behaviour change:
Authenticated userlogs at DEBUG, so at INFO a connection logs only its
CONNECTION and CLOSED lines. - Behaviour change: a CONNECT logs its
CONNECTIONline once the destination has connected,
showing the address it connected to. A CONNECT that fails logs only its reply-code line, so
CONNECTIONlines no longer count failed attempts.
Fixed
- When the server can't start (for example, the port is already in use), it now exits with code 1
underpython -Stoo. Before, it crashed withNameError: name 'exit' is not defined. - IPv6 addresses are shown in brackets in the
Server started online and the UDPRELAYdebug
lines, for example[::]:1080instead of:::1080. - A CONNECT by hostname tries every address the name resolves to, in the order the system returns
them, until one connects (at most 4, each withSOCKS5_CONNECT_TIMEOUT). Before, only the first
was tried, solocalhost(which usually resolves to::1first) failed with "connection refused"
against a server listening on 127.0.0.1 only, and dual-stack hosts failed with "network
unreachable" where IPv6 is broken. - A hostname that doesn't resolve within the DNS timeout gets "host unreachable" straight away.
Before, the proxy passed the name toconnect(), which looked it up again with no time limit.
Unfinished lookups are capped, so a hung resolver can't pile up threads. - A hostname with an empty or over-long label gets "host unreachable" without logging an ERROR.