paint-brush
Installing Shadowsocks-rust: a Secure, Open-source Proxy Server, Better Than VPNby@xakru
6,270 reads
6,270 reads

Installing Shadowsocks-rust: a Secure, Open-source Proxy Server, Better Than VPN

by Ruslan Kh.June 29th, 2023
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Struggling with VPN blocks? This guide provides a step-by-step method to tunnel OpenVPN through Shadowsocks to bypass VPN restrictions. Learn about the requirements, necessary OpenVPN server settings, and how to modify the OpenVPN configuration. Improve your online privacy and enjoy unrestricted access to global content while complying with local laws and regulations. Remember, information is power, and everyone deserves access to it.
featured image - Installing Shadowsocks-rust: a Secure, Open-source Proxy Server, Better Than VPN
Ruslan Kh. HackerNoon profile picture

Links:

Shadowsocks-rust homepage

Shadowsock-rust Doc

Outline Apps


Shadowsocks is a secure, open-source proxy server that allows users to bypass Internet censorship and restrictions in countries where VPN connections are prohibited. It is designed to provide encryption and confidentiality for users' Internet traffic, making it a popular choice for those who do not need a full VPN server but still want to protect their online activities. Shadowsocks offers better performance than OpenVPN, providing faster connections and lower latency.


In this article, we will walk you through the process of setting up a Shadowsocks-Rust server on Ubuntu 22 or Rocky Linux 9.1 for both x86_64, arm64 architectures, and show you how to bypass firewalls and Internet censorship and restrictions in countries where VPN connections are prohibited with various clients, including Windows, macOS, Linux, Android, and iOS.


In the vast expanse of today's interconnected world, the Internet stands as an unprecedented source of information, a vital tool for education, communication, and expression. However, not all users enjoy the same level of access or freedom. In many regions, Internet censorship and surveillance are serious concerns, limiting access to information and violating privacy rights.


For those living under such conditions, virtual private networks (VPNs) have been a common tool for circumventing these restrictions. However, popular VPN technologies such as OpenVPN are often targeted and blocked. Enter Shadowsocks - a secure Socks5 proxy designed to protect your Internet traffic. This article will dive into the world of Shadowsocks, compare it to OpenVPN, and guide you through setting up a Shadowsocks server in a Linux virtual machine.

Unveiling the Shadowsocks: An Overview

Shadowsocks, an open source project born in the mid-2010s, was created by a Chinese programmer using the pseudonym "clowwindy" as a method of circumventing the Great Firewall of China. Unlike traditional VPN protocols, Shadowsocks works at the socket level, which means it's less likely to be detected and blocked.


One of the main advantages of Shadowsocks is its flexibility. It works on a client-server model and can be configured to use multiple ports and servers. This makes it highly adaptable to different network environments and difficult to block outright, especially when compared to VPNs such as OpenVPN.

Shadowsocks vs. OpenVPN: A Comparison

When comparing Shadowsocks to OpenVPN, the first noticeable difference is in the design philosophy. OpenVPN is a full-featured open source VPN solution that implements Virtual Private Networking techniques to create secure point-to-point or site-to-site connections. It uses robust encryption and offers a wide range of configuration options, making it a popular choice for businesses and individuals seeking a high level of security and privacy.


Shadowsocks, on the other hand, is not technically a VPN - it's a secure proxy. It was designed to be lightweight, flexible, and undetectable, rather than focusing on creating a fully encrypted tunnel for all traffic. This makes Shadowsocks faster and more suitable for circumventing censorship, while OpenVPN may be more appropriate for sensitive communications that require high levels of encryption.


However, the main advantage of Shadowsocks is its resistance to detection and blocking. Because it operates at the socket level and mimics regular HTTPS traffic, it's more difficult for censors to detect and block than traditional VPN protocols like OpenVPN.


Pros and Cons of Shadowsocks VS OpenVPN:


Pros:

  1. Faster connections and lower latency than OpenVPN

  2. Lightweight, easy to set up and use

  3. Suitable for bypassing censorship and securing internet traffic


Cons:

  1. Less secure than OpenVPN
  2. Not suitable for a full VPN solution
  3. Less well-known and less widely supported than OpenVPN


Note: This tutorial assumes that you have basic knowledge of the Linux command line interface and that you've already rented a virtual private server (VPS). If not, I recommend providers like DigitalOcean, Linode, Hetzner, Google Cloud Platform, Amazon Lightsail or Vultr for their low prices and high quality service.

Setting up an Shadowsocks Server on Linux

Now that we understand the advantage of Shadowsocks in circumventing censorship, let's move on to the practical side of things: setting up an Shadowsocks-rust server.

Prerequisites

Before setting up a Shadowsocks-rust server, make sure you have the following

  • A virtual machine running Ubuntu 22 or Rocky Linux 9.x, CentOS 9
  • A stable Internet connection
  • Root access to your virtual machine


The following steps will guide you through setting up an Shadowsocks-rust server on Linux-based distributions such as Ubuntu, Debian, and Rocky Linux 9.

Step 1: Connect to your server via SSH

Using a terminal application, connect to your server via SSH. The command should look like this:

ssh root@your_server_ip

Enabling the Firewall - Ubuntu (ufw), Rocky Linux (firewalld)

For our example, we will use port 12345 for the shadowsocks-rust server.

  • For Ubuntu, enable the Uncomplicated Firewall (ufw) and allow connections to the chosen port number:
sudo apt install ufw
sudo ufw enable
sudo ufw allow 12345


  • For Rocky Linux, enable firewalld and add the chosen port number:
sudo dnf install firewalld
sudo systemctl enable firewalld
sudo systemctl start firewalld
sudo firewall-cmd --add-port=12345/tcp --permanent
sudo firewall-cmd --add-port=12345/udp --permanent
sudo firewall-cmd --reload


Getting binary

  • Download Linux arm64 binary
wget https://github.com/shadowsocks/shadowsocks-rust/releases/latest/download/shadowsocks-v1.15.3.aarch64-unknown-linux-gnu.tar.xz -P /opt/
  • Download Linux amd64 binary
wget https://github.com/shadowsocks/shadowsocks-rust/releases/latest/download/shadowsocks-v1.15.3.x86_64-unknown-linux-gnu.tar.xz -P /opt/


  • Unpack the archive and place the binaries in /sbin
tar xf /opt/shadowsocks-*-linux-gnu.tar.xz -C /sbin/ --owner=root --group=root
rm /opt/shadowsocks-*-unknown-linux-gnu.tar.xz


The sslocal, ssserver, ssmanager, and ssurl files are components of the Shadowsocks software that serve several purposes:

  1. sslocal: This is the client-side component of Shadowsocks that runs on the client machine and sets up a local SOCKS5 proxy server. sslocal connects to a remote Shadowsocks server and routes network traffic over an encrypted connection.
  2. sserver: This is the server-side component of Shadowsocks, running on a remote server. ssserver receives encrypted network traffic from sslocal clients, decrypts it, and forwards it to the appropriate resources on the network. It provides network protection and circumvents censorship.
  3. ssmanager: This is a management tool provided by Shadowsocks. It allows you to manage and monitor the Shadowsocks server instance, including user management, connections, and other configuration aspects.
  4. ssurl: This is a command line tool that provides a convenient way to create and manipulate Shadowsocks URL links. With ssurl you can create URL links containing Shadowsocks connection parameters that can be easily shared or used for automated configuration of client applications.


Each of these components serves a purpose within the Shadowsocks ecosystem and allows you to use Shadowsocks to circumvent Internet censorship, encrypt traffic, and ensure the security of data transmitted over the network.

Preparing setup the shadowsocks-rust server

Please follow these steps:

  • Create config directory - shadowsocks-rust:
mkdir /etc/shadowsocks-rust


Choosing the right way to generate passwords

Generate a strong and secure password for a particular encryption method (aes-256-gcm in the example) using ssservice command:

PASSWORD_0=$(ssservice genkey -m "aes-256-gcm")
PASSWORD_1=$(ssservice genkey -m "aes-256-gcm")
PASSWORD_2=$(ssservice genkey -m "aes-256-gcm")

echo $PASSWORD_0
> sL6AGKwpq7jL9rzuNw2WYMqwwshdDaD5GZfMEPPLkD4=

echo $PASSWORD_1
> owFeiip+csfybzDORoM1iYx+BkWtm8M98LaSpbbEQvU=

echo $PASSWORD_2
> HF53R3jOZxptyR3JN/rvqTLatjDMXANgEyGNAiNiO1s=


Or we can generate a safe and secured password for a specific encryption method (chacha20-ietf-poly1305 in the example) with options below:

PASSWORD_0=$(ssservice genkey -m "chacha20-ietf-poly1305")
PASSWORD_1=$(ssservice genkey -m "chacha20-ietf-poly1305")
PASSWORD_2=$(ssservice genkey -m "chacha20-ietf-poly1305")

# password for main config
echo $PASSWORD_0
> VzallAhG0DD7p4mxM706LM30giGCehiOuFNb/Lv3/qY=

# password for guest1
echo $PASSWORD_1
> x6NSC8qE2bpt9tZ/DsQQlULD8MuonFcy2IJEvuI0yZo=

# password for guest2
echo $PASSWORD_2
> YA5PQFwD6zHCkH8QA5oCDLGWSa2G7hSZxMIsslvEJaM=


Choosing AEAD ciphers (method)

Supported ciphers

AEAD 2022 ciphers

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

These ciphers require "password" to be a Base64 key string of exactly the same length as the cipher's key size.

It is recommended to use the command below to generate a secure and safe key:

sservice genkey -m "METHOD_NAME"`


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)

Deprecated on Jun-2023

  • table
  • aes-128-cfb, aes-128-cfb1, aes-128-cfb8, aes-128-cfb128
  • aes-192-cfb, aes-192-cfb1, aes-192-cfb8, aes-192-cfb128
  • aes-256-cfb, aes-256-cfb1, aes-256-cfb8, aes-256-cfb128
  • aes-128-ctr
  • aes-192-ctr
  • aes-256-ctr
  • camellia-128-cfb, camellia-128-cfb1, camellia-128-cfb8, camellia-128-cfb128
  • camellia-192-cfb, camellia-192-cfb1, camellia-192-cfb8, camellia-192-cfb128
  • camellia-256-cfb, camellia-256-cfb1, camellia-256-cfb8, camellia-256-cfb128
  • rc4-md5
  • chacha20-ietf


For the average user, the differences between the ChaCha20-IETF-Poly1305 and AES-256-GCM encryption algorithms are obvious in terms of performance, security, and compatibility.

  1. Performance:

    ChaCha20-IETF-Poly1305 is often faster on devices with less powerful processors or without hardware support for AES. It is designed to provide high performance on a variety of platforms, especially mobile and IoT devices. AES-256-GCM performs well on modern devices with hardware acceleration for AES. On devices with AES-NI (Intel) or ARMv8-A Cryptography Extensions (ARM), AES-256-GCM may be faster than ChaCha20-IETF-Poly1305.

  2. Security: Both ChaCha20-IETF-Poly1305 and AES-256-GCM provide a high level of security. ChaCha20 is a stream cipher combined with the Poly1305 authenticator, which together form an authenticated encryption with associated data (AEAD) construction. AES-256-GCM is also an AEAD cipher that combines the AES block cipher with the Galois/Counter Mode (GCM) operation. Both ciphers have been extensively analyzed by the cryptographic community and are considered secure. However, the choice between them may depend on your confidence in the implementation and potential vulnerabilities in the hardware acceleration.

  3. Compatibility:

    AES-256-GCM is more widely adopted and has better compatibility across devices and platforms. It has been a standard for longer and benefits from built-in hardware acceleration on many modern processors. ChaCha20-IETF-Poly1305, while increasingly popular, may not be supported on all platforms or by all software.


In summary, for the average user, the choice between ChaCha20-IETF-Poly1305 and AES-256-GCM may depend on the devices being used and their specific performance characteristics. ChaCha20-IETF-Poly1305 may be a better choice for mobile devices and IoT devices without hardware acceleration for AES, while AES-256-GCM may be more suitable for devices with hardware support for AES and a need for cross-platform compatibility. Both encryption methods are considered secure and provide strong protection for your data.


Configuring shadowsocks-rust service

Create a JSON configuration file for the shadowsocks server. Replace <PORT> and <PASSWORD> with the port number and password you chose earlier:


aes-256-gcm:

{
    "server": "::",
    "outbound-bind-interface": "eth0",
    "ipv6_first": false,
    "ipv6_only": false,
    "server_port": 12345,
    "mode": "tcp_and_udp",
    "method": "aes-256-gcm",
    "password": "<PASSWORD>",
    "timeout": 300,
    "udp_timeout": 300,
    "udp_max_associations": 512
}


chacha20-ietf-poly1305:

{
    "server": "::",
    "outbound-bind-interface": "eth0",
    "ipv6_first": false,
    "ipv6_only": false,
    "server_port": 12345,
    "password": "<PASSWORD>",
    "mode": "tcp_and_udp",
    "method": "chacha20-ietf-poly1305",
    "timeout": 300,
    "udp_timeout": 300,
    "udp_max_associations": 512
}


To add multiuser support in shadowsocks-rust, you need to modify the configuration file accordingly:

 {
    "server": "::",
    "outbound-bind-interface": "eth0",
    "ipv6_first": false,
    "ipv6_only": false,
    "server_port": 12345,
    "password": "<PASSWORD>",
    "mode": "tcp_and_udp",
    "method": "chacha20-ietf-poly1305",
    "timeout": 300,
    "udp_timeout": 300,
    "udp_max_associations": 512,
    "users": {
        "guest1": "<PASSWORD_1>",
        "guest2": "<PASSWORD_2>"
    }
}


Save the file as ssserver-guest.json in a /etc/shadowsocks-rust/ location that we created earlier in the virtual machine.


Creating Systemd Unit file.

  • Create a new file with a .service extension, for our example /etc/systemd/system/[email protected]. We use the systemd template with the @ sign.


touch /etc/systemd/system/[email protected]


  • Open the file in a text editor.


[Unit]
Description=Shadowsocks-rust ssserver on %I
Documentation=https://github.com/shadowsocks/shadowsocks/wiki
After=network.target
Wants=network.target

[Service]
ExecStart=/sbin/ssserver -c /etc/shadowsocks-rust/ssserver-%i.json
Restart=on-failure
User=nobody
Group=nobody
LimitNOFILE=4096

[Install]
WantedBy=multi-user.target


  • After creating the systemd unit file, then run the following commands to apply the changes and start the service:


systemctl daemon-reload
systemctl start ssserver@guest
systemctl enable ssserver@guest


  • Now, ssserver will be running as a service through systemd and will start automatically on system boot. You can use commands to manage the service:


systemctl status shadowsocks-server
systemctl restart shadowsocks-server
systemctl stop shadowsocks-server


Setup shadowsocks clients.

Crossplatform solution: Outline

  • Get the Outline Client App for your platform.



  • Generate Access Keys (Go to the "Generate Access Keys" step)


Setting up Shadowsocks clients on Windows, macOS:

Windows

- Download the latest release of the Shadowsocks Windows client from the official GitHub repository. - Extract the zip file. - Run Shadowsocks.exe.



- Right-click on the tray icon, go to Servers > Server.



- Fill in the Server FQDN or Server IP, Server Port, Password, and Encryption method as per your Shadowsocks server configuration.

- Click on OK.

- Go to your web browsers proxy settings (Firefox proxy settings are shown below). Set your settings to be like below. Now all your browser traffic will be going via the ShadowSocks Server.



- Right-click on the tray icon and choose Enable System Proxy to start using Shadowsocks.




macOS - Download the latest release of the ShadowsocksX-NG client from the official GitHub repository. - Open the dmg file and drag the application to your Applications folder. - Run ShadowsocksX-NG. - Click on the tray icon, go to Servers > Server Preferences.


- Click on the + button at the bottom left.


- Fill in the Server IP, Server Port, Password, and Encryption method as per your Shadowsocks server configuration. - Click on OK. - Click on the tray icon and choose Turn Shadowsocks On to start using Shadowsocks.


ShadowsocksX-NG modes


ShadowsocksX-NG provides three modes of operation: PAC (Proxy Auto Config) mode, Global mode, and Manual mode:

  • PAC (Proxy Auto Config) Mode: In this mode, ShadowsocksX-NG generates a PAC (Proxy Auto Config) file from the GFW (Great Firewall of China) list and sets the system's network settings to use this PAC file. As a result, when running in this mode, the domain names listed in the GFW list will be accessed through Shadowsocks Server.
  • Global mode: In this mode, ShadowsocksX-NG sets the system's network preferences to use the Shadowsocks proxy server for all network activity. This means that all network traffic, regardless of its destination, will be sent through Shadowsocks Server.
  • Manual mode: In this mode, ShadowsocksX-NG starts the proxy server, but doesn't set any network system preferences. This gives you the flexibility to set the network system preferences yourself, or set preferences for specific applications to use the Shadowsocks proxy. Essentially, this mode allows selective routing of network traffic through the Shadowsocks Server.


Generate Access Keys

To create Shadowsocks URLs for your users, who can then use it for Outline, Shadowsocks clients, you will need to use the --encode parameter for the ssurl command, which takes a JSON configuration file as an argument.


  1. Let's go back to our shadowsocks server configuration file. We're going to generate passwords according to the instructions at the beginning.


  • Passwords:
PASSWORD_0=$(ssservice genkey -m "chacha20-ietf-poly1305")
PASSWORD_1=$(ssservice genkey -m "chacha20-ietf-poly1305")
PASSWORD_2=$(ssservice genkey -m "chacha20-ietf-poly1305")

# password for main config
echo $PASSWORD_0
> VzallAhG0DD7p4mxM706LM30giGCehiOuFNb/Lv3/qY=

# password for guest1
echo $PASSWORD_1
> x6NSC8qE2bpt9tZ/DsQQlULD8MuonFcy2IJEvuI0yZo=

# password for guest2
echo $PASSWORD_2
> YA5PQFwD6zHCkH8QA5oCDLGWSa2G7hSZxMIsslvEJaM=


  • Shadowsocks-rust server config:
 {
    "server": "::",
    "outbound-bind-interface": "eth0",
    "ipv6_first": false,
    "ipv6_only": false,
    "server_port": 12345,
    "password": "VzallAhG0DD7p4mxM706LM30giGCehiOuFNb/Lv3/qY=",  // PASSWORD_0
    "mode": "tcp_and_udp",
    "method": "chacha20-ietf-poly1305",
    "timeout": 300,
    "udp_timeout": 300,
    "udp_max_associations": 512,
    "users": {
        "guest1": "x6NSC8qE2bpt9tZ/DsQQlULD8MuonFcy2IJEvuI0yZo=",  // PASSWORD_1
        "guest2": "YA5PQFwD6zHCkH8QA5oCDLGWSa2G7hSZxMIsslvEJaM="   // PASSWORD_2
    }
}


  1. Now, based on the server configuration, we will prepare the client JSON configuration

for each user for the ssurl link generator.


{
    "server": "SERVER_IP / SEVER_FQDN",
    "server_port": 12345,
    "password": "x6NSC8qE2bpt9tZ/DsQQlULD8MuonFcy2IJEvuI0yZo=", // PASSWORD_1
    "method": "chacha20-ietf-poly1305"  // encryption_method
}


{
    "server": "SERVER_IP / SEVER_FQDN",
    "server_port": 12345,
    "password": "YA5PQFwD6zHCkH8QA5oCDLGWSa2G7hSZxMIsslvEJaM=", // PASSWORD_2
    "method": "chacha20-ietf-poly1305"  // encryption_method
}


  1. Use the ssurl utility with the --encode option to generate a Shadowsocks URL for each user:
ssurl --encode path_to_user_config.json
> ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTp4Nk5TQzhxRTJicHQ5dFovRHNRUWxVTEQ4TXVvbkZjeTJJSkV2dUkweVpvPQ@SERVER_IP:12345


Replace path_to_user_config.json with the path to the user's JSON configuration file.


  1. If you want to generate a QR code in your terminal, you can add the --qrcode option:
ssurl --encode path_to_user_config.json --qrcode
> ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTp4Nk5TQzhxRTJicHQ5dFovRHNRUWxVTEQ4TXVvbkZjeTJJSkV2dUkweVpvPQ@SERVER_IP:12345


example of QR-code for Outline app


This will output a QR code that your users can scan with their Shadowsocks client, Camera app from their smartphone and open with Outline application.


Remember to send each user their own Shadowsocks URL or QR code and remind them to keep it secure. If a user's Shadowsocks URL or QR code is compromised, you should change their password and generate a new Shadowsocks URL and QR code for them.


OpenVPN and Shadowsocks

In certain situations, especially in countries where VPN connections are easily identified and blocked using Deep Packet Inspection (DPI), you may want to secure your OpenVPN connection inside a Shadowsocks tunnel. This configuration allows you to bypass VPN restrictions while specifying that only VPN traffic is sent through the Shadowsocks tunnel.


There are a few prerequisites for this to work:

  1. The OpenVPN server should be set to operate in TCP mode.
  2. The connection type should be tun, not tap.


When setting up OpenVPN to work with Shadowsocks, you'll need to add the following lines to your OpenVPN configuration file:

socks-proxy-retry 
socks-proxy 127.0.0.1 1080 
route SHADOWSOCKS_SERVER_IP 255.255.255.255 net_gateway


Let's break down what each line does:

  • socks-proxy-retry: This directive tells OpenVPN to retry the SOCKS proxy connection if it fails initially. This is especially useful for temporary network problems, as it helps ensure that your VPN connection isn't broken just because the SOCKS proxy connection failed once.
  • socks-proxy 127.0.0.1 1080: This is where socks-proxy tells OpenVPN to route its traffic through a SOCKS proxy. The IP address 127.0.0.1 is the loopback address, meaning the traffic is sent to the same device. The number 1080 is the port the SOCKS proxy listens on. So this line tells OpenVPN to send its traffic to the Shadowsocks proxy running on the same machine and listening on port 1080.
  • route SHADOWSOCKS_SERVER_IP 255.255.255.255 net_gateway: This command changes the system's routing table to ensure that traffic to the Shadowsocks server goes directly through the network gateway and not through the VPN. Replace SHADOWSOCKS_SERVER_IP with the actual IP address of your Shadowsocks server. The 255.255.255.255 is a subnet mask that specifies a single host. net_gateway refers to the system's default gateway. By adding these lines to the OpenVPN configuration, you'll ensure that VPN traffic is properly tunneled through the Shadowsocks proxy, providing a mechanism to bypass VPN blocks while maintaining the integrity of the VPN connection.


Here's an example of how you might need to modify your OpenVPN configuration file to facilitate this setup:

client
dev tun
proto tcp
remote VPN_SERVER_IP
port VPN_SERVER_PORT
nobind
compress lzo
cipher AES-256-CBC
auth SHA512
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256
remote-cert-tls server
tls-version-min 1.2
tls-client
key-direction 1
socks-proxy-retry
socks-proxy 127.0.0.1 1080  # port you have used in shadowsocks client for proxy
route SHADOWSOCKS_SERVER_IP 255.255.255.255 net_gateway

<ca>
...
</ca>

<tls-auth>
...
</tls-auth>

<cert>
...
</cert>

<key>
...
</key>


Remember to replace with your actual server "VPN_SERVER_IP", "VPN_SERVER_PORT", "SHADOWSOCKS_SERVER_IP", respectively.