English translation of my post, original version in Russian is here.
Just a few words before we get started. You can skip this part if you want.
Introduction.
With internet regulation and censorship on the rise, states increasingly engaging in online surveillance, and state cyber-policing capabilities rapidly evolving globally, concerns about regulatory “chilling effects” online – the idea that laws, regulations, or state surveillance can deter people from exercising their freedoms or engaging in legal activities on the internet have taken on greater urgency and public importance [1]. Today, the most popular way to bypass Internet censorship are VPN services. However, they have quite significant drawbacks, which are completely or partially solved by setting up your own shadowsocks server. In this guide I will teach how to do it.
You can ask a reasonable question: why bother so much when there is a VPN services? So, to begin with, I will list the pros and cons of a VPN over a shadowsocks server:
Pros of VPN services:
The user does not need any technical knowledge and time-consuming configuration, just install a VPN client and use it. Setting up an SS server, especially with traffic obfuscation, requires some skills and knowledge that most users do not have.
Cons:
– VPN services can be slow, including the paid ones. I won’t even mention the free ones, as they are often extremely slow and may not provide adequate privacy protection. ISPs may intentionally throttle the speed of suspicious encrypted traffic originating from VPNs. This issue can be addressed by employing traffic obfuscation through basic TLS encryption, which appears legitimate to your ISP.
– VPNs are not entirely secure. If someone is determined, they can find you relatively quickly: either the VPN service might hand over your information to authorities, or your ISP could track you using a so-called “correlation attack.” This is when an ISP compares the IP address a user utilizes to access certain online content or visit a restricted website with the IP addresses connected at that time, enabling the ISP to potentially identify an internet dissident’s real IP address. In this context, SS + v2ray + tls is a safer option for users residing in totalitarian countries like Russia or China. By the way, the Shadowsocks protocol and v2ray were developed by users in China.
Besides speed and security, circumventing internet censorship and surveillance with SS+v2ray can be absolutely free! You just need to find a shareware virtual server (for example, Oracle Cloud, which has an unlimited trial period) and a free domain (such as a .tk domain provided by Freenom). However, using free services can be somewhat risky since you don’t have full ownership, and both the VPS and domain could be taken away from you at any moment.
Steps to set up your SS server:
– Getting a virtual server (VPS) running on Debian (you can use any distro you want, but in this tutorial I’m using Debian 10)
– Getting a domain (you can go with any domain, Freenom’s .tk for example)
– Signing up on Cloudflare and linking the domain there
– Deploying the shadowsocks and a web server on the VPS
– Getting a free SSL certificate and setting up traffic obfuscation
– Setting up a client for windows/android/ios/linux.
Let’s get started.
Getting a virtual server (VPS)
Any inexpensive virtual server provider will do. Oracle Cloud and Microsoft Azure are fine and they’re free too! (though, there is a limit on the amount of traffic). There is nothing complicated in getting a virtual server, just make sure that you are provided with a dedicated static IP address and have open ports 80, 443 and 22 (usually they are opened by default). You can also choose a suitable VPS from this list: https://bitcoin-vps.com/
Getting a domain
Get any domain you want, .tk domains are free (you can get one here: https://www.freenom.com)
Signing up on Cloudflare and linking the domain (adding DNS records)
As an example, let’s take the bernd32.xyz domain. To do this, in the cloudflare, specify the IP address of our SS server, one is just bernd32.xyz, the second is www.bernd32.xyz, click next.
In this guide I’ll use one of my domains bernd32.xyz, replace with your own. We need to make two DNS records:
1) “A” record with the name “www” and IP address of your VPS
2) “A” record with the name “bernd32.xyz” and IP address of your VPS
Next, click “Continue.” Afterward, Cloudflare will generate name servers that should be entered into the control panel of your domain registrar. If you obtained your free .tk domain from Freenom, the control panel page might look something like this:
Wait for a few hours for the DNS records to update. In the meantime, let’s navigate to the Cloudflare Firewall settings and change the Security level to “Essentially Off”:
That’s it.
Setting up the shadowsocks and a web server for traffic obfuscation
First, we need to open incoming ports on the firewall of your VPS. If you’re an inexperienced user, create a snapshot of your virtual server before proceeding. If something goes wrong (for example, if you can’t connect to the VPS via SSH), you can easily restore it to the point when everything was working fine. Keep in mind that on some VPS providers (such as Oracle Cloud and Microsoft Azure), ports need to be opened not only on the server itself but also in the control panel. For instance, in Oracle, this is done through the Security List: https://docs.oracle.com/en-us/iaas/Content/Network/Concepts/securitylists.htm
However, the required ports are usually open by default.
Remember that all commands in the terminal are executed using root.
Moreover, you shouldn’t blindly copy the commands below. Always carefully consider what you are entering in the terminal.
Connect to our server by SSH:
ssh root@<ip of your VPS>
for example:
ssh root@23.78.206.154
Add ports for http and https. The easiest way to do this is through UFW. Install UFW if don’t have this package:
apt install ufw
Opening ports with ufw:
ufw allow 443/tcp
ufw allow 443/udp
ufw allow 80/tcp
ufw allow 80/udp
ufw allow ssh
ufw enable
Installing nginx as your web server:
apt update && sudo apt upgrade apt install nginx
Remove the default config file:
rm /etc/nginx/sites-available/default && sudo rm /etc/nginx/sites-enabled/default
If you got error rm: cannot remove ‘/etc/nginx/sites-available/default’: No such file or directory, then create the needed directories:
mkdir /etc/nginx/sites-available
mkdir /etc/nginx/sites-enabled
Make a directory in which your website files will be stored:
sudo mkdir /var/www/<your_domain>
Create index.html file there:
nano /var/www/<your_domain>/index.html
Edit index.html and write down anything you want, it doesn’t really matter. Here’s my example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1> Ололо! Всё работает</h1>
</body>
</html>
Open the nginx’s config file (/etc/nginx/nginx.conf) and specify our website config directory in http module:
include /etc/nginx/sites-enabled/*;
Make config for your nginx website:
nano /etc/nginx/sites-available/<your_domain>
Paste to the config file (don’t forget to change <your_domain>):
server {
listen 80;
#listen [::]:80;
server_name <your_domain>;
root /var/www/<your_domain>;
index index.html;
location /anime {
proxy_redirect off;
proxy_http_version 1.1;
proxy_pass http://localhost:8008;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Enable the website:
ln -s /etc/nginx/sites-available/<домен> /etc/nginx/sites-enabled/
Restart nginx:
sudo systemctl restart nginx
Your website should be working right know. Check it in your browser:
If everything was successful, proceed to the next part – setting up Shadowsocks. I recommend creating a snapshot of your VPS so that if something goes wrong, you can roll back. If something has gone wrong and the site does not load, it’s possible that you have misconfigured the firewall settings or that the iptables settings are conflicting with the UFW.You can try to return the default policies of iptables (DON’T DO IT IF EVERYTHING WORKS FINE SO FAR):
iptables --policy INPUT ACCEPT;
iptables --policy OUTPUT ACCEPT;
iptables --policy FORWARD ACCEPT;
iptables -Z;
iptables -F;
iptables -X;
Setting up shadowsocks (ss)
Make the directory for SS binaries:
mkdir /etc/ss-go
Download SS binaries from GitHub:
wget https://github.com/shadowsocks/go-shadowsocks2/releases/download/v0.1.5/shadowsocks2-linux.gz
Unpack the archive:
gzip -d shadowsocks2-linux.gz
Move and rename the binary directory:
mv shadowsocks2-linux /etc/ss-go/ss-go
Make the binary files executable:
chmod +x /etc/ss-go/ss-go
Elevate permissions and allow it to occupy privileged ports:
setcap "cap_net_bind_service=+eip" /etc/ss-go/ss-go
Installing v2ray plugin:
Download the plugin (here instead of “v1.3.1/v2ray-plugin-linux-amd64-v1.3.1.tar.gz” may be something else, the latest version is here: https://github.com/shadowsocks/v2ray-plugin/releases/latest)
wget https://github.com/shadowsocks/v2ray-plugin/releases/download/v1.3.1/v2ray-plugin-linux-amd64-v1.3.1.tar.gz
Unpack the archive:
tar -xf v2ray-plugin-linux-amd64-v1.3.1.tar.gz
Rename and move:
mv v2ray-plugin_linux_amd64 /etc/ss-go/v2ray-plugin
Set file capabilities for the plugin:
setcap "cap_net_bind_service=+eip" /etc/ss-go/v2ray-plugin
Create ss-v2ray service file :
nano /etc/systemd/system/ss-v2ray.service
File contents (don’t forget to replace <password> with your actual password for shadowsocks):
[Unit]
Description=Go-shadowsocks2 with V2RAY-websocket obfuscation
After=network.target
[Service]
Type=simple
User=nobody
Group=nogroup
LimitNOFILE=51200
ExecStart=/etc/ss-go/ss-go -s localhost:8008 -password <password> -cipher AEAD_CHACHA20_POLY1305 -plugin /etc/ss-go/v2ray-plugin -plugin-opts "server;loglevel=none;path=/anime"
[Install]
WantedBy=multi-user.target
Save the file and enable the service:
systemctl enable ss-v2ray.service
Setting up shadowsocks client on Windows.
Download and install the latest version of shadowsocks client for Windows here: https://github.com/shadowsocks/shadowsocks-windows/releases
Download the latest version of v2ray plugin: https://github.com/shadowsocks/v2ray-plugin/releases
Move the v2ray-plugin_windows_amd64.exe file to the same folder with the Shadowsocks.exe ss-client executable file.
Enter the following data in the settings fields
server addr - <domain>
server port - 443
password - <your password from previous steps>
encryption - chacha20-ietf-poly1305
plugin program - v2ray-plugin_windows_amd64.exe
plugin options - tls;host=<domain>;path=/anime
proxy port - local proxy port that will be used in browser, your system settings etc. (1080 by default)
It should be something like this:
Getting SSL let’s encrypt certificate using certbot:
apt install snapd
snap install core
snap refresh core
snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot
certbot --nginx
After that, the terminal should have a congratulation message, it will also show the path to the certificate:
A few words about the renewal of the certificate. In theory, the certificate should be automatically updated by the certbot daemon sitting in the server processes, but if automatic renewal did not work for some reason, then you can do it manually with just one command:
certbot renew
If you have several domains and you need to renew the certificate for a specific domain, then the command will look something like this:
certbot certonly --force-renew -d example.com
Restart nginx:
systemctl restart nginx
Restart v2ray:
systemctl restart ss-v2ray
Completing the setup of Cloudflare.
In the settings of your domain on cloudflare, in the SSL / TLS section, set Full (strict):
Go to your site, make sure everything works:
Specify proxy settings in the applications that you want to proxy. For example, in Firefox it looks like this (don’t mind the “No proxy for” field:
You can also proxy the whole Windows if you want.
That’s it! If you go to your site, it should open with https. Now your ISP sees a legit https traffic from you to Cloudflare servers, and if Freenom decides to scan our domain, it will find our page (Freenom can take away the domain if the site on the domain is empty).
[1] Penney, Jonathon W.. 2017. “Internet surveillance, regulation, and chilling effects online: a comparative case study”. Internet Policy Review 6 (2). DOI: 10.14763/2017.2.692. https://policyreview.info/articles/analysis/internet-surveillance-regulation-and-chilling-effects-online-comparative-case.