How to setup an encrypted SOCKS proxy using stunnel

Why using SOCKS

There are times in which setting up a complete VPN tunnel might be an overkill (or not be an option at all).

For example, assume the followings:

  • You don’t want to tunnel all the traffic, just want to do so for your browsers.
  • Your OS is running under a limited account and doesn’t allow creation of tun interfaces.
  • Your provider does not allow setting up a tun device.
  • You want to securely surf the web on your old android device that doesn’t support tunneling.

stunnel can be used on your Android phone. SOCKS functionality could then be directly used in your phone for apps that support it: Firefox, Telegram, etc.

To see how to install and setup stunnel on android, take a look at:

How to run stunnel on your android device

These are just couple of examples. In such cases, setting up a SOCKS proxy might just do the trick.

Another interesting aspect of SOCKS proxy, is that after the initial per each connection handshake, it doesn’t add much overhead to the underlying traffic.

Overhead might not look like a big deal at first, but it adds up. This is specially true when you have a per packet ones. SOCKS connections generally has a per connection overhead, which is neglectable.

OpenSSH SOCKS or stunnel’s

SOCKS protocol (including SOCKS5), does not provide any means of encryption by itself1. To overcome this, a very popular method for setting up a SOCKS server, is to use the OpenSSH port forwarding capability along with its built-in SOCKS support.

But using OpenSSH this way, is not always the best option. The most serious problem with such approach, is that you need to have an active SSH connection to the server at all times (That is unless you do some ugly hacking).

stunnel on the other hand, comes with its own implementation of secure SOCKS5, SOCKS4, and SOCKS4a protocol. It can do so without the need of any additional software, and to top that off, you don’t need to keep any other session active for it to work2.

There are some limitations to the stunnel SOCKS implementation however that you should be aware of:

  • Only TCP tunneling is supported (not UDP).
  • Advanced options like BIND is not supported.
  • SOCKS5 built-in Authentication is not supported (though stunnel has its own methods of authentication on top of SOCKS5).
  • Only suited for personal use (as after the initial client verification, it’s not easy to setup client access control).

But even with those limitations (most of which also applies to OpenSSH SOCKS), it is still suited for most applications.

If these limitations are not acceptable to you, I have another article for more advanced setup using Dante and stunnel together to make a full featured (and encrypted) SOCKS server. You can fine it here:

Setting up an encrypted SOCKS proxy using Dante and stunnel

Assumptions

Throughout this article, we assume the followings:

  • Server IP address is 10.0.0.1
  • Client IP address is 10.0.0.2
  • Client can access port 1081 on the server (that’s the port we’ll be using for the encrypted SOCKS traffic)
  • PSKsecrets is used for both encryption and authentication

Now obviously, all those assumptions could be adjusted if needed. For example, there is absolutely no requirement that you have to use PSKsecrets. You could use a full PKI system instead if you want to.

To see how to properly install and setup stunnel on Ubuntu (and possibly other distros), refer to my other article on the topic:

How to install and configure stunnel on Ubuntu

Process overview

The setup is easy and straight forward and what is happening under the hood, is rather interesting:

Server side

On the server side, stunnel exposes a SOCKS port. This is your typical SOCKS4a/5 protocol, supporting basic features like name resolution and TCP/IP stream connection.

Accessing to that SOCKS port on the server, is guarded by the stunnel authentication layer. This ensures that the underlying SOCKS traffic is fully authenticated and encrypted. You can use either PKI systems (with CA, client/server certs, CRL, OSCP, etc), or just a simple PSKsecrets file.

Client side

On the client side, you setup any authentication/encryption method set on the server, and simply forward a local port to the stunnel SOCKS port on the server. Applications then will be able to talk to that local port using SOCKS protocol. The traffic then will be encrypted and passed along to the stunnel SOCKS server port.

Config files

A sample of server and client SOCKS config is provided below. Don’t forget to adjust them first if needed:

Global config

These samples assume you are running stunnel on Ubuntu. You may need to slightly change the global options for other distros/OSes.

These are basically extracted from my post on How to install and configure stunnel on Ubuntu.

You actually may not need to set any global config at all. If you don’t plan to use the stunnel init package (or just using anther OS like Windows), you can safely skip this section.

pid = /var/run/stunnel4/stunnel.pid
output = /var/log/stunnel4/stunnel.log

setuid = stunnel4
setgid = stunnel4

debug = 4

Server config

# https://www.stunnel.org/faq.html
socket = l:TCP_NODELAY=1

[socks_server]
protocol = socks
accept = 1081
PSKsecrets = /etc/stunnel/stunnel.secrets

Client config

# https://www.stunnel.org/faq.html
socket = r:TCP_NODELAY=1

[socks_client]
client = yes
accept = 127.0.0.1:1080
connect = 10.0.0.1:1081
PSKsecrets = /etc/stunnel/stunnel.secrets

Port 1080, is the standard port for SOCKS protocol. You might need to change it if it’s already in use by another program.

Also you obviously have to setup a PSKsecrets file on both server and client.

You may now use curl on the client side to ensure you can connect to the remote SOCKS proxy, and also that the name resolution works and your IP address has been changed (We’ll be using SOCKS5 for this):

curl --proxy 'socks5h://127.0.0.1:1080' 'https://api.ipify.org'

If you get a response with your server’s public IP address, then you’re ready to go. Just setup your programs to use SOCKS4a/SOCKS5 proxy (with remote name resolution) on 127.0.0.1:1080.

Troubleshooting

If this setup did not work for you, the easiest way to troubleshoot is by looking at the stunnel’s own logs on both client and server side.

stop the stunnel processes, increase the debug level, and optionally make it to temporarily run on the foreground by including the followings in the conf files:

debug = 6
foreground = yes
Don’t use the foreground option in init (or service) mode. If you decide to use this option, directly run stunnel process in the terminal (with its config file as the argument).

As always, your thoughts on this article will be most appreciated. Please share them with me in the comment section below.


  1. Well, technically there is RFC 1961 to add GSS-API support, but that’s not easy to setup and also requires an advanced SOCKS server. ↩︎

  2. In more advanced setups, it’s even possible to use stunnel SOCKS as a transparent proxy ↩︎

Hamy
Hamy
a sysadmin in the wind
comments powered by Disqus

Related