Skip to main content

Install and Configure Shadowsocks with Cloak: A fast, secure Open-source tunnel proxy to bypass firewalls

12 minutes


Introduction

Shadowsocks is an open-source, fast, and secure proxy protocol that allows users to protect their internet traffic and bypass restrictions where VPN connections are blocked.
It conceals your online activity by establishing a secure pathway between your device and a distant server, rendering socks traffic undetectable.

Shadowsocks is sought after by many due to its superior traffic concealment capability, cross-platform, and being fastest proxy.

During the mid-nineties, Virtual Private Networks(VPNs) were developed and used to secure connections over the internet. Not too soon after, The commercial VPN was also made available to the public in early 2000. Back then, OpenVPN was utilized to circumvent censorship and to successfully retrieve information from the Internet.

However, VPN traffic is susceptible to being identified by firewalls (Deep Packet Inspection), leading to its prohibition. Enter Shadowsocks - A secure and fast tunnel proxy designed to protect internet traffic and was first released in April 2012.

This article will guide you through setting up a Shadowsocks proxy server(socks 5 proxy server) with Cloak on Ubuntu 22/AlmaLinux 9/Rocky Linux 9 to circumvent firewalls. Moreover, this post will also show you how to configure Shadowsocks client in any Linux and Android device. 

What is Shadowsocks?

Shadowsocks is a secure and freely available proxy protocol created to circumvent online censorship by encrypting data packets as they travel from the user to the server.  It is a secure proxy based on SOCKS5 and connects through an external server to hide the user's apparent location.

When a user from a restricted region connects to a Shadowsocks server, it not only encrypts traffic but also obfuscates the connection making it hard for the intermediaries to determine the type of information being sent. The encrypted data is subsequently tunneled through the secured link, enabling users to reach the internet without any restrictions.

 

 

How do Shadowsocks work?

Shadowsocks functions using a client-server architecture and operates at the socket level, but it is not classified as a VPN protocol. The Shadowsocks encrypt the connection between your device and the proxy server using SOCKS5 protocol and mask the traffic as a normal and legitimate connection, indistinguishable from normal web traffic, rendering detection extremely difficult for firewalls.      

The main advantage of Shadowsocks is that it is fast compared to traditional VPNs and flexible. It can be used to run on multiple servers and ports in diverse network environments and cannot be outrightly blocked like OpenVPN.

Prerequisites

To install the Shadowsocks proxy server on Ubuntu 22.04, AlmaLinux 9, or Rocky Linux 9, ensure you meet the following requirements.

  • A virtual machine running AlmaLinux 9, Rocky Linux 9, or Ubuntu 22.04.
  • SSH access to the virtual machine with sudo privilege.

The steps given in the next section will guide you through setting up a Shadowsocks-rust (a port of Shadowsocks) server on a Linux-based distro such as AlmaLinux 9, Ubuntu 22.04, or Rocky Linux 9.

Setting up Shadowsocks server in Linux

There are 4 different implementations of Shadowsocks available. Have a look at Shadowsock's different implementations and feature comparisons. Nonetheless, this guide will show you how to install a shadowsocks-rust server and connect it using a Shadowsocks client.

Download and extract Shadowsocks binary

Download Shadowsocks rust implementation and unpack the tar file.

$ sudo mkdir -p /opt/shadowsocks-rust
$ cd /opt/shadowsocks-rust
$ sudo wget https://github.com/shadowsocks/shadowsocks-rust/releases/download/v1.20.3/shadowsocks-v1.20.3.x86_64-unknown-linux-gnu.tar.xz
$ sudo tar xf shadowsocks-v1.20.3.x86_64-unknown-linux-gnu.tar.xz
$ sudo rm shadowsocks-v1.20.3.x86_64-unknown-linux-gnu.tar.xz
$ export PATH=$PATH://opt/shadowsocks-rust

Update the PATH environment variable in the bash profile to make the setting permanent.

$ echo 'export PATH=$PATH:/opt/shadowsocks-rust' >> ~/.bashrc
$  .  ~/.bashrc

