Deploying a lightweight proxy like Shadowsocks on AWS EC2 gives you a fast, low-latency way to encrypt TCP traffic and securely route client requests. This guide walks you through a complete, production-ready deployment on Ubuntu EC2 instances: launching the server, installing and configuring shadowsocks-libev, opening the right ports in AWS Security Groups and the OS firewall, creating a systemd service, adding obfuscation for censorship resistance, and best practices for security and performance.

Prerequisites and planning

Before you begin, make sure you have the following:

  • An AWS account with permissions to create EC2 instances and Security Groups.
  • Basic familiarity with SSH, Linux commands, and editing files with vi or nano.
  • The AWS region you select should be appropriate for your users (latency considerations).
  • Knowledge of compliance and local laws: using proxies may have legal restrictions in some jurisdictions.

Step 1 — Launch an EC2 instance

For most use cases, a small instance is sufficient. Recommended starting point:

  • AMI: Ubuntu 22.04 LTS (or 20.04 LTS where appropriate).
  • Instance type: t3.micro or t3a.small for low-cost; scale up to c5 or m5 families for high throughput.
  • Storage: 8–20 GB EBS General Purpose SSD (gp3).
  • Networking: assign a public IPv4 (or Elastic IP if you need a static IP).
  • Key pair: create or reuse an SSH key pair for root/ubuntu access.

When configuring Security Groups, add an inbound rule for the port you’ll use for Shadowsocks (for example, port 8388 TCP) and SSH (port 22). For UDP relay you may also need to allow UDP on the same port.

Step 2 — Connect to your instance

SSH into the instance from your local machine:

ssh -i /path/to/your-key.pem ubuntu@YOUR_EC2_PUBLIC_IP

Update packages:

sudo apt update && sudo apt upgrade -y

Step 3 — Install shadowsocks-libev

We recommend shadowsocks-libev; it’s lightweight, actively maintained, and suitable for production. Install from the official Ubuntu packages or the project repo for newer versions.

Install via apt (Ubuntu 22.04+):

sudo apt install -y shadowsocks-libev

If you need the latest release, add the upstream repository or build from source. For most deployments the packaged version is fine.

Required utilities

Install common tools:

sudo apt install -y ufw jq curl htop

Step 4 — Configure Shadowsocks

Create a JSON configuration file for the server. The file is usually located at /etc/shadowsocks-libev/config.json (path may vary by distribution).

Example configuration with recommended settings:

{
"server":"0.0.0.0",
"server_port":8388,
"password":"A_STRONG_RANDOM_PASSWORD_HERE",
"timeout":300,
"method":"chacha20-ietf-poly1305",
"fast_open":false,
"no_delay":true,
"nameserver":"1.1.1.1",
"mode":"tcp_and_udp",
"plugin":"/usr/bin/v2ray-plugin",
"plugin_opts":"server;tls;host=example.com"
}

Key notes:

  • server: bind to 0.0.0.0 to accept connections on all interfaces (or bind to the Elastic IP for extra control).
  • server_port: choose a non-standard port (not 80/443) to reduce noise. For TCP+UDP use "mode":"tcp_and_udp".
  • password: use a long, randomly generated passphrase. Consider a password manager or a 32+ character string.
  • method: choose an AEAD cipher. chacha20-ietf-poly1305 is recommended for performance on non-x86 devices; aes-256-gcm is also supported.
  • fast_open: enabling TCP Fast Open can reduce latency but requires kernel support and careful testing.
  • plugin: enable v2ray-plugin or obfs-local to add obfuscation (see below).

Step 5 — Open ports in AWS Security Group and instance firewall

In the AWS Console, update your instance’s Security Group:

  • Inbound: SSH (22 TCP) from your admin IP only.
  • Inbound: Shadowsocks port (e.g., 8388) — allow TCP and UDP from the expected client IP ranges. If you must allow the whole internet, consider rate limiting and monitoring.

On the server, enable UFW and allow the ports:

sudo ufw allow OpenSSH
sudo ufw allow 8388/tcp
sudo ufw allow 8388/udp
sudo ufw enable

Verify rules with sudo ufw status verbose.

Step 6 — Start and enable the shadowsocks service

Start the installed service using systemd (names may differ by package, commonly shadowsocks-libev or ss-server):

sudo systemctl restart shadowsocks-libev
sudo systemctl enable shadowsocks-libev
sudo systemctl status shadowsocks-libev

If you installed shadowsocks manually, create a systemd unit at /etc/systemd/system/shadowsocks.service with content like:

[Unit] Description=Shadowsocks-libev Service
After=network.target

[Service] Type=simple
ExecStart=/usr/bin/ss-server -c /etc/shadowsocks-libev/config.json
Restart=on-failure
LimitNOFILE=32768

[Install] WantedBy=multi-user.target

Then run:

sudo systemctl daemon-reload
sudo systemctl enable --now shadowsocks.service

Step 7 — Add obfuscation (optional but recommended)

Many networks perform DPI to detect Shadowsocks. Use a transport-layer obfuscation plugin such as v2ray-plugin or obfs-local. v2ray-plugin supports TLS and WebSocket modes which help mimic normal HTTPS/Web traffic.

Install v2ray-plugin on Ubuntu:

sudo apt install -y v2ray-plugin

Server-side config example (plugin): "plugin":"v2ray-plugin","plugin_opts":"server;tls;host=your.domain.com"

On the client, mirror the plugin settings, and make sure you own a TLS certificate for your domain (use Let’s Encrypt and certbot) if you enable TLS for v2ray-plugin.

Step 8 — Client configuration and testing

Client apps exist for Windows, macOS, Linux, Android, and iOS. Use a modern client that supports AEAD ciphers and plugins.

Minimal client config:

  • Server: YOUR_EC2_PUBLIC_IP or domain
  • Port: 8388
  • Password: same as server
  • Encryption: chacha20-ietf-poly1305 (or matching server cipher)
  • Plugin: configure the same plugin and plugin options as server

Verify connectivity with:

curl --socks5-hostname 127.0.0.1:1080 https://ifconfig.co

or by configuring the system proxy and visiting an IP geolocation page to confirm the server IP is shown.

Troubleshooting common issues

Cannot connect

  • Check AWS Security Group inbound rules and UFW status.
  • Confirm the server is listening: sudo ss -tunlp | grep ss-server or sudo lsof -i -P -n | grep 8388.
  • Check logs: sudo journalctl -u shadowsocks-libev -b or sudo tail -f /var/log/syslog.

High latency or poor throughput

  • Try a different cipher: AES-GCM on x86 can be faster with hardware AES-NI; ChaCha20 is good for mobile/ARM.
  • Increase instance network performance (move to a higher instance class).
  • Enable TCP Fast Open if kernel and client support it; test carefully.
  • Use multiple EC2 instances across regions and implement load balancing or failover.

Plugin or TLS errors

  • Confirm the plugin binary path and permissions.
  • Check certificate files and domain mapping if using TLS.
  • Use openssl s_client -connect your.domain.com:443 to inspect TLS handshake if v2ray-plugin uses TLS.

Security hardening and operational best practices

  • Use a strong password and rotate it periodically. Consider authenticated users with unique credentials if running a multi-user service.
  • Limit SSH access with Security Group rules or a AllowUsers directive in /etc/ssh/sshd_config. Consider disabling password login and using SSH keys only.
  • Run Shadowsocks under an unprivileged user or use systemd directives that limit capabilities (e.g., NoNewPrivileges=yes, ProtectSystem=full).
  • Monitor logs and connections. Tools like netdata or CloudWatch can provide visibility into bandwidth and anomalous spikes.
  • Set resource limits in systemd (LimitNOFILE, CPU and memory limits) to mitigate abuse.
  • Consider rate-limiting with iptables/nftables or tools like fail2ban for brute-force defense on exposed ports.

Scaling and advanced features

If you need higher capacity or redundancy:

  • Run multiple Shadowsocks servers in different AZs/regions and use DNS-based failover or a load balancer (note: ELB/ALB is not ideal for UDP).
  • Use a small upstream proxy or SOCKS multiplexers to aggregate connections.
  • Automate provisioning with Terraform for reproducible deployments and predictable networking/security group configuration.
  • Integrate with monitoring and alerting (CloudWatch metrics, Prometheus exporters) to detect performance regressions.

Compliance and legal considerations

Remember that running an encrypted proxy can have legal and policy implications depending on your jurisdiction and customer use. Ensure you have acceptable use policies, data retention and logging policies where required, and legal counsel if deploying for a business or public audience.

Deploying Shadowsocks on AWS EC2 is straightforward when you follow secure practices: use modern AEAD ciphers, enable obfuscation plugins if necessary, lock down networking, and run the service as a systemd-managed daemon. With proper monitoring, automated provisioning, and a conservative exposure policy, Shadowsocks can provide a performant and secure transport for your users.

For more in-depth tutorials and VPN-related guides, visit Dedicated-IP-VPN.