How to Deploy a Censorship Resistant Shadowsocks-libev Server

Authors: Anonymous

Last update: Sunday, February 28, 2021

中文版: 如何部署一台抗封锁的Shadowsocks-libev服务器

This tutorial documents how to install, configure and maintain a Shadowsocks-libev server. One cool thing about this tutorial is, by following this tutorial, your Shadowsocks-libev servers should be able to defend against various attacks, including active probing from the GFW and the partitioning oracle attack. Additionally, we compile a list of commonly asked questions, debunking common myths of Shadowsocks-libev.

Please consider bookmark this page because we commit to make this tutorial up-to-date and provide latest best practices to defend against emerging attacks. This tutorial is intended to be friendly to non-technical users. If you get lost at any step of this tutorial, please let us know and we will improve the documentation.


Install Snap

Snap is the officially recommended way to install Shadowsocks-libev.

  • If your server is running Ubuntu 16.04 LTS or later, Snap is already installed.
  • If your server is running some other Linux distributions, simply follow the corresponding installation instructions.

Now double check you have both snapd and Snap core installed:

sudo snap install core

Install Shadowsocks-libev

Now we install the latest Shadowsocks-libev from the edge channel:

sudo snap install shadowsocks-libev --edge


Below is the recommended configuration for Shadowsocks-libev server:


You need to replace the password ExamplePassword with a much stronger one. A strong password is recommended to mitigate the latest Partitioning Oracle Attacks against Shadowsocks servers. A handy way to generate a strong password from your terminal is: openssl rand -base64 16.

You may also want to change the server_port from 8388 to a different value between 1024 and 65535.

Now, open the default configuration file:

sudo nano /var/snap/shadowsocks-libev/common/etc/shadowsocks-libev/config.json

After copying and pasting your settings to the file, type Ctrl + x to exit. The text editor will ask "Save modified buffer?", and you can type y and then hit Enter.

The default configuration file path is too long to remember, and it is not well documented elsewhere yet. We thus encourage you to bookmark this page so that you can go back to check it whenever you want.


We use ufw to open ports for the Shadowsocks server.

To install ufw on a Debian-based server:

sudo apt update && sudo apt install -y ufw

Then open ports for ssh and Shadowsocks-libev. Note that if you set the server_port to a value different than 8388 in /var/snap/shadowsocks-libev/common/etc/shadowsocks-libev/config.json, you need to change the value 8388 below accordingly:

sudo ufw allow ssh
sudo ufw allow 8388/tcp

Now enable ufw:

sudo ufw enable

If it prompts Command may disrupt existing ssh connections. Proceed with operation (y|n)?, type y and hit Enter.

Finally, run sudo ufw status, and the output should look like this:

Status: active

To                         Action      From
--                         ------      ----
SSH                        ALLOW       Anywhere
8388/tcp                   ALLOW       Anywhere
SSH (v6)                   ALLOW       Anywhere (v6)
8388/tcp (v6)              ALLOW       Anywhere (v6)

Run Shadowsocks-libev

Now you can start the Shadowsocks-libev:

sudo systemctl start

Remember to let Shadowsocks-libev auto-start after a server reboot:

sudo systemctl enable


Check status and log

To check the status of the service:

sudo systemctl status

If you see Active: active (running) in green, your Shadowsocks-libev server is running properly; if you see Active: failed in red, jump to the end of journalctl -u to see what is wrong.

Reload configuration file

Whenever you change the configuration file, remember to restart Shadowsocks-libev to load the latest settings:

sudo systemctl restart


Q: Why did my server still get blocked when I followed your tutorial?

A: Usually, this shouldn’t be the case, as this tutorial can defend all known active probing attacks by the GFW. If this indeed happened, it is a clear sign that the censor has employed some unknown attacks against Shadowsocks-libev. Please report the block to us and we will carefully investigate it.

Q: Should I install Shadowsocks-libev from a distribution repo?

A: A distribution repo may not always include the latest version of Shadowsocks-libev. For example, as of January 2021, the version included in Debian buster repo was v3.2.5, which was not sufficient to defend active probings from the GFW (see Figure 10).

Q: How can I update Shadowsocks-libev via snap?

A: Usually you don’t have to update it manually because snap automatically updates all apps once per day. To manually update immediately: sudo snap refresh.

Q: Why do you use chacha20-ietf-poly1305?

A: Because it is one of the AEAD ciphers, which can defend the active probings by the GFW. It is also the default encryption method for both Shadowsocks-libev and OutlineVPN.

Q: Should I use any stream cipher in Shadowsocks?

A: No. It is unacceptably insecure. Even the latest version of Shadowsocks-libev operating in stream cipher mode is vulnerable to active probing (see Figure 10). More devastatingly, an attacker can get full decryption of recorded Shadowsocks sessions, without knowing the password.

Q: But my “airport” is still using stream cipher?

A: Then it is clear sign that your “airport” has very poor security awareness. Point the owners to this tutorial, as well as this post and this summary.

Q: Should I change the server_port to some common ports like 443?

A: No. The GFW can still suspect your Shadowsocks traffic, regardless of the server port you use.

Q: Why do you operate Shadowsocks-libev in tcp_only mode?

A: To mitigate the Partitioning Oracle Attacks against Shadowsocks servers, “the Shadowsocks developers took immediate action to disable UDP proxying where it was enabled by default”. As Vinicius pointed out, the partitioning oracle attack is not feasible when you have long random passwords, and it is recommended to “enable UDP support in order to enjoy better video calls”.

Q: Why do you disable fast_open?

A: We recommend that you read this rationale.


This report appeared first on GFW Report.

We encourage you to share your comments publicly or privately. Our private contact information can be found at the footer of GFW Report.