The extracted tar file will contain the following five binaries -

  • sslocal: The Shadowsocks client-side component that runs on the local machine and routes encrypted traffic to the Shadowsocks server. It creates a local proxy on your machine.
  • ssserver: The server-side component of Shadowsocks. The ssserver is used to set up a Shadowsocks server on a remote machine.
  • ssservice: A service-oriented interface for managing the Shadowsocks server. It is designed to run as a system service or daemon, making it more suitable for production environments to start and stop Shadowsocks servers easily.
  • ssmanager: Another server-side component designed to handle advanced features such as managing multiple server instances, monitoring connections, and dynamically adjusting configurations.
  • ssurl: A utility for generating Shadowsocks configuration URLs. You can create a Shadowsocks URL encapsulating the necessary connection parameters for Shadowsocks clients. 

All these components work together to provide a reliable and encrypted proxy service to bypass censorship and maintain privacy. A specific role is attached to each of these components in the Shadowsocks eco-system, whether it's handling server operations, managing client connections, or facilitating configuration and management.

Setup shadowsocks-rust server

The setup process of the Shadowsocks-rust server consists of creating a configuration file by specifying an encryption method and a password for Shadowsocks server and optional users.

First of all, generate secured passwords for Shadowsocks main config and two test users  - user1 and user2, specifying an encryption method.

$ ssservice genkey -m "chacha20-ietf-poly1305"
OjTfu6bpRC3PYcL5sG8gg2rsqEAA553vw0nQjByP7Qw=   ← Password for the main config.
$ ssservice genkey -m "chacha20-ietf-poly1305"
FAY+RIcbrdzZtF8D2H36f8iyJsoY5srAIb59oYwJOi8=  ← Password for User1
$ ssservice genkey -m "chacha20-ietf-poly1305"
1RHu7Q+UDbdBRNmi01UCNTV3EAFC5P3FDTMEnsvhcEQ=  ← Password for User2

The cipher used in the above example is chacha20-ietf-poly1305. The supported ciphers are:

AEAD 2022 Ciphers

  • 2022-blake3-aes-128-gcm, 2022-blake3-aes-256-gcm
  • 2022-blake3-chacha20-poly1305, 2022-blake3-chacha8-poly1305

These Encryption methods require "password" to be Base64 sequence of keys, all of which should match the length of the Cipher's Key Size. 

AEAD Ciphers

  • chacha20-ietf-poly1305
  • aes-128-gcm, aes-256-gcm

Stream Ciphers

  • plain or none (No encryption, only used for debugging or with plugins that ensure transport security)

In this step, you will create a JSON configuration file(config.json) for the Shadowsocks rust server.  Adjust the values for SERVER_IP, INTERFACE and PASSWORD from the following configuration file according to your environment. 

$ sudo mkdir -p /etc/shadowsocks-rust
$ sudo vi /etc/shadowsocks-rust/config.json
{
   "server": "0.0.0.0", 
   "outbound-bind-interface": "<INTERFACE>", ← Outbound network interface
   "ipv6_first": false,
   "ipv6_only": false,
   "server_port": 1080,
   "password": "<PASSWORD>", ← Password for main config.
   "mode": "tcp_and_udp",
   "method": "chacha20-ietf-poly1305",  ← Method you choose previously to generate above password.
   "timeout": 300,
   "udp_timeout": 300,
   "udp_max_associations": 512,
   "nameserver": "1.1.1.1",
   "users": {
              "user1": "<PASSWORD_USER1>",  ← Password for User1
              "user2": "<PASSWORD_USER2>"   ← Password for User2
    }
}

Save the configuration file and run Shadowsocks rust server.

$ ssserver -c /etc/shadowsocks-rust/config.json 
2024-08-05T19:55:59.503899239+05:30  INFO shadowsocks server 1.20.3 build 2024-07-28T17:34:01.470449595+00:00    
2024-08-05T19:55:59.504820481+05:30  INFO shadowsocks tcp server listening on 0.0.0.0:1080, inbound address 0.0.0.0:1080    
2024-08-05T19:55:59.534968792+05:30  INFO shadowsocks udp server listening on 0.0.0.0:1080, inbound address 0.0.0.0:1080
...
...

To start the server in the background, use the following command.

$ ssserver -c /etc/shadowsocks-rust/config.json -d start
$ ssserver -c /etc/shadowsocks-rust/config.json -d stop

Create a Systemd unit file for Shadowsocks server

To make it easier to start/stop Shadowsocks server and to run automatically during reboot, create a systemd service unit file and paste the following content.

$ sudo vi /etc/systemd/system/shadowsocks-rust-server@.service
[Unit]
Description=Shadowsocks-rust ssserver on %I
Documentation=https://github.com/shadowsocks/shadowsocks/wiki
After=network.target
Wants=network.target
[Service]
ExecStart=/opt/shadowsocks-rust/ssserver -c /etc/shadowsocks-rust/config.json
Restart=on-failure
LimitNOFILE=4096
[Install]
WantedBy=multi-user.target

Reload the systemd configurations and enable the service unit.

$ sudo systemctl daemon-reload
$ sudo systemctl enable --now shadowsocks-rust-server@config
$ sudo systemctl status shadowsocks-rust-server@config
● shadowsocks-rust-server@config.service - Shadowsocks-rust ssserver on config
     Loaded: loaded (/etc/systemd/system/shadowsocks-rust-server@.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2024-08-05 20:19:17 IST; 3min 46s ago
       Docs: https://github.com/shadowsocks/shadowsocks/wiki
   Main PID: 491482 (ssserver)
      Tasks: 4 (limit: 8890)
     Memory: 1.7M
        CPU: 8ms
     CGroup: /system.slice/system-shadowsocks\x2drust\x2dserver.slice/shadowsocks-rust-server@config.service
             └─491482 /opt/shadowsocks-rust/ssserver -c /etc/shadowsocks-rust/config.json

Adjust Firewall for shadowsocks-rust server

If firewall is active in your server then open the port used by server_port as set in the configuration file.

On AlmaLinux or Rocky Linux:

$ sudo firewall-cmd --permanent --add-port=1080/tcp 
$ sudo firewall-cmd --permanent --add-port=1080/udp
$ firewall-cmd --reload

On Ubuntu:

$ sudo ufw allow 1080/tcp
$ sudo ufw allow 1080/udp
$ sudo ufw reload

Setup Shadowsocks Client

The Shadowsocks-rust server is now ready to accept proxy connections from clients. To connect with the Shadowsocks server, you require a Shadowsocks client. This official download page provides a list of all Shadowsocks clients.

Select a client for yourself and try out the connection Shadowsocks server using the steps given below.

Connect from Linux client(CLI)

To establish a connection from a Linux device, please extract and install the Shadowsocks binary that we've previously utilized for setting up the Shadowsocks server. However, this time, we'll employ the sslocal CLI rather than the ssserver.

Create a JSON configuration file for the Shadowsocks client specifying the IP address of the socks server, port, password, method, and a few others as deemed necessary.

$ cat client_user1.json
{
   "server":"13.215.228.234",
   "server_port":1080,
   "local_address":"127.0.0.1",
   "local_port":1080,
   "password":"FAY+RIcbrdzZtF8D2H36f8iyJsoY5srAIb59oYwJOi8=",
   "timeout":60,
   "method":"chacha20-ietf-poly1305",
    "nameserver":"1.1.1.1"
}

Connect Shadowsocks server using sslocal CLI.

$ sslocal -c client_user1.json
2024-08-06T10:48:58.011575718+05:30  INFO shadowsocks local 1.20.3 build 2024-07-28T17:34:01.470449595+00:00    
2024-08-06T10:48:58.015918885+05:30  INFO shadowsocks socks TCP listening on 127.0.0.1:1080
…
…

This creates a local proxy in the client system establishes a connection with the remote Shadowsocks server and routes traffic through this tunnel.

Verify that the traffic is routing through socks proxy server.

$ curl --proxy socks5://127.0.0.1:1080 https://ifconfig.me
2406:da18:5cd:9800:95fa:d87f:d031:3844

In case you want to utilize a web browser to route packets via this local proxy client, modify the browser's connection settings. For instance, the connection settings for Firefox to leverage the local proxy client is given below.


Firefox Shadowsocks Proxy settings


 

Connect from an Android device

To connect the Shadowsocks proxy server from your Android phone, you need to first search and install the Shadowsocks app from PlayStore.

Once the installation of the Shadowsocks app is over, Update service mode to Proxy through Settings->Advanced->Service.

Next, use the ssurl utility to generate and encode the socks proxy URL for each user. Optionally you can use the option --qrcode to generate a QR code for the user in the terminal. 

To generate a URL for each user using the ssurl utility, specify the server address, password for the user, and the method used in a JSON configuration file.

{
   "server": "SERVER_ADDRESS",
   "server_port": 1080,
   "password": "FAY+RIcbrdzZtF8D2H36f8iyJsoY5srAIb59oYwJOi8=", 
   "method": "chacha20-ietf-poly1305" 
}

Now generate an encoded URL for user1.

$ ssurl --encode user1.json
ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpGQVkrUkljYnJkelp0RjhEMkgzNmY4aXlKc29ZNXNyQUliNTlvWXdKT2k4PQ@SERVER_IP:1080 

Add the option --qrcode in case you want to generate QR code for the user.

$ ssurl --encode user1.json --qrcode
ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpGQVkrUkljYnJkelp0RjhEMkgzNmY4aXlKc29ZNXNyQUliNTlvWXdKT2k4PQ@SERVER_IP:1080

In your handset, import either encoded URI or QR code using Shadowsocks app. Edit the profile and change Route to 'GFW list' and optionally tick the IPv6 Route option.


Update Cloak Client Setting in Android


To activate the connection, select the imported profile and tap on the Shadowsocks icon to get connected with the socks proxy server.

So far so good. The Shadowsocks proxy is operational. However, the concern remains - Could the traffic be flagged by the firewall? Unfortunately, yes. The reason for this is that the hardware used in the firewalls has improved significantly since Shadowsocks was first introduced in the year 2012 and secondly the introduction of an active probing system in restricted regions to detect Shadowsocks traffic.

Does this imply that traffic from Shadowsocks can't get past the firewalls? Not at all. Since the Shadowsocks has been implemented with plugin architecture(SIP003), adding a layer of obfuscation using any one of these plugins allows Shadowsocks traffic to slip past the firewalls.

A few known good plugins are -

Let's Continue with adding the Cloak plugin to the shadowsocks proxy server to add a layer of obfuscation.

Configure Shadowsocks with Cloak

Cloak is a pluggable transport utility that can mask proxy traffic as genuine HTTPS traffic and appear as regular web traffic. It can be used alongside any proxy system such as Shadowsocks, OpenVPN, and Tor. In this section, we will configure Shadowsocks with Cloak plugin (Shadowsocks + Cloak).

The Cloak plugin can be installed either by building from source or by downloading the binary depending on the architecture. We will use the second option.

$ cd /opt/shadowsocks-rust
$ sudo mkdir -p cloak
$ cd cloak
$ sudo wget https://github.com/cbeuw/Cloak/releases/download/v2.9.0/ck-server-linux-amd64-v2.9.0
$ sudo mv ck-server-linux-amd64-v2.9.0 ck-server-linux
$ sudo chmod 755 ck-server-linux

Update the Shadowsocks server configuration file with Cloak plugin path and options.

$ sudo vi /etc/shadowsocks-rust/config.json
{
  "server": "0.0.0.0",
  "outbound-bind-interface": "ens5",
  "ipv6_first": false,
  "ipv6_only": false,
  "server_port": 1080,
  "password": "OjTfu6bpRC3PYcL5sG8gg2rsqEAA553vw0nQjByP7Qw=",
  "mode": "tcp_and_udp",
  "method": "chacha20-ietf-poly1305",
  "timeout": 300,
  "udp_timeout": 300,
  "udp_max_associations": 512,
  "nameserver": "1.1.1.1",
  "users": {
             "user1": "FAY+RIcbrdzZtF8D2H36f8iyJsoY5srAIb59oYwJOi8=",
             "user2": "1RHu7Q+UDbdBRNmi01UCNTV3EAFC5P3FDTMEnsvhcEQ="
   },
  "plugin": "/opt/shadowsocks-rust/cloak/ck-server-linux", ← Cloak plugin path.
  "plugin_opts": "/opt/shadowsocks-rust/cloak/ckserver.json" ← Cloak ProxyBook configuration file.
}

At this moment, we need to add a Cloak proxybook configuration file. But Before creating this configuration file(ckserver.json), generate keys for the Cloak server.

$ /opt/shadowsocks-rust/cloak/ck-server-linux -key
Your PUBLIC key is:                      H9IFQgcmlC95mjG88oNDffy/G18+dclpG6CKkUnDMig=
Your PRIVATE key is (keep it secret):    6LYMCXu49jpRhiWyp9kvxjMOpUVI8WKdxbHCAS4f9FA=

We will use the generated public key to configure the Cloak server while the private key must remain confidential.

Next, generate an UID to be used as AdminUID in the Cloak server.

$ /opt/shadowsocks-rust/cloak/ck-server-linux -uid
Your UID is: ZnW1HxgQWhaWIJG5SJeu/w==

Now, add the proxy servers running in the localhost along with the Keys and Admin ID in the Cloak ProxyBook configuration file. Apart from adding Shadowsocks server in the proxybook configuration, you can also configure Cloak to obfuscate OpenVPN traffic.  But for that you need to install a OpenVPN server which we will not cover in this article.

$ sudo vi /opt/shadowsocks-rust/cloak/ckserver.json
{
 "ProxyBook": {
   "shadowsocks": [
     "tcp",
     "127.0.0.1:1080"
   ],
   "openvpn": [
     "udp",
     "127.0.0.1:8389"
   ]
 },
 "BindAddr": [
   ":443",
   ":80"
 ],
 "RedirAddr": "cloudflare.com",
 "PrivateKey": "4G/RC0Dci6P/4hoOBxsuypmiPX7jUvflWQGkfBgHZGg=",
 "AdminUID": "qpuXi+xuwqcM3NPakF9i5w==",
 "DatabasePath": "userinfo.db"
}

Add the capability to the Clock server executable so as to bind to a port less than 1024(80 and 443). 

$ sudo setcap cap_net_bind_service+ep /opt/shadowsocks-rust/cloak/ck-server-linux

Update the shadowsocks rust server service configuration.

$ sudo vi /etc/systemd/system/shadowsocks-rust-server@.service
…
…
[Service]
ExecStart=/opt/shadowsocks-rust/ssserver -c /etc/shadowsocks-rust/config.json
Restart=on-failure
LimitNOFILE=32768
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
…
…

Restart Shadowsocks server.

$ sudo systemctl daemon-reload
$ sudo systemctl restart shadowsocks-rust-server@config

Verify the port number opened by Cloak.

$ sudo netstat -pltn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:37929         0.0.0.0:*               LISTEN      4094/ssserver       
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1232/sshd: /usr/sbi 
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      331/systemd-resolve 
tcp6       0      0 :::443                  :::*                    LISTEN      4098/ck-server-linu 
tcp6       0      0 :::80                   :::*                    LISTEN      4098/ck-server-linu 
tcp6       0      0 :::22                   :::*                    LISTEN      1232/sshd: /usr/sbi 
tcp6       0      0 :::1080                 :::*                    LISTEN      4098/ck-server-linu

Adjust the firewall rules for port number 80 and 443 opened by Cloak.

Ubuntu:

$ sudo ufw allow 80/tcp
$ sudo ufw allow 443/udp
$ sudo ufw reload

AlmaLinux/RockyLinux:

$ sudo firewall-cmd --permanent --add-port=80/tcp 
$ sudo firewall-cmd --permanent --add-port=443/udp
$ firewall-cmd --reload

Shadowsocks + Cloak Client Setup

Linux Client

Reconfigure your Shadowsocks client to add Cloak configuration in the client machine. First of all, Download  and extract Cloak client for Linux in a suitable location. 

$ cd /opt/shadowsocks-rust/cloak
$ sudo wget https://github.com/cbeuw/Cloak/releases/download/v2.9.0/ck-client-linux-amd64-v2.9.0
$ sudo sudo mv ck-client-linux-amd64-v2.9.0 ck-client
$ sudo chmod 755 ck-client
$ sudo setcap cap_net_bind_service+ep ck-client ← In case you want to bind cloak client to port < 1024

Create JSON file for Cloak client configuration and add the following parameters which includes UID and Public key that you have created previously.

$ sudo vi /opt/shadowsocks-rust/cloak/cloak-client.json
{
 "Transport": "direct",
 "ProxyMethod": "shadowsocks",
 "EncryptionMethod": "chacha20-ietf-poly1305",
 "UID": "T+Qh4JGRpgT8PK/r0T2GXQ==",
 "PublicKey": "dXqI9u+2PVxPBYNv96GW3yFyMjy+kuX50nGvadbzxS4=",
 "ServerName": "www.bing.com",
 "NumConn": 4,
 "BrowserSig": "chrome",
 "StreamTimeout": 300
}

Finally reconfigure the local proxy user’s settings and append the path of cloak plugin along with options.

$ vi ~/connect-user1.json
{
    "server":"SERVER_IP",
    "server_port":1080,
    "local_address":"127.0.0.1",
    "local_port":1080,
    "method":"chacha20-ietf-poly1305",
    "password":"PBO7kocJ+GwKDuLPOemHrakUgOZVuF5KAU+Pww496kY=",
    "timeout":60,
    "nameserver":"1.1.1.1",
    "plugin":"/opt/shadowsocks-rust/cloak/ck-client",
    "plugin_opts":"/opt/shadowsocks-rust/cloak/cloak-client.json"
}

Connect Shadowsocks server which was configured with Cloak. 

$ sslocal -c connect-user1.json -vvv

Verify that your traffic is running through the proxy.

$ curl --proxy socks5://127.0.0.1:1080 https://ifconfig.me
2406:da18:5cd:9800:95fa:d87f:d031:3844

Update the connection settings in the web browser in case you want access internet using Shadowsocks proxy.

Cloak Android Client

To use Cloak plugin alongside Shadowsocks in Android, download the Cloak-Android apk and install it. Once installation of Cloak-Android is over, open Shadowsocks app and tap edit profile icon. Now tap the Plugin and select Cloak plugin. Again tap Configure setting and provide Transport, UID, Public Key, Encryption method, Server Name, Browser Signatures, Timeout values. For testing as a shadowsocks vpn, bring back the service mode to VPN through Settings->Advanced->Service.


Shadowsocks Cloak settings in Android


Tap the Cloak icon to start the Shadowsocks client in your handset. 
 


Shadowsocks with Cloak in Android


Update the proxy settings in the web browser and navigate to https://ifconfig.me to verify the IP address of the Shadowsocks proxy server.

 

 

Conclusion

In conclusion, it doesn't make much sense to utilize Shadowsocks without any additional plugins, since it can be easily blocked. But using shadowsocks along with a plugin for example, Cloak is a better option. Nonetheless, Shadowsocks is an open-source, secure and fastest proxy available freely for maintaining anonymity. 

The Shadowsocks proxy server is undoubtedly one of the best proxy server and generally used to bypass censorship and to remains undetected. However, anonymous proxies are used by unscrupulous elements for illegal activities due to their anonymity. Therefore, it is also equally important to have tools to detect proxy traffic. The detection of proxy traffic using deep learning is a hot research topic nowadays since it can automatically extract and select traffic signatures.

fivestar_rating
No votes yet