hoses: enhanced socks5 tools
Introduction
The hose is a python package that implements:
- socks5 proxy with SSL support
- netcat style cli to use the proxy
- simple stunnel implementation
For a project I had, I needed for remote systems to connect back to a central management system over the Internet. This provides a simple application level proxy that implements this connectivity.
Rather than re-inventing the wheel, it makes use of the python SSL module to provide security and certificate based authentication.
The certificate authentication uses standard X509 certifcates as supported by OpenSSL.
Application proxy uses the SOCKS, which is properly defined as RFC1928.
As functionality goes, it focus mostly in connecting network sockets and in netcat functionality piping to running commands.
Access control can be defined in static files, but also it can be delegated to external scripts or a REST API server.
Features
The following is implemented:
- SOCKS v5 protocol, with
CONNECT
andBIND
commands. It does not implementUDP Associate
commands. The Authentication handshake is performed, but no Authentication is implemented. hoses expects the connection to be wrapped in a SSL/TLS stream and clients are authenticated using certificates at that level. - As mentioned earlier, SSL/TLS is used to secure the application proxy and it is performed before SOCKS protocol starts running.
- The SOCKS protocol is further extended to allow connecting/binding to UNIX sockets.
- Proxy activity is logged in an optional audit.log.
- Access control is largely untested, but implemented as either:
- script/command that runs in the background and accepts JSON requests with client data
and returns
allow
ordeny
. - Or a combination of:
- static access list
- script that runs with environment variables containing request data and returns an access list
- REST API endpoint that access JSON content and retunrs an access list.
- script/command that runs in the background and accepts JSON requests with client data
and returns
In order to use the application proxy, netcat type functionality is implemented with the following features:
- Connect to remote hosts either directly or via hoses application proxy.
- Listen to incoming connections and spawn an external program.
- SSL/TLS wrapped connections with optional client certificate validation.
- Connections to TCP ports and UNIX sockets.
To facilitate securing legacy servers, stunnel functionality is available:
- Port forwarding with optional SSL/TLS
- SSL/TLS wiht optional client certificate validation
Where to find
The project is hosted on github.
Examples
Proxy
The main usage is as a socks proxy.
Basic socks5 compatible proxy:
hoses -S * -P 1080 proxy
-S *
will listen on all IPv4 and IPv6 addresses.-P 1080
listen on port 1080
Enable TLS and listen only on loopback address:
hoses -S 127.0.0.1 -P 3340 --cert server.crt --key server.key
Enable TLS and enable client certificate verification:
--cert server.crt
: file path to server certificate--key server.key
: file path to corresponding key.
hoses -S 127.0.0.1 -P 3340 --cert server.crt --key server.key --ca ca.crt
--ca ca.crt
Certificate file signing client certificates (or the client certificate itself for self-signed certificates.
netcat server
It can be used as netcat --listen
replacement.
Listen on localhost, port 4040 and run a command:
hose listen --exec localhost 4040 'sh -c "python3 eliza.py"
Listen on unix socket on the socks server, and forward connections to port 22 on remotehost. And persist bindings.
hose -S socks-server -P 1080 listen -p unix:/tmp/sshsock 0 remotehost 22
Like previous but with TLS:
hose -S socks-server -P 1080 --cert client.crt --key client.key --ca ca.crt listen -p unix:/tmp/sshsock 0 remotehost 22
netcat client
It can be used as a netcat client to connect to network ports.
Connect to remote:
hose connect remotehost 4583
Connect to a remote TLS server with certificate based client authentication
hose --cert client.crt --key client.key --ca ca.crt connect remotehost 4583
Connect to a remote host through a SSL socks proxy with client authentication
hose -S socks-server -P 1080 --cert client.crt --key client.key --ca ca.crt connect remotehost 4583
stunnel
This is used as a replacement for stunnel
.
Accept TLS connections and forward them to a different port. This is used to provide TLS encryption to protocol servers that do not support this out of the box.
hose --cert server.crt --key server.key listen --unwrap -p localhost 8011 remotehost 11
Accept unencrypted connection and forward them to a TLS server. This is used to give TLS encryption to protocol clients that do not support it out of the box.
hose --cert server.crt --key server.key listen --wrap -p localhost 11 remotehost 8011
SSH tunnel
You can use it as an ssh proxy command to make ssh go through a Socks proxy:
ssh -o "ProxyCommand hoses -S sockserver -P 1080 connect %h %p" remotehost
References
- https://www.electricmonk.nl/log/2018/06/02/ssl-tls-client-certificate-verification-with-python-v3-4-sslcontext/
- https://github.com/MisterDaneel/pysoxy
- https://stackoverflow.com/questions/7186601/is-socks5-bind-persistent-or-one-time-only
- https://en.wikipedia.org/wiki/SOCKS
- socks clients
- https://pypi.org/project/PySocks/
- Using requests:
- Monkey patching: https://www.michaelrinderle.com/2020/05/21/patching-a-python-socket-to-use-socks5-protocol/