How to Setup Shadowsocks
In this age of ideology and censorship, those of us who are still looking for the truth or at least in want to expose ourselves to lies from another perspective, are able to use a tool called Shadowsocks.
This is a free and open-source protocol widely used in several totalitarian countries to circumbent Internet censorship.
Most mainstream users will probably use a system such as NordVPN to achieve this.
However, Shadowsocks has the advantage of being more focused on traffic obfuscation given that it shows itself as pure HTTPS traffic as well as being more private if you take the DIY route.
The server
In my case I installed it on a VPS running Arch Linux.
After setting up the yay
packet manager, I installed shadowsocks-rust
from the AUR to have the actively developed implementation of the server.
Then I did the same on my client computer.
On the server I used a configuration similar to the following at /etc/shadowsocks-rust/config_rust.json
{
"server": "my_server_ip_or_domain",
"server_port": "port_where_shadowsocs_server_listens",
"password": "A randomly generated and secure password",
"method": "aes-256-gcm",
"user" : "A non-root user"
}
Tip: You can generate a pretty strong password with the following one liner in Linux.
tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~' </dev/urandom | head -c 64 ; echo
In order to launch the server, it is enough to run:
sudo ssserver -c /etc/shadowsocks-rust/config.json
The port choice for the service will depend on what ports are kept open on the firewall you are trying to evade. Normally, these will be HTTP and HTTPS ports for web related access, which are ports 80 and 443 respectively.
Notice that if your server port is lower than 1024, you will need to run this command as root. However, this is not a secure approach regarding internet-facing services.
There are several solutions for this issue.
The first one is to use a tool such as authbind
to bind sockets to priviledged ports without root.
The second one is to tell the shadowsocks server to listen in localhost, then setup an inverse proxy using nginx
or iptables
which are simpler utilities with a greater degree of trust.
If the machine runs additional services, the second solution might be the most scalable.
But right now this is the only service I plan to run on this machine, so wrapping the binary within authbind
is the fastest way to get this thing going in a relatively secure manner.
In order for this trick to work, we need to do some preparations first.
Giving access to port 443 the steps would be:
sudo touch /etc/authbind/byport/443
sudo chmod 777 /etc/authbind/byport/443
Then, as the user you want to execute as, run:
authbind --deep ssserver -c /etc/shadowsocks-rust/config.json
You can see that the server is running in usermode by checking the user with this command:
ps -aux | grep shadow
Manage with systemd
We can use systemd order to automatically start the service if the server is restarted, also to stop it and to start it as a daemon from the command line.
Create this file at /etc/systemd/system/shadowsocks-server.service
.
Unit]
Description=Shadowsocks Server
After=network.target
[Service]
ExecStart=/usr/bin/authbind --deep /usr/bin/ssserver -c /etc/shadowsocks-rust/config.json
Restart=always
User=nonroot
[Install]
WantedBy=multi-user.target
The enable it and start it via:
sudo systemctl enable /etc/systemd/system/shadowsocks-server.service
sudo systemctl start shadowsocks-server.service
Verify the service is online via:
sudo systemctl status shadowsocks-server.service
The client
I did set the same configuration file on the client with a couple more parameters in order to specify the local port and address of the SOCKS server.
{
"server": "my_server_ip_or_domain",
"server_port": "port_where_shadowsocs_server_listens",
"local_port": "localhost port where the socks5 proxy is set",
"local_address": "127.0.0.1",
"password": "A randomly generated and secure password",
"timeout": 300,
"method": "aes-256-gcm"
}
Given that the client service is not required to open priviledged ports, you do not need to use authbind
and can use ports over 1024 in localhost.
You can use the following command and can convert it into a systemd service as explained in the previous section.
/usr/bin/sslocal -c /etc/shadowsocks-rust/config_rust.json
In order to test that you have been successful, you may go to the proxy settings of your system and set them to the local address and port in your client configuration.
Then you can ask google what is your ip and verify that it is indeed the one of the server, as proof that your HTTP requests are being routed through it.