ShadowSocks server setup notes, with 2025 updates
Contents
I used to build ShadowSocks servers when I was running a China-facing service. I found my old notes, so I am putting them here together with the current state of things.
What ShadowSocks is
ShadowSocks is a SOCKS5 proxy developed in 2012 by the Chinese programmer “clowwindy”. It is mainly used to bypass China’s internet censorship, the GFW (Great Firewall).
People often call it “ShadowSocks VPN” or “China VPN”, but strictly speaking it is a proxy, not a VPN. I know, I know, but “VPN” is the word that gets the point across faster.
Compared with a VPN:
- VPN: routes all traffic through an encrypted tunnel
- ShadowSocks: can proxy only selected apps or browsers, so it is lightweight and fast
From around 2019, ShadowSocks detection and blocking became serious in China, and successors such as V2Ray and Trojan have also appeared.
Server setup
These steps are for CentOS 7. I used a ConoHa VPS back then.
Install
Use teddysun’s install script:
wget --no-check-certificate -O shadowsocks.sh https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks.sh
chmod +x shadowsocks.sh
./shadowsocks.sh 2>&1 | tee shadowsocks.log
The installer will ask for a password, port, and encryption method.
Service management
# Start
/etc/init.d/shadowsocks start
# Stop
/etc/init.d/shadowsocks stop
# Restart
/etc/init.d/shadowsocks restart
# Status
/etc/init.d/shadowsocks status
Firewall
ConoHa disabled SELinux and iptables by default. If firewalld is enabled, stop it.
systemctl stop firewalld
systemctl disable firewalld
Or just open the port used by ShadowSocks:
firewall-cmd --permanent --add-port=8388/tcp
firewall-cmd --permanent --add-port=8388/udp
firewall-cmd --reload
DNS
To avoid name-resolution problems, add Google Public DNS:
vi /etc/resolv.conf
Add:
nameserver 8.8.8.8
nameserver 8.8.4.4
File descriptor limits
To raise concurrent connections:
vi /etc/security/limits.conf
Add:
root soft nofile 51200
root hard nofile 51200
Kernel tuning
vi /etc/sysctl.conf
Add:
# max open files
fs.file-max = 51200
# max read buffer
net.core.rmem_max = 67108864
# max write buffer
net.core.wmem_max = 67108864
# max processor input queue
net.core.netdev_max_backlog = 250000
# max backlog
net.core.somaxconn = 4096
# resist SYN flood attacks
net.ipv4.tcp_syncookies = 1
# reuse timewait sockets when safe
net.ipv4.tcp_tw_reuse = 0
# turn off fast timewait sockets recycling
net.ipv4.tcp_tw_recycle = 0
# short FIN timeout
net.ipv4.tcp_fin_timeout = 30
# short keepalive time
net.ipv4.tcp_keepalive_time = 1200
# outbound port range
net.ipv4.ip_local_port_range = 10000 65000
# max SYN backlog
net.ipv4.tcp_max_syn_backlog = 8192
# max timewait sockets held by system simultaneously
net.ipv4.tcp_max_tw_buckets = 5000
# TCP Fast Open
net.ipv4.tcp_fastopen = 3
# TCP memory
net.ipv4.tcp_mem = 25600 51200 102400
# TCP receive buffer
net.ipv4.tcp_rmem = 4096 87380 67108864
# TCP write buffer
net.ipv4.tcp_wmem = 4096 65536 67108864
# turn on path MTU discovery
net.ipv4.tcp_mtu_probing = 1
# TCP congestion control
net.ipv4.tcp_congestion_control = hybla
Apply the settings:
sysctl -p
Check logs
less -n /var/log/shadowsocks.log
Configuration file
The ShadowSocks config lives at /etc/shadowsocks.json.
{
"server": "0.0.0.0",
"server_port": 8388,
"password": "your_password",
"method": "aes-256-gcm",
"timeout": 300
}
If you want separate passwords per user, edit /etc/shadowsocks.json like this:
{
"server": "0.0.0.0",
"port_password": {
"8388": "user1_password",
"8389": "user2_password",
"8390": "user3_password"
},
"method": "aes-256-gcm",
"timeout": 300
}
Using different ports makes it easier to track who is using which connection.
Recommended settings in 2025
Encryption method
In the past, aes-256-cfb and chacha20 were common. Today I would recommend:
- AES-256-GCM: good balance of security and speed for servers
- ChaCha20-IETF-Poly1305: power-efficient for mobile devices and ARM CPUs
Avoid these older ciphers:
- RC4-based ciphers (
rc4-md5, etc.) - DES-based ciphers
- CFB mode (
aes-256-cfb, etc.) because of weak security
Kernel tuning improvements
The sysctl.conf settings above were fine at the time, but if I were doing it now I would change a few things.
Enable tcp_tw_reuse
# original
net.ipv4.tcp_tw_reuse = 0
# recommended
net.ipv4.tcp_tw_reuse = 1
This allows reuse of TIME_WAIT sockets. 0 still works, but 1 is more efficient. Keep tcp_tw_recycle set to 0 - the official wiki warns not to enable it.
Switch congestion control to BBR
# original
net.ipv4.tcp_congestion_control = hybla
# recommended (Linux 4.9+)
net.ipv4.tcp_congestion_control = bbr
hybla was a reasonable choice for very high-latency links such as satellite connections, and it was not unreasonable for China-Japan traffic either. But today Google’s BBR performs better. It is available on Linux 4.9 and later.
Notes
- Since 2019, China has used DPI (Deep Packet Inspection) to detect ShadowSocks
- The server IP itself may get blocked
- It is worth considering harder-to-detect protocols such as V2Ray, Trojan, or Xray
Successors
ShadowSocks led to protocols that focus more on bypassing censorship:
- V2Ray / Xray: support multiple protocols and can disguise traffic as HTTPS with WebSocket or gRPC
- Trojan: designed to fully imitate HTTPS traffic
They are more complex to configure, but they are useful in heavily restricted environments.
-> Continue with: V2Ray (WebSocket+TLS) server setup notes
-> Summary: Comparison of VPN protocols for China-facing connectivity
I am not publishing this because of tensions between Japan and China. Absolutely not.