A SOCKS proxy server is useful to mask your IP address especially when you want to connect to TCP/UDP ports that are not running on ports 80 and 443, such as IRC or SSH or a cryptocurrency node such as Bitcoin, Ethereum or Dogecoin node.

Setting it up on a Debian or Ubuntu system is very easy and this post will show you how.

+================+       +===============+                                       +==============+ 
|                |       |               |                                       |              |
|  APPLICATION   |<=====>|  SOCKS CLIENT |<=====> || ENCRYPTED PACKETS || <=====>| SOCKS SERVER |<=====>|||| INTERNET
|                |       |               |                                       |              |
+================+       +===============+                                       +==============+


If you want to run a SOCKS proxy, you need a server that is publicly visible on the internet. So for this example, you can use a Linode nanode which is $5 per month or a DigitalOcean VM.

Once you have setup the latest Debian (Buster as of this writing) or Ubuntu (2022.01 as of this writing) you can install the shadowsocks-libev software. Once it installs it starts up, but we need to configure it so we shut it down.

$ sudo su - root
root$ apt update && apt upgrade && apt -y install shadowsocks-libev
root$ systemctl stop shadowsocks-libev.service


Now let’s configure the software. Edit the /etc/shadowsocks-libev/config.json file that has been auto-generated:

    "server":["", "::", "", "::1"],
    "fast_open": true,

The server_port is the port that the proxy server is listening on for inbound external connections for applications connecting to the proxy server from different networks.

The local_port is the port that the proxy server is listening on for inbound connections for applications running on the same server that need to use the proxy server. This is for the ss-local program that will be described later.

The password should be something long and difficult to crack, so that external connections can authenticate against it and only allowed applications that have the password can connect to the server.

The server is the list of interfaces, IPv4 and IPv6, that the proxy server should be listening on for external connections on the server_port.

The rest of the configuration is selected as the best possible defaults as described in the documentation.

Once you are done configuring the JSON file, change the permissions. We make the file read-write by root user and read-only by the shadowsocks-libev user under which Debian/Ubuntu run the server.

root$ chmod 0640 /etc/shadowsocks-libev/config.json
root$ chown root:shadowsocks-libev /etc/shadowsocks-libev/config.json

On Debian and Ubuntu servers, there is another configuration file that systemd uses which is /etc/default/shadowsocks-libev. The only change I suggest is to add -v to the DAEMON_ARGS so that you can see the connections come and go in the /var/log/syslog file.

$ cat /etc/default/shadowsocks-libev
# Defaults for shadowsocks initscript
# sourced by /etc/init.d/shadowsocks-libev
# installed at /etc/default/shadowsocks-libev by the maintainer scripts

# This is a POSIX shell fragment
# Note: `START', `GROUP' and `MAXFD' options are not recognized by systemd.
# Please change those settings in the corresponding systemd unit file.

# Configuration file

# Extra command line arguments

# User and group to run the server as

# Number of maximum file descriptors

Now we need to enable fast_open in the kernel network stack using sysctl as described here.

Add the following lines to /etc/sysctl.conf.

fs.file-max = 51200
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864
net.core.netdev_max_backlog = 250000
net.core.somaxconn = 4096
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.ip_local_port_range = 10000 65000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_mem = 25600 51200 102400
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
net.ipv4.tcp_mtu_probing = 1
net.ipv4.tcp_congestion_control = hybla

Add the following lines to /etc/security/limits.conf.

* soft nofile 51200
* hard nofile 51200

# for server running in root:
root soft nofile 51200
root hard nofile 51200

Once that is done run the following to get the kernel to reload the configuration:

root$ sysctl -p
root$ ulimit -n 51200

Now you can restart the server:

root$ systemctl start shadowsocks-libev.service
root$ netstat -vnatp | grep ss-server | grep LISTEN
tcp        0      0  *               LISTEN      11111/ss-server
tcp6       0      0 :::8388                 :::*                    LISTEN      11111/ss-server


Now we have the SOCKS server running on a Linode VM. Let’s note its IP address and let’s call it $IP_EXTERNAL.

Let’s say we are now in our personal LAN in our home, and are running a Bitcoin node that needs to connect to the rest of the network, but you do not want to reveal your home IP address.

You then use the SOCKS server running on $IP_EXTERNAL and get the Bitcoin daemon to connect to that SOCKS proxy.

For that to work, let’s assume your Bitcoin node is also running on Debian/Ubuntu system. You need to install the shadowsocks-libev package and shutdown the service, and also disable it.

We do not need the server module on this system, which is the client system, and only need to use the client application ss-local.

$ sudo su - root
root$ apt update && apt upgrade && apt -y install shadowsocks-libev
root$ systemctl stop shadowsocks-libev.service
root$ systemctl disable shadowsocks-libev.service

Run the local client application that now will connect to your SOCKS server using the password that was setup above. This can be run as your regular user and does not need root privileges.

$ nohup /usr/bin/ss-local -s $IP_EXTERNAL -p 8388 -l 1080 -b -k 'ENTER_LONG_PASSWORD_HERE' -m 'chacha20-ietf-poly1305' --reuse-port --fast-open -v > /tmp/shadowsocks.log 2>&1 &
$ netstat -vnat | grep 1080 | grep LISTEN
tcp        0      0*               LISTEN      -

You can see the ss-local application listening on port 1080 on the localhost IP address

NOTE:If you do not want to use the commandline you can setup the config.json above in the client machine as well and follow the CONFIG SECTION in the man shadowsocks-libev page.

Now we can run the Bitcoin node and make it connect via the SOCKS proxy to the broader worldwide network.

$ bitcoind -proxy='' -datadir=${HOME}/.bitcoin -server -daemon -par=-1

Or if you are running a Dogecoin node you can do the following:

$ dogecoind -proxy='' -par=-1 -server -daemon

If you want to use the SOCKS server to make web requests, you can do the following:

$ curl -v --socks5


To secure the connection, it makes sense to setup a firewall such as ufw or use Linode’s cloud firewall setup to allow only connections from known IP addresses. If you want to allow global access, you must use a very strong password and keep your server up to date since you will see bot attacks. In my case, I have restricted access to the SOCKS server to my home IP and manually adjust the firewall when the IP changes.


With this we come to the end of setting up an external SOCKS proxy server that allows you to have applications hide their IP address.

Donate DOGECOIN to DBevjMg3fd8C5oxZbV8sFpAffo6Tas1s8Q. DBevjMg3fd8C5oxZbV8sFpAffo6Tas1s8Q Donate BITCOIN to 19hrWWw1dPvBE1wVPfCnH8LqnUwsT3NsHW. 19hrWWw1dPvBE1wVPfCnH8LqnUwsT3NsHW
As an Amazon Associate I earn from qualifying purchases.