Hack the Great Firewall
Shadowsocks is a versatile open-source proxy tool designed to bypass internet censorship and provide users with secure and private access to the internet. It works by creating an encrypted tunnel between the user’s device and a remote server, allowing them to circumvent firewalls and access blocked content. With its lightweight and efficient design, Shadowsocks has become a popular choice for individuals seeking to maintain anonymity and freedom while browsing the web, particularly in regions with strict online censorship policies.
Shadowsocks differs from traditional Virtual Private Networks (VPNs) in several key ways. While both technologies aim to provide users with secure and private access to the internet, they employ different methods to achieve this goal.
Shadowsocks can indeed be utilized to encrypt all traffic passing through a device, providing a quick and efficient means of maintaining encryption, even on unsecured or unsafe WiFi connections. By encrypting all traffic, Shadowsocks helps to safeguard sensitive information and protect user privacy, regardless of the network environment. This can be particularly valuable when connecting to public WiFi networks in cafes, airports, or other shared spaces where security may be a concern. In such scenarios, Shadowsocks offers a convenient and effective solution for ensuring that selective data transmitted over the network remains secure and private.
However, differently than VPNs with full-redirection of traffic, clients are responsible to configure which traffic is going to be forwarded to the local proxy to ensure it is encrypted and forwarded through the proxy server.
Shadowsocks works over TCP/UDP at the application level of the ISO/OSI stack and this is visible up to the clients applications (for example, browsers). VPNs also work on TCP/UDP connection at an application level for the actual client-server communication, but the client OS masks this communication by leveraging the network stack in the Kernel: usually, a virtual network interface is created and the route table is modified such that all the traffic is sent through the gateway reachable through the virtual network interface, except the actual communication with the VPN server.
Shadowsocks Clients run another server locally to encrypt any traffic directed through them and forward it in the other side to the Shadowsocks Server that will de-encapsulate the request, forward to the final destination and then back to the client, re-encrypted.
So far, this has been the quickest way for me to hack the great firewall and access censored websites while in China.
Fully-encrypted VPNs are blocked very quickly thanks to the anomaly detection systems the Chinese telecommunication companies run in their networks.
Shadowsocks servers could be banned too: I got a server in a Japan data-center banned after a few hours. Another, though, is still active and reachable after months of activity.
Deploying the Shadowsocks server on Microshift⌗
Microshift is a project by Red Hat that optimizes OpenShift, a container orchestration platform based on Kubernetes, for small form-factor devices and edge computing environments.
Microshift focuses on Resource Efficiency, providing a very reduced set of APIs compared to the Openshift ones and is based on almost null set of cluster operators. I use to deploy it on my cheap virtual private servers through a dedicated Fedora CoreOS container image leveraging layering.
In the context of deploying a Shadowsocks server, we can consider it just as another Kubernetes distribution that we can run on our servers.
Here are the minimum manifests I managed to use for deploying this solution on my deployment:
RBAC⌗
Like Openshift, Microshift implements SecurityContextConstraints (SCC) to enforce the capabilities of pods. As Shadowsocks servers require specific Linux capabilities, we need to allow the service account running it to use the privileged SCC:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: scc-privileged-shadowsocks
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:openshift:scc:privileged
subjects:
- kind: ServiceAccount
name: default
namespace: shadowsocks
Configuration secret⌗
The configuration of Shadowsocks is well-described in their documentation. We can use a secret to store the configuration and mount it later in the deployment object:
kind: Secret
apiVersion: v1
metadata:
name: shadowsocks-conf
stringData:
config.json: |
{
"server": [ "::", "0.0.0.0" ],
"mode": "tcp_and_udp",
"server_port": 8388,
"local_port": 1080,
"password": "CHANGE-ME---CHANGE-ME",
"timeout": 86400,
"method": "xchacha20-ietf-poly1305"
}
As you can see, shadowsocks can work on both UDP and TCP.
Service⌗
We can rely on NodePort services to expose shadowsocks.
kind: Service
apiVersion: v1
metadata:
name: shadowsocks
spec:
type: NodePort
selector:
app: shadowsocks
ports:
- port: 8388
targetPort: 8388
nodePort: 32000
protocol: TCP
- port: 8388
targetPort: 8388
nodePort: 32000
protocol: UDP
Be careful on dedicating a proper NodePort that is not already bound and statically such that it is easier for you to compute the endpoint for the client
Deployment⌗
kind: Deployment
apiVersion: apps/v1
metadata:
name: shadowsocks
spec:
selector:
matchLabels:
app: shadowsocks
template:
metadata:
labels:
app: shadowsocks
spec:
containers:
- name: shadowsocks
securityContext:
runAsUser: 999
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
add:
- NET_RAW
image: docker.io/shadowsocks/shadowsocks-libev:v3.3.5
command:
- /usr/bin/ss-server
- -c
args:
- /etc/shadowsocks/config.json
volumeMounts:
- mountPath: /etc/shadowsocks
name: shadowsocks-conf
readinessProbe:
tcpSocket:
port: 8388
livenessProbe:
tcpSocket:
port: 8388
volumes:
- name: shadowsocks-conf
secret:
secretName: shadowsocks-conf
defaultMode: 0444
Clients⌗
Mobile⌗
There are mobile applications available to connect to the web through the Shadowsocks server. You will mostly have to
resemble the same configuration as in the config.json
stored in the secret and refer to the IP of the server for the
connection.
It’s worth noting it that chinese-specific applications like WeChat and AliPay may detect you on another country, leading some services like payment services to fail. Be sure of excluding these applications in the Shadowsocks client app configuration.
Linux Desktops⌗
You can run the client via Podman/Docker using a similar configuration file to the one for the server:
{
"server": [ "SERVER_IP" ],
"mode": "tcp_and_udp",
"server_port": 32000,
"local_port": 1080,
"password": "CHANGE-ME---CHANGE-ME",
"timeout": 86400,
"method": "xchacha20-ietf-poly1305"
}
server_port
is set to the NodePort chosen as in the previous section.
For example, assuming the json file is stored at /home/user/shadowsocks.json, you can run
podman run -p 1080:1080 -v /home/user/shadowsocks.json:/etc/shadowsocks.json:Z -it \
docker.io/shadowsocks/shadowsocks-libev:v3.3.5 /usr/bin/ss-local -c /etc/shadowsocks.json
As anticipated, you will have to specify each application that you want to go through the proxy:
http_proxy=socks5h://localhost:1080 https_proxy=socks5h://localhost:1080 curl https://ifconfig.me
You can configure your browser, or any other applications to forward traffic through the local proxy.
Here in the following, a systemd unit that I use to run the server locally:
[Unit]
Description=Runs the Shadowsocks client
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers
AssertPathExists=/etc/shadowsocks.json
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
ExecStartPre=/usr/bin/podman rm -f --ignore shadowsocks-client
ExecStart=/usr/bin/podman run \
-p 127.0.0.1:1080:1080/tcp
--name shadowsocks-client -v /etc/shadowsocks.json:/etc/shadowsocks.json:Z \
docker.io/shadowsocks/shadowsocks-libev:v3.3.5 \
/usr/bin/ss-local -c /etc/shadowsocks.json
ExecStop=/usr/bin/podman stop --ignore shadowsocks-client
ExecStopPost=/usr/bin/podman rm -f --ignore shadowsocks-client
Restart=always
RestartSec=5
Type=simple
[Install]
WantedBy=default.target
Linux users will be familiar on how to configure their environment to forward the traffic properly.