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.
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.
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:
Faster connections and lower latency than OpenVPN
Lightweight, easy to set up and use
Suitable for bypassing censorship and securing internet traffic
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.
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.
Before setting up a Shadowsocks-rust server, make sure you have the following
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.
Using a terminal application, connect to your server via SSH. The command should look like this:
ssh root@your_server_ip
For our example, we will use port
sudo apt install ufw
sudo ufw enable
sudo ufw allow 12345
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
wget https://github.com/shadowsocks/shadowsocks-rust/releases/latest/download/shadowsocks-v1.15.3.aarch64-unknown-linux-gnu.tar.xz -P /opt/
wget https://github.com/shadowsocks/shadowsocks-rust/releases/latest/download/shadowsocks-v1.15.3.x86_64-unknown-linux-gnu.tar.xz -P /opt/
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:
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.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.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.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.
Please follow these steps:
mkdir /etc/shadowsocks-rust
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=
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"`
plain
or none
(No encryption, only used for debugging or with plugins that ensure transport security)
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.
Performance:
Security: Both
Compatibility:
In summary, for the average user, the choice between
Create a JSON configuration file for the shadowsocks server. Replace <PORT>
and <PASSWORD>
with the port number and password you chose earlier:
{
"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
}
{
"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.
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
systemctl status shadowsocks-server
systemctl restart shadowsocks-server
systemctl stop shadowsocks-server
Get the Outline Client App for your platform.
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:
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
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=
{
"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
}
}
for each user for the
{
"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
}
--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.
--qrcode
option:ssurl --encode path_to_user_config.json --qrcode
> ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTp4Nk5TQzhxRTJicHQ5dFovRHNRUWxVTEQ4TXVvbkZjeTJJSkV2dUkweVpvPQ@SERVER_IP:12345
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.
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:
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